aboutsummaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/cs4265.c6
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c51
-rw-r--r--sound/soc/davinci/davinci-mcasp.c11
-rw-r--r--sound/soc/rockchip/rockchip_i2s.c13
-rw-r--r--sound/soc/samsung/i2s.c5
5 files changed, 62 insertions, 24 deletions
diff --git a/sound/soc/codecs/cs4265.c b/sound/soc/codecs/cs4265.c
index 98523209f739..69a85164357c 100644
--- a/sound/soc/codecs/cs4265.c
+++ b/sound/soc/codecs/cs4265.c
@@ -458,12 +458,12 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
if (params_width(params) == 16) {
snd_soc_update_bits(codec, CS4265_DAC_CTL,
CS4265_DAC_CTL_DIF, (1 << 5));
- snd_soc_update_bits(codec, CS4265_ADC_CTL,
+ snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
CS4265_SPDIF_CTL2_DIF, (1 << 7));
} else {
snd_soc_update_bits(codec, CS4265_DAC_CTL,
CS4265_DAC_CTL_DIF, (3 << 5));
- snd_soc_update_bits(codec, CS4265_ADC_CTL,
+ snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
CS4265_SPDIF_CTL2_DIF, (1 << 7));
}
break;
@@ -472,7 +472,7 @@ static int cs4265_pcm_hw_params(struct snd_pcm_substream *substream,
CS4265_DAC_CTL_DIF, 0);
snd_soc_update_bits(codec, CS4265_ADC_CTL,
CS4265_ADC_DIF, 0);
- snd_soc_update_bits(codec, CS4265_ADC_CTL,
+ snd_soc_update_bits(codec, CS4265_SPDIF_CTL2,
CS4265_SPDIF_CTL2_DIF, (1 << 6));
break;
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 0f64c7890eed..aea9e1ff9126 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -189,46 +189,57 @@ static const struct aic31xx_rate_divs aic31xx_divs[] = {
/* mclk rate pll: p j d dosr ndac mdac aors nadc madc */
/* 8k rate */
{12000000, 8000, 1, 8, 1920, 128, 48, 2, 128, 48, 2},
+ {12000000, 8000, 1, 8, 1920, 128, 32, 3, 128, 32, 3},
{24000000, 8000, 2, 8, 1920, 128, 48, 2, 128, 48, 2},
{25000000, 8000, 2, 7, 8643, 128, 48, 2, 128, 48, 2},
/* 11.025k rate */
{12000000, 11025, 1, 7, 5264, 128, 32, 2, 128, 32, 2},
+ {12000000, 11025, 1, 8, 4672, 128, 24, 3, 128, 24, 3},
{24000000, 11025, 2, 7, 5264, 128, 32, 2, 128, 32, 2},
{25000000, 11025, 2, 7, 2253, 128, 32, 2, 128, 32, 2},
/* 16k rate */
{12000000, 16000, 1, 8, 1920, 128, 24, 2, 128, 24, 2},
+ {12000000, 16000, 1, 8, 1920, 128, 16, 3, 128, 16, 3},
{24000000, 16000, 2, 8, 1920, 128, 24, 2, 128, 24, 2},
{25000000, 16000, 2, 7, 8643, 128, 24, 2, 128, 24, 2},
/* 22.05k rate */
{12000000, 22050, 1, 7, 5264, 128, 16, 2, 128, 16, 2},
+ {12000000, 22050, 1, 8, 4672, 128, 12, 3, 128, 12, 3},
{24000000, 22050, 2, 7, 5264, 128, 16, 2, 128, 16, 2},
{25000000, 22050, 2, 7, 2253, 128, 16, 2, 128, 16, 2},
/* 32k rate */
{12000000, 32000, 1, 8, 1920, 128, 12, 2, 128, 12, 2},
+ {12000000, 32000, 1, 8, 1920, 128, 8, 3, 128, 8, 3},
{24000000, 32000, 2, 8, 1920, 128, 12, 2, 128, 12, 2},
{25000000, 32000, 2, 7, 8643, 128, 12, 2, 128, 12, 2},
/* 44.1k rate */
{12000000, 44100, 1, 7, 5264, 128, 8, 2, 128, 8, 2},
+ {12000000, 44100, 1, 8, 4672, 128, 6, 3, 128, 6, 3},
{24000000, 44100, 2, 7, 5264, 128, 8, 2, 128, 8, 2},
{25000000, 44100, 2, 7, 2253, 128, 8, 2, 128, 8, 2},
/* 48k rate */
{12000000, 48000, 1, 8, 1920, 128, 8, 2, 128, 8, 2},
+ {12000000, 48000, 1, 7, 6800, 96, 5, 4, 96, 5, 4},
{24000000, 48000, 2, 8, 1920, 128, 8, 2, 128, 8, 2},
{25000000, 48000, 2, 7, 8643, 128, 8, 2, 128, 8, 2},
/* 88.2k rate */
{12000000, 88200, 1, 7, 5264, 64, 8, 2, 64, 8, 2},
+ {12000000, 88200, 1, 8, 4672, 64, 6, 3, 64, 6, 3},
{24000000, 88200, 2, 7, 5264, 64, 8, 2, 64, 8, 2},
{25000000, 88200, 2, 7, 2253, 64, 8, 2, 64, 8, 2},
/* 96k rate */
{12000000, 96000, 1, 8, 1920, 64, 8, 2, 64, 8, 2},
+ {12000000, 96000, 1, 7, 6800, 48, 5, 4, 48, 5, 4},
{24000000, 96000, 2, 8, 1920, 64, 8, 2, 64, 8, 2},
{25000000, 96000, 2, 7, 8643, 64, 8, 2, 64, 8, 2},
/* 176.4k rate */
{12000000, 176400, 1, 7, 5264, 32, 8, 2, 32, 8, 2},
+ {12000000, 176400, 1, 8, 4672, 32, 6, 3, 32, 6, 3},
{24000000, 176400, 2, 7, 5264, 32, 8, 2, 32, 8, 2},
{25000000, 176400, 2, 7, 2253, 32, 8, 2, 32, 8, 2},
/* 192k rate */
{12000000, 192000, 1, 8, 1920, 32, 8, 2, 32, 8, 2},
+ {12000000, 192000, 1, 7, 6800, 24, 5, 4, 24, 5, 4},
{24000000, 192000, 2, 8, 1920, 32, 8, 2, 32, 8, 2},
{25000000, 192000, 2, 7, 8643, 32, 8, 2, 32, 8, 2},
};
@@ -680,7 +691,9 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
struct snd_pcm_hw_params *params)
{
struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec);
+ int bclk_score = snd_soc_params_to_frame_size(params);
int bclk_n = 0;
+ int match = -1;
int i;
/* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */
@@ -691,15 +704,37 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) {
if (aic31xx_divs[i].rate == params_rate(params) &&
- aic31xx_divs[i].mclk == aic31xx->sysclk)
- break;
+ aic31xx_divs[i].mclk == aic31xx->sysclk) {
+ int s = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) %
+ snd_soc_params_to_frame_size(params);
+ int bn = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac) /
+ snd_soc_params_to_frame_size(params);
+ if (s < bclk_score && bn > 0) {
+ match = i;
+ bclk_n = bn;
+ bclk_score = s;
+ }
+ }
}
- if (i == ARRAY_SIZE(aic31xx_divs)) {
- dev_err(codec->dev, "%s: Sampling rate %u not supported\n",
+ if (match == -1) {
+ dev_err(codec->dev,
+ "%s: Sample rate (%u) and format not supported\n",
__func__, params_rate(params));
+ /* See bellow for details how fix this. */
return -EINVAL;
}
+ if (bclk_score != 0) {
+ dev_warn(codec->dev, "Can not produce exact bitclock");
+ /* This is fine if using dsp format, but if using i2s
+ there may be trouble. To fix the issue edit the
+ aic31xx_divs table for your mclk and sample
+ rate. Details can be found from:
+ http://www.ti.com/lit/ds/symlink/tlv320aic3100.pdf
+ Section: 5.6 CLOCK Generation and PLL
+ */
+ }
+ i = match;
/* PLL configuration */
snd_soc_update_bits(codec, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
@@ -729,14 +764,6 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec,
snd_soc_write(codec, AIC31XX_AOSR, aic31xx_divs[i].aosr);
/* Bit clock divider configuration. */
- bclk_n = (aic31xx_divs[i].dosr * aic31xx_divs[i].mdac)
- / snd_soc_params_to_frame_size(params);
- if (bclk_n == 0) {
- dev_err(codec->dev, "%s: Not enough BLCK bandwidth\n",
- __func__);
- return -EINVAL;
- }
-
snd_soc_update_bits(codec, AIC31XX_BCLKN,
AIC31XX_PLL_MASK, bclk_n);
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 6a6b2ff7d7d7..68347b55f6e1 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -467,8 +467,17 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp,
{
u32 fmt;
u32 tx_rotate = (word_length / 4) & 0x7;
- u32 rx_rotate = (32 - word_length) / 4;
u32 mask = (1ULL << word_length) - 1;
+ /*
+ * For captured data we should not rotate, inversion and masking is
+ * enoguh to get the data to the right position:
+ * Format data from bus after reverse (XRBUF)
+ * S16_LE: |LSB|MSB|xxx|xxx| |xxx|xxx|MSB|LSB|
+ * S24_3LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB|
+ * S24_LE: |LSB|DAT|MSB|xxx| |xxx|MSB|DAT|LSB|
+ * S32_LE: |LSB|DAT|DAT|MSB| |MSB|DAT|DAT|LSB|
+ */
+ u32 rx_rotate = 0;
/*
* if s BCLK-to-LRCLK ratio has been configured via the set_clkdiv()
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c
index 8d8e4b59049f..fb9e05c9f471 100644
--- a/sound/soc/rockchip/rockchip_i2s.c
+++ b/sound/soc/rockchip/rockchip_i2s.c
@@ -165,13 +165,14 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
struct rk_i2s_dev *i2s = to_info(cpu_dai);
unsigned int mask = 0, val = 0;
- mask = I2S_CKR_MSS_SLAVE;
+ mask = I2S_CKR_MSS_MASK;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBS_CFS:
- val = I2S_CKR_MSS_SLAVE;
+ /* Set source clock in Master mode */
+ val = I2S_CKR_MSS_MASTER;
break;
case SND_SOC_DAIFMT_CBM_CFM:
- val = I2S_CKR_MSS_MASTER;
+ val = I2S_CKR_MSS_SLAVE;
break;
default:
return -EINVAL;
@@ -361,6 +362,8 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)
case I2S_XFER:
case I2S_CLR:
case I2S_RXDR:
+ case I2S_FIFOLR:
+ case I2S_INTSR:
return true;
default:
return false;
@@ -370,8 +373,8 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)
static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
- case I2S_FIFOLR:
case I2S_INTSR:
+ case I2S_CLR:
return true;
default:
return false;
@@ -381,8 +384,6 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
- case I2S_FIFOLR:
- return true;
default:
return false;
}
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
index 03eec22f0f46..9d513473b300 100644
--- a/sound/soc/samsung/i2s.c
+++ b/sound/soc/samsung/i2s.c
@@ -462,7 +462,7 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
if (dir == SND_SOC_CLOCK_IN)
rfs = 0;
- if ((rfs && other->rfs && (other->rfs != rfs)) ||
+ if ((rfs && other && other->rfs && (other->rfs != rfs)) ||
(any_active(i2s) &&
(((dir == SND_SOC_CLOCK_IN)
&& !(mod & MOD_CDCLKCON)) ||
@@ -762,7 +762,8 @@ static void i2s_shutdown(struct snd_pcm_substream *substream,
} else {
u32 mod = readl(i2s->addr + I2SMOD);
i2s->cdclk_out = !(mod & MOD_CDCLKCON);
- other->cdclk_out = i2s->cdclk_out;
+ if (other)
+ other->cdclk_out = i2s->cdclk_out;
}
/* Reset any constraint on RFS and BFS */
i2s->rfs = 0;