Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Unverified Commit 5fb6589a authored by Andrew F. Davis's avatar Andrew F. Davis Committed by Mark Brown
Browse files

ASoC: tas6424: Add channel fault reporting



The TAS6426 has a register that reports channel faults such as
overcurrent and continuous DC output. Add reporting of this here.

Signed-off-by: default avatarAndrew F. Davis <afd@ti.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4c11d767
Loading
Loading
Loading
Loading
+46 −6
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ struct tas6424_data {
	struct regmap *regmap;
	struct regulator_bulk_data supplies[TAS6424_NUM_SUPPLIES];
	struct delayed_work fault_check_work;
	unsigned int last_cfault;
	unsigned int last_fault1;
	unsigned int last_fault2;
	unsigned int last_warn;
@@ -406,6 +407,51 @@ static void tas6424_fault_check_work(struct work_struct *work)
	unsigned int reg;
	int ret;

	ret = regmap_read(tas6424->regmap, TAS6424_CHANNEL_FAULT, &reg);
	if (ret < 0) {
		dev_err(dev, "failed to read CHANNEL_FAULT register: %d\n", ret);
		goto out;
	}

	if (!reg) {
		tas6424->last_cfault = reg;
		goto check_global_fault1_reg;
	}

	/*
	 * Only flag errors once for a given occurrence. This is needed as
	 * the TAS6424 will take time clearing the fault condition internally
	 * during which we don't want to bombard the system with the same
	 * error message over and over.
	 */
	if ((reg & TAS6424_FAULT_OC_CH1) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH1))
		dev_crit(dev, "experienced a channel 1 overcurrent fault\n");

	if ((reg & TAS6424_FAULT_OC_CH2) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH2))
		dev_crit(dev, "experienced a channel 2 overcurrent fault\n");

	if ((reg & TAS6424_FAULT_OC_CH3) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH3))
		dev_crit(dev, "experienced a channel 3 overcurrent fault\n");

	if ((reg & TAS6424_FAULT_OC_CH4) && !(tas6424->last_cfault & TAS6424_FAULT_OC_CH4))
		dev_crit(dev, "experienced a channel 4 overcurrent fault\n");

	if ((reg & TAS6424_FAULT_DC_CH1) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH1))
		dev_crit(dev, "experienced a channel 1 DC fault\n");

	if ((reg & TAS6424_FAULT_DC_CH2) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH2))
		dev_crit(dev, "experienced a channel 2 DC fault\n");

	if ((reg & TAS6424_FAULT_DC_CH3) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH3))
		dev_crit(dev, "experienced a channel 3 DC fault\n");

	if ((reg & TAS6424_FAULT_DC_CH4) && !(tas6424->last_cfault & TAS6424_FAULT_DC_CH4))
		dev_crit(dev, "experienced a channel 4 DC fault\n");

	/* Store current fault1 value so we can detect any changes next time */
	tas6424->last_cfault = reg;

check_global_fault1_reg:
	ret = regmap_read(tas6424->regmap, TAS6424_GLOB_FAULT1, &reg);
	if (ret < 0) {
		dev_err(dev, "failed to read GLOB_FAULT1 register: %d\n", ret);
@@ -429,12 +475,6 @@ static void tas6424_fault_check_work(struct work_struct *work)
		goto check_global_fault2_reg;
	}

	/*
	 * Only flag errors once for a given occurrence. This is needed as
	 * the TAS6424 will take time clearing the fault condition internally
	 * during which we don't want to bombard the system with the same
	 * error message over and over.
	 */
	if ((reg & TAS6424_FAULT_PVDD_OV) && !(tas6424->last_fault1 & TAS6424_FAULT_PVDD_OV))
		dev_crit(dev, "experienced a PVDD overvoltage fault\n");

+10 −0
Original line number Diff line number Diff line
@@ -115,6 +115,16 @@
#define TAS6424_LDGBYPASS_SHIFT		0
#define TAS6424_LDGBYPASS_MASK		BIT(TAS6424_LDGBYPASS_SHIFT)

/* TAS6424_GLOB_FAULT1_REG */
#define TAS6424_FAULT_OC_CH1		BIT(7)
#define TAS6424_FAULT_OC_CH2		BIT(6)
#define TAS6424_FAULT_OC_CH3		BIT(5)
#define TAS6424_FAULT_OC_CH4		BIT(4)
#define TAS6424_FAULT_DC_CH1		BIT(3)
#define TAS6424_FAULT_DC_CH2		BIT(2)
#define TAS6424_FAULT_DC_CH3		BIT(1)
#define TAS6424_FAULT_DC_CH4		BIT(0)

/* TAS6424_GLOB_FAULT1_REG */
#define TAS6424_FAULT_CLOCK		BIT(4)
#define TAS6424_FAULT_PVDD_OV		BIT(3)