On Fri, Apr 18, 2008 at 11:58:49AM +0300, Jarkko Nikula wrote: > > No, the 256-clock mode is for output only, while in my setup the TLV is > > in slave mode. I attached this chip to the I2S output of an PXA270 which > > always outputs sample rate * 256 as system clock. In this very case, the > > PLL can be bypassed by selecting the left path described on page 27. > > > > Ok, now I see. Probably you should refer it as, at least in comment, 128*Q > instead of 256 eventhough the driver is not currently touching the Q value > in AIC3X_PLL_PROGA_REG. Well, the constraint for that condition is that MCLK = 256*WCLK, and the reason why that works for the chip without PLL is that Q=2. I stated that a little better in the attached patch. > > AIC3X_SAMPLE_RATE_SEL_REG defaults to 0 which is what I want in this > > case. Thus, I don't have to write it. > > > > > Are you sure this is a general case? Well, the reset default is 0 (as stated on page 44) and set_hw_params() is the only location where this value is written. So if it's never written with a different value, it should always be set to its default, no? Daniel
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 630684f..0f0bda2 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -720,7 +720,7 @@ static inline int aic3x_get_divs(int mclk, int rate) return i; } - return 0; + return -1; } static int aic3x_hw_params(struct snd_pcm_substream *substream, @@ -730,11 +730,42 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_codec *codec = socdev->codec; struct aic3x_priv *aic3x = codec->private_data; - int i; + int i, skip_pll; u8 data, pll_p, pll_r, pll_j; u16 pll_d; - i = aic3x_get_divs(aic3x->sysclk, params_rate(params)); + /* select data word length */ + data = + aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + data |= (0x01 << 4); + break; + case SNDRV_PCM_FORMAT_S24_LE: + data |= (0x02 << 4); + break; + case SNDRV_PCM_FORMAT_S32_LE: + data |= (0x03 << 4); + break; + } + aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data); + + /* Do not use the PLL in case our MCLK is 256 * sample rate. + * The Q value defaults to 2 so the codec sees MCLK as clock + * input (refer to datasheet page 27). + * In this case, use a fake entry in the dividers table to get + * the reference freq */ + skip_pll = (aic3x->sysclk == params_rate(params) * 256); + + if (skip_pll) + i = aic3x_get_divs(aic3x_divs[0].mclk, params_rate(params)); + else + i = aic3x_get_divs(aic3x->sysclk, params_rate(params)); + + if (i < 0) + return -EINVAL; /* Route Left DAC to left channel input and * right DAC to right channel input */ @@ -755,6 +786,9 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, } aic3x_write(codec, AIC3X_CODEC_DATAPATH_REG, data); + if (skip_pll) + return 0; + /* codec sample rate select */ data = aic3x_divs[i].sr_reg; data |= (data << 4); @@ -782,24 +816,6 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, aic3x_write(codec, AIC3X_PLL_PROGD_REG, (pll_d & 0x3F) << PLLD_LSB_SHIFT); - /* select data word length */ - data = - aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & (~(0x3 << 4)); - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - data |= (0x01 << 4); - break; - case SNDRV_PCM_FORMAT_S24_LE: - data |= (0x02 << 4); - break; - case SNDRV_PCM_FORMAT_S32_LE: - data |= (0x03 << 4); - break; - } - aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, data); - return 0; } @@ -826,16 +842,8 @@ static int aic3x_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; struct aic3x_priv *aic3x = codec->private_data; - switch (freq) { - case 12000000: - case 19200000: - case 22579200: - case 33868800: - aic3x->sysclk = freq; - return 0; - } - - return -EINVAL; + aic3x->sysclk = freq; + return 0; } static int aic3x_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
_______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel