[Audio: PWMDAC] Add standard system clock tree api
authorcurry.zhang <curry.zhang@starfivetech.com>
Wed, 4 May 2022 06:13:49 +0000 (23:13 -0700)
committercurry.zhang <curry.zhang@starfivetech.com>
Thu, 5 May 2022 13:39:02 +0000 (06:39 -0700)
Signed-off-by: curry.zhang <curry.zhang@starfivetech.com>
arch/riscv/boot/dts/starfive/jh7110.dtsi
arch/riscv/boot/dts/starfive/jh7110_clk.dtsi
arch/riscv/configs/starfive_jh7110_defconfig
sound/soc/starfive/pwmdac.h [changed mode: 0644->0755]
sound/soc/starfive/starfive_pwmdac.c [changed mode: 0644->0755]
sound/soc/starfive/starfive_pwmdac_transmitter.c [changed mode: 0644->0755]

index f6aabc2..d97ad00 100755 (executable)
                pwmdac: pwmdac@100b0000 {
                        compatible = "sf,pwmdac";
                        reg = <0x0 0x100b0000 0x0 0x1000>;
-                       clocks = <&apb0clk>;
+                       clocks = <&clkgen JH7110_APB0>,
+                               <&clkgen JH7110_PWMDAC_CLK_APB>,
+                               <&clkgen JH7110_PWMDAC_CLK_CORE>;
+                       clock-names = "apb0", "pwmdac-apb", "pwmdac-core";
+                       resets = <&rstgen RSTN_U0_PWMDAC_APB>;
+                       reset-names = "rst-apb";
                        dmas = <&dma 22 1>;
                        dma-names = "tx";
                        #sound-dai-cells = <0>;
                        };
                };
 
-               sound_pwmdac: snd-card_pwmdac {
+               sound:snd-card {
                        compatible = "simple-audio-card";
-                       simple-audio-card,name = "Starfive-Pwmdac-Sound-Card";
-                       simple-audio-card,bitclock-master = <&pwmdac_dailink_master>;
-                       simple-audio-card,frame-master = <&pwmdac_dailink_master>;
-                       simple-audio-card,format = "left_j";
-                       status = "disabled";
+                       simple-audio-card,name = "Starfive-Multi-Sound-Card";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
 
-                       pwmdac_dailink_master: simple-audio-card,cpu {
-                               sound-dai = <&pwmdac>;
-                       };
+                       simple-audio-card,dai-link@0 {
+                               reg = <0>;
+                               format = "left_j";
+                               bitclock-master = <&sndcpu0>;
+                               frame-master = <&sndcpu0>;
+                               status = "okay";
+
+                               sndcpu0: cpu {
+                                       sound-dai = <&pwmdac>;
+                               };
 
-                       simple-audio-card,codec {
-                               sound-dai = <&pwmdac_codec>;
+                               codec {
+                                       sound-dai = <&pwmdac_codec>;
+                               };
                        };
                };
 
index a98b4b8..dc2cfe2 100644 (file)
                clock-frequency = <4000000>;
        };
 
-       stg_axiahb_clk: stg_axiahb_clk {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <204800000>;
-       };
-
-       stg_apbclk: stg_apbclk {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <51200000>;
-       };
-
        gpu_core_clk: gpu_core_clk {
                compatible = "fixed-clock";
                #clock-cells = <0>;
index 4e2630f..282ec90 100644 (file)
@@ -173,6 +173,11 @@ CONFIG_DRM_VKMS=y
 CONFIG_FB=y
 CONFIG_BACKLIGHT_CLASS_DEVICE=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_STARFIVE_PWMDAC=y
+CONFIG_SND_SIMPLE_CARD=y
 CONFIG_USB=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_STORAGE=y
old mode 100644 (file)
new mode 100755 (executable)
index 75ec6b8..9e94cbd
@@ -3,19 +3,14 @@
   * @file  pwmdac.h
   * @author  StarFive Technology
   * @version  V1.0
-  * @date  05/27/2021
+  * @date  05/05/2022
   * @brief
   ******************************************************************************
   * @copy
   *
-  * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-  * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
-  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-  * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  * PWMDAC driver for the StarFive JH7110 SoC
   *
-  * <h2><center>&copy; COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
+  * Copyright (C) 2022 StarFive Technology Co., Ltd.
   */
   
 #ifndef __STARFIVE_PWMDAC_LOCAL_H
 #include <sound/dmaengine_pcm.h>
 #include <sound/pcm.h>
 
-#define PWMDAC_WDATA   0///PWMDAC_BASE_ADDR
-#define PWMDAC_CTRL            0x04///PWMDAC_BASE_ADDR + 0x04
-#define PWMDAC_SATAE   0x08///PWMDAC_BASE_ADDR + 0x08
-#define PWMDAC_RESERVED        0x0C///PWMDAC_BASE_ADDR + 0x0C
+#define PWMDAC_WDATA           0       /*PWMDAC_BASE_ADDR*/
+#define PWMDAC_CTRL            0x04    /*PWMDAC_BASE_ADDR + 0x04*/
+#define PWMDAC_SATAE           0x08    /*PWMDAC_BASE_ADDR + 0x08*/
+#define PWMDAC_RESERVED                0x0C    /*PWMDAC_BASE_ADDR + 0x0C*/
 
-#define SFC_PWMDAC_SHIFT               BIT(1)
-#define SFC_PWMDAC_DUTY_CYCLE  BIT(2)
-#define SFC_PWMDAC_CNT_N               BIT(4)
+#define SFC_PWMDAC_SHIFT                       BIT(1)
+#define SFC_PWMDAC_DUTY_CYCLE                  BIT(2)
+#define SFC_PWMDAC_CNT_N                       BIT(4)
 
 #define SFC_PWMDAC_LEFT_RIGHT_DATA_CHANGE      BIT(13)
-#define SFC_PWMDAC_DATA_MODE   BIT(14)
+#define SFC_PWMDAC_DATA_MODE                   BIT(14)
 
 #define FIFO_UN_FULL   0
 #define FIFO_FULL      1
 
-#define PWMDAC_MCLK    (4096000)
+#define PWMDAC_MCLK    4096000
 
 enum pwmdac_lr_change{
        NO_CHANGE = 0,
@@ -56,7 +51,7 @@ enum pwmdac_d_mode{
 
 enum pwmdac_shift_bit{
        PWMDAC_SHIFT_8 = 8,             /*pwmdac shift 8 bit*/
-       PWMDAC_SHIFT_10 = 10,   /*pwmdac shift 10 bit*/
+       PWMDAC_SHIFT_10 = 10,           /*pwmdac shift 10 bit*/
 };
 
 enum pwmdac_duty_cycle{
@@ -74,7 +69,7 @@ enum pwmdac_sample_count{
        PWMDAC_SAMPLE_CNT_5,
        PWMDAC_SAMPLE_CNT_6,
        PWMDAC_SAMPLE_CNT_7,
-       PWMDAC_SAMPLE_CNT_8 = 1,    //(32.468/8) == (12.288/3) == 4.096
+       PWMDAC_SAMPLE_CNT_8 = 1,        /*(32.468/8) == (12.288/3) == 4.096*/
        PWMDAC_SAMPLE_CNT_9,
        PWMDAC_SAMPLE_CNT_10,
        PWMDAC_SAMPLE_CNT_11,
@@ -130,6 +125,11 @@ struct sf_pwmdac_dev {
        bool use_pio;
        spinlock_t lock;
        int active;
+
+       struct clk *clk_apb0;
+       struct clk *clk_pwmdac_apb;
+       struct clk *clk_pwmdac_core;
+       struct reset_control *rst_apb;
        
        struct device *dev;
        struct snd_dmaengine_dai_dma_data play_dma_data;
old mode 100644 (file)
new mode 100755 (executable)
index 191a165..3a7639e
@@ -1,21 +1,16 @@
 /**
   ******************************************************************************
-  * @file  sf_pwmdac.c
+  * @file  starfive_pwmdac.c
   * @author  StarFive Technology
   * @version  V1.0
-  * @date  05/27/2021
+  * @date  05/05/2022
   * @brief
   ******************************************************************************
   * @copy
   *
-  * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
-  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
-  * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
-  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
-  * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
-  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  * PWMDAC driver for the StarFive JH7110 SoC
   *
-  * <h2><center>&copy; COPYRIGHT 20120 Shanghai StarFive Technology Co., Ltd. </center></h2>
+  * Copyright (C) 2022 StarFive Technology Co., Ltd.
   */
 
 #include <linux/clk.h>
@@ -30,8 +25,9 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/dmaengine_pcm.h>
-#include "pwmdac.h"
 #include <linux/kthread.h>
+#include <linux/reset.h>
+#include "pwmdac.h"
 
 struct ct_pwmdac {
        char *name; 
@@ -469,14 +465,14 @@ static int get_pwmdac_fifo_state(struct sf_pwmdac_dev *dev)
 
 static void pwmdac_set(struct sf_pwmdac_dev *dev)
 {
-       ///8-bit + left + N=16
-    pwmdac_set_ctrl_shift(dev, dev->shift_bit);
-    pwmdac_set_ctrl_dutyCycle(dev, dev->duty_cycle);
-    pwmdac_set_ctrl_N(dev, dev->datan);
-    pwmdac_set_ctrl_enable(dev);
+       /*8-bit + left + N=16*/
+       pwmdac_set_ctrl_shift(dev, dev->shift_bit);
+       pwmdac_set_ctrl_dutyCycle(dev, dev->duty_cycle);
+       pwmdac_set_ctrl_N(dev, dev->datan);
+       pwmdac_set_ctrl_enable(dev);
 
-    pwmdac_LR_data_change(dev, dev->lr_change);
-    pwmdac_data_mode(dev, dev->data_mode);
+       pwmdac_LR_data_change(dev, dev->lr_change);
+       pwmdac_data_mode(dev, dev->data_mode);
        if (dev->shift) {
                pwmdac_data_shift(dev, dev->shift);             
        }
@@ -543,30 +539,8 @@ static int pwmdac_config(struct sf_pwmdac_dev *dev)
 static int sf_pwmdac_prepare(struct snd_pcm_substream *substream,
                          struct snd_soc_dai *dai)
 {
-       struct sf_pwmdac_dev *dev = snd_soc_dai_get_drvdata(dai);
-       //pwmdac_set(dev);
        return 0;
 }
-#if 0
-static int pwmdac_tx_thread(void *dev)
-{
-       struct sf_pwmdac_dev *pwmdac_dev =  (struct sf_pwmdac_dev *)dev;
-
-       set_current_state(TASK_INTERRUPTIBLE);
-       while (!schedule_timeout(usecs_to_jiffies(50))) {
-               if (pwmdac_dev->tx_thread_exit)
-                       break;
-               if (get_pwmdac_fifo_state(pwmdac_dev)==0) {
-                       sf_pwmdac_pcm_push_tx(pwmdac_dev);
-               }
-               
-               set_current_state(TASK_INTERRUPTIBLE);
-       }
-       
-       pwmdac_dev->tx_thread = NULL;
-       return 0;
-}
-#else
 
 int pwmdac_tx_thread(void *dev)
 {
@@ -590,8 +564,6 @@ int pwmdac_tx_thread(void *dev)
        return 0;
 }
 
-
-#endif
 static int sf_pwmdac_trigger(struct snd_pcm_substream *substream,
                int cmd, struct snd_soc_dai *dai)
 {
@@ -657,10 +629,76 @@ static int sf_pwmdac_hw_params(struct snd_pcm_substream *substream,
        
        snd_soc_dai_init_dma_data(dai, &dev->play_dma_data, NULL);
        snd_soc_dai_set_drvdata(dai, dev);
-       
+
+       return 0;
+}
+
+static int sf_pwmdac_clks_get(struct platform_device *pdev,
+                               struct sf_pwmdac_dev *dev)
+{
+       dev->clk_apb0 = devm_clk_get(&pdev->dev, "apb0");
+       if (IS_ERR(dev->clk_apb0))
+               return PTR_ERR(dev->clk_apb0);
+
+       dev->clk_pwmdac_apb = devm_clk_get(&pdev->dev, "pwmdac-apb");
+       if (IS_ERR(dev->clk_pwmdac_apb))
+               return PTR_ERR(dev->clk_pwmdac_apb);
+
+       dev->clk_pwmdac_core = devm_clk_get(&pdev->dev, "pwmdac-core");
+       if (IS_ERR(dev->clk_pwmdac_core))
+               return PTR_ERR(dev->clk_pwmdac_core);
+
+       return 0;
+}
+
+static int sf_pwmdac_resets_get(struct platform_device *pdev,
+                               struct sf_pwmdac_dev *dev)
+{
+       dev->rst_apb = devm_reset_control_get_exclusive(&pdev->dev, "rst-apb");
+       if (IS_ERR(dev->rst_apb)) {
+               dev_err(&pdev->dev, "%s: failed to get pwmdac apb reset control\n", __func__);
+               return PTR_ERR(dev->rst_apb);
+       }
+
        return 0;
 }
 
+static int sf_pwmdac_clk_init(struct platform_device *pdev,
+                               struct sf_pwmdac_dev *dev)
+{
+       int ret = 0;
+
+       ret = clk_prepare_enable(dev->clk_apb0);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to prepare enable clk_apb0\n");
+               goto err_clk_pwmdac;
+       }
+
+       ret = clk_prepare_enable(dev->clk_pwmdac_apb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to prepare enable clk_pwmdac_apb\n");
+               goto err_clk_pwmdac;
+       }
+
+       ret = clk_prepare_enable(dev->clk_pwmdac_core);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to prepare enable clk_pwmdac_core\n");
+               goto err_clk_pwmdac;
+       }
+       dev_info(&pdev->dev, "clk_apb0 = %lu, clk_pwmdac_apb = %lu, clk_pwmdac_core = %lu\n",
+               clk_get_rate(dev->clk_apb0), clk_get_rate(dev->clk_pwmdac_apb),
+               clk_get_rate(dev->clk_pwmdac_core));
+
+       ret = reset_control_deassert(dev->rst_apb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to deassert apb\n");
+               goto err_clk_pwmdac;
+       }
+
+err_clk_pwmdac:
+       return ret;
+}
+
 static int sf_pwmdac_dai_probe(struct snd_soc_dai *dai)
 {
        struct sf_pwmdac_dev *dev = dev_get_drvdata(dai->dev);
@@ -739,13 +777,31 @@ static int sf_pwmdac_probe(struct platform_device *pdev)
                return PTR_ERR(dev->pwmdac_base);
 
        dev->mapbase = res->start;
+
+       ret = sf_pwmdac_clks_get(pdev, dev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to get pwmdac clock\n");
+               return ret;
+       }
+
+       ret = sf_pwmdac_resets_get(pdev, dev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to get pwmdac reset controls\n");
+               return ret;
+        }
+
+       ret = sf_pwmdac_clk_init(pdev, dev);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to enable pwmdac clock\n");
+               return ret;
+       }
+
        dev->dev = &pdev->dev;
        dev->mode = shift_8Bit_inverter;
        dev->fifo_th = 1;//8byte
        pwmdac_config(dev);
 
        dev->use_pio = false;
-       //dev->use_pio = true;
        dev_set_drvdata(&pdev->dev, dev);
        ret = devm_snd_soc_register_component(&pdev->dev, &sf_pwmdac_component,
                                         &pwmdac_dai, 1);
@@ -789,9 +845,21 @@ static struct platform_driver sf_pwmdac_driver = {
        },
 };
 
-module_platform_driver(sf_pwmdac_driver);
 
-MODULE_AUTHOR("jenny.zhang <jenny.zhang@starfivetech.com>");
+static int __init pwmdac_driver_init(void)
+{
+       return platform_driver_register(&sf_pwmdac_driver);
+}
+
+static void pwmdac_driver_exit(void)
+{
+       platform_driver_unregister(&sf_pwmdac_driver);
+}
+
+late_initcall(pwmdac_driver_init);
+module_exit(pwmdac_driver_exit);
+
+MODULE_AUTHOR("curry.zhang <curry.zhang@starfivetech.com>");
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("starfive pwmdac SoC Interface");
 MODULE_ALIAS("platform:starfive-pwmdac");
old mode 100644 (file)
new mode 100755 (executable)
index c459878..b5445e5
@@ -90,9 +90,21 @@ static struct platform_driver pwmdac_dit_driver = {
        },
 };
 
-module_platform_driver(pwmdac_dit_driver);
+static int __init pwmdac_dit_driver_init(void)
+{
+       return platform_driver_register(&pwmdac_dit_driver);
+}
+
+static void pwmdac_dit_driver_exit(void)
+{
+       platform_driver_unregister(&pwmdac_dit_driver);
+}
+
+late_initcall(pwmdac_dit_driver_init);
+module_exit(pwmdac_dit_driver_exit);
+
 
-MODULE_AUTHOR("jenny.zhang <jenny.zhang@starfivetech.com>");
+MODULE_AUTHOR("curry.zhang <curry.zhang@starfivetech.com>");
 MODULE_DESCRIPTION("pwmdac dummy codec driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform: starfive-pwmdac dummy codec");