Loading sound/soc/codecs/max98090.c +109 −2 Original line number Diff line number Diff line Loading @@ -1972,6 +1972,102 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (!max98090->master && dai->active == 1) queue_delayed_work(system_power_efficient_wq, &max98090->pll_det_enable_work, msecs_to_jiffies(10)); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (!max98090->master && dai->active == 1) schedule_work(&max98090->pll_det_disable_work); break; default: break; } return 0; } static void max98090_pll_det_enable_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, struct max98090_priv, pll_det_enable_work.work); struct snd_soc_codec *codec = max98090->codec; unsigned int status, mask; /* * Clear status register in order to clear possibly already occurred * PLL unlock. If PLL hasn't still locked, the status will be set * again and PLL unlock interrupt will occur. * Note this will clear all status bits */ regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status); /* * Queue jack work in case jack state has just changed but handler * hasn't run yet */ regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask); status &= mask; if (status & M98090_JDET_MASK) queue_delayed_work(system_power_efficient_wq, &max98090->jack_work, msecs_to_jiffies(100)); /* Enable PLL unlock interrupt */ snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, M98090_IULK_MASK, 1 << M98090_IULK_SHIFT); } static void max98090_pll_det_disable_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, struct max98090_priv, pll_det_disable_work); struct snd_soc_codec *codec = max98090->codec; cancel_delayed_work_sync(&max98090->pll_det_enable_work); /* Disable PLL unlock interrupt */ snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, M98090_IULK_MASK, 0); } static void max98090_pll_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, struct max98090_priv, pll_work); struct snd_soc_codec *codec = max98090->codec; if (!snd_soc_codec_is_active(codec)) return; dev_info(codec->dev, "PLL unlocked\n"); /* Toggle shutdown OFF then ON */ snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, M98090_SHDNN_MASK, 0); msleep(10); snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, M98090_SHDNN_MASK, M98090_SHDNN_MASK); /* Give PLL time to lock */ msleep(10); } static void max98090_jack_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, Loading Loading @@ -2103,8 +2199,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data) if (active & M98090_SLD_MASK) dev_dbg(codec->dev, "M98090_SLD_MASK\n"); if (active & M98090_ULK_MASK) dev_err(codec->dev, "M98090_ULK_MASK\n"); if (active & M98090_ULK_MASK) { dev_dbg(codec->dev, "M98090_ULK_MASK\n"); schedule_work(&max98090->pll_work); } if (active & M98090_JDET_MASK) { dev_dbg(codec->dev, "M98090_JDET_MASK\n"); Loading Loading @@ -2177,6 +2275,7 @@ static struct snd_soc_dai_ops max98090_dai_ops = { .set_tdm_slot = max98090_set_tdm_slot, .hw_params = max98090_dai_hw_params, .digital_mute = max98090_dai_digital_mute, .trigger = max98090_dai_trigger, }; static struct snd_soc_dai_driver max98090_dai[] = { Loading Loading @@ -2258,6 +2357,11 @@ static int max98090_probe(struct snd_soc_codec *codec) max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); INIT_DELAYED_WORK(&max98090->pll_det_enable_work, max98090_pll_det_enable_work); INIT_WORK(&max98090->pll_det_disable_work, max98090_pll_det_disable_work); INIT_WORK(&max98090->pll_work, max98090_pll_work); /* Enable jack detection */ snd_soc_write(codec, M98090_REG_JACK_DETECT, Loading Loading @@ -2310,6 +2414,9 @@ static int max98090_remove(struct snd_soc_codec *codec) struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); cancel_delayed_work_sync(&max98090->jack_work); cancel_delayed_work_sync(&max98090->pll_det_enable_work); cancel_work_sync(&max98090->pll_det_disable_work); cancel_work_sync(&max98090->pll_work); return 0; } Loading sound/soc/codecs/max98090.h +3 −0 Original line number Diff line number Diff line Loading @@ -1532,6 +1532,9 @@ struct max98090_priv { int irq; int jack_state; struct delayed_work jack_work; struct delayed_work pll_det_enable_work; struct work_struct pll_det_disable_work; struct work_struct pll_work; struct snd_soc_jack *jack; unsigned int dai_fmt; int tdm_slots; Loading sound/soc/codecs/tlv320aic31xx.c +39 −12 Original line number Diff line number Diff line Loading @@ -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}, }; Loading Loading @@ -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 */ Loading @@ -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, Loading Loading @@ -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); Loading sound/soc/davinci/davinci-mcasp.c +10 −1 Original line number Diff line number Diff line Loading @@ -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() Loading sound/soc/samsung/i2s.c +3 −2 Original line number Diff line number Diff line Loading @@ -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)) || Loading Loading @@ -762,6 +762,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, } else { u32 mod = readl(i2s->addr + I2SMOD); i2s->cdclk_out = !(mod & MOD_CDCLKCON); if (other) other->cdclk_out = i2s->cdclk_out; } /* Reset any constraint on RFS and BFS */ Loading Loading
sound/soc/codecs/max98090.c +109 −2 Original line number Diff line number Diff line Loading @@ -1972,6 +1972,102 @@ static int max98090_dai_digital_mute(struct snd_soc_dai *codec_dai, int mute) return 0; } static int max98090_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (!max98090->master && dai->active == 1) queue_delayed_work(system_power_efficient_wq, &max98090->pll_det_enable_work, msecs_to_jiffies(10)); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (!max98090->master && dai->active == 1) schedule_work(&max98090->pll_det_disable_work); break; default: break; } return 0; } static void max98090_pll_det_enable_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, struct max98090_priv, pll_det_enable_work.work); struct snd_soc_codec *codec = max98090->codec; unsigned int status, mask; /* * Clear status register in order to clear possibly already occurred * PLL unlock. If PLL hasn't still locked, the status will be set * again and PLL unlock interrupt will occur. * Note this will clear all status bits */ regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status); /* * Queue jack work in case jack state has just changed but handler * hasn't run yet */ regmap_read(max98090->regmap, M98090_REG_INTERRUPT_S, &mask); status &= mask; if (status & M98090_JDET_MASK) queue_delayed_work(system_power_efficient_wq, &max98090->jack_work, msecs_to_jiffies(100)); /* Enable PLL unlock interrupt */ snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, M98090_IULK_MASK, 1 << M98090_IULK_SHIFT); } static void max98090_pll_det_disable_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, struct max98090_priv, pll_det_disable_work); struct snd_soc_codec *codec = max98090->codec; cancel_delayed_work_sync(&max98090->pll_det_enable_work); /* Disable PLL unlock interrupt */ snd_soc_update_bits(codec, M98090_REG_INTERRUPT_S, M98090_IULK_MASK, 0); } static void max98090_pll_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, struct max98090_priv, pll_work); struct snd_soc_codec *codec = max98090->codec; if (!snd_soc_codec_is_active(codec)) return; dev_info(codec->dev, "PLL unlocked\n"); /* Toggle shutdown OFF then ON */ snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, M98090_SHDNN_MASK, 0); msleep(10); snd_soc_update_bits(codec, M98090_REG_DEVICE_SHUTDOWN, M98090_SHDNN_MASK, M98090_SHDNN_MASK); /* Give PLL time to lock */ msleep(10); } static void max98090_jack_work(struct work_struct *work) { struct max98090_priv *max98090 = container_of(work, Loading Loading @@ -2103,8 +2199,10 @@ static irqreturn_t max98090_interrupt(int irq, void *data) if (active & M98090_SLD_MASK) dev_dbg(codec->dev, "M98090_SLD_MASK\n"); if (active & M98090_ULK_MASK) dev_err(codec->dev, "M98090_ULK_MASK\n"); if (active & M98090_ULK_MASK) { dev_dbg(codec->dev, "M98090_ULK_MASK\n"); schedule_work(&max98090->pll_work); } if (active & M98090_JDET_MASK) { dev_dbg(codec->dev, "M98090_JDET_MASK\n"); Loading Loading @@ -2177,6 +2275,7 @@ static struct snd_soc_dai_ops max98090_dai_ops = { .set_tdm_slot = max98090_set_tdm_slot, .hw_params = max98090_dai_hw_params, .digital_mute = max98090_dai_digital_mute, .trigger = max98090_dai_trigger, }; static struct snd_soc_dai_driver max98090_dai[] = { Loading Loading @@ -2258,6 +2357,11 @@ static int max98090_probe(struct snd_soc_codec *codec) max98090->jack_state = M98090_JACK_STATE_NO_HEADSET; INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work); INIT_DELAYED_WORK(&max98090->pll_det_enable_work, max98090_pll_det_enable_work); INIT_WORK(&max98090->pll_det_disable_work, max98090_pll_det_disable_work); INIT_WORK(&max98090->pll_work, max98090_pll_work); /* Enable jack detection */ snd_soc_write(codec, M98090_REG_JACK_DETECT, Loading Loading @@ -2310,6 +2414,9 @@ static int max98090_remove(struct snd_soc_codec *codec) struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); cancel_delayed_work_sync(&max98090->jack_work); cancel_delayed_work_sync(&max98090->pll_det_enable_work); cancel_work_sync(&max98090->pll_det_disable_work); cancel_work_sync(&max98090->pll_work); return 0; } Loading
sound/soc/codecs/max98090.h +3 −0 Original line number Diff line number Diff line Loading @@ -1532,6 +1532,9 @@ struct max98090_priv { int irq; int jack_state; struct delayed_work jack_work; struct delayed_work pll_det_enable_work; struct work_struct pll_det_disable_work; struct work_struct pll_work; struct snd_soc_jack *jack; unsigned int dai_fmt; int tdm_slots; Loading
sound/soc/codecs/tlv320aic31xx.c +39 −12 Original line number Diff line number Diff line Loading @@ -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}, }; Loading Loading @@ -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 */ Loading @@ -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, Loading Loading @@ -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); Loading
sound/soc/davinci/davinci-mcasp.c +10 −1 Original line number Diff line number Diff line Loading @@ -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() Loading
sound/soc/samsung/i2s.c +3 −2 Original line number Diff line number Diff line Loading @@ -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)) || Loading Loading @@ -762,6 +762,7 @@ static void i2s_shutdown(struct snd_pcm_substream *substream, } else { u32 mod = readl(i2s->addr + I2SMOD); i2s->cdclk_out = !(mod & MOD_CDCLKCON); if (other) other->cdclk_out = i2s->cdclk_out; } /* Reset any constraint on RFS and BFS */ Loading