From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Mack Subject: Re: [PATCH] asoc tlv320aic33: skip usage of PLL in some cases Date: Fri, 18 Apr 2008 11:38:21 +0200 Message-ID: <20080418093821.GA23651@buzzloop.caiaq.de> References: <20080417191245.GA17039@buzzloop.caiaq.de> <20080417192552.GC17039@buzzloop.caiaq.de> <20080418081315.GA23555@buzzloop.caiaq.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="5vNYLRcllDrimb99" Return-path: Received: from buzzloop.caiaq.de (buzzloop.caiaq.de [212.112.241.133]) by alsa0.perex.cz (Postfix) with ESMTP id 16D9C24AE5 for ; Fri, 18 Apr 2008 11:38:30 +0200 (CEST) Content-Disposition: inline In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: alsa-devel-bounces@alsa-project.org Errors-To: alsa-devel-bounces@alsa-project.org To: Jarkko Nikula Cc: alsa-devel@alsa-project.org List-Id: alsa-devel@alsa-project.org --5vNYLRcllDrimb99 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 --5vNYLRcllDrimb99 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="alsa-tlv320aic33-skip-pll.diff" 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, --5vNYLRcllDrimb99 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel --5vNYLRcllDrimb99--