]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
ASoC: cs35l45: Support for GPIO pins configuration.
authorVlad.Karpovich <vkarpovi@opensource.cirrus.com>
Wed, 15 Mar 2023 15:47:18 +0000 (10:47 -0500)
committerMark Brown <broonie@kernel.org>
Tue, 21 Mar 2023 12:46:39 +0000 (12:46 +0000)
Adds device tree configuration for cs35l45 GPIOs

Signed-off-by: Vlad Karpovich <vkarpovi@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230315154722.3911463-1-vkarpovi@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/dt-bindings/sound/cs35l45.h
sound/soc/codecs/cs35l45-tables.c
sound/soc/codecs/cs35l45.c
sound/soc/codecs/cs35l45.h

index 076da4b2c28dd9ae081d9c083037388f7eb9f860..25386af184451b025bf2ab0220c06e9d506a9c8f 100644 (file)
 #define CS35L45_ASP_TX_HIZ_UNUSED      0x1
 #define CS35L45_ASP_TX_HIZ_DISABLED    0x2
 
+/*
+ * Optional GPIOX Sub-nodes:
+ *  The cs35l45 node can have up to three "cirrus,gpio-ctrlX" ('X' = [1,2,3])
+ *  sub-nodes for configuring the GPIO pins.
+ *
+ * - gpio-dir : GPIO pin direction. Valid only when 'gpio-ctrl'
+ *   is 1.
+ *    0 = Output
+ *    1 = Input (Default)
+ *
+ * - gpio-lvl : GPIO level. Valid only when 'gpio-ctrl' is 1 and 'gpio-dir' is 0.
+ *
+ *    0 = Low (Default)
+ *    1 = High
+ *
+ * - gpio-op-cfg : GPIO output configuration. Valid only when 'gpio-ctrl' is 1
+ *   and 'gpio-dir' is 0.
+ *
+ *    0 = CMOS (Default)
+ *    1 = Open Drain
+ *
+ * - gpio-pol : GPIO output polarity select. Valid only when 'gpio-ctrl' is 1
+ *   and 'gpio-dir' is 0.
+ *
+ *    0 = Non-inverted, Active High (Default)
+ *    1 = Inverted, Active Low
+ *
+ * - gpio-invert : Defines the polarity of the GPIO pin if configured
+ *   as input.
+ *
+ *    0 = Not inverted (Default)
+ *    1 = Inverted
+ *
+ * - gpio-ctrl : Defines the function of the GPIO pin.
+ *
+ * GPIO1:
+ *   0 = High impedance input (Default)
+ *   1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ *   2 = Pin acts as MDSYNC, direction controlled by MDSYNC
+ *   3-7 = Reserved
+ *
+ * GPIO2:
+ *   0 = High impedance input (Default)
+ *   1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ *   2 = Pin acts as open drain INT
+ *   3 = Reserved
+ *   4 = Pin acts as push-pull output INT. Active low.
+ *   5 = Pin acts as push-pull output INT. Active high.
+ *   6,7 = Reserved
+ *
+ * GPIO3:
+ *   0 = High impedance input (Default)
+ *   1 = Pin acts as a GPIO, direction controlled by 'gpio-dir'
+ *   2-7 = Reserved
+ */
+#define CS35L45_NUM_GPIOS      0x3
+
 #endif /* DT_CS35L45_H */
index 4b1320a2e6e97fda9bbab2f72726b1f838543853..997ea418a6dc104daf69cf9972c043fa32455355 100644 (file)
@@ -43,6 +43,9 @@ EXPORT_SYMBOL_NS_GPL(cs35l45_apply_patch, SND_SOC_CS35L45);
 static const struct reg_default cs35l45_defaults[] = {
        { CS35L45_BLOCK_ENABLES,                0x00003323 },
        { CS35L45_BLOCK_ENABLES2,               0x00000010 },
+       { CS35L45_SYNC_GPIO1,                   0x00000007 },
+       { CS35L45_INTB_GPIO2_MCLK_REF,          0x00000005 },
+       { CS35L45_GPIO3,                        0x00000005 },
        { CS35L45_REFCLK_INPUT,                 0x00000510 },
        { CS35L45_GLOBAL_SAMPLE_RATE,           0x00000003 },
        { CS35L45_ASP_ENABLES1,                 0x00000000 },
@@ -61,6 +64,9 @@ static const struct reg_default cs35l45_defaults[] = {
        { CS35L45_ASPTX4_INPUT,                 0x00000028 },
        { CS35L45_ASPTX5_INPUT,                 0x00000048 },
        { CS35L45_AMP_PCM_CONTROL,              0x00100000 },
+       { CS35L45_GPIO1_CTRL1,                  0x81000001 },
+       { CS35L45_GPIO2_CTRL1,                  0x81000001 },
+       { CS35L45_GPIO3_CTRL1,                  0x81000001 },
 };
 
 static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
@@ -72,6 +78,9 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
        case CS35L45_BLOCK_ENABLES:
        case CS35L45_BLOCK_ENABLES2:
        case CS35L45_ERROR_RELEASE:
+       case CS35L45_SYNC_GPIO1:
+       case CS35L45_INTB_GPIO2_MCLK_REF:
+       case CS35L45_GPIO3:
        case CS35L45_REFCLK_INPUT:
        case CS35L45_GLOBAL_SAMPLE_RATE:
        case CS35L45_ASP_ENABLES1:
@@ -92,6 +101,10 @@ static bool cs35l45_readable_reg(struct device *dev, unsigned int reg)
        case CS35L45_AMP_PCM_CONTROL:
        case CS35L45_AMP_PCM_HPF_TST:
        case CS35L45_IRQ1_EINT_4:
+       case CS35L45_GPIO_STATUS1:
+       case CS35L45_GPIO1_CTRL1:
+       case CS35L45_GPIO2_CTRL1:
+       case CS35L45_GPIO3_CTRL1:
                return true;
        default:
                return false;
@@ -107,6 +120,7 @@ static bool cs35l45_volatile_reg(struct device *dev, unsigned int reg)
        case CS35L45_ERROR_RELEASE:
        case CS35L45_AMP_PCM_HPF_TST:   /* not cachable */
        case CS35L45_IRQ1_EINT_4:
+       case CS35L45_GPIO_STATUS1:
                return true;
        default:
                return false;
index 855d9f13e6ff1711da627e6bc8bb0dfad37eae4b..c87dccb3382ec12c0349c531d842b6f855b0462b 100644 (file)
@@ -536,7 +536,63 @@ static int __maybe_unused cs35l45_runtime_resume(struct device *dev)
 
 static int cs35l45_apply_property_config(struct cs35l45_private *cs35l45)
 {
+       struct device_node *node = cs35l45->dev->of_node;
+       unsigned int gpio_regs[] = {CS35L45_GPIO1_CTRL1, CS35L45_GPIO2_CTRL1,
+                                   CS35L45_GPIO3_CTRL1};
+       unsigned int pad_regs[] = {CS35L45_SYNC_GPIO1,
+                                  CS35L45_INTB_GPIO2_MCLK_REF, CS35L45_GPIO3};
+       struct device_node *child;
        unsigned int val;
+       char of_name[32];
+       int ret, i;
+
+       if (!node)
+               return 0;
+
+       for (i = 0; i < CS35L45_NUM_GPIOS; i++) {
+               sprintf(of_name, "cirrus,gpio-ctrl%d", i + 1);
+               child = of_get_child_by_name(node, of_name);
+               if (!child)
+                       continue;
+
+               ret = of_property_read_u32(child, "gpio-dir", &val);
+               if (!ret)
+                       regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+                                          CS35L45_GPIO_DIR_MASK,
+                                          val << CS35L45_GPIO_DIR_SHIFT);
+
+               ret = of_property_read_u32(child, "gpio-lvl", &val);
+               if (!ret)
+                       regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+                                          CS35L45_GPIO_LVL_MASK,
+                                          val << CS35L45_GPIO_LVL_SHIFT);
+
+               ret = of_property_read_u32(child, "gpio-op-cfg", &val);
+               if (!ret)
+                       regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+                                          CS35L45_GPIO_OP_CFG_MASK,
+                                          val << CS35L45_GPIO_OP_CFG_SHIFT);
+
+               ret = of_property_read_u32(child, "gpio-pol", &val);
+               if (!ret)
+                       regmap_update_bits(cs35l45->regmap, gpio_regs[i],
+                                          CS35L45_GPIO_POL_MASK,
+                                          val << CS35L45_GPIO_POL_SHIFT);
+
+               ret = of_property_read_u32(child, "gpio-ctrl", &val);
+               if (!ret)
+                       regmap_update_bits(cs35l45->regmap, pad_regs[i],
+                                          CS35L45_GPIO_CTRL_MASK,
+                                          val << CS35L45_GPIO_CTRL_SHIFT);
+
+               ret = of_property_read_u32(child, "gpio-invert", &val);
+               if (!ret)
+                       regmap_update_bits(cs35l45->regmap, pad_regs[i],
+                                          CS35L45_GPIO_INVERT_MASK,
+                                          val << CS35L45_GPIO_INVERT_SHIFT);
+
+               of_node_put(child);
+       }
 
        if (device_property_read_u32(cs35l45->dev,
                                     "cirrus,asp-sdout-hiz-ctrl", &val) == 0) {
index 53fe9d2b7b15f44d80c2063c97daacea6ccc6113..f3a54fc57d533028c595fefb0b6c78033ceeb12a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
+#include <dt-bindings/sound/cs35l45.h>
 
 #define CS35L45_DEVID                          0x00000000
 #define CS35L45_REVID                          0x00000004
@@ -24,6 +25,9 @@
 #define CS35L45_BLOCK_ENABLES                  0x00002018
 #define CS35L45_BLOCK_ENABLES2                 0x0000201C
 #define CS35L45_ERROR_RELEASE                  0x00002034
+#define CS35L45_SYNC_GPIO1                     0x00002430
+#define CS35L45_INTB_GPIO2_MCLK_REF            0x00002434
+#define CS35L45_GPIO3                          0x00002438
 #define CS35L45_REFCLK_INPUT                   0x00002C04
 #define CS35L45_GLOBAL_SAMPLE_RATE             0x00002C0C
 #define CS35L45_BOOST_CCM_CFG                  0x00003808
 #define CS35L45_AMP_PCM_CONTROL                        0x00007000
 #define CS35L45_AMP_PCM_HPF_TST                        0x00007004
 #define CS35L45_IRQ1_EINT_4                    0x0000E01C
-#define CS35L45_LASTREG                                0x0000E01C
-
+#define CS35L45_GPIO_STATUS1                   0x0000F000
+#define CS35L45_GPIO1_CTRL1                    0x0000F008
+#define CS35L45_GPIO2_CTRL1                    0x0000F00C
+#define CS35L45_GPIO3_CTRL1                    0x0000F010
+#define CS35L45_LASTREG                        0x0000F010
 /* SFT_RESET */
 #define CS35L45_SOFT_RESET_TRIGGER             0x5A000000
 
 #define CS35L45_OTP_BOOT_DONE_STS_MASK         BIT(1)
 #define CS35L45_OTP_BUSY_MASK                  BIT(0)
 
+/* GPIOX_CTRL1 */
+#define CS35L45_GPIO_DIR_SHIFT                 31
+#define CS35L45_GPIO_DIR_MASK                  BIT(31)
+#define CS35L45_GPIO_LVL_SHIFT                 15
+#define CS35L45_GPIO_LVL_MASK                  BIT(15)
+#define CS35L45_GPIO_OP_CFG_SHIFT              14
+#define CS35L45_GPIO_OP_CFG_MASK               BIT(14)
+#define CS35L45_GPIO_POL_SHIFT                 12
+#define CS35L45_GPIO_POL_MASK                  BIT(12)
+
+/* SYNC_GPIO1, INTB_GPIO2_MCLK_REF, GPIO3 */
+#define CS35L45_GPIO_CTRL_SHIFT                20
+#define CS35L45_GPIO_CTRL_MASK                 GENMASK(22, 20)
+#define CS35L45_GPIO_INVERT_SHIFT              19
+#define CS35L45_GPIO_INVERT_MASK               BIT(19)
+
 /* Mixer sources */
 #define CS35L45_PCM_SRC_MASK                   0x7F
 #define CS35L45_PCM_SRC_ZERO                   0x00