|
@@ -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, ®);
|
|
|
+ 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, ®);
|
|
|
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");
|
|
|
|