[PATCH 3/6] ASoC: usp-pcm: add CPU DAI driver for PCM simulated from USP

Barry Song 21cnbao at gmail.com
Thu Jul 25 05:32:12 EDT 2013


2013/7/20 Mark Brown <broonie at kernel.org>:
> On Fri, Jul 19, 2013 at 07:07:19PM +0800, Barry Song wrote:
>
>> +static int sirf_usp_pcm_divider(struct snd_soc_dai *dai, int div_id, int rate)
>> +{
>> +     struct sirf_usp *susp = snd_soc_dai_get_drvdata(dai);
>> +
>> +     u32 clk_rate = clk_get_rate(susp->clk);
>> +     u32 clk_div = (clk_rate/(2*rate)) - 1;
>> +     u32 clk_div_hi = (clk_div & 0xC00)>>10;
>> +     u32 clk_div_lo = (clk_div & 0x3FF);
>> +
>> +     writel((clk_div_lo<<21) | readl(susp->base + USP_MODE2),
>> +             susp->base + USP_MODE2);
>> +     writel((clk_div_hi<<30) | readl(susp->base + USP_TX_FRAME_CTRL),
>> +             susp->base + USP_TX_FRAME_CTRL);
>> +
>> +     return 0;
>> +}
>
> I'd be happier if this did some validation on the supplied rate (for
> example, checking that it's less than the master rate) and had arguments
> specifying which clock was being affected (in case there's more in
> future revisions).

sounds good.

>
> Also what exactly is the rate being set - can the driver just figure
> this out automatically from the sample rate?

here it is generating the right pcm clock by an internal DIVISOR in USP module.

For USP_MODE2:
30:21 (R/W) USP_CLK_DIVISOR 10’h0 USP serial clock divider

For USP_TX_FRAME_CTRL:
31:30 (R/W) USP_CLK_DIVISOR 2’h0 This is the two bit [11:10] of
USP_CLK_DIVISOR in USP_MODE2

for figuring this out automatically from the sample rate, do you mean
a lookup table for common sample rate?

>
>> +#ifdef CONFIG_PM
>> +static int sirf_usp_pcm_suspend(struct platform_device *pdev,
>> +     pm_message_t state)
>> +{
>> +     struct sirf_usp *susp = platform_get_drvdata(pdev);
>> +
>> +     susp->mode1_reg = readl(susp->base + USP_MODE1);
>> +     susp->mode2_reg = readl(susp->base + USP_MODE2);
>> +     sirf_usp_controller_uninit(susp);
>> +     clk_disable_unprepare(susp->clk);
>> +
>> +     return 0;
>> +}
>
> Can this be done as runtime PM as well?  Seems like it'd save power.

agree.

>
>> +     susp->clk = clk_get(&pdev->dev, NULL);
>> +     if (IS_ERR(susp->clk)) {
>> +             dev_err(&pdev->dev, "Get clock failed.\n");
>> +             return PTR_ERR(susp->clk);
>> +     }
>
> devm_clk_get().

agree. missed this one.

-barry



More information about the linux-arm-kernel mailing list