Commit 80863ee2 authored by Andrew F. Davis's avatar Andrew F. Davis Committed by Mark Brown

ASoC: tlv320aic31xx: Add short circuit detection support

These devices support detecting and reporting short circuits across
the output stages. Add support for reporting these issue. Do this
by registering an interrupt if available and enabling this error
to trigger that interrupt in the device.
Signed-off-by: default avatarAndrew F. Davis <afd@ti.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 63a886f3
......@@ -167,6 +167,7 @@ struct aic31xx_priv {
u8 p_div;
int rate_div_line;
bool master_dapm_route_applied;
int irq;
};
struct aic31xx_rate_divs {
......@@ -1391,6 +1392,40 @@ static const struct acpi_device_id aic31xx_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, aic31xx_acpi_match);
#endif
static irqreturn_t aic31xx_irq(int irq, void *data)
{
struct aic31xx_priv *aic31xx = data;
struct device *dev = aic31xx->dev;
unsigned int value;
bool handled = false;
int ret;
ret = regmap_read(aic31xx->regmap, AIC31XX_INTRDACFLAG, &value);
if (ret) {
dev_err(dev, "Failed to read interrupt mask: %d\n", ret);
goto exit;
}
if (value)
handled = true;
else
goto exit;
if (value & AIC31XX_HPLSCDETECT)
dev_err(dev, "Short circuit on Left output is detected\n");
if (value & AIC31XX_HPRSCDETECT)
dev_err(dev, "Short circuit on Right output is detected\n");
if (value & ~(AIC31XX_HPLSCDETECT |
AIC31XX_HPRSCDETECT))
dev_err(dev, "Unknown DAC interrupt flags: 0x%08x\n", value);
exit:
if (handled)
return IRQ_HANDLED;
else
return IRQ_NONE;
}
static int aic31xx_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
......@@ -1413,6 +1448,7 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
return ret;
}
aic31xx->dev = &i2c->dev;
aic31xx->irq = i2c->irq;
aic31xx->codec_type = id->driver_data;
......@@ -1456,6 +1492,25 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
return ret;
}
if (aic31xx->irq > 0) {
regmap_update_bits(aic31xx->regmap, AIC31XX_GPIO1,
AIC31XX_GPIO1_FUNC_MASK,
AIC31XX_GPIO1_INT1 <<
AIC31XX_GPIO1_FUNC_SHIFT);
regmap_write(aic31xx->regmap, AIC31XX_INT1CTRL,
AIC31XX_SC);
ret = devm_request_threaded_irq(aic31xx->dev, aic31xx->irq,
NULL, aic31xx_irq,
IRQF_ONESHOT, "aic31xx-irq",
aic31xx);
if (ret) {
dev_err(aic31xx->dev, "Unable to request IRQ\n");
return ret;
}
}
if (aic31xx->codec_type & DAC31XX_BIT)
return devm_snd_soc_register_component(&i2c->dev,
&soc_codec_driver_aic31xx,
......
......@@ -191,6 +191,22 @@ struct aic31xx_pdata {
#define AIC31XX_SC BIT(3)
#define AIC31XX_ENGINE BIT(2)
/* AIC31XX_GPIO1 */
#define AIC31XX_GPIO1_FUNC_MASK GENMASK(5, 2)
#define AIC31XX_GPIO1_FUNC_SHIFT 2
#define AIC31XX_GPIO1_DISABLED 0x00
#define AIC31XX_GPIO1_INPUT 0x01
#define AIC31XX_GPIO1_GPI 0x02
#define AIC31XX_GPIO1_GPO 0x03
#define AIC31XX_GPIO1_CLKOUT 0x04
#define AIC31XX_GPIO1_INT1 0x05
#define AIC31XX_GPIO1_INT2 0x06
#define AIC31XX_GPIO1_ADC_WCLK 0x07
#define AIC31XX_GPIO1_SBCLK 0x08
#define AIC31XX_GPIO1_SWCLK 0x09
#define AIC31XX_GPIO1_ADC_MOD_CLK 0x10
#define AIC31XX_GPIO1_SDOUT 0x11
/* AIC31XX_DACSETUP */
#define AIC31XX_SOFTSTEP_MASK GENMASK(1, 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment