135 lines
4.3 KiB
C
135 lines
4.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
/*
|
|
* Rockchip DLP (Digital Loopback) driver
|
|
*
|
|
* Copyright (C) 2022 Rockchip Electronics Co., Ltd.
|
|
* Author: Sugar Zhang <sugar.zhang@rock-chips.com>
|
|
*
|
|
*/
|
|
|
|
#ifndef _ROCKCHIP_DLP_H
|
|
#define _ROCKCHIP_DLP_H
|
|
|
|
#include "rockchip_dlp_pcm.h"
|
|
|
|
#define DLP_MAX_DRDS 8
|
|
|
|
/* MUST: enum dlp_mode should be match to dlp_text */
|
|
enum dlp_mode {
|
|
DLP_MODE_DISABLED,
|
|
DLP_MODE_2CH_1LP_1MIC, /* replace cap-ch-0 with play-ch-0 */
|
|
DLP_MODE_2CH_1MIC_1LP, /* replace cap-ch-1 with play-ch-1 */
|
|
DLP_MODE_2CH_1MIC_1LP_MIX, /* replace cap-ch-1 with play-ch-all-mix */
|
|
DLP_MODE_2CH_2LP, /* replace cap-ch-0~1 with play-ch-0~1 */
|
|
DLP_MODE_4CH_2MIC_2LP, /* replace cap-ch-2~3 with play-ch-0~1 */
|
|
DLP_MODE_4CH_2MIC_1LP_MIX, /* replace cap-ch-3 with play-ch-all-mix */
|
|
DLP_MODE_4CH_4LP, /* replace cap-ch-0~3 with play-ch-0~3 */
|
|
DLP_MODE_6CH_4MIC_2LP, /* replace cap-ch-4~5 with play-ch-0~1 */
|
|
DLP_MODE_6CH_4MIC_1LP_MIX, /* replace cap-ch-4 with play-ch-all-mix */
|
|
DLP_MODE_6CH_6LP, /* replace cap-ch-0~5 with play-ch-0~5 */
|
|
DLP_MODE_8CH_6MIC_2LP, /* replace cap-ch-6~7 with play-ch-0~1 */
|
|
DLP_MODE_8CH_6MIC_1LP_MIX, /* replace cap-ch-6 with play-ch-all-mix */
|
|
DLP_MODE_8CH_8LP, /* replace cap-ch-0~7 with play-ch-0~7 */
|
|
DLP_MODE_10CH_8MIC_2LP, /* replace cap-ch-8~9 with play-ch-0~1 */
|
|
DLP_MODE_10CH_8MIC_1LP_MIX, /* replace cap-ch-8 with play-ch-all-mix */
|
|
DLP_MODE_16CH_8MIC_8LP, /* replace cap-ch-8~f with play-ch-8~f */
|
|
};
|
|
|
|
struct dlp;
|
|
|
|
struct dlp_runtime_data {
|
|
struct dlp *parent;
|
|
struct kref refcount;
|
|
struct list_head node;
|
|
char *buf;
|
|
snd_pcm_uframes_t buf_sz;
|
|
snd_pcm_uframes_t last_buf_sz;
|
|
snd_pcm_uframes_t period_sz;
|
|
int64_t hw_ptr;
|
|
int64_t hw_ptr_delta; /* play-ptr - cap-ptr */
|
|
atomic64_t period_elapsed;
|
|
atomic_t stop;
|
|
unsigned int frame_bytes;
|
|
unsigned int channels;
|
|
unsigned int buf_ofs;
|
|
int stream;
|
|
};
|
|
|
|
struct dlp {
|
|
struct device *dev;
|
|
struct list_head drd_avl_list;
|
|
struct list_head drd_rdy_list;
|
|
struct list_head drd_ref_list;
|
|
struct dlp_runtime_data drds[DLP_MAX_DRDS];
|
|
struct dlp_runtime_data *drd_pb_shadow;
|
|
struct snd_soc_component component;
|
|
const struct snd_dlp_config *config;
|
|
enum dlp_mode mode;
|
|
int drd_avl_count;
|
|
atomic_t active;
|
|
spinlock_t lock;
|
|
};
|
|
|
|
typedef snd_pcm_uframes_t (*dma_pointer_f)(struct snd_soc_component *component,
|
|
struct snd_pcm_substream *substream);
|
|
|
|
static inline struct dlp *soc_component_to_dlp(struct snd_soc_component *p)
|
|
{
|
|
return container_of(p, struct dlp, component);
|
|
}
|
|
|
|
static inline struct dlp_runtime_data *substream_to_drd(
|
|
const struct snd_pcm_substream *substream)
|
|
{
|
|
if (!substream || !substream->runtime)
|
|
return NULL;
|
|
|
|
return substream->runtime->private_data;
|
|
}
|
|
|
|
static inline ssize_t dlp_channels_to_bytes(struct dlp_runtime_data *drd,
|
|
int channels)
|
|
{
|
|
return (drd->frame_bytes / drd->channels) * channels;
|
|
}
|
|
|
|
static inline ssize_t dlp_frames_to_bytes(struct dlp_runtime_data *drd,
|
|
snd_pcm_sframes_t size)
|
|
{
|
|
return size * drd->frame_bytes;
|
|
}
|
|
|
|
static inline snd_pcm_sframes_t dlp_bytes_to_frames(struct dlp_runtime_data *drd,
|
|
ssize_t size)
|
|
{
|
|
return size / drd->frame_bytes;
|
|
}
|
|
|
|
void dlp_dma_complete(struct dlp *dlp, struct dlp_runtime_data *drd);
|
|
int dlp_open(struct dlp *dlp, struct dlp_runtime_data *drd,
|
|
struct snd_pcm_substream *substream);
|
|
int dlp_close(struct dlp *dlp, struct dlp_runtime_data *drd,
|
|
struct snd_pcm_substream *substream);
|
|
int dlp_hw_params(struct snd_soc_component *component,
|
|
struct snd_pcm_substream *substream,
|
|
struct snd_pcm_hw_params *params);
|
|
int dlp_start(struct snd_soc_component *component,
|
|
struct snd_pcm_substream *substream,
|
|
struct device *dev,
|
|
dma_pointer_f dma_pointer);
|
|
void dlp_stop(struct snd_soc_component *component,
|
|
struct snd_pcm_substream *substream,
|
|
dma_pointer_f dma_pointer);
|
|
int dlp_copy_user(struct snd_soc_component *component,
|
|
struct snd_pcm_substream *substream,
|
|
int channel, unsigned long hwoff,
|
|
void __user *buf, unsigned long bytes);
|
|
int dlp_prepare(struct snd_soc_component *component,
|
|
struct snd_pcm_substream *substream);
|
|
int dlp_probe(struct snd_soc_component *component);
|
|
int dlp_register(struct dlp *dlp, struct device *dev,
|
|
const struct snd_soc_component_driver *driver,
|
|
const struct snd_dlp_config *config);
|
|
|
|
#endif
|