Unverified Commit fa8c052b authored by Vlad.Karpovich's avatar Vlad.Karpovich Committed by Mark Brown
Browse files

ASoC: cs35l45: Support for GPIO pins configuration.

parent 00a7ef32
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
@@ -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 */
+14 −0
Original line number Diff line number Diff line
@@ -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;
+56 −0
Original line number Diff line number Diff line
@@ -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) {
+25 −2
Original line number Diff line number Diff line
@@ -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