2018-04-30 08:31:23

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [PATCH v3 0/3] ASoc: TAS6424: Add support for mute, standby, and faster power on

mute and standby pins are available on the codec. If they are connected, they
should be managed by the driver, instead of relying on gpio hogs or on the
initial state of the GPIOs.

This series also includes a patch to improve the start-up time of the channels
by disabling built-in DC diagnostics. Those diagnosdtics basically serve to
detect :
- wires shorted together
- wire shorted to ground or vbat
- wire disconnected
This is not useful for all platforms and the addition to the startup time is
quite noticeable (230ms). The diagnostics can be enabled/disabled using a
dedicated ALSA control.

Changes in v3:
- use SOC_SINGLE_STROBE() to register the "auto diagniostics switch" control

Changes in v2:
- use a ALSA control to enable/disable the auto diagnostics instead of
relying on a DTS property.
- fixed typos
- use gpios (plural) instead of gpio in the documentation of the bindings

Jean-Jacques Hiblot (3):
ASoC: tas6424: Add support for the standby pin
ASoC: tas6424: Add support for the mute pin
ASoC: tas6424: Allow disabling auto diagnostics for faster power-on

.../devicetree/bindings/sound/ti,tas6424.txt | 2 +
sound/soc/codecs/tas6424.c | 72 +++++++++++++++++++++-
sound/soc/codecs/tas6424.h | 4 ++
3 files changed, 75 insertions(+), 3 deletions(-)

--
2.7.4



2018-04-30 08:31:43

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [PATCH v3 2/3] ASoC: tas6424: Add support for the mute pin

mute can be connected to GPIO. In that case we have to drive it to the
correct value

Signed-off-by: Jean-Jacques Hiblot <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
.../devicetree/bindings/sound/ti,tas6424.txt | 1 +
sound/soc/codecs/tas6424.c | 37 +++++++++++++++++++++-
2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/ti,tas6424.txt b/Documentation/devicetree/bindings/sound/ti,tas6424.txt
index df71e41..eacb54f 100644
--- a/Documentation/devicetree/bindings/sound/ti,tas6424.txt
+++ b/Documentation/devicetree/bindings/sound/ti,tas6424.txt
@@ -7,6 +7,7 @@ Required properties:
- reg: I2C slave address
- sound-dai-cells: must be equal to 0
- standby-gpios: GPIO used to shut the TAS6424 down.
+ - mute-gpios: GPIO used to mute all the outputs

Example:

diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c
index 5abb17f..89fd0c1 100644
--- a/sound/soc/codecs/tas6424.c
+++ b/sound/soc/codecs/tas6424.c
@@ -45,6 +45,7 @@ struct tas6424_data {
unsigned int last_fault2;
unsigned int last_warn;
struct gpio_desc *standby_gpio;
+ struct gpio_desc *mute_gpio;
};

/*
@@ -251,10 +252,16 @@ static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai,
static int tas6424_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_component *component = dai->component;
+ struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
unsigned int val;

dev_dbg(component->dev, "%s() mute=%d\n", __func__, mute);

+ if (tas6424->mute_gpio) {
+ gpiod_set_value_cansleep(tas6424->mute_gpio, mute);
+ return 0;
+ }
+
if (mute)
val = TAS6424_ALL_STATE_MUTE;
else
@@ -289,6 +296,7 @@ static int tas6424_power_on(struct snd_soc_component *component)
{
struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
int ret;
+ u8 chan_states;

ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),
tas6424->supplies);
@@ -305,7 +313,18 @@ static int tas6424_power_on(struct snd_soc_component *component)
return ret;
}

- snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE);
+ if (tas6424->mute_gpio) {
+ gpiod_set_value_cansleep(tas6424->mute_gpio, 0);
+ /*
+ * channels are muted via the mute pin. Don't also mute
+ * them via the registers so that subsequent register
+ * access is not necessary to un-mute the channels
+ */
+ chan_states = TAS6424_ALL_STATE_PLAY;
+ } else {
+ chan_states = TAS6424_ALL_STATE_MUTE;
+ }
+ snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, chan_states);

/* any time we come out of HIZ, the output channels automatically run DC
* load diagnostics, wait here until this completes
@@ -645,6 +664,22 @@ static int tas6424_i2c_probe(struct i2c_client *client,
tas6424->standby_gpio = NULL;
}

+ /*
+ * Get control of the mute pin and set it HIGH in order to start with
+ * all the output muted.
+ * Note: The actual pin polarity is taken care of in the GPIO lib
+ * according the polarity specified in the DTS.
+ */
+ tas6424->mute_gpio = devm_gpiod_get_optional(dev, "mute",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(tas6424->mute_gpio)) {
+ if (PTR_ERR(tas6424->mute_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(dev, "failed to get nmute GPIO: %ld\n",
+ PTR_ERR(tas6424->mute_gpio));
+ tas6424->mute_gpio = NULL;
+ }
+
for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++)
tas6424->supplies[i].supply = tas6424_supply_names[i];
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies),
--
2.7.4


2018-04-30 08:32:15

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [PATCH v3 3/3] ASoC: tas6424: Allow disabling auto diagnostics for faster power-on

The TAS6424 incorporates both DC-load and AC-load diagnostics which are
used to determine the status of the load. The DC diagnostics runs when any
channel is directed to leave the Hi-Z state and enter the MUTE or PLAY
state.
The DC diagnostics are turned on by default but, if a fast startup without
diagnostics is required, the diagnostics can be disabled using a dedicated
ALSA control.

Signed-off-by: Jean-Jacques Hiblot <[email protected]>
---
sound/soc/codecs/tas6424.c | 13 +++++++++++--
sound/soc/codecs/tas6424.h | 4 ++++
2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c
index 89fd0c1..12d1e35 100644
--- a/sound/soc/codecs/tas6424.c
+++ b/sound/soc/codecs/tas6424.c
@@ -64,6 +64,8 @@ static const struct snd_kcontrol_new tas6424_snd_controls[] = {
TAS6424_CH3_VOL_CTRL, 0, 0xff, 0, dac_tlv),
SOC_SINGLE_TLV("Speaker Driver CH4 Playback Volume",
TAS6424_CH4_VOL_CTRL, 0, 0xff, 0, dac_tlv),
+ SOC_SINGLE_STROBE("Auto Diagnostics switch", TAS6424_DC_DIAG_CTRL1,
+ TAS6424_LDGBYPASS_SHIFT, 1),
};

static int tas6424_dac_event(struct snd_soc_dapm_widget *w,
@@ -297,6 +299,11 @@ static int tas6424_power_on(struct snd_soc_component *component)
struct tas6424_data *tas6424 = snd_soc_component_get_drvdata(component);
int ret;
u8 chan_states;
+ int no_auto_diags = 0;
+ unsigned int reg_val;
+
+ if (!regmap_read(tas6424->regmap, TAS6424_DC_DIAG_CTRL1, &reg_val))
+ no_auto_diags = reg_val & TAS6424_LDGBYPASS_MASK;

ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies),
tas6424->supplies);
@@ -327,9 +334,11 @@ static int tas6424_power_on(struct snd_soc_component *component)
snd_soc_component_write(component, TAS6424_CH_STATE_CTRL, chan_states);

/* any time we come out of HIZ, the output channels automatically run DC
- * load diagnostics, wait here until this completes
+ * load diagnostics if autodiagnotics are enabled. wait here until this
+ * completes.
*/
- msleep(230);
+ if (!no_auto_diags)
+ msleep(230);

return 0;
}
diff --git a/sound/soc/codecs/tas6424.h b/sound/soc/codecs/tas6424.h
index 4305883..b5958c4 100644
--- a/sound/soc/codecs/tas6424.h
+++ b/sound/soc/codecs/tas6424.h
@@ -111,6 +111,10 @@
TAS6424_CH3_STATE_DIAG | \
TAS6424_CH4_STATE_DIAG)

+/* TAS6424_DC_DIAG_CTRL1 */
+#define TAS6424_LDGBYPASS_SHIFT 0
+#define TAS6424_LDGBYPASS_MASK BIT(TAS6424_LDGBYPASS_SHIFT)
+
/* TAS6424_GLOB_FAULT1_REG */
#define TAS6424_FAULT_CLOCK BIT(4)
#define TAS6424_FAULT_PVDD_OV BIT(3)
--
2.7.4


2018-04-30 08:33:55

by Jean-Jacques Hiblot

[permalink] [raw]
Subject: [PATCH v3 1/3] ASoC: tas6424: Add support for the standby pin

The standby pin can be connected to a GPIO. In that case we have to drive
it to the correct values for the TAS6424 to operate properly.

Signed-off-by: Jean-Jacques Hiblot <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
---
.../devicetree/bindings/sound/ti,tas6424.txt | 1 +
sound/soc/codecs/tas6424.c | 22 ++++++++++++++++++++++
2 files changed, 23 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/ti,tas6424.txt b/Documentation/devicetree/bindings/sound/ti,tas6424.txt
index 1c4ada0..df71e41 100644
--- a/Documentation/devicetree/bindings/sound/ti,tas6424.txt
+++ b/Documentation/devicetree/bindings/sound/ti,tas6424.txt
@@ -6,6 +6,7 @@ Required properties:
- compatible: "ti,tas6424" - TAS6424
- reg: I2C slave address
- sound-dai-cells: must be equal to 0
+ - standby-gpios: GPIO used to shut the TAS6424 down.

Example:

diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c
index 4f3a16c..5abb17f 100644
--- a/sound/soc/codecs/tas6424.c
+++ b/sound/soc/codecs/tas6424.c
@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
+#include <linux/gpio/consumer.h>

#include <sound/pcm.h>
#include <sound/pcm_params.h>
@@ -43,6 +44,7 @@ struct tas6424_data {
unsigned int last_fault1;
unsigned int last_fault2;
unsigned int last_warn;
+ struct gpio_desc *standby_gpio;
};

/*
@@ -627,6 +629,22 @@ static int tas6424_i2c_probe(struct i2c_client *client,
return ret;
}

+ /*
+ * Get control of the standby pin and set it LOW to take the codec
+ * out of the stand-by mode.
+ * Note: The actual pin polarity is taken care of in the GPIO lib
+ * according the polarity specified in the DTS.
+ */
+ tas6424->standby_gpio = devm_gpiod_get_optional(dev, "standby",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(tas6424->standby_gpio)) {
+ if (PTR_ERR(tas6424->standby_gpio) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ dev_info(dev, "failed to get standby GPIO: %ld\n",
+ PTR_ERR(tas6424->standby_gpio));
+ tas6424->standby_gpio = NULL;
+ }
+
for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++)
tas6424->supplies[i].supply = tas6424_supply_names[i];
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies),
@@ -671,6 +689,10 @@ static int tas6424_i2c_remove(struct i2c_client *client)

cancel_delayed_work_sync(&tas6424->fault_check_work);

+ /* put the codec in stand-by */
+ if (tas6424->standby_gpio)
+ gpiod_set_value_cansleep(tas6424->standby_gpio, 1);
+
ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies),
tas6424->supplies);
if (ret < 0) {
--
2.7.4


2018-05-01 20:43:34

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v3 0/3] ASoc: TAS6424: Add support for mute, standby, and faster power on

On Mon, Apr 30, 2018 at 10:30:15AM +0200, Jean-Jacques Hiblot wrote:
> mute and standby pins are available on the codec. If they are connected, they
> should be managed by the driver, instead of relying on gpio hogs or on the
> initial state of the GPIOs.

Please do not submit new versions of already applied patches, please
submit incremental updates to the existing code. Modifying existing
commits creates problems for other users building on top of those
commits so it's best practice to only change pubished git commits if
absolutely essential.


Attachments:
(No filename) (562.00 B)
signature.asc (499.00 B)
Download all attachments

2018-05-01 20:45:40

by Mark Brown

[permalink] [raw]
Subject: Re: [PATCH v3 3/3] ASoC: tas6424: Allow disabling auto diagnostics for faster power-on

On Mon, Apr 30, 2018 at 10:30:18AM +0200, Jean-Jacques Hiblot wrote:

> + SOC_SINGLE_STROBE("Auto Diagnostics switch", TAS6424_DC_DIAG_CTRL1,
> + TAS6424_LDGBYPASS_SHIFT, 1),

This should be "Auto Diagnostics Switch" with a capital on the Switch.
Otherwise this looks good!


Attachments:
(No filename) (285.00 B)
signature.asc (499.00 B)
Download all attachments