ASoC: cs35l45: Support for GPIO pins configuration.

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>
This commit is contained in:
Vlad.Karpovich 2023-03-15 10:47:18 -05:00 committed by Mark Brown
parent 00a7ef3242
commit fa8c052b4c
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
4 changed files with 152 additions and 2 deletions

View File

@ -17,4 +17,61 @@
#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 */

View 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;

View 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) {

View 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
@ -48,8 +52,11 @@
#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
@ -165,6 +172,22 @@
#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