From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matt Flax Subject: Re: [PATCH 2/2] ASoc: wm8731: add normal mode with 12MHz XTAL Date: Mon, 20 Jun 2016 08:23:49 +1000 Message-ID: <57671B75.4020003@flatmax.org> References: <1465517516-1917-1-git-send-email-flatmax@flatmax.org> <1465517516-1917-2-git-send-email-flatmax@flatmax.org> <575BD6F2.70600@flatmax.org> <575CD572.2040700@flatmax.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: Received: from nschwmtas01p.mx.bigpond.com (nschwmtas01p.mx.bigpond.com [61.9.189.137]) by alsa0.perex.cz (Postfix) with ESMTP id 721DB264F45 for ; Mon, 20 Jun 2016 00:23:59 +0200 (CEST) In-Reply-To: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org To: Rob Calhoun Cc: alsa-devel@alsa-project.org, broonie@kernel.org, ckeepax@opensource.wolfsonmicro.com, patches@opensource.wolfsonmicro.com List-Id: alsa-devel@alsa-project.org Hi Rob, Thanks for the information. I also discovered what you mention regarding bit clock in USB mode. Charles mentioned it in one of his earlier mails as well, it didn't sink in till I saw on the I2S what you are saying below ! Luckily the bcm2835 i2s controller is capable of shifting the R channel bits (w.r.t. the LRCLK leading edge) with a resolution of ten bits. Here is the patch which makes it all happen : https://github.com/raspberrypi/linux/commit/19343c782de3ef73e5e4903906e658a9193eb177 I made a few versions of this hardware with a 12 MHz and 18.432 MHz crystal, I prefer the 12 MHz version because it provides more usable sample rates ... as you can see from the patch, it can't replicate 8 kHz because the I2S controller needs 11 bits resolution to make it work ! Matt On 20/06/16 07:46, Rob Calhoun wrote: > Hi Matt, > > Based on my experience with the WM8737, the bitclock will always run > at 12 MHz on these devices in USB mode. While the carrying capacity of > the channel is always 12 Mbps, the data put on the wire by the codec > depend on the sample rate, number of channels, and bit depth. This > leaves some unused capacity in the channel. It is the responsibility > of the receiving digital audio interface to pull off the appropriate > number of bits every time the LRCLK/frameclock fires and ignore the > rest of it. For example in I2S mode, 2-channel, 32-bit, the DAI should > pull off the first 32 bits following each LRCLK transition. > > Whether you can use USB mode or not depends on the capabilities of the > receiving digital audio interface. For example, we tried to use WM8737 > USB mode on a TI AM335x-based board because the AM335x has a 24 MHz > master clock. This will not work because the MCASP unit on AM335x has > a hard limit of 32 bits per "slot" (thus 64 bits per frame with > two-channel acquisition) and there are 128 bits per frame at 96 kHz, > which is as fast as the WM8737 will go. (Oddly the MCASP would be fine > 192 kHz x 2 or 96 KHz x 4 ; the limit is based on the size of the > XRBUF register MCASP uses to swizzle data, not the speed of the > interface.) > > 12.288 MHz (or 24.576 MHz) are much more commonly used a master clock > frequencies in the audio world than 12 MHz, so unless you are trying > to squeeze the last dollar out of your board BOM cost you will > probably find it easier to get everything working if you switch to a > 12.288 MHz master clock. > > Best regards, > > Rob Calhoun > > On Sat, Jun 11, 2016 at 11:22 PM, Matt Flax wrote: >> It appears that my logic here is flawed. >> From what I can tell, it isn't possible to get a suitable bit clock out of >> the codec when using a 12 MHz crystal. For that reason, in my hardware I >> will change crystals from 12 MHz. >> >> I just want to check ... are there any versions of this codec which output >> the bit clock when in USB mode on the BCLK pin ? >> >> thanks >> Matt >> >> On 11/06/16 19:16, Matt Flax wrote: >>> I have realised that this second patch may not be necessary. It is also >>> likely that it will skew the actual sample rate. >>> >>> Charles, can you please advise me on the following... >>> >>> I notice that I can probably get the correct sample rates by spoofing the >>> crystal frequencies in my machine driver. For example ... >>> The ratio between the USB and Normal mode fs multipliers with BOSR=0 is : >>> 250/256 = 0.97656 >>> Similarly, I can match this with the following crystal frequency ratio >>> (crystal f in MHz) : >>> 12/12.288 = 0.97656 >>> By induction, I assume that I can spoof a 12.288 clock with BOSR=0 for >>> sample rate = 48kHz, 96 kHz when using a 12 MHz crystal. >>> >>> Again, I can match ratios between the following crystal frequecies (in >>> MHz) : >>> 12/16.9344 = 0.70862 >>> With BOSR = 1, I assume that can get 44.1 kHz and 88.2 kHz because the fs >>> ratio between normal and usb mode is : >>> 272/384 = 0.70833 >>> >>> Now these two ratios are skew by 0.41% which is equvalent to the skew in >>> 12 MHz USB mode clocks of 44.1kHz to 44.118kHz as reported in the wm8731 >>> datasheet. >>> >>> Can you advise me whether my idea of spoofing clocks in the machine driver >>> is perhaps a better way of acquiring the correct sample rates, rather then >>> this patch ? >>> >>> thanks >>> Matt >>> >>> On 10/06/16 10:11, Matt Flax wrote: >>>> This patch allows a machine to set normal mode when using a >>>> 12 MHz crystal. In USB_MODE the 12 MHz crystal signal is output on >>>> the BCLK pin. In NORMAL_MODE the bit clock is output on the BCLK pin. >>>> The previously ignored direction variable input to the >>>> wm8731_set_dai_sysclk function is used to indicate whether crystal >>>> or bit clock is output on the BCLK codec pin. >>>> I have ensured that this does not effect the db1200.c machine driver >>>> (the only other driver to use a 12 MHz crystal in USB_MODE). It also >>>> does not effect the other machine drivers which use the wm8731 codec >>>> as they don't use USB_MODE nor 12 MHz crystals. >>>> >>>> When driving the wm8731 in normal mode with a 12 MHz crystal, the >>>> DSP filters are expected to be effected. If the filters are activated >>>> then it is expected that the filter cut offs are shifted by 2.3% at >>>> 250 fs and 29.1% at 272 fs. The assumption is that the filters are >>>> linear, which implies a linear shift in rate scaling effects the >>>> filter cut off frequencies linearly. If the filters are not active, >>>> there will be no effects. >>>> >>>> Signed-off-by: Matt Flax >>>> --- >>>> sound/soc/codecs/wm8731.c | 14 ++++++++++++-- >>>> 1 file changed, 12 insertions(+), 2 deletions(-) >>>> >>>> diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c >>>> index d18261a..ec98d5a 100644 >>>> --- a/sound/soc/codecs/wm8731.c >>>> +++ b/sound/soc/codecs/wm8731.c >>>> @@ -5,6 +5,7 @@ >>>> * Copyright 2006-12 Wolfson Microelectronics, plc >>>> * >>>> * Author: Richard Purdie >>>> + * Author: Matt Flax 12Mhz XTAL normal mode and >>>> 32bit mode. >>>> * >>>> * Based on wm8753.c by Liam Girdwood >>>> * >>>> @@ -53,6 +54,7 @@ struct wm8731_priv { >>>> int sysclk_type; >>>> int playback_fs; >>>> bool deemph; >>>> + bool bclk_12_mhz; >>>> struct mutex lock; >>>> }; >>>> @@ -341,8 +343,11 @@ static int wm8731_hw_params(struct snd_pcm_substream >>>> *substream, >>>> struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); >>>> u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; >>>> int i = get_coeff(wm8731->sysclk, params_rate(params)); >>>> - u16 srate = (coeff_div[i].sr << 2) | >>>> - (coeff_div[i].bosr << 1) | coeff_div[i].usb; >>>> + u16 srate = (coeff_div[i].sr << 2) | (coeff_div[i].bosr << 1); >>>> + >>>> + /* this determines whether to output bit or crystal clk */ >>>> + if (wm8731->bclk_12_mhz) >>>> + srate |= coeff_div[i].usb; >>>> wm8731->playback_fs = params_rate(params); >>>> @@ -420,6 +425,11 @@ static int wm8731_set_dai_sysclk(struct >>>> snd_soc_dai *codec_dai, >>>> wm8731->sysclk = freq; >>>> + if (dir == SND_SOC_CLOCK_IN) /* output the 12 MHz clock */ >>>> + wm8731->bclk_12_mhz = 1; >>>> + else /* SND_SOC_CLOCK_OUT, output the bit clock */ >>>> + wm8731->bclk_12_mhz = 0; >>>> + >>>> snd_soc_dapm_sync(dapm); >>>> return 0; >>> >> _______________________________________________ >> Alsa-devel mailing list >> Alsa-devel@alsa-project.org >> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel > _______________________________________________ > Alsa-devel mailing list > Alsa-devel@alsa-project.org > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel