mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 11:26:02 +09:00
audio: support the number of datain+loopback beyond 8 channel feature
PD#168268: add support datain+loopback beyond 8 channel feature
You need add datain_datalb_total = <10>; at the end
of aml_loopback node on dts or amixer command to enable.
e.g. pdm 8ch + loopback 2ch case
pdm 8ch + loopback 8ch case
pdm 6ch + loopback 4ch case
if total number of channel beyond 8 , must utilize 16ch to capture.
so that we change relevant parameter like this:
if (lb_cfg->datain_datalb_total > 8) {
lb_cfg->datain_chnum = 8;
lb_cfg->datain_chmask = 0xff;
lb_cfg->datalb_chnum = 8;
lb_cfg->datalb_chmask = 0xff;
lb_cfg->datalb_chswap = 0x76543210;
}
capture command:
arecord -Dhw:0,3 -c 16 -r 48000 -f S32_LE /test.wav
You can use asound.conf to choose your channel.
Change-Id: I0a59c4c12da603efd8709bf36d6dac640fdf788a
Signed-off-by: Renjun Xu <renjun.xu@amlogic.com>
This commit is contained in:
@@ -38,6 +38,7 @@ struct snd_elem_info {
|
||||
|
||||
static unsigned int loopback_enable;
|
||||
static unsigned int loopback_is_running;
|
||||
static unsigned int datain_datalb_total;
|
||||
|
||||
static const char *const loopback_enable_texts[] = {
|
||||
"Disable",
|
||||
@@ -69,6 +70,23 @@ static int loopback_enable_set_enum(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int datain_datalb_total_get_param(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.bytes.data[0] = datain_datalb_total;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int datain_datalb_total_set_param(
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
datain_datalb_total = ucontrol->value.bytes.data[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int loopback_datain;
|
||||
|
||||
@@ -626,6 +644,10 @@ static const struct snd_kcontrol_new snd_auge_controls[] = {
|
||||
loopback_enable_get_enum,
|
||||
loopback_enable_set_enum),
|
||||
|
||||
SND_SOC_BYTES_EXT("datain_datalb_total", 1,
|
||||
datain_datalb_total_get_param,
|
||||
datain_datalb_total_set_param),
|
||||
|
||||
/* loopback data in source */
|
||||
SOC_ENUM_EXT("Loopback datain source",
|
||||
loopback_datain_enum,
|
||||
@@ -995,6 +1017,7 @@ int loopback_parse_of(struct device_node *node,
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
of_slot_mask = of_get_property(node, "datalb-lane-mask-in", &val);
|
||||
if (!of_slot_mask) {
|
||||
pr_err("if use extern loopback, pls set datalb-lane-mask-in\n");
|
||||
@@ -1012,8 +1035,30 @@ int loopback_parse_of(struct device_node *node,
|
||||
(i * 2 + 1) << (set_num++ * 4);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ret = of_property_read_u32(node, "datalb_clk",
|
||||
&lb_cfg->datalb_clk);
|
||||
if (ret) {
|
||||
pr_err("if no datalb_clk on dts, it equal is datalb_src\n");
|
||||
lb_cfg->datalb_clk = lb_cfg->datalb_src;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(node, "datain_datalb_total",
|
||||
&lb_cfg->datain_datalb_total);
|
||||
if (ret) {
|
||||
pr_err("no register datain_datalb_total,it also can work\n");
|
||||
lb_cfg->datain_datalb_total = 0;
|
||||
} else {
|
||||
if (lb_cfg->datain_datalb_total > 8) {
|
||||
lb_cfg->datain_chnum = 8;
|
||||
lb_cfg->datain_chmask = 0xff;
|
||||
lb_cfg->datalb_chnum = 8;
|
||||
lb_cfg->datalb_chmask = 0xff;
|
||||
lb_cfg->datalb_chswap = 0x76543210;
|
||||
}
|
||||
}
|
||||
datain_datalb_total = lb_cfg->datain_datalb_total;
|
||||
|
||||
loopback_datain = lb_cfg->datain_src;
|
||||
loopback_tdminlb = lb_cfg->datalb_src;
|
||||
|
||||
@@ -1026,7 +1071,7 @@ int loopback_parse_of(struct device_node *node,
|
||||
pr_info("\tdatalb_src:%d, datalb_chnum:%d\n",
|
||||
lb_cfg->datalb_src,
|
||||
lb_cfg->datalb_chnum);
|
||||
pr_info("\tdatalb_chswap:0x%x,datalb_chumask:%x\n",
|
||||
pr_info("\tdatalb_chswap:0x%x,datalb_chmask:%x\n",
|
||||
lb_cfg->datalb_chswap,
|
||||
lb_cfg->datalb_chmask);
|
||||
|
||||
@@ -1189,6 +1234,15 @@ int loopback_prepare(
|
||||
datain_config(&datain);
|
||||
datalb_config(&datalb);
|
||||
|
||||
lb_cfg->datain_datalb_total = datain_datalb_total;
|
||||
|
||||
if (lb_cfg->datain_datalb_total > 8) {
|
||||
lb_cfg->datain_chnum = 8;
|
||||
lb_cfg->datain_chmask = 0xff;
|
||||
lb_cfg->datalb_chnum = 8;
|
||||
lb_cfg->datalb_chmask = 0xff;
|
||||
lb_cfg->datalb_chswap = 0x76543210;
|
||||
}
|
||||
datalb_ctrl(lb_cfg);
|
||||
lb_mode(lb_cfg->lb_mode);
|
||||
|
||||
|
||||
@@ -123,10 +123,12 @@ struct loopback_cfg {
|
||||
int toddr_index;
|
||||
|
||||
enum tdmin_lb_src datalb_src;
|
||||
enum tdmin_lb_src datalb_clk;
|
||||
unsigned int datalb_chnum;
|
||||
unsigned int datalb_chswap;
|
||||
unsigned int datalb_chmask;
|
||||
int frddr_index;
|
||||
unsigned int datain_datalb_total;
|
||||
};
|
||||
|
||||
extern void loopback_set_status(int is_running);
|
||||
|
||||
@@ -122,35 +122,46 @@ void datalb_ctrl(struct loopback_cfg *lb_cfg)
|
||||
return;
|
||||
}
|
||||
|
||||
/*swap same as tdmout */
|
||||
reg = reg_base + offset * id;
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_SWAP,
|
||||
audiobus_read(reg));
|
||||
if (lb_cfg->datain_datalb_total > 8) {
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_SWAP,
|
||||
lb_cfg->datalb_chswap);
|
||||
|
||||
/*mask same as datalb*/
|
||||
/* mask 0 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK0,
|
||||
audiobus_read(reg));
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK0, 3);
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK1, 3);
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK2, 3);
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_MASK3, 3);
|
||||
} else {
|
||||
/*swap same as tdmout */
|
||||
reg = reg_base + offset * id;
|
||||
audiobus_write(EE_AUDIO_TDMIN_LB_SWAP,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 1 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK1,
|
||||
audiobus_read(reg));
|
||||
/*mask same as datalb*/
|
||||
/* mask 0 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK0,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 2 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK2,
|
||||
audiobus_read(reg));
|
||||
/* mask 1 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK1,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 3 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK3,
|
||||
audiobus_read(reg));
|
||||
/* mask 2 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK2,
|
||||
audiobus_read(reg));
|
||||
|
||||
/* mask 3 */
|
||||
reg += 1;
|
||||
audiobus_write(
|
||||
EE_AUDIO_TDMIN_LB_MASK3,
|
||||
audiobus_read(reg));
|
||||
}
|
||||
}
|
||||
|
||||
void lb_mode(int mode)
|
||||
|
||||
Reference in New Issue
Block a user