TDM:change reset interface
authorWalker Chen <walker.chen@starfivetech.com>
Wed, 20 Jul 2022 09:53:32 +0000 (17:53 +0800)
committerWalker Chen <walker.chen@starfivetech.com>
Thu, 21 Jul 2022 09:31:38 +0000 (17:31 +0800)
1.Modify reset interface with devm_reset_control_array_get_exclusive
2.Support more sample rate: 11025, 22050, 32000, 44100, 48000

Signed-off-by: Walker Chen <walker.chen@starfivetech.com>
sound/soc/codecs/wm8960.c
sound/soc/starfive/starfive_tdm.c [changed mode: 0755->0644]
sound/soc/starfive/starfive_tdm.h [changed mode: 0755->0644]

index f5bb359..589c0af 100755 (executable)
@@ -9,7 +9,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/device.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/pm.h>
@@ -816,9 +815,10 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_component *component = dai->component;
        struct wm8960_priv *wm8960 = snd_soc_component_get_drvdata(component);
        u16 iface = snd_soc_component_read(component, WM8960_IFACE1) & 0xfff3;
-       u16 audio_format = iface & 0x3;
        bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
-       int i;
+       u16 audio_format = iface & 0x3;
+       int freq_out, freq_in;
+       int i, j, k;
 
        wm8960->bclk = snd_soc_params_to_bclk(params);
        if (params_channels(params) == 1)
@@ -862,15 +862,20 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
        /* set iface */
        snd_soc_component_write(component, WM8960_IFACE1, iface);
 
-       if (audio_format == 0x3) //TDM Format
-       {
+       if (audio_format == 0x3) {//TDM Format
                snd_soc_component_write(component, WM8960_POWER1, 0xfe);
                snd_soc_component_write(component, WM8960_POWER2, 0x1f8);
                snd_soc_component_write(component, WM8960_POWER2, 0x1f9);
                snd_soc_component_write(component, WM8960_PLL1, 0x28);
                snd_soc_component_write(component, WM8960_PLL1, 0x38);
-               snd_soc_component_write(component, WM8960_CLOCK1, 0xdd);
-               snd_soc_component_write(component, WM8960_CLOCK2, 0x1cc);
+
+               freq_in = wm8960->freq_in;
+               freq_out = wm8960_configure_pll(component, freq_in, &i, &j, &k);
+               snd_soc_component_update_bits(component, WM8960_CLOCK1, 3 << 1, i << 1);
+               snd_soc_component_update_bits(component, WM8960_CLOCK1, 0x7 << 3, j << 3);
+               snd_soc_component_update_bits(component, WM8960_CLOCK1, 0x7 << 6, j << 6);
+               snd_soc_component_update_bits(component, WM8960_CLOCK2, 0xf, k);
+
                snd_soc_component_write(component, WM8960_POWER3, 0x3c);
 
                if (tx) {
@@ -909,12 +914,16 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
                snd_soc_component_write(component, WM8960_NOISEG, 0xf9);
                snd_soc_component_write(component, WM8960_ALC1, 0x1bb);
                snd_soc_component_write(component, WM8960_ALC2, 0x30);
+
+               for (i = 0; i < ARRAY_SIZE(alc_rates); i++)
+                       if (alc_rates[i].rate == params_rate(params))
+                               snd_soc_component_update_bits(component,
+                                                               WM8960_ADDCTL3, 0x7,
+                                                               alc_rates[i].val);
                /* bclk inverted */
                snd_soc_component_update_bits(component, WM8960_IFACE1, 0x80, 0x80);
-               snd_soc_component_write(component, WM8960_POWER2, 0x1f9);
-       } else if (audio_format == 0x2) { //I2S Format
-               if (!tx)
-               {
+       } else if (audio_format == 0x2) {//I2S Format
+               if (!tx) {
                        snd_soc_component_update_bits(component, WM8960_LINVOL, 0x3<<7, 0x2<<7);
                        snd_soc_component_update_bits(component, WM8960_RINVOL, 0x3<<7, 0x2<<7);
                        snd_soc_component_write(component, WM8960_CLOCK1, 0x00); //0xd8
@@ -1385,10 +1394,14 @@ static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
 }
 
 #define WM8960_RATES SNDRV_PCM_RATE_8000_48000
-
+/*
 #define WM8960_FORMATS \
        (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
        SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+*/
+
+#define WM8960_FORMATS \
+       (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
 
 static const struct snd_soc_dai_ops wm8960_dai_ops = {
        .hw_params = wm8960_hw_params,
@@ -1577,8 +1590,8 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
        regmap_update_bits(wm8960->regmap, WM8960_LOUT2, 0x100, 0x100);
        regmap_update_bits(wm8960->regmap, WM8960_ROUT2, 0x100, 0x100);
 
-       regmap_update_bits(wm8960->regmap, WM8960_LINPATH, 0x138, 0x138);
-       regmap_update_bits(wm8960->regmap, WM8960_RINPATH, 0x138, 0x138);
+       regmap_update_bits(wm8960->regmap, WM8960_LINPATH, 0x138, 0x108);
+       regmap_update_bits(wm8960->regmap, WM8960_RINPATH, 0x138, 0x108);
        regmap_update_bits(wm8960->regmap, WM8960_POWER1, 0x7E, 0x7E);
        regmap_update_bits(wm8960->regmap, WM8960_POWER3, 0x30, 0x30);
        regmap_update_bits(wm8960->regmap, WM8960_LINVOL, 0x1ff, 0x128);
@@ -1635,7 +1648,6 @@ static struct i2c_driver wm8960_i2c_driver = {
 
 module_i2c_driver(wm8960_i2c_driver);
 
-
 MODULE_DESCRIPTION("ASoC WM8960 driver");
 MODULE_AUTHOR("Liam Girdwood");
 
old mode 100755 (executable)
new mode 100644 (file)
index b51a6cf..b551243
@@ -18,8 +18,6 @@
 #include <sound/tlv.h>
 #include "starfive_tdm.h"
 
-#define CLOCK_BASE     0x13020000UL
-
 static inline u32 sf_tdm_readl(struct sf_tdm_dev *dev, u16 reg)
 {
        return readl_relaxed(dev->tdm_base + reg);
@@ -137,17 +135,41 @@ static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
        struct snd_dmaengine_dai_dma_data *dma_data = NULL;
        unsigned int data_width;
        unsigned int mclk_rate;
+       unsigned int dma_bus_width;
        int ret;
 
        dev->samplerate = params_rate(params);
        switch (dev->samplerate) {
+       /*  There is a issue with 8k sample rate  */
+/*
        case 8000:
-               mclk_rate = 12288000;
-               dev->pcmclk = 256000;
+               mclk_rate = 11289600; //sysclk
+               dev->pcmclk = 352800; //bit clock
+               break;
+*/
+       case 11025:
+               mclk_rate = 11289600; //sysclk
+               dev->pcmclk = 352800; //bit clock, for 16-bit
                break;
        case 16000:
+               mclk_rate = 12288000; //sysclk
+               dev->pcmclk = 512000; //bit clock
+               break;
+       case 22050:
+               mclk_rate = 11289600;
+               dev->pcmclk = 705600;
+               break;
+       case 32000:
+               mclk_rate = 12288000;
+               dev->pcmclk = 1024000;
+               break;
+       case 44100:
+               mclk_rate = 11289600;
+               dev->pcmclk = 1411200;
+               break;
+       case 48000:
                mclk_rate = 12288000;
-               dev->pcmclk = 512000;
+               dev->pcmclk = 1536000;
                break;
        default:
                pr_err("TDM: not support sample rate:%d\n", dev->samplerate);
@@ -155,27 +177,37 @@ static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
        }
 
        data_width = params_width(params);
+
        dev->pcmclk = 2 * dev->samplerate * data_width;
 
        switch (params_format(params)) {
+/*
        case SNDRV_PCM_FORMAT_S8:
                chan_wl = TDM_8BIT_WORD_LEN;
                chan_sl = TDM_8BIT_SLOT_LEN;
+               dma_bus_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
                break;
+*/
 
        case SNDRV_PCM_FORMAT_S16_LE:
                chan_wl = TDM_16BIT_WORD_LEN;
                chan_sl = TDM_16BIT_SLOT_LEN;
+               dma_bus_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
                break;
 
+       /*  There is a issue with 24-bit  */
+/*
        case SNDRV_PCM_FORMAT_S24_LE:
                chan_wl = TDM_24BIT_WORD_LEN;
                chan_sl = TDM_32BIT_SLOT_LEN;
+               dma_bus_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
                break;
+*/
 
        case SNDRV_PCM_FORMAT_S32_LE:
                chan_wl = TDM_32BIT_WORD_LEN;
                chan_sl = TDM_32BIT_SLOT_LEN;
+               dma_bus_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
                break;
 
        default:
@@ -199,11 +231,13 @@ static int sf_tdm_hw_params(struct snd_pcm_substream *substream,
                dev->tx.wl = chan_wl;
                dev->tx.sl = chan_sl;
                dev->tx.sscale = chan_nr;
+               dev->play_dma_data.addr_width = dma_bus_width;
                dma_data = &dev->play_dma_data;
        } else {
                dev->rx.wl = chan_wl;
                dev->rx.sl = chan_sl;
                dev->rx.sscale = chan_nr;
+               dev->capture_dma_data.addr_width = dma_bus_width;
                dma_data = &dev->capture_dma_data;
        }
 
@@ -310,13 +344,11 @@ static int sf_tdm_dai_probe(struct snd_soc_dai *dai)
        return 0;
 }
 
-#define SF_TDM_RATE    (SNDRV_PCM_RATE_8000 | \
-                       SNDRV_PCM_RATE_16000 | \
-                       SNDRV_PCM_RATE_32000)
+#define SF_TDM_RATES   (SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
+                       SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | \
+                       SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
 
-#define SF_TDM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
-                       SNDRV_PCM_FMTBIT_S16_LE | \
-                       SNDRV_PCM_FMTBIT_S24_LE | \
+#define SF_TDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
                        SNDRV_PCM_FMTBIT_S32_LE)
 
 static struct snd_soc_dai_driver sf_tdm_dai = {
@@ -326,14 +358,14 @@ static struct snd_soc_dai_driver sf_tdm_dai = {
                .stream_name    = "Playback",
                .channels_min   = 2,
                .channels_max   = 8,
-               .rates          = SF_TDM_RATE,
+               .rates          = SF_TDM_RATES,
                .formats        = SF_TDM_FORMATS,
        },
        .capture = {
                .stream_name    = "Capture",
                .channels_min   = 2,
                .channels_max   = 8,
-               .rates          = SF_TDM_RATE,
+               .rates          = SF_TDM_RATES,
                .formats        = SF_TDM_FORMATS,
        },
        .ops = &sf_tdm_dai_ops,
@@ -404,42 +436,16 @@ static int sf_tdm_clk_reset_init(struct platform_device *pdev, struct sf_tdm_dev
        dev->clk_tdm = clks[6].clk;
        dev->clk_mclk_inner = clks[7].clk;
 
-       dev->rst_ahb = devm_reset_control_get_exclusive(&pdev->dev, "tdm_ahb");
-       if (IS_ERR(dev->rst_ahb)) {
-               dev_err(&pdev->dev, "Failed to get tdm_ahb reset control\n");
-               ret = PTR_ERR(dev->rst_ahb);
-               goto exit;
-       }
-
-       dev->rst_apb = devm_reset_control_get_exclusive(&pdev->dev, "tdm_apb");
-       if (IS_ERR(dev->rst_apb)) {
-               dev_err(&pdev->dev, "Failed to get tdm_apb reset control\n");
-               ret = PTR_ERR(dev->rst_apb);
-               goto exit;
-       }
-
-       dev->rst_tdm = devm_reset_control_get_exclusive(&pdev->dev, "tdm_rst");
-       if (IS_ERR(dev->rst_tdm)) {
-               dev_err(&pdev->dev, "Failed to get tdm_rst reset control\n");
-               ret = PTR_ERR(dev->rst_tdm);
-               goto exit;
-       }
-
-       ret = reset_control_assert(dev->rst_ahb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to assert rst_ahb\n");
-               goto exit;
-       }
-
-       ret = reset_control_assert(dev->rst_apb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to assert rst_apb\n");
+       dev->resets = devm_reset_control_array_get_exclusive(&pdev->dev);
+       if (IS_ERR(dev->resets)) {
+               ret = PTR_ERR(dev->resets);
+               dev_err(&pdev->dev, "Failed to get tdm resets");
                goto exit;
        }
 
-       ret = reset_control_assert(dev->rst_tdm);
+       ret = reset_control_assert(dev->resets);
        if (ret) {
-               dev_err(&pdev->dev, "failed to assert rst_tdm\n");
+               dev_err(&pdev->dev, "Failed to assert tdm resets\n");
                goto exit;
        }
 
@@ -485,21 +491,9 @@ static int sf_tdm_clk_reset_init(struct platform_device *pdev, struct sf_tdm_dev
                goto err_dis_tdm_ext;
        }
 
-       ret = reset_control_deassert(dev->rst_ahb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to deassert rst_ahb\n");
-               goto err_clk_disable;
-       }
-
-       ret = reset_control_deassert(dev->rst_apb);
-       if (ret) {
-               dev_err(&pdev->dev, "failed to deassert rst_apb\n");
-               goto err_clk_disable;
-       }
-
-       ret = reset_control_deassert(dev->rst_tdm);
+       ret = reset_control_deassert(dev->resets);
        if (ret) {
-               dev_err(&pdev->dev, "failed to deassert rst_tdm\n");
+               dev_err(&pdev->dev, "Failed to deassert tdm resets\n");
                goto err_clk_disable;
        }
 
old mode 100755 (executable)
new mode 100644 (file)
index 2f81fcd..04f6a9d
@@ -37,7 +37,8 @@
 
 /*  DMA registers */
 #define TDM_FIFO               0x170c0000
-#define TDM_FIFO_DEPTH                 16
+//#define TDM_FIFO_DEPTH                       16
+#define TDM_FIFO_DEPTH                 32
 
 #define TWO_CHANNEL_SUPPORT            2       
 #define FOUR_CHANNEL_SUPPORT           4
@@ -123,9 +124,7 @@ struct sf_tdm_dev {
        struct clk *clk_tdm_ext;
        struct clk *clk_tdm;
        struct clk *clk_mclk_inner;
-       struct reset_control *rst_ahb;
-       struct reset_control *rst_apb;
-       struct reset_control *rst_tdm;
+       struct reset_control *resets;
        int active;
        
        enum TDM_CLKPOL clkpolity;