audio: add tdm lanemask config

PD#142470: audio: add lanesmask

Change-Id: I56d01ff4f77c90c4fb5575fc654b3459fec1ed14
Signed-off-by: Shuai Li <shuai.li@amlogic.com>
This commit is contained in:
Shuai Li
2017-06-04 17:37:30 -07:00
parent eea55b9463
commit 197e4f880d
3 changed files with 52 additions and 35 deletions

View File

@@ -391,7 +391,8 @@
system-clock-frequency = <12288000>;
};
codec {
sound-dai = <&tas5707_36 &tas5707_3a>;
sound-dai = <&tas5707_36 &tas5707_3a
&dummy_codec>;
};
};
@@ -730,7 +731,7 @@
GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "tdmin", "tdmout";
pinctrl-names = "tdm_pins";
pinctrl-0 = <&tdmc_mclk &tdmout_c>;// &tdmin_c>;
pinctrl-0 = <&tdmc_mclk &tdmout_c &tdmin_c>;
};
aml_spdif: spdif {
@@ -825,18 +826,18 @@
tdmout_c:tdmout_c {
mux {
pins = "GPIOA_2", "GPIOA_3", "GPIOA_4",
"GPIOA_5", "GPIOA_6", "GPIOA_7";
"GPIOA_6", "GPIOA_7";
function = "tdmc_out";
};
};
//tdmin_c:tdmin_c {
// mux {
// pins = "GPIOA_4", "GPIOA_5", "GPIOA_6", "GPIOA_7";
// function = "tdmc_in";
// };
//};
tdmin_c:tdmin_c {
mux {
pins = "GPIOA_5";
function = "tdmc_in";
};
};
spdifout: spidfout {
mux {

View File

@@ -119,7 +119,7 @@ static irqreturn_t aml_tdmin_isr(int irq, void *devid)
return IRQ_HANDLED;
}
#if 0
/* get counts of '1's in val */
static unsigned int pop_count(unsigned int val)
{
@@ -132,7 +132,7 @@ static unsigned int pop_count(unsigned int val)
return count;
}
#endif
static int snd_soc_of_get_slot_mask(struct device_node *np,
const char *prop_name,
unsigned int *mask)
@@ -484,34 +484,52 @@ static int aml_tdm_set_lanes(struct aml_tdm *p_tdm,
{
struct pcm_setting *setting = &p_tdm->setting;
unsigned int lanes, swap_val;
unsigned int lane_mask;
unsigned int set_num = 0;
unsigned int i;
pr_info("asoc debug: %d-%d\n", channels, setting->slots);
swap_val = 0;
// assume mask channels one lane
// calc lanes by channels and slots
lanes = (channels - 1) / setting->slots + 1;
pr_info("asoc debug: lanes_ddr = %d\n", lanes);
// set channels swap
for (i = 0; i < channels; i++)
swap_val |= i << (i * 4);
aml_tdm_set_lane_channel_swap(p_tdm->actrl,
stream, p_tdm->id, swap_val);
if (lanes > 4) {
pr_err("lanes setting error\n");
return -EINVAL;
}
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
aml_tdm_set_channel_mask(p_tdm->actrl,
stream, p_tdm->id, lanes, setting->tx_mask);
// set lanes mask acordingly
lane_mask = setting->lane_mask_out;
for (i = 0; i < 4; i++) {
unsigned int ch = i * 2;
if (pop_count(setting->tx_mask) > 2)
swap_val = 1 << 4;
if (i < lanes)
aml_tdm_set_channel_mask(p_tdm->actrl,
stream, p_tdm->id, i, setting->tx_mask);
if ((1 << i) & lane_mask) {
// each lane only L/R swap
swap_val |= set_num++ << (ch++ * 4);
swap_val |= set_num++ << (ch * 4);
}
}
aml_tdm_set_lane_channel_swap(p_tdm->actrl,
stream, p_tdm->id, swap_val);
} else {
aml_tdm_set_channel_mask(p_tdm->actrl,
stream, p_tdm->id, lanes, setting->rx_mask);
lane_mask = setting->lane_mask_in;
for (i = 0; i < 4; i++) {
if (i < lanes)
aml_tdm_set_channel_mask(p_tdm->actrl,
stream, p_tdm->id, i, setting->rx_mask);
if ((1 << i) & lane_mask) {
// each lane only L/R masked
pr_info("tdmin set lane %d\n", i);
swap_val |= (i * 2) << (set_num++ * 4);
swap_val |= (i * 2 + 1) << (set_num++ * 4);
}
}
aml_tdm_set_lane_channel_swap(p_tdm->actrl,
stream, p_tdm->id, swap_val);
@@ -560,9 +578,11 @@ static int aml_dai_tdm_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai)
{
struct aml_tdm *p_tdm = snd_soc_dai_get_drvdata(cpu_dai);
int i;
aml_tdm_set_channel_mask(p_tdm->actrl,
substream->stream, p_tdm->id, 4, 0);
for (i = 0; i < 4; i++)
aml_tdm_set_channel_mask(p_tdm->actrl,
substream->stream, p_tdm->id, i, 0);
return 0;
}

View File

@@ -164,7 +164,7 @@ void aml_tdm_set_format(
case SND_SOC_DAIFMT_I2S:
if (master_mode) {
bclkout_skew = 1;
bclkin_skew = 5;
bclkin_skew = 3;
} else {
bclkout_skew = 2;
bclkin_skew = 3;
@@ -273,10 +273,9 @@ void aml_tdm_set_slot(
void aml_tdm_set_channel_mask(
struct aml_audio_controller *actrl,
int stream, int index, int lanes, int mask)
int stream, int index, int lane, int mask)
{
unsigned int offset, reg;
int i;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
offset = EE_AUDIO_TDMOUT_B_MASK0 - EE_AUDIO_TDMOUT_A_MASK0;
@@ -286,10 +285,7 @@ void aml_tdm_set_channel_mask(
reg = EE_AUDIO_TDMIN_A_MASK0 + offset * index;
}
/* mask 0~3 */
for (i = 0; i < lanes; i++)
aml_audiobus_write(actrl, reg + i, mask);
aml_audiobus_write(actrl, reg + lane, mask);
}
void aml_tdm_set_lane_channel_swap(