All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Preston <thomas.preston@codethink.co.uk>
To: Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	Charles Keepax <ckeepax@opensource.cirrus.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
	Marco Felsch <m.felsch@pengutronix.de>,
	Paul Cercueil <paul@crapouillou.net>,
	Kirill Marinushkin <kmarinushkin@birdec.tech>,
	Cheng-Yi Chiang <cychiang@chromium.org>,
	Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>,
	Vinod Koul <vkoul@kernel.org>,
	Annaliese McDermond <nh6z@nh6z.net>,
	Thomas Preston <thomas.preston@codethink.co.uk>,
	alsa-devel@alsa-project.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
Date: Tue, 30 Jul 2019 13:09:37 +0100	[thread overview]
Message-ID: <20190730120937.16271-4-thomas.preston@codethink.co.uk> (raw)
In-Reply-To: <20190730120937.16271-1-thomas.preston@codethink.co.uk>

Add a debugfs device node which initiates the turn-on diagnostic routine
feature of the TDA7802 amplifier. The four status registers (one per
channel) are returned.

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
Changes since v1:
- Rename speaker-test to (turn-on) diagnostics
- Move turn-on diagnostic to debugfs as there is no standard ALSA
  interface for this kind of routine.

 sound/soc/codecs/tda7802.c | 186 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 185 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/tda7802.c b/sound/soc/codecs/tda7802.c
index 0f82a88bc1a4..74436212241d 100644
--- a/sound/soc/codecs/tda7802.c
+++ b/sound/soc/codecs/tda7802.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2016-2019 Tesla Motors, Inc.
  */
 
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
@@ -26,6 +27,7 @@
 #define TDA7802_IB5			0x05
 
 #define TDA7802_DB0			0x10
+#define TDA7802_DB1			0x11
 #define TDA7802_DB5			0x15
 
 #define IB2_DIGITAL_MUTE_DISABLED	(1 << 2)
@@ -47,6 +49,17 @@
 #define IB3_FORMAT_TDM16_DEV3		(6 << IB3_FORMAT_SHIFT)
 #define IB3_FORMAT_TDM16_DEV4		(7 << IB3_FORMAT_SHIFT)
 
+#define IB4_DIAG_MODE_ENABLE		(1 << 0)
+
+#define IB5_AMPLIFIER_ON		(1 << 0)
+
+#define DB0_STARTUP_DIAG_STATUS		(1 << 6)
+
+#define DIAGNOSTIC_POLL_PERIOD_US	5000
+#define DIAGNOSTIC_TIMEOUT_US		5000000
+#define DIAGNOSTIC_SETTLE_MS		20
+#define NUM_IB				6
+
 enum tda7802_type {
 	tda7802_base,
 };
@@ -55,6 +68,12 @@ struct tda7802_priv {
 	struct i2c_client *i2c;
 	struct regmap *regmap;
 	struct regulator *enable_reg;
+	struct dentry *debugfs;
+	struct mutex diagnostic_mutex;
+};
+
+struct reg_update {
+	unsigned int reg, mask, val;
 };
 
 static const struct reg_default tda7802_reg[] = {
@@ -113,6 +132,19 @@ static const struct regmap_config tda7802_regmap_config = {
 	.cache_type = REGCACHE_RBTREE,
 };
 
+/* The following bits need to be updated before diagnostics mode is set. */
+static const struct reg_update diagnostic_state[NUM_IB] = {
+	{ TDA7802_IB0, 0, 0 },
+	{ TDA7802_IB1, 0, 0 },
+	{ TDA7802_IB2,
+		IB2_CH13_UNMUTED | IB2_CH24_UNMUTED | IB2_DIGITAL_MUTE_DISABLED,
+		IB2_CH13_UNMUTED | IB2_CH24_UNMUTED | IB2_DIGITAL_MUTE_DISABLED,
+	},
+	{ TDA7802_IB3, 0, 0 },
+	{ TDA7802_IB4, IB4_DIAG_MODE_ENABLE, 0 },
+	{ TDA7802_IB5, IB5_AMPLIFIER_ON, 0 },
+};
+
 static int tda7802_digital_mute(struct snd_soc_dai *dai, int mute)
 {
 	const u8 mute_disabled = mute ? 0 : IB2_DIGITAL_MUTE_DISABLED;
@@ -414,7 +446,6 @@ static const struct snd_kcontrol_new tda7802_snd_controls[] = {
 	SOC_SINGLE("AC diag enable", TDA7802_IB4, 3, 1, 0),
 	SOC_ENUM("Diag mode channels 1 & 3", diag_mode_ch13),
 	SOC_ENUM("Diag mode channels 2 & 4", diag_mode_ch24),
-	SOC_SINGLE("Diag mode enable", TDA7802_IB4, 0, 1, 0),
 
 	SOC_ENUM("Clipping detect channels 1 & 3", clip_detect_ch13),
 	SOC_ENUM("Clipping detect channels 2 & 4", clip_detect_ch24),
@@ -432,7 +463,160 @@ static const struct snd_soc_dapm_route tda7802_dapm_routes[] = {
 	{ "SPK", NULL, "DAC" },
 };
 
+static int tda7802_bulk_update(struct regmap *map, struct reg_update *update,
+		size_t update_count)
+{
+	int i, err;
+
+	for (i = 0; i < update_count; i++) {
+		err = regmap_update_bits(map, update[i].reg, update[i].mask,
+				update[i].val);
+		if (err < 0)
+			return err;
+	}
+
+	return i;
+}
+
+static int run_turn_on_diagnostic(struct tda7802_priv *tda7802, u8 *status)
+{
+	struct device *dev = &tda7802->i2c->dev;
+	int err_status, err;
+	unsigned int val;
+	u8 state[NUM_IB];
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	/* Save state and prepare for diagnostic */
+	err = regmap_bulk_read(tda7802->regmap, TDA7802_IB0, state,
+			ARRAY_SIZE(state));
+	if (err < 0) {
+		dev_err(dev, "Could not save device state, %d\n", err);
+		return err;
+	}
+
+	err = tda7802_bulk_update(tda7802->regmap, diagnostic_state,
+			ARRAY_SIZE(diagnostic_state));
+	if (err < 0) {
+		dev_err(dev, "Could not prepare for diagnostics, %d\n", err);
+		goto diagnostic_restore;
+	}
+
+	/* We must wait 20ms for device to settle, otherwise diagnostics will
+	 * not start and regmap poll will timeout.
+	 */
+	msleep(DIAGNOSTIC_SETTLE_MS);
+
+	/* Turn on diagnostic */
+	err = regmap_update_bits(tda7802->regmap, TDA7802_IB4,
+			IB4_DIAG_MODE_ENABLE, IB4_DIAG_MODE_ENABLE);
+	if (err < 0) {
+		dev_err(dev, "Could not enable diagnostic mode, %d\n", err);
+		goto diagnostic_restore;
+	}
+
+	/* Wait until DB0_STARTUP_DIAG_STATUS is set, then read status */
+	err_status = regmap_read_poll_timeout(tda7802->regmap, TDA7802_DB0, val,
+			val & DB0_STARTUP_DIAG_STATUS,
+			DIAGNOSTIC_POLL_PERIOD_US,
+			DIAGNOSTIC_TIMEOUT_US);
+	if (err_status < 0) {
+		dev_err(dev, "Diagnostic did not complete, err %d, reg %x",
+				err_status, val);
+		goto diagnostic_restore;
+	}
+
+	err = regmap_bulk_read(tda7802->regmap, TDA7802_DB1, status, 4);
+	if (err < 0) {
+		dev_err(dev, "Could not read channel status, %d\n", err);
+		goto diagnostic_restore;
+	}
+
+diagnostic_restore:
+	err = regmap_bulk_write(tda7802->regmap, TDA7802_IB0, state,
+			ARRAY_SIZE(state));
+	if (err < 0)
+		dev_err(dev, "Could not restore state, %d\n", err);
+
+	if (err_status < 0)
+		return err_status;
+	else
+		return err;
+}
+
+static int tda7802_diagnostic_show(struct seq_file *f, void *p)
+{
+	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	struct tda7802_priv *tda7802 = f->private;
+	u8 status[4] = { 0 };
+	int i, err;
+
+	mutex_lock(&tda7802->diagnostic_mutex);
+	err = run_turn_on_diagnostic(tda7802, status);
+	mutex_unlock(&tda7802->diagnostic_mutex);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < ARRAY_SIZE(status); i++)
+		seq_printf(f, "%02x: %02x\n", TDA7802_DB1+i, status[i]);
+
+	return 0;
+}
+
+static int tda7802_diagnostic_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, tda7802_diagnostic_show, inode->i_private);
+}
+
+static const struct file_operations tda7802_diagnostic_fops = {
+	.open = tda7802_diagnostic_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int tda7802_probe(struct snd_soc_component *component)
+{
+	struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
+	struct device *dev = &tda7802->i2c->dev;
+	int err;
+
+	tda7802->debugfs = debugfs_create_dir(dev_name(dev), NULL);
+	if (IS_ERR_OR_NULL(tda7802->debugfs)) {
+		dev_info(dev,
+			"Failed to create debugfs node, err %ld\n",
+			PTR_ERR(tda7802->debugfs));
+		return 0;
+	}
+
+	mutex_init(&tda7802->diagnostic_mutex);
+	err = debugfs_create_file("diagnostic", 0444, tda7802->debugfs, tda7802,
+			&tda7802_diagnostic_fops);
+	if (err < 0) {
+		dev_err(dev,
+			"debugfs: Failed to create diagnostic node, err %d\n",
+			err);
+		goto cleanup_diagnostic;
+	}
+
+	return 0;
+
+cleanup_diagnostic:
+	mutex_destroy(&tda7802->diagnostic_mutex);
+	return err;
+}
+
+static void tda7802_remove(struct snd_soc_component *component)
+{
+	struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
+
+	debugfs_remove_recursive(tda7802->debugfs);
+	mutex_destroy(&tda7802->diagnostic_mutex);
+}
+
 static const struct snd_soc_component_driver tda7802_component_driver = {
+	.probe = tda7802_probe,
+	.remove = tda7802_remove,
 	.set_bias_level = tda7802_set_bias_level,
 	.idle_bias_on = 1,
 	.suspend_bias_off = 1,
-- 
2.21.0


WARNING: multiple messages have this Message-ID (diff)
From: Thomas Preston <thomas.preston@codethink.co.uk>
To: Liam Girdwood <lgirdwood@gmail.com>,
	Mark Brown <broonie@kernel.org>, Rob Herring <robh+dt@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Jaroslav Kysela <perex@perex.cz>, Takashi Iwai <tiwai@suse.com>,
	Charles Keepax <ckeepax@opensource.cirrus.com>,
	Jerome Brunet <jbrunet@baylibre.com>,
	Srinivas Kandagatla <srinivas.kandagatla@linaro.org>,
	Marco Felsch <m.felsch@pengutronix.de>,
	Paul Cercueil <paul@crapouillou.net>,
	Kirill Marinushkin <kmarinushkin@birdec.tech>,
	Cheng-Yi Chiang <cychiang@chromium.org>,
	Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>,
	Vinod Koul <vkoul@kernel.org>,
	Annaliese McDermond <nh6z@nh6z.net>,
	Thomas Preston <thomas.preston@codethink.co.uk>,
	alsa-devel@alsa-project.org, devicetree@vger.kernel.org,
	linux-kernel
Subject: [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine
Date: Tue, 30 Jul 2019 13:09:37 +0100	[thread overview]
Message-ID: <20190730120937.16271-4-thomas.preston@codethink.co.uk> (raw)
In-Reply-To: <20190730120937.16271-1-thomas.preston@codethink.co.uk>

Add a debugfs device node which initiates the turn-on diagnostic routine
feature of the TDA7802 amplifier. The four status registers (one per
channel) are returned.

Signed-off-by: Thomas Preston <thomas.preston@codethink.co.uk>
---
Changes since v1:
- Rename speaker-test to (turn-on) diagnostics
- Move turn-on diagnostic to debugfs as there is no standard ALSA
  interface for this kind of routine.

 sound/soc/codecs/tda7802.c | 186 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 185 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/tda7802.c b/sound/soc/codecs/tda7802.c
index 0f82a88bc1a4..74436212241d 100644
--- a/sound/soc/codecs/tda7802.c
+++ b/sound/soc/codecs/tda7802.c
@@ -5,6 +5,7 @@
  * Copyright (C) 2016-2019 Tesla Motors, Inc.
  */
 
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
@@ -26,6 +27,7 @@
 #define TDA7802_IB5			0x05
 
 #define TDA7802_DB0			0x10
+#define TDA7802_DB1			0x11
 #define TDA7802_DB5			0x15
 
 #define IB2_DIGITAL_MUTE_DISABLED	(1 << 2)
@@ -47,6 +49,17 @@
 #define IB3_FORMAT_TDM16_DEV3		(6 << IB3_FORMAT_SHIFT)
 #define IB3_FORMAT_TDM16_DEV4		(7 << IB3_FORMAT_SHIFT)
 
+#define IB4_DIAG_MODE_ENABLE		(1 << 0)
+
+#define IB5_AMPLIFIER_ON		(1 << 0)
+
+#define DB0_STARTUP_DIAG_STATUS		(1 << 6)
+
+#define DIAGNOSTIC_POLL_PERIOD_US	5000
+#define DIAGNOSTIC_TIMEOUT_US		5000000
+#define DIAGNOSTIC_SETTLE_MS		20
+#define NUM_IB				6
+
 enum tda7802_type {
 	tda7802_base,
 };
@@ -55,6 +68,12 @@ struct tda7802_priv {
 	struct i2c_client *i2c;
 	struct regmap *regmap;
 	struct regulator *enable_reg;
+	struct dentry *debugfs;
+	struct mutex diagnostic_mutex;
+};
+
+struct reg_update {
+	unsigned int reg, mask, val;
 };
 
 static const struct reg_default tda7802_reg[] = {
@@ -113,6 +132,19 @@ static const struct regmap_config tda7802_regmap_config = {
 	.cache_type = REGCACHE_RBTREE,
 };
 
+/* The following bits need to be updated before diagnostics mode is set. */
+static const struct reg_update diagnostic_state[NUM_IB] = {
+	{ TDA7802_IB0, 0, 0 },
+	{ TDA7802_IB1, 0, 0 },
+	{ TDA7802_IB2,
+		IB2_CH13_UNMUTED | IB2_CH24_UNMUTED | IB2_DIGITAL_MUTE_DISABLED,
+		IB2_CH13_UNMUTED | IB2_CH24_UNMUTED | IB2_DIGITAL_MUTE_DISABLED,
+	},
+	{ TDA7802_IB3, 0, 0 },
+	{ TDA7802_IB4, IB4_DIAG_MODE_ENABLE, 0 },
+	{ TDA7802_IB5, IB5_AMPLIFIER_ON, 0 },
+};
+
 static int tda7802_digital_mute(struct snd_soc_dai *dai, int mute)
 {
 	const u8 mute_disabled = mute ? 0 : IB2_DIGITAL_MUTE_DISABLED;
@@ -414,7 +446,6 @@ static const struct snd_kcontrol_new tda7802_snd_controls[] = {
 	SOC_SINGLE("AC diag enable", TDA7802_IB4, 3, 1, 0),
 	SOC_ENUM("Diag mode channels 1 & 3", diag_mode_ch13),
 	SOC_ENUM("Diag mode channels 2 & 4", diag_mode_ch24),
-	SOC_SINGLE("Diag mode enable", TDA7802_IB4, 0, 1, 0),
 
 	SOC_ENUM("Clipping detect channels 1 & 3", clip_detect_ch13),
 	SOC_ENUM("Clipping detect channels 2 & 4", clip_detect_ch24),
@@ -432,7 +463,160 @@ static const struct snd_soc_dapm_route tda7802_dapm_routes[] = {
 	{ "SPK", NULL, "DAC" },
 };
 
+static int tda7802_bulk_update(struct regmap *map, struct reg_update *update,
+		size_t update_count)
+{
+	int i, err;
+
+	for (i = 0; i < update_count; i++) {
+		err = regmap_update_bits(map, update[i].reg, update[i].mask,
+				update[i].val);
+		if (err < 0)
+			return err;
+	}
+
+	return i;
+}
+
+static int run_turn_on_diagnostic(struct tda7802_priv *tda7802, u8 *status)
+{
+	struct device *dev = &tda7802->i2c->dev;
+	int err_status, err;
+	unsigned int val;
+	u8 state[NUM_IB];
+
+	dev_dbg(dev, "%s\n", __func__);
+
+	/* Save state and prepare for diagnostic */
+	err = regmap_bulk_read(tda7802->regmap, TDA7802_IB0, state,
+			ARRAY_SIZE(state));
+	if (err < 0) {
+		dev_err(dev, "Could not save device state, %d\n", err);
+		return err;
+	}
+
+	err = tda7802_bulk_update(tda7802->regmap, diagnostic_state,
+			ARRAY_SIZE(diagnostic_state));
+	if (err < 0) {
+		dev_err(dev, "Could not prepare for diagnostics, %d\n", err);
+		goto diagnostic_restore;
+	}
+
+	/* We must wait 20ms for device to settle, otherwise diagnostics will
+	 * not start and regmap poll will timeout.
+	 */
+	msleep(DIAGNOSTIC_SETTLE_MS);
+
+	/* Turn on diagnostic */
+	err = regmap_update_bits(tda7802->regmap, TDA7802_IB4,
+			IB4_DIAG_MODE_ENABLE, IB4_DIAG_MODE_ENABLE);
+	if (err < 0) {
+		dev_err(dev, "Could not enable diagnostic mode, %d\n", err);
+		goto diagnostic_restore;
+	}
+
+	/* Wait until DB0_STARTUP_DIAG_STATUS is set, then read status */
+	err_status = regmap_read_poll_timeout(tda7802->regmap, TDA7802_DB0, val,
+			val & DB0_STARTUP_DIAG_STATUS,
+			DIAGNOSTIC_POLL_PERIOD_US,
+			DIAGNOSTIC_TIMEOUT_US);
+	if (err_status < 0) {
+		dev_err(dev, "Diagnostic did not complete, err %d, reg %x",
+				err_status, val);
+		goto diagnostic_restore;
+	}
+
+	err = regmap_bulk_read(tda7802->regmap, TDA7802_DB1, status, 4);
+	if (err < 0) {
+		dev_err(dev, "Could not read channel status, %d\n", err);
+		goto diagnostic_restore;
+	}
+
+diagnostic_restore:
+	err = regmap_bulk_write(tda7802->regmap, TDA7802_IB0, state,
+			ARRAY_SIZE(state));
+	if (err < 0)
+		dev_err(dev, "Could not restore state, %d\n", err);
+
+	if (err_status < 0)
+		return err_status;
+	else
+		return err;
+}
+
+static int tda7802_diagnostic_show(struct seq_file *f, void *p)
+{
+	char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	struct tda7802_priv *tda7802 = f->private;
+	u8 status[4] = { 0 };
+	int i, err;
+
+	mutex_lock(&tda7802->diagnostic_mutex);
+	err = run_turn_on_diagnostic(tda7802, status);
+	mutex_unlock(&tda7802->diagnostic_mutex);
+	if (err < 0)
+		return err;
+
+	for (i = 0; i < ARRAY_SIZE(status); i++)
+		seq_printf(f, "%02x: %02x\n", TDA7802_DB1+i, status[i]);
+
+	return 0;
+}
+
+static int tda7802_diagnostic_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, tda7802_diagnostic_show, inode->i_private);
+}
+
+static const struct file_operations tda7802_diagnostic_fops = {
+	.open = tda7802_diagnostic_open,
+	.read = seq_read,
+	.llseek = seq_lseek,
+	.release = single_release,
+};
+
+static int tda7802_probe(struct snd_soc_component *component)
+{
+	struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
+	struct device *dev = &tda7802->i2c->dev;
+	int err;
+
+	tda7802->debugfs = debugfs_create_dir(dev_name(dev), NULL);
+	if (IS_ERR_OR_NULL(tda7802->debugfs)) {
+		dev_info(dev,
+			"Failed to create debugfs node, err %ld\n",
+			PTR_ERR(tda7802->debugfs));
+		return 0;
+	}
+
+	mutex_init(&tda7802->diagnostic_mutex);
+	err = debugfs_create_file("diagnostic", 0444, tda7802->debugfs, tda7802,
+			&tda7802_diagnostic_fops);
+	if (err < 0) {
+		dev_err(dev,
+			"debugfs: Failed to create diagnostic node, err %d\n",
+			err);
+		goto cleanup_diagnostic;
+	}
+
+	return 0;
+
+cleanup_diagnostic:
+	mutex_destroy(&tda7802->diagnostic_mutex);
+	return err;
+}
+
+static void tda7802_remove(struct snd_soc_component *component)
+{
+	struct tda7802_priv *tda7802 = snd_soc_component_get_drvdata(component);
+
+	debugfs_remove_recursive(tda7802->debugfs);
+	mutex_destroy(&tda7802->diagnostic_mutex);
+}
+
 static const struct snd_soc_component_driver tda7802_component_driver = {
+	.probe = tda7802_probe,
+	.remove = tda7802_remove,
 	.set_bias_level = tda7802_set_bias_level,
 	.idle_bias_on = 1,
 	.suspend_bias_off = 1,
-- 
2.21.0

  parent reply	other threads:[~2019-07-30 12:10 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-30 12:09 [PATCH v2 0/3] ASoC: Codecs: Add TDA7802 codec Thomas Preston
2019-07-30 12:09 ` Thomas Preston
2019-07-30 12:09 ` [PATCH v2 1/3] dt-bindings: ASoC: Add TDA7802 amplifier Thomas Preston
2019-07-30 12:09   ` Thomas Preston
2019-07-30 12:27   ` Charles Keepax
2019-07-30 12:27     ` Charles Keepax
2019-07-30 13:12     ` Marco Felsch
2019-07-30 13:12       ` Marco Felsch
2019-07-30 14:12       ` [alsa-devel] " Thomas Preston
2019-07-30 14:33         ` Mark Brown
2019-07-30 14:10     ` Thomas Preston
2019-07-30 12:09 ` [PATCH v2 2/3] ASoC: Add codec driver for ST TDA7802 Thomas Preston
2019-07-30 12:09   ` Thomas Preston
2019-07-30 12:38   ` Charles Keepax
2019-07-30 12:38     ` Charles Keepax
2019-07-30 15:49     ` [alsa-devel] " Thomas Preston
2019-07-30 14:58   ` Mark Brown
2019-07-30 14:58     ` Mark Brown
2019-07-30 17:26     ` [alsa-devel] " Thomas Preston
2019-07-31  6:06       ` Marco Felsch
2019-07-31  8:57         ` Thomas Preston
2019-07-30 12:09 ` Thomas Preston [this message]
2019-07-30 12:09   ` [PATCH v2 3/3] ASoC: TDA7802: Add turn-on diagnostic routine Thomas Preston
2019-07-30 12:41   ` Charles Keepax
2019-07-30 12:41     ` Charles Keepax
2019-07-30 14:04     ` [alsa-devel] " Thomas Preston
2019-07-30 14:18       ` Charles Keepax
2019-07-30 14:18         ` Charles Keepax
2019-07-30 14:20       ` [alsa-devel] " Mark Brown
2019-07-30 15:27         ` Thomas Preston
2019-07-30 14:19   ` Mark Brown
2019-07-30 14:19     ` Mark Brown
2019-07-30 15:25     ` [alsa-devel] " Thomas Preston
2019-07-30 15:50       ` Mark Brown
2019-07-30 16:28         ` Thomas Preston
2019-07-31  8:03           ` Charles Keepax
2019-07-31  8:03             ` Charles Keepax
2019-08-01 23:42           ` Mark Brown
2019-08-02  8:32             ` Thomas Preston
2019-08-02 11:10               ` Mark Brown
2019-08-02 14:51                 ` Thomas Preston
2019-08-02 17:27                   ` Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190730120937.16271-4-thomas.preston@codethink.co.uk \
    --to=thomas.preston@codethink.co.uk \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=ckeepax@opensource.cirrus.com \
    --cc=cychiang@chromium.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jbrunet@baylibre.com \
    --cc=kmarinushkin@birdec.tech \
    --cc=kuninori.morimoto.gx@renesas.com \
    --cc=lgirdwood@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.felsch@pengutronix.de \
    --cc=mark.rutland@arm.com \
    --cc=nh6z@nh6z.net \
    --cc=paul@crapouillou.net \
    --cc=perex@perex.cz \
    --cc=robh+dt@kernel.org \
    --cc=srinivas.kandagatla@linaro.org \
    --cc=tiwai@suse.com \
    --cc=vkoul@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.