linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances
@ 2016-06-18  3:26 Helen Koike
  2016-06-18  3:26 ` [PATCH 1/4] ASoC: tpa6130a2: Register component Helen Koike
                   ` (5 more replies)
  0 siblings, 6 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-18  3:26 UTC (permalink / raw)
  To: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai
  Cc: Helen Koike

The current tpa6130a2 driver supports only a single instance.
This patch series add support for multiple instances by removing the global
variable that holds the instance.
This is performed by using the component API, regmap, the
snd_soc_{info,put,get}_volsw API and DAPM.

This patch series also touches code from the Nokia RX51 which I didn't tested (as
I am testing the tpa6130a2 in another board that is not upstream).
I would appreciate is if someone who possesses the Nokia RX51 (n900) could please
test the code.

This patch series is based on git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Available at https://git.collabora.com/cgit/user/koike/linux.git/log/?h=sound/review/tpa6130a2

Helen Koike (4):
  ASoC: tpa6130a2: Register component
  ASoC: tap6130a2: Use regmap
  ASoC: tpa6130a2: Use snd soc volsw functions
  ASoC: tpa6130a2: Add DAPM support

 sound/soc/codecs/tpa6130a2.c | 382 ++++++++++++-------------------------------
 sound/soc/codecs/tpa6130a2.h |  14 +-
 sound/soc/omap/rx51.c        |  45 ++---
 3 files changed, 130 insertions(+), 311 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH 1/4] ASoC: tpa6130a2: Register component
  2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
@ 2016-06-18  3:26 ` Helen Koike
  2016-06-18 22:28   ` Sebastian Reichel
  2016-06-18  3:26 ` [PATCH 2/4] ASoC: tap6130a2: Use regmap Helen Koike
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Helen Koike @ 2016-06-18  3:26 UTC (permalink / raw)
  To: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai
  Cc: Helen Koike

Add tpa6130a2 controls by the component API and update rx51 accordingly

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
---
 sound/soc/codecs/tpa6130a2.c | 26 +++++++++++++-------------
 sound/soc/codecs/tpa6130a2.h |  1 -
 sound/soc/omap/rx51.c        | 23 ++++++++++++-----------
 3 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 11d85c5..f700d92 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -348,23 +348,22 @@ int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
 }
 EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
 
-int tpa6130a2_add_controls(struct snd_soc_codec *codec)
+static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
-	struct	tpa6130a2_data *data;
-
-	if (tpa6130a2_client == NULL)
-		return -ENODEV;
-
-	data = i2c_get_clientdata(tpa6130a2_client);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
 
 	if (data->id == TPA6140A2)
-		return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
-						ARRAY_SIZE(tpa6140a2_controls));
+		return snd_soc_add_component_controls(component,
+			tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls));
 	else
-		return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
-						ARRAY_SIZE(tpa6130a2_controls));
+		return snd_soc_add_component_controls(component,
+			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
-EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
+
+struct snd_soc_component_driver tpa6130a2_component_driver = {
+	.name = "tpa6130a2",
+	.probe = tpa6130a2_component_probe,
+};
 
 static int tpa6130a2_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
@@ -451,7 +450,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (ret != 0)
 		goto err_gpio;
 
-	return 0;
+	return devm_snd_soc_register_component(&client->dev,
+			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
 	tpa6130a2_client = NULL;
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 4174440..78ee723 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -56,7 +56,6 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
 extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
 
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 5494924..b59cf89 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -286,16 +286,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
 
 static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_card *card = rtd->card;
 	struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
 	int err;
 
-	err = tpa6130a2_add_controls(codec);
-	if (err < 0) {
-		dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
-		return err;
-	}
 	snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
 
 	err = omap_mcbsp_st_add_controls(rtd, 2);
@@ -357,6 +351,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
 		.name = "TLV320AIC34b",
 		.codec_name = "tlv320aic3x-codec.2-0019",
 	},
+	{
+		.name = "TPA61320A2",
+		.codec_name = "tpa6130a2.2-0060",
+	},
 };
 
 static struct snd_soc_codec_conf rx51_codec_conf[] = {
@@ -364,6 +362,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = {
 		.dev_name = "tlv320aic3x-codec.2-0019",
 		.name_prefix = "b",
 	},
+	{
+		.dev_name = "tpa6130a2.2-0060",
+		.name_prefix = "TPA6130A2",
+	},
 };
 
 /* Audio card */
@@ -435,11 +437,10 @@ static int rx51_soc_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
 			return -EINVAL;
 		}
-
-		/* TODO: tpa6130a2a driver supports only a single instance, so
-		 * this driver ignores the headphone-amplifier node for now.
-		 * It's already mandatory in the DT binding to be future proof.
-		 */
+		rx51_aux_dev[1].codec_name = NULL;
+		rx51_aux_dev[1].codec_of_node = dai_node;
+		rx51_codec_conf[1].dev_name = NULL;
+		rx51_codec_conf[1].of_node = dai_node;
 	}
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 2/4] ASoC: tap6130a2: Use regmap
  2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
  2016-06-18  3:26 ` [PATCH 1/4] ASoC: tpa6130a2: Register component Helen Koike
@ 2016-06-18  3:26 ` Helen Koike
  2016-06-18 22:33   ` Sebastian Reichel
  2016-06-23 14:38   ` Applied "ASoC: tap6130a2: Use regmap" to the asoc tree Mark Brown
  2016-06-18  3:26 ` [PATCH 3/4] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-18  3:26 UTC (permalink / raw)
  To: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai
  Cc: Helen Koike

Use regmap instead of open-coding IO access and caching

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
---
 sound/soc/codecs/tpa6130a2.c | 166 ++++++++++++-------------------------------
 sound/soc/codecs/tpa6130a2.h |   2 -
 2 files changed, 46 insertions(+), 122 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index f700d92..0be70a4 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -32,6 +32,7 @@
 #include <sound/tlv.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/regmap.h>
 
 #include "tpa6130a2.h"
 
@@ -45,92 +46,16 @@ static struct i2c_client *tpa6130a2_client;
 /* This struct is used to save the context */
 struct tpa6130a2_data {
 	struct mutex mutex;
-	unsigned char regs[TPA6130A2_CACHEREGNUM];
+	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
 	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_i2c_read(int reg)
-{
-	struct tpa6130a2_data *data;
-	int val;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	/* If powered off, return the cached value */
-	if (data->power_state) {
-		val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
-		if (val < 0)
-			dev_err(&tpa6130a2_client->dev, "Read failed\n");
-		else
-			data->regs[reg] = val;
-	} else {
-		val = data->regs[reg];
-	}
-
-	return val;
-}
-
-static int tpa6130a2_i2c_write(int reg, u8 value)
-{
-	struct tpa6130a2_data *data;
-	int val = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (data->power_state) {
-		val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
-		if (val < 0) {
-			dev_err(&tpa6130a2_client->dev, "Write failed\n");
-			return val;
-		}
-	}
-
-	/* Either powered on or off, we save the context */
-	data->regs[reg] = value;
-
-	return val;
-}
-
-static u8 tpa6130a2_read(int reg)
-{
-	struct tpa6130a2_data *data;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return 0;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	return data->regs[reg];
-}
-
-static int tpa6130a2_initialize(void)
-{
-	struct tpa6130a2_data *data;
-	int i, ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	for (i = 1; i < TPA6130A2_REG_VERSION; i++) {
-		ret = tpa6130a2_i2c_write(i, data->regs[i]);
-		if (ret < 0)
-			break;
-	}
-
-	return ret;
-}
-
 static int tpa6130a2_power(u8 power)
 {
 	struct	tpa6130a2_data *data;
-	u8	val;
 	int	ret = 0;
 
 	if (WARN_ON(!tpa6130a2_client))
@@ -153,7 +78,7 @@ static int tpa6130a2_power(u8 power)
 			gpio_set_value(data->power_gpio, 1);
 
 		data->power_state = 1;
-		ret = tpa6130a2_initialize();
+		ret = regcache_sync(data->regmap);
 		if (ret < 0) {
 			dev_err(&tpa6130a2_client->dev,
 				"Failed to initialize chip\n");
@@ -165,9 +90,8 @@ static int tpa6130a2_power(u8 power)
 		}
 	} else {
 		/* set SWS */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val |= TPA6130A2_SWS;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+			TPA6130A2_SWS, TPA6130A2_SWS);
 
 		/* Power off */
 		if (data->power_gpio >= 0)
@@ -181,6 +105,8 @@ static int tpa6130a2_power(u8 power)
 		}
 
 		data->power_state = 0;
+		/* device regs does not match the cache state anymore */
+		regcache_mark_dirty(data->regmap);
 	}
 
 exit:
@@ -196,7 +122,7 @@ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
 	struct tpa6130a2_data *data;
 	unsigned int reg = mc->reg;
 	unsigned int shift = mc->shift;
-	int max = mc->max;
+	int max = mc->max, val;
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 
@@ -206,8 +132,8 @@ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&data->mutex);
 
-	ucontrol->value.integer.value[0] =
-		(tpa6130a2_read(reg) >> shift) & mask;
+	regmap_read(data->regmap, reg, &val);
+	ucontrol->value.integer.value[0] = (val >> shift) & mask;
 
 	if (invert)
 		ucontrol->value.integer.value[0] =
@@ -229,7 +155,7 @@ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned int val = (ucontrol->value.integer.value[0] & mask);
-	unsigned int val_reg;
+	bool change;
 
 	if (WARN_ON(!tpa6130a2_client))
 		return -EINVAL;
@@ -239,20 +165,11 @@ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
 		val = max - val;
 
 	mutex_lock(&data->mutex);
-
-	val_reg = tpa6130a2_read(reg);
-	if (((val_reg >> shift) & mask) == val) {
-		mutex_unlock(&data->mutex);
-		return 0;
-	}
-
-	val_reg &= ~(mask << shift);
-	val_reg |= val << shift;
-	tpa6130a2_i2c_write(reg, val_reg);
-
+	regmap_update_bits_check(data->regmap, reg, mask << shift, val << shift,
+				 &change);
 	mutex_unlock(&data->mutex);
 
-	return 1;
+	return change;
 }
 
 /*
@@ -301,31 +218,26 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
  */
 static void tpa6130a2_channel_enable(u8 channel, int enable)
 {
-	u8	val;
+	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
 
 	if (enable) {
 		/* Enable channel */
 		/* Enable amplifier */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val |= channel;
-		val &= ~TPA6130A2_SWS;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
 
 		/* Unmute channel */
-		val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
-		val &= ~channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
+				   channel, 0);
 	} else {
 		/* Disable channel */
 		/* Mute channel */
-		val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
-		val |= channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
+				   channel, channel);
 
 		/* Disable amplifier */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val &= ~channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+				   channel, 0);
 	}
 }
 
@@ -365,6 +277,20 @@ struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.probe = tpa6130a2_component_probe,
 };
 
+static const struct reg_default tpa6130a2_reg_defaults[] = {
+	{ TPA6130A2_REG_CONTROL, TPA6130A2_SWS },
+	{ TPA6130A2_REG_VOL_MUTE, TPA6130A2_MUTE_R | TPA6130A2_MUTE_L },
+};
+
+static const struct regmap_config tpa6130a2_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TPA6130A2_REG_VERSION,
+	.reg_defaults = tpa6130a2_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(tpa6130a2_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
 static int tpa6130a2_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
 {
@@ -373,6 +299,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	struct tpa6130a2_platform_data *pdata = client->dev.platform_data;
 	struct device_node *np = client->dev.of_node;
 	const char *regulator;
+	unsigned int version;
 	int ret;
 
 	dev = &client->dev;
@@ -381,6 +308,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (!data)
 		return -ENOMEM;
 
+	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
+	if (IS_ERR(data->regmap))
+		return PTR_ERR(data->regmap);
+
 	if (pdata) {
 		data->power_gpio = pdata->power_gpio;
 	} else if (np) {
@@ -399,11 +330,6 @@ static int tpa6130a2_probe(struct i2c_client *client,
 
 	mutex_init(&data->mutex);
 
-	/* Set default register values */
-	data->regs[TPA6130A2_REG_CONTROL] =	TPA6130A2_SWS;
-	data->regs[TPA6130A2_REG_VOL_MUTE] =	TPA6130A2_MUTE_R |
-						TPA6130A2_MUTE_L;
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -440,10 +366,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 
 
 	/* Read version */
-	ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
-				 TPA6130A2_VERSION_MASK;
-	if ((ret != 1) && (ret != 2))
-		dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
+	regmap_read(data->regmap, TPA6130A2_REG_VERSION, &version);
+	version &= TPA6130A2_VERSION_MASK;
+	if ((version != 1) && (version != 2))
+		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
 	ret = tpa6130a2_power(0);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 78ee723..ef05a3f 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -30,8 +30,6 @@
 #define TPA6130A2_REG_OUT_IMPEDANCE	0x03
 #define TPA6130A2_REG_VERSION		0x04
 
-#define TPA6130A2_CACHEREGNUM	(TPA6130A2_REG_VERSION + 1)
-
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
 #define TPA6130A2_SWS			(0x01 << 0)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 3/4] ASoC: tpa6130a2: Use snd soc volsw functions
  2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
  2016-06-18  3:26 ` [PATCH 1/4] ASoC: tpa6130a2: Register component Helen Koike
  2016-06-18  3:26 ` [PATCH 2/4] ASoC: tap6130a2: Use regmap Helen Koike
@ 2016-06-18  3:26 ` Helen Koike
  2016-06-18 22:34   ` Sebastian Reichel
  2016-06-18  3:26 ` [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support Helen Koike
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Helen Koike @ 2016-06-18  3:26 UTC (permalink / raw)
  To: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai
  Cc: Helen Koike

Use snd_soc_{info,get,put}_volsw instead of custom volume functions

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
---
 sound/soc/codecs/tpa6130a2.c | 64 ++------------------------------------------
 1 file changed, 2 insertions(+), 62 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 0be70a4..dc7bfc9 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -114,64 +114,6 @@ exit:
 	return ret;
 }
 
-static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
-		struct snd_ctl_elem_value *ucontrol)
-{
-	struct soc_mixer_control *mc =
-		(struct soc_mixer_control *)kcontrol->private_value;
-	struct tpa6130a2_data *data;
-	unsigned int reg = mc->reg;
-	unsigned int shift = mc->shift;
-	int max = mc->max, val;
-	unsigned int mask = (1 << fls(max)) - 1;
-	unsigned int invert = mc->invert;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-
-	regmap_read(data->regmap, reg, &val);
-	ucontrol->value.integer.value[0] = (val >> shift) & mask;
-
-	if (invert)
-		ucontrol->value.integer.value[0] =
-			max - ucontrol->value.integer.value[0];
-
-	mutex_unlock(&data->mutex);
-	return 0;
-}
-
-static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
-		struct snd_ctl_elem_value *ucontrol)
-{
-	struct soc_mixer_control *mc =
-		(struct soc_mixer_control *)kcontrol->private_value;
-	struct tpa6130a2_data *data;
-	unsigned int reg = mc->reg;
-	unsigned int shift = mc->shift;
-	int max = mc->max;
-	unsigned int mask = (1 << fls(max)) - 1;
-	unsigned int invert = mc->invert;
-	unsigned int val = (ucontrol->value.integer.value[0] & mask);
-	bool change;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (invert)
-		val = max - val;
-
-	mutex_lock(&data->mutex);
-	regmap_update_bits_check(data->regmap, reg, mask << shift, val << shift,
-				 &change);
-	mutex_unlock(&data->mutex);
-
-	return change;
-}
-
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -190,9 +132,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6130_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6130a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
+	SOC_SINGLE_TLV("TPA6130A2 Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
-		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6130_tlv),
 };
 
@@ -203,9 +144,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6140a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
+	SOC_SINGLE_TLV("TPA6140A2 Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
-		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6140_tlv),
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support
  2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
                   ` (2 preceding siblings ...)
  2016-06-18  3:26 ` [PATCH 3/4] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
@ 2016-06-18  3:26 ` Helen Koike
  2016-06-18 23:21   ` Sebastian Reichel
  2016-06-20  8:34   ` Peter Ujfalusi
  2016-06-18 10:40 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
  2016-06-19 20:14 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
  5 siblings, 2 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-18  3:26 UTC (permalink / raw)
  To: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai
  Cc: Helen Koike

Add DAPM support and updated rx51 accordingly.
As a consequence:
- the exported function tpa6130a2_stereo_enable is not needed anymore
- the mutex is dealt in the DAPM
- the power state is tracked by the DAPM

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
---
 sound/soc/codecs/tpa6130a2.c | 184 +++++++++++++++++--------------------------
 sound/soc/codecs/tpa6130a2.h |  11 +--
 sound/soc/omap/rx51.c        |  22 ++----
 3 files changed, 86 insertions(+), 131 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index dc7bfc9..7cb5066 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -41,79 +41,71 @@ enum tpa_model {
 	TPA6140A2,
 };
 
-static struct i2c_client *tpa6130a2_client;
-
 /* This struct is used to save the context */
 struct tpa6130a2_data {
-	struct mutex mutex;
 	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
-	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_power(u8 power)
+static int tpa6130a2_power(struct device *dev, bool enable)
 {
-	struct	tpa6130a2_data *data;
-	int	ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-	if (power == data->power_state)
-		goto exit;
+	struct tpa6130a2_data *data = dev_get_drvdata(dev);
+	int ret;
 
-	if (power) {
+	if (enable) {
 		ret = regulator_enable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
-				"Failed to enable supply: %d\n", ret);
-			goto exit;
+			dev_err(dev, "Failed to enable supply: %d\n", ret);
+			return ret;
 		}
 		/* Power on */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 1);
-
-		data->power_state = 1;
-		ret = regcache_sync(data->regmap);
-		if (ret < 0) {
-			dev_err(&tpa6130a2_client->dev,
-				"Failed to initialize chip\n");
-			if (data->power_gpio >= 0)
-				gpio_set_value(data->power_gpio, 0);
-			regulator_disable(data->supply);
-			data->power_state = 0;
-			goto exit;
-		}
 	} else {
-		/* set SWS */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			TPA6130A2_SWS, TPA6130A2_SWS);
-
 		/* Power off */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 0);
 
 		ret = regulator_disable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
-				"Failed to disable supply: %d\n", ret);
-			goto exit;
+			dev_err(dev, "Failed to disable supply: %d\n", ret);
+			return ret;
 		}
 
-		data->power_state = 0;
 		/* device regs does not match the cache state anymore */
 		regcache_mark_dirty(data->regmap);
 	}
 
-exit:
-	mutex_unlock(&data->mutex);
 	return ret;
 }
 
+static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kctrl, int event)
+{
+	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
+	int ret;
+
+	/* before widget power up */
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Turn on the chip */
+		tpa6130a2_power(c->dev, true);
+		/* Sync the registers */
+		ret = regcache_sync(data->regmap);
+		if (ret < 0) {
+			dev_err(c->dev, "Failed to initialize chip\n");
+			tpa6130a2_power(c->dev, false);
+			return ret;
+		}
+	/* after widget power down */
+	} else
+		tpa6130a2_power(c->dev, false);
+
+	return 0;
+}
+
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -149,57 +141,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
 		       tpa6140_tlv),
 };
 
-/*
- * Enable or disable channel (left or right)
- * The bit number for mute and amplifier are the same per channel:
- * bit 6: Right channel
- * bit 7: Left channel
- * in both registers.
- */
-static void tpa6130a2_channel_enable(u8 channel, int enable)
-{
-	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (enable) {
-		/* Enable channel */
-		/* Enable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
-
-		/* Unmute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, 0);
-	} else {
-		/* Disable channel */
-		/* Mute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, channel);
-
-		/* Disable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-				   channel, 0);
-	}
-}
-
-int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
-{
-	int ret = 0;
-	if (enable) {
-		ret = tpa6130a2_power(1);
-		if (ret < 0)
-			return ret;
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 1);
-	} else {
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 0);
-		ret = tpa6130a2_power(0);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
-
 static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
 	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
@@ -212,9 +153,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
 			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
 
+static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("LEFTIN"),
+	SND_SOC_DAPM_INPUT("RIGHTIN"),
+	SND_SOC_DAPM_OUTPUT("HPLEFT"),
+	SND_SOC_DAPM_OUTPUT("HPRIGHT"),
+
+	SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
+			    TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
+	{ "Left PGA", NULL, "LEFTIN" },
+	{ "Right PGA", NULL, "RIGHTIN" },
+
+	{ "Left Mute", NULL, "Left PGA" },
+	{ "Right Mute", NULL, "Right PGA" },
+
+	{ "HPLEFT", NULL, "Left Mute" },
+	{ "HPRIGHT", NULL, "Right Mute" },
+
+	{ "Left PGA", NULL, "Power" },
+	{ "Right PGA", NULL, "Power" },
+};
+
 struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.name = "tpa6130a2",
 	.probe = tpa6130a2_component_probe,
+	.dapm_widgets = tpa6130a2_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
+	.dapm_routes = tpa6130a2_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
 };
 
 static const struct reg_default tpa6130a2_reg_defaults[] = {
@@ -262,14 +241,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	tpa6130a2_client = client;
-
-	i2c_set_clientdata(tpa6130a2_client, data);
+	i2c_set_clientdata(client, data);
 
 	data->id = id->driver_data;
 
-	mutex_init(&data->mutex);
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -300,7 +275,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		goto err_gpio;
 	}
 
-	ret = tpa6130a2_power(1);
+	ret = tpa6130a2_power(dev, true);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -312,7 +287,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
-	ret = tpa6130a2_power(0);
+	ret = tpa6130a2_power(dev, false);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -320,19 +295,9 @@ static int tpa6130a2_probe(struct i2c_client *client,
 			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
-	tpa6130a2_client = NULL;
-
 	return ret;
 }
 
-static int tpa6130a2_remove(struct i2c_client *client)
-{
-	tpa6130a2_power(0);
-	tpa6130a2_client = NULL;
-
-	return 0;
-}
-
 static const struct i2c_device_id tpa6130a2_id[] = {
 	{ "tpa6130a2", TPA6130A2 },
 	{ "tpa6140a2", TPA6140A2 },
@@ -355,7 +320,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
 		.of_match_table = of_match_ptr(tpa6130a2_of_match),
 	},
 	.probe = tpa6130a2_probe,
-	.remove = tpa6130a2_remove,
 	.id_table = tpa6130a2_id,
 };
 
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index ef05a3f..f19cad5 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -32,15 +32,18 @@
 
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
-#define TPA6130A2_SWS			(0x01 << 0)
+#define TPA6130A2_SWS_SHIFT		0
+#define TPA6130A2_SWS			(0x01 << TPA6130A2_SWS_SHIFT)
 #define TPA6130A2_TERMAL		(0x01 << 1)
 #define TPA6130A2_MODE(x)		(x << 4)
 #define TPA6130A2_MODE_STEREO		(0x00)
 #define TPA6130A2_MODE_DUAL_MONO	(0x01)
 #define TPA6130A2_MODE_BRIDGE		(0x02)
 #define TPA6130A2_MODE_MASK		(0x03)
-#define TPA6130A2_HP_EN_R		(0x01 << 6)
-#define TPA6130A2_HP_EN_L		(0x01 << 7)
+#define TPA6130A2_HP_EN_R_SHIFT		6
+#define TPA6130A2_HP_EN_R		(0x01 << TPA6130A2_HP_EN_R_SHIFT)
+#define TPA6130A2_HP_EN_L_SHIFT		7
+#define TPA6130A2_HP_EN_L		(0x01 << TPA6130A2_HP_EN_L_SHIFT)
 
 /* TPA6130A2_REG_VOL_MUTE (0x02) */
 #define TPA6130A2_VOLUME(x)		((x & 0x3f) << 0)
@@ -54,6 +57,4 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
-
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index b59cf89..8c29a34 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -164,19 +164,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int rx51_hp_event(struct snd_soc_dapm_widget *w,
-			 struct snd_kcontrol *k, int event)
-{
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		tpa6130a2_stereo_enable(codec, 1);
-	else
-		tpa6130a2_stereo_enable(codec, 0);
-
-	return 0;
-}
-
 static int rx51_get_input(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
@@ -235,7 +222,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
 static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
 	SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
 	SND_SOC_DAPM_MIC("DMic", NULL),
-	SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 	SND_SOC_DAPM_MIC("HS Mic", NULL),
 	SND_SOC_DAPM_LINE("FM Transmitter", NULL),
 	SND_SOC_DAPM_SPK("Earphone", NULL),
@@ -246,11 +233,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Ext Spk", NULL, "HPROUT"},
 	{"Ext Spk", NULL, "HPLCOM"},
 	{"Ext Spk", NULL, "HPRCOM"},
-	{"Headphone Jack", NULL, "LLOUT"},
-	{"Headphone Jack", NULL, "RLOUT"},
 	{"FM Transmitter", NULL, "LLOUT"},
 	{"FM Transmitter", NULL, "RLOUT"},
 
+	{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
+	{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
+	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
+	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"},
+
 	{"DMic Rate 64", NULL, "DMic"},
 	{"DMic", NULL, "Mic Bias"},
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances
  2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
                   ` (3 preceding siblings ...)
  2016-06-18  3:26 ` [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support Helen Koike
@ 2016-06-18 10:40 ` Sebastian Reichel
  2016-06-18 21:33   ` Sebastian Reichel
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
  2016-06-19 20:14 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
  5 siblings, 2 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-18 10:40 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]

Hi,

On Sat, Jun 18, 2016 at 12:26:27AM -0300, Helen Koike wrote:
> The current tpa6130a2 driver supports only a single instance.
> This patch series add support for multiple instances by removing
> the global variable that holds the instance. This is performed by
> using the component API, regmap, the snd_soc_{info,put,get}_volsw
> API and DAPM.

yay! *stroking cleanup of the driver from my todo list*

> This patch series also touches code from the Nokia RX51 which I
> didn't tested (as I am testing the tpa6130a2 in another board, that
> is not upstream). I would appreciate is if someone who possesses
> the Nokia RX51 (n900) could please test the code.

I had a look at the rx51 parts and will test later/tomorrow.
From looking at the source code: You can also remove the
"../codecs/tpa6130a2.h" include from rx51.c.

> This patch series is based on git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
> Available at https://git.collabora.com/cgit/user/koike/linux.git/log/?h=sound/review/tpa6130a2
> 
> Helen Koike (4):
>   ASoC: tpa6130a2: Register component
>   ASoC: tap6130a2: Use regmap
>   ASoC: tpa6130a2: Use snd soc volsw functions
>   ASoC: tpa6130a2: Add DAPM support
> 
>  sound/soc/codecs/tpa6130a2.c | 382 ++++++++++++-------------------------------
>  sound/soc/codecs/tpa6130a2.h |  14 +-
>  sound/soc/omap/rx51.c        |  45 ++---
>  3 files changed, 130 insertions(+), 311 deletions(-)

nice stats :)

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances
  2016-06-18 10:40 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
@ 2016-06-18 21:33   ` Sebastian Reichel
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
  1 sibling, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-18 21:33 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 2284 bytes --]

Hi,

On Sat, Jun 18, 2016 at 12:40:38PM +0200, Sebastian Reichel wrote:
> On Sat, Jun 18, 2016 at 12:26:27AM -0300, Helen Koike wrote:
> > The current tpa6130a2 driver supports only a single instance.
> > This patch series add support for multiple instances by removing
> > the global variable that holds the instance. This is performed by
> > using the component API, regmap, the snd_soc_{info,put,get}_volsw
> > API and DAPM.
> 
> yay! *stroking cleanup of the driver from my todo list*
> 
> > This patch series also touches code from the Nokia RX51 which I
> > didn't tested (as I am testing the tpa6130a2 in another board, that
> > is not upstream). I would appreciate is if someone who possesses
> > the Nokia RX51 (n900) could please test the code.
> 
> I had a look at the rx51 parts and will test later/tomorrow.

Ok, here are some notes (I used the git branch you provided). First
of all kernel messages contain:

[    4.217163] ALSA: Control name 'TPA6130A2 TPA6130A2 Headphone Playback Volum' truncated to 'TPA6130A2 TPA6130A2 Headphone Playback Volu'

Next here is a amixer output diff:

root@n900:~# amixer > amixer.old (v4.7-rc [without your patches])
root@n900:~# amixer > amixer.new
root@n900:~# diff -u amixer.old amixer.new
--- amixer.old	2016-06-18 23:08:57.478027343 +0200
+++ amixer.new	2016-06-18 22:26:13.878102558 +0200
@@ -480,11 +480,12 @@
   Capabilities: pswitch pswitch-joined
   Playback channels: Mono
   Mono: Playback [off]
-Simple mixer control 'TPA6130A2 Headphone',0
-  Capabilities: pvolume pvolume-joined
+Simple mixer control 'TPA6130A2 TPA6130A2 Headphone Playback Volu',0
+  Capabilities: volume volume-joined
   Playback channels: Mono
-  Limits: Playback 0 - 42
-  Mono: Playback 0 [0%] [-59.50dB]
+  Capture channels: Mono
+  Limits: 0 - 63
+  Mono: 0 [0%]
 Simple mixer control 'b ADC HPF Cut-off',0
   Capabilities: enum
   Items: 'Disabled' '0.0045xFs' '0.0125xFs' '0.025xFs'

If I remember correctly, the reduced playback limit up to 42 is
important on N900, since hardware can be destroyed. It may have been
another control, though. Also the capture channel looks wrong.

Last but not least: Audio output doesn't work, but works on a kernel
without these changes.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 1/4] ASoC: tpa6130a2: Register component
  2016-06-18  3:26 ` [PATCH 1/4] ASoC: tpa6130a2: Register component Helen Koike
@ 2016-06-18 22:28   ` Sebastian Reichel
  0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-18 22:28 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 5484 bytes --]

Hi Helen,

On Sat, Jun 18, 2016 at 12:26:28AM -0300, Helen Koike wrote:
> Add tpa6130a2 controls by the component API and update rx51 accordingly
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
> ---
>  sound/soc/codecs/tpa6130a2.c | 26 +++++++++++++-------------
>  sound/soc/codecs/tpa6130a2.h |  1 -
>  sound/soc/omap/rx51.c        | 23 ++++++++++++-----------
>  3 files changed, 25 insertions(+), 25 deletions(-)
> 
> diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
> index 11d85c5..f700d92 100644
> --- a/sound/soc/codecs/tpa6130a2.c
> +++ b/sound/soc/codecs/tpa6130a2.c
> @@ -348,23 +348,22 @@ int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
>  }
>  EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
>  
> -int tpa6130a2_add_controls(struct snd_soc_codec *codec)
> +static int tpa6130a2_component_probe(struct snd_soc_component *component)
>  {
> -	struct	tpa6130a2_data *data;
> -
> -	if (tpa6130a2_client == NULL)
> -		return -ENODEV;
> -
> -	data = i2c_get_clientdata(tpa6130a2_client);
> +	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
>  
>  	if (data->id == TPA6140A2)
> -		return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
> -						ARRAY_SIZE(tpa6140a2_controls));
> +		return snd_soc_add_component_controls(component,
> +			tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls));
>  	else
> -		return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
> -						ARRAY_SIZE(tpa6130a2_controls));
> +		return snd_soc_add_component_controls(component,
> +			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
>  }
> -EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
> +
> +struct snd_soc_component_driver tpa6130a2_component_driver = {
> +	.name = "tpa6130a2",
> +	.probe = tpa6130a2_component_probe,
> +};
>  
>  static int tpa6130a2_probe(struct i2c_client *client,
>  			   const struct i2c_device_id *id)
> @@ -451,7 +450,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
>  	if (ret != 0)
>  		goto err_gpio;
>  
> -	return 0;
> +	return devm_snd_soc_register_component(&client->dev,
> +			&tpa6130a2_component_driver, NULL, 0);
>  
>  err_gpio:
>  	tpa6130a2_client = NULL;
> diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
> index 4174440..78ee723 100644
> --- a/sound/soc/codecs/tpa6130a2.h
> +++ b/sound/soc/codecs/tpa6130a2.h
> @@ -56,7 +56,6 @@
>  /* TPA6130A2_REG_VERSION (0x04) */
>  #define TPA6130A2_VERSION_MASK		(0x0f)
>  
> -extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
>  extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
>  
>  #endif /* __TPA6130A2_H__ */
> diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
> index 5494924..b59cf89 100644
> --- a/sound/soc/omap/rx51.c
> +++ b/sound/soc/omap/rx51.c
> @@ -286,16 +286,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
>  
>  static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
>  {
> -	struct snd_soc_codec *codec = rtd->codec;
>  	struct snd_soc_card *card = rtd->card;
>  	struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
>  	int err;
>  
> -	err = tpa6130a2_add_controls(codec);
> -	if (err < 0) {
> -		dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
> -		return err;
> -	}
>  	snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
>  
>  	err = omap_mcbsp_st_add_controls(rtd, 2);
> @@ -357,6 +351,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
>  		.name = "TLV320AIC34b",
>  		.codec_name = "tlv320aic3x-codec.2-0019",
>  	},
> +	{
> +		.name = "TPA61320A2",
> +		.codec_name = "tpa6130a2.2-0060",
> +	},
>  };
>  
>  static struct snd_soc_codec_conf rx51_codec_conf[] = {
> @@ -364,6 +362,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = {
>  		.dev_name = "tlv320aic3x-codec.2-0019",
>  		.name_prefix = "b",
>  	},
> +	{
> +		.dev_name = "tpa6130a2.2-0060",
> +		.name_prefix = "TPA6130A2",

This results in the control being named "TPA6130A2 TPA6130A2
Headphone Playback Volume", which is too long, so its shortened to
"TPA6130A2 TPA6130A2 Headphone Playback Volu".  That in turn results
in incorrect detection making it playback + capture and the
snd_soc_limit_volume() from above does not work.

I suggest to keep the name_prefix here and remove it in the codec
instead, so that other boards (esp. those with more than one TPA)
can choose another prefix.

> +	},
>  };
>  
>  /* Audio card */
> @@ -435,11 +437,10 @@ static int rx51_soc_probe(struct platform_device *pdev)
>  			dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
>  			return -EINVAL;
>  		}
> -
> -		/* TODO: tpa6130a2a driver supports only a single instance, so
> -		 * this driver ignores the headphone-amplifier node for now.
> -		 * It's already mandatory in the DT binding to be future proof.
> -		 */
> +		rx51_aux_dev[1].codec_name = NULL;
> +		rx51_aux_dev[1].codec_of_node = dai_node;
> +		rx51_codec_conf[1].dev_name = NULL;
> +		rx51_codec_conf[1].of_node = dai_node;
>  	}
>  
>  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);

If you fix the double prefix the patch is

Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 2/4] ASoC: tap6130a2: Use regmap
  2016-06-18  3:26 ` [PATCH 2/4] ASoC: tap6130a2: Use regmap Helen Koike
@ 2016-06-18 22:33   ` Sebastian Reichel
  2016-06-23 14:38   ` Applied "ASoC: tap6130a2: Use regmap" to the asoc tree Mark Brown
  1 sibling, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-18 22:33 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 353 bytes --]

Hi,

On Sat, Jun 18, 2016 at 12:26:29AM -0300, Helen Koike wrote:
> Use regmap instead of open-coding IO access and caching
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>

[On N900]
Tested-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 3/4] ASoC: tpa6130a2: Use snd soc volsw functions
  2016-06-18  3:26 ` [PATCH 3/4] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
@ 2016-06-18 22:34   ` Sebastian Reichel
  0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-18 22:34 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 365 bytes --]

Hi,

On Sat, Jun 18, 2016 at 12:26:30AM -0300, Helen Koike wrote:
> Use snd_soc_{info,get,put}_volsw instead of custom volume functions
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>

[On N900]
Tested-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support
  2016-06-18  3:26 ` [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support Helen Koike
@ 2016-06-18 23:21   ` Sebastian Reichel
  2016-06-19  9:39     ` Lars-Peter Clausen
  2016-06-20  8:34   ` Peter Ujfalusi
  1 sibling, 1 reply; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-18 23:21 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 431 bytes --]

Hi,

On Sat, Jun 18, 2016 at 12:26:31AM -0300, Helen Koike wrote:
> Add DAPM support and updated rx51 accordingly.
> As a consequence:
> - the exported function tpa6130a2_stereo_enable is not needed anymore
> - the mutex is dealt in the DAPM
> - the power state is tracked by the DAPM

This breaks headphone on N900. So far I only checked, that
tpa6130a2_power_event() is not called. I guess the DAPM
graph is wrong.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support
  2016-06-18 23:21   ` Sebastian Reichel
@ 2016-06-19  9:39     ` Lars-Peter Clausen
  2016-06-19 20:03       ` Sebastian Reichel
  0 siblings, 1 reply; 36+ messages in thread
From: Lars-Peter Clausen @ 2016-06-19  9:39 UTC (permalink / raw)
  To: Sebastian Reichel, Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, k.kozlowski,
	alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 741 bytes --]

On 06/19/2016 01:21 AM, Sebastian Reichel wrote:
> Hi,
> 
> On Sat, Jun 18, 2016 at 12:26:31AM -0300, Helen Koike wrote:
>> Add DAPM support and updated rx51 accordingly.
>> As a consequence:
>> - the exported function tpa6130a2_stereo_enable is not needed anymore
>> - the mutex is dealt in the DAPM
>> - the power state is tracked by the DAPM
> 
> This breaks headphone on N900. So far I only checked, that
> tpa6130a2_power_event() is not called. I guess the DAPM
> graph is wrong.

Can you try with

+	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
+	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"}

being replaced with

+       {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
+       {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},

Thanks,
- Lars



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support
  2016-06-19  9:39     ` Lars-Peter Clausen
@ 2016-06-19 20:03       ` Sebastian Reichel
  0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-19 20:03 UTC (permalink / raw)
  To: Lars-Peter Clausen
  Cc: Helen Koike, lgirdwood, broonie, peter.ujfalusi, jarkko.nikula,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 960 bytes --]

Hi,

On Sun, Jun 19, 2016 at 11:39:15AM +0200, Lars-Peter Clausen wrote:
> On 06/19/2016 01:21 AM, Sebastian Reichel wrote:
> > On Sat, Jun 18, 2016 at 12:26:31AM -0300, Helen Koike wrote:
> >> Add DAPM support and updated rx51 accordingly.
> >> As a consequence:
> >> - the exported function tpa6130a2_stereo_enable is not needed anymore
> >> - the mutex is dealt in the DAPM
> >> - the power state is tracked by the DAPM
> > 
> > This breaks headphone on N900. So far I only checked, that
> > tpa6130a2_power_event() is not called. I guess the DAPM
> > graph is wrong.
> 
> Can you try with
> 
> +	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
> +	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"}
> 
> being replaced with
> 
> +       {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
> +       {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},

With that change:

Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances
  2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
                   ` (4 preceding siblings ...)
  2016-06-18 10:40 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
@ 2016-06-19 20:14 ` Sebastian Reichel
  5 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-19 20:14 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai

[-- Attachment #1: Type: text/plain, Size: 1190 bytes --]

Hi,

On Sat, Jun 18, 2016 at 12:26:27AM -0300, Helen Koike wrote:
> The current tpa6130a2 driver supports only a single instance.
> This patch series add support for multiple instances by removing the global
> variable that holds the instance.
> This is performed by using the component API, regmap, the
> snd_soc_{info,put,get}_volsw API and DAPM.
> 
> This patch series also touches code from the Nokia RX51 which I didn't tested (as
> I am testing the tpa6130a2 in another board that is not upstream).
> I would appreciate is if someone who possesses the Nokia RX51 (n900) could please
> test the code.
> 
> This patch series is based on git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
> Available at https://git.collabora.com/cgit/user/koike/linux.git/log/?h=sound/review/tpa6130a2

Locking at the resulting tpa6130a2.c I suggest to add a patch
removing the useless "goto err_gpio" in tpa6130a2_probe().

Also switching to gpiod_get() safes some more lines of code.
It may make sense to postpone this to 4.9, though (this change
involves removing the gpio from the platform data and the rx51
will become DT only in 4.8).

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support
  2016-06-18  3:26 ` [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support Helen Koike
  2016-06-18 23:21   ` Sebastian Reichel
@ 2016-06-20  8:34   ` Peter Ujfalusi
  1 sibling, 0 replies; 36+ messages in thread
From: Peter Ujfalusi @ 2016-06-20  8:34 UTC (permalink / raw)
  To: Helen Koike, lgirdwood, broonie, perex, tiwai, jarkko.nikula,
	lars, k.kozlowski, alsa-devel, linux-kernel, linux-omap

On 06/18/2016 07:42 AM, Helen Koike wrote:
> Add DAPM support and updated rx51 accordingly.
> As a consequence:
> - the exported function tpa6130a2_stereo_enable is not needed anymore
> - the mutex is dealt in the DAPM
> - the power state is tracked by the DAPM
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
> ---
>  sound/soc/codecs/tpa6130a2.c | 184 +++++++++++++++++--------------------------
>  sound/soc/codecs/tpa6130a2.h |  11 +--
>  sound/soc/omap/rx51.c        |  22 ++----
>  3 files changed, 86 insertions(+), 131 deletions(-)
> 
> diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
> index dc7bfc9..7cb5066 100644
> --- a/sound/soc/codecs/tpa6130a2.c
> +++ b/sound/soc/codecs/tpa6130a2.c
> @@ -41,79 +41,71 @@ enum tpa_model {
>  	TPA6140A2,
>  };
>  
> -static struct i2c_client *tpa6130a2_client;
> -
>  /* This struct is used to save the context */
>  struct tpa6130a2_data {
> -	struct mutex mutex;
>  	struct regmap *regmap;
>  	struct regulator *supply;
>  	int power_gpio;
> -	u8 power_state:1;
>  	enum tpa_model id;
>  };
>  
> -static int tpa6130a2_power(u8 power)
> +static int tpa6130a2_power(struct device *dev, bool enable)

I would rather add 'struct device *dev' to tpa6130a2_data and pass the pointer
to the private struct instead to the device.

>  {
> -	struct	tpa6130a2_data *data;
> -	int	ret = 0;
> -
> -	if (WARN_ON(!tpa6130a2_client))
> -		return -EINVAL;
> -	data = i2c_get_clientdata(tpa6130a2_client);
> -
> -	mutex_lock(&data->mutex);
> -	if (power == data->power_state)
> -		goto exit;
> +	struct tpa6130a2_data *data = dev_get_drvdata(dev);
> +	int ret;
>  
> -	if (power) {
> +	if (enable) {

-- 
Péter

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 0/5] ASoC: tpa6130a2: Add support for multiple instances
  2016-06-18 10:40 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
  2016-06-18 21:33   ` Sebastian Reichel
@ 2016-06-20 17:12   ` Helen Koike
  2016-06-20 17:12     ` [PATCH v2 1/5] ASoC: tpa6130a2: Register component Helen Koike
                       ` (5 more replies)
  1 sibling, 6 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-20 17:12 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

The current tpa6130a2 driver supports only a single instance.
This patch series add support for multiple instances by removing the global
variable that holds the instance.
This is performed by using the component API, regmap, the
snd_soc_{info,put,get}_volsw API and DAPM.

This patch series also touches code from the Nokia RX51 which I didn't tested (as
I am testing the tpa6130a2 in another board that is not upstream).
I would appreciate is if someone who possesses the Nokia RX51 (n900) could please
test the code.

This patch series is based on git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Available at https://git.collabora.com/cgit/user/koike/linux.git/log/?h=sound/review/tpa6130a2

Helen Koike (5):
  ASoC: tpa6130a2: Register component
  ASoC: tap6130a2: Use regmap
  ASoC: tpa6130a2: Use snd soc volsw functions
  ASoC: tpa6130a2: Add DAPM support
  ASoC: tpa6130a2: Remove goto err_gpio

 sound/soc/codecs/tpa6130a2.c | 393 ++++++++++++-------------------------------
 sound/soc/codecs/tpa6130a2.h |  14 +-
 sound/soc/omap/rx51.c        |  46 ++---
 3 files changed, 136 insertions(+), 317 deletions(-)


Changes since v1:
  ASoC: tpa6130a2: Register component
	- Remove prefix from snd_kcontrol_new in tpa6130a2.c
	- Add tested-by and reviewd-by from Sebastian
  ASoC: tap6130a2: Use regmap
	- Add tested-by from Sebastian
  ASoC: tpa6130a2: Use snd soc volsw functions
	- Add tested-by from Sebastian
  ASoC: tpa6130a2: Add DAPM support
	- Replace
		+	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
		+	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"}
	
		by
	
		+       {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
		+       {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
	- Add tested-by and reviewed-by from Sebastian
	- Add struct device dev* in struct tpa6130a2_data and pass data instead
	of dev to tpa6130a2_power function
	- remove #include "../codecs/tpa6130a2.h" in rx51.c
  ASoC: tpa6130a2: Remove goto err_gpio
	- this is a new patch in the series
-- 
1.9.1

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v2 1/5] ASoC: tpa6130a2: Register component
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
@ 2016-06-20 17:12     ` Helen Koike
  2016-06-23 14:38       ` Applied "ASoC: tpa6130a2: Register component" to the asoc tree Mark Brown
  2016-06-20 17:12     ` [PATCH v2 2/5] ASoC: tap6130a2: Use regmap Helen Koike
                       ` (4 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Helen Koike @ 2016-06-20 17:12 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Add tpa6130a2 controls by the component API and update rx51 accordingly

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>

---

Changes since v1:
- Remove prefix from snd_kcontrol_new in tpa6130a2.c
- Add tested-by and reviewd-by from Sebastian

 sound/soc/codecs/tpa6130a2.c | 30 +++++++++++++++---------------
 sound/soc/codecs/tpa6130a2.h |  1 -
 sound/soc/omap/rx51.c        | 23 ++++++++++++-----------
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 11d85c5..f31326a 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -273,7 +273,7 @@ static const DECLARE_TLV_DB_RANGE(tpa6130_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6130a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
+	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
 		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6130_tlv),
@@ -286,7 +286,7 @@ static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6140a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
+	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
 		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6140_tlv),
@@ -348,23 +348,22 @@ int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
 }
 EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
 
-int tpa6130a2_add_controls(struct snd_soc_codec *codec)
+static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
-	struct	tpa6130a2_data *data;
-
-	if (tpa6130a2_client == NULL)
-		return -ENODEV;
-
-	data = i2c_get_clientdata(tpa6130a2_client);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
 
 	if (data->id == TPA6140A2)
-		return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
-						ARRAY_SIZE(tpa6140a2_controls));
+		return snd_soc_add_component_controls(component,
+			tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls));
 	else
-		return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
-						ARRAY_SIZE(tpa6130a2_controls));
+		return snd_soc_add_component_controls(component,
+			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
-EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
+
+struct snd_soc_component_driver tpa6130a2_component_driver = {
+	.name = "tpa6130a2",
+	.probe = tpa6130a2_component_probe,
+};
 
 static int tpa6130a2_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
@@ -451,7 +450,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (ret != 0)
 		goto err_gpio;
 
-	return 0;
+	return devm_snd_soc_register_component(&client->dev,
+			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
 	tpa6130a2_client = NULL;
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 4174440..78ee723 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -56,7 +56,6 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
 extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
 
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 5494924..b59cf89 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -286,16 +286,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
 
 static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_card *card = rtd->card;
 	struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
 	int err;
 
-	err = tpa6130a2_add_controls(codec);
-	if (err < 0) {
-		dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
-		return err;
-	}
 	snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
 
 	err = omap_mcbsp_st_add_controls(rtd, 2);
@@ -357,6 +351,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
 		.name = "TLV320AIC34b",
 		.codec_name = "tlv320aic3x-codec.2-0019",
 	},
+	{
+		.name = "TPA61320A2",
+		.codec_name = "tpa6130a2.2-0060",
+	},
 };
 
 static struct snd_soc_codec_conf rx51_codec_conf[] = {
@@ -364,6 +362,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = {
 		.dev_name = "tlv320aic3x-codec.2-0019",
 		.name_prefix = "b",
 	},
+	{
+		.dev_name = "tpa6130a2.2-0060",
+		.name_prefix = "TPA6130A2",
+	},
 };
 
 /* Audio card */
@@ -435,11 +437,10 @@ static int rx51_soc_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
 			return -EINVAL;
 		}
-
-		/* TODO: tpa6130a2a driver supports only a single instance, so
-		 * this driver ignores the headphone-amplifier node for now.
-		 * It's already mandatory in the DT binding to be future proof.
-		 */
+		rx51_aux_dev[1].codec_name = NULL;
+		rx51_aux_dev[1].codec_of_node = dai_node;
+		rx51_codec_conf[1].dev_name = NULL;
+		rx51_codec_conf[1].of_node = dai_node;
 	}
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 2/5] ASoC: tap6130a2: Use regmap
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
  2016-06-20 17:12     ` [PATCH v2 1/5] ASoC: tpa6130a2: Register component Helen Koike
@ 2016-06-20 17:12     ` Helen Koike
  2016-06-21  1:41       ` Sebastian Reichel
  2016-06-20 17:12     ` [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
                       ` (3 subsequent siblings)
  5 siblings, 1 reply; 36+ messages in thread
From: Helen Koike @ 2016-06-20 17:12 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Use regmap instead of open-coding IO access and caching

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
[On N900]
Tested-By: Sebastian Reichel <sre@kernel.org>

---

Changes since v1:
- Add tested-by from Sebastian

 sound/soc/codecs/tpa6130a2.c | 166 ++++++++++++-------------------------------
 sound/soc/codecs/tpa6130a2.h |   2 -
 2 files changed, 46 insertions(+), 122 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index f31326a..d90388a 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -32,6 +32,7 @@
 #include <sound/tlv.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/regmap.h>
 
 #include "tpa6130a2.h"
 
@@ -45,92 +46,16 @@ static struct i2c_client *tpa6130a2_client;
 /* This struct is used to save the context */
 struct tpa6130a2_data {
 	struct mutex mutex;
-	unsigned char regs[TPA6130A2_CACHEREGNUM];
+	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
 	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_i2c_read(int reg)
-{
-	struct tpa6130a2_data *data;
-	int val;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	/* If powered off, return the cached value */
-	if (data->power_state) {
-		val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
-		if (val < 0)
-			dev_err(&tpa6130a2_client->dev, "Read failed\n");
-		else
-			data->regs[reg] = val;
-	} else {
-		val = data->regs[reg];
-	}
-
-	return val;
-}
-
-static int tpa6130a2_i2c_write(int reg, u8 value)
-{
-	struct tpa6130a2_data *data;
-	int val = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (data->power_state) {
-		val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
-		if (val < 0) {
-			dev_err(&tpa6130a2_client->dev, "Write failed\n");
-			return val;
-		}
-	}
-
-	/* Either powered on or off, we save the context */
-	data->regs[reg] = value;
-
-	return val;
-}
-
-static u8 tpa6130a2_read(int reg)
-{
-	struct tpa6130a2_data *data;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return 0;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	return data->regs[reg];
-}
-
-static int tpa6130a2_initialize(void)
-{
-	struct tpa6130a2_data *data;
-	int i, ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	for (i = 1; i < TPA6130A2_REG_VERSION; i++) {
-		ret = tpa6130a2_i2c_write(i, data->regs[i]);
-		if (ret < 0)
-			break;
-	}
-
-	return ret;
-}
-
 static int tpa6130a2_power(u8 power)
 {
 	struct	tpa6130a2_data *data;
-	u8	val;
 	int	ret = 0;
 
 	if (WARN_ON(!tpa6130a2_client))
@@ -153,7 +78,7 @@ static int tpa6130a2_power(u8 power)
 			gpio_set_value(data->power_gpio, 1);
 
 		data->power_state = 1;
-		ret = tpa6130a2_initialize();
+		ret = regcache_sync(data->regmap);
 		if (ret < 0) {
 			dev_err(&tpa6130a2_client->dev,
 				"Failed to initialize chip\n");
@@ -165,9 +90,8 @@ static int tpa6130a2_power(u8 power)
 		}
 	} else {
 		/* set SWS */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val |= TPA6130A2_SWS;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+			TPA6130A2_SWS, TPA6130A2_SWS);
 
 		/* Power off */
 		if (data->power_gpio >= 0)
@@ -181,6 +105,8 @@ static int tpa6130a2_power(u8 power)
 		}
 
 		data->power_state = 0;
+		/* device regs does not match the cache state anymore */
+		regcache_mark_dirty(data->regmap);
 	}
 
 exit:
@@ -196,7 +122,7 @@ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
 	struct tpa6130a2_data *data;
 	unsigned int reg = mc->reg;
 	unsigned int shift = mc->shift;
-	int max = mc->max;
+	int max = mc->max, val;
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 
@@ -206,8 +132,8 @@ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&data->mutex);
 
-	ucontrol->value.integer.value[0] =
-		(tpa6130a2_read(reg) >> shift) & mask;
+	regmap_read(data->regmap, reg, &val);
+	ucontrol->value.integer.value[0] = (val >> shift) & mask;
 
 	if (invert)
 		ucontrol->value.integer.value[0] =
@@ -229,7 +155,7 @@ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned int val = (ucontrol->value.integer.value[0] & mask);
-	unsigned int val_reg;
+	bool change;
 
 	if (WARN_ON(!tpa6130a2_client))
 		return -EINVAL;
@@ -239,20 +165,11 @@ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
 		val = max - val;
 
 	mutex_lock(&data->mutex);
-
-	val_reg = tpa6130a2_read(reg);
-	if (((val_reg >> shift) & mask) == val) {
-		mutex_unlock(&data->mutex);
-		return 0;
-	}
-
-	val_reg &= ~(mask << shift);
-	val_reg |= val << shift;
-	tpa6130a2_i2c_write(reg, val_reg);
-
+	regmap_update_bits_check(data->regmap, reg, mask << shift, val << shift,
+				 &change);
 	mutex_unlock(&data->mutex);
 
-	return 1;
+	return change;
 }
 
 /*
@@ -301,31 +218,26 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
  */
 static void tpa6130a2_channel_enable(u8 channel, int enable)
 {
-	u8	val;
+	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
 
 	if (enable) {
 		/* Enable channel */
 		/* Enable amplifier */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val |= channel;
-		val &= ~TPA6130A2_SWS;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
 
 		/* Unmute channel */
-		val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
-		val &= ~channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
+				   channel, 0);
 	} else {
 		/* Disable channel */
 		/* Mute channel */
-		val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
-		val |= channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
+				   channel, channel);
 
 		/* Disable amplifier */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val &= ~channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+				   channel, 0);
 	}
 }
 
@@ -365,6 +277,20 @@ struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.probe = tpa6130a2_component_probe,
 };
 
+static const struct reg_default tpa6130a2_reg_defaults[] = {
+	{ TPA6130A2_REG_CONTROL, TPA6130A2_SWS },
+	{ TPA6130A2_REG_VOL_MUTE, TPA6130A2_MUTE_R | TPA6130A2_MUTE_L },
+};
+
+static const struct regmap_config tpa6130a2_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TPA6130A2_REG_VERSION,
+	.reg_defaults = tpa6130a2_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(tpa6130a2_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
 static int tpa6130a2_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
 {
@@ -373,6 +299,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	struct tpa6130a2_platform_data *pdata = client->dev.platform_data;
 	struct device_node *np = client->dev.of_node;
 	const char *regulator;
+	unsigned int version;
 	int ret;
 
 	dev = &client->dev;
@@ -381,6 +308,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (!data)
 		return -ENOMEM;
 
+	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
+	if (IS_ERR(data->regmap))
+		return PTR_ERR(data->regmap);
+
 	if (pdata) {
 		data->power_gpio = pdata->power_gpio;
 	} else if (np) {
@@ -399,11 +330,6 @@ static int tpa6130a2_probe(struct i2c_client *client,
 
 	mutex_init(&data->mutex);
 
-	/* Set default register values */
-	data->regs[TPA6130A2_REG_CONTROL] =	TPA6130A2_SWS;
-	data->regs[TPA6130A2_REG_VOL_MUTE] =	TPA6130A2_MUTE_R |
-						TPA6130A2_MUTE_L;
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -440,10 +366,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 
 
 	/* Read version */
-	ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
-				 TPA6130A2_VERSION_MASK;
-	if ((ret != 1) && (ret != 2))
-		dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
+	regmap_read(data->regmap, TPA6130A2_REG_VERSION, &version);
+	version &= TPA6130A2_VERSION_MASK;
+	if ((version != 1) && (version != 2))
+		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
 	ret = tpa6130a2_power(0);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 78ee723..ef05a3f 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -30,8 +30,6 @@
 #define TPA6130A2_REG_OUT_IMPEDANCE	0x03
 #define TPA6130A2_REG_VERSION		0x04
 
-#define TPA6130A2_CACHEREGNUM	(TPA6130A2_REG_VERSION + 1)
-
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
 #define TPA6130A2_SWS			(0x01 << 0)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
  2016-06-20 17:12     ` [PATCH v2 1/5] ASoC: tpa6130a2: Register component Helen Koike
  2016-06-20 17:12     ` [PATCH v2 2/5] ASoC: tap6130a2: Use regmap Helen Koike
@ 2016-06-20 17:12     ` Helen Koike
  2016-06-21  1:41       ` Sebastian Reichel
  2016-06-23 14:38       ` Applied "ASoC: tpa6130a2: Use snd soc volsw functions" to the asoc tree Mark Brown
  2016-06-20 17:12     ` [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support Helen Koike
                       ` (2 subsequent siblings)
  5 siblings, 2 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-20 17:12 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Use snd_soc_{info,get,put}_volsw instead of custom volume functions

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
[On N900]
Tested-By: Sebastian Reichel <sre@kernel.org>

---

Changes since v1:
- Add tested-by from Sebastian

 sound/soc/codecs/tpa6130a2.c | 64 ++------------------------------------------
 1 file changed, 2 insertions(+), 62 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index d90388a..81bf584 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -114,64 +114,6 @@ exit:
 	return ret;
 }
 
-static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
-		struct snd_ctl_elem_value *ucontrol)
-{
-	struct soc_mixer_control *mc =
-		(struct soc_mixer_control *)kcontrol->private_value;
-	struct tpa6130a2_data *data;
-	unsigned int reg = mc->reg;
-	unsigned int shift = mc->shift;
-	int max = mc->max, val;
-	unsigned int mask = (1 << fls(max)) - 1;
-	unsigned int invert = mc->invert;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-
-	regmap_read(data->regmap, reg, &val);
-	ucontrol->value.integer.value[0] = (val >> shift) & mask;
-
-	if (invert)
-		ucontrol->value.integer.value[0] =
-			max - ucontrol->value.integer.value[0];
-
-	mutex_unlock(&data->mutex);
-	return 0;
-}
-
-static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
-		struct snd_ctl_elem_value *ucontrol)
-{
-	struct soc_mixer_control *mc =
-		(struct soc_mixer_control *)kcontrol->private_value;
-	struct tpa6130a2_data *data;
-	unsigned int reg = mc->reg;
-	unsigned int shift = mc->shift;
-	int max = mc->max;
-	unsigned int mask = (1 << fls(max)) - 1;
-	unsigned int invert = mc->invert;
-	unsigned int val = (ucontrol->value.integer.value[0] & mask);
-	bool change;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (invert)
-		val = max - val;
-
-	mutex_lock(&data->mutex);
-	regmap_update_bits_check(data->regmap, reg, mask << shift, val << shift,
-				 &change);
-	mutex_unlock(&data->mutex);
-
-	return change;
-}
-
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -190,9 +132,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6130_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6130a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
+	SOC_SINGLE_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
-		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6130_tlv),
 };
 
@@ -203,9 +144,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6140a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
+	SOC_SINGLE_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
-		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6140_tlv),
 };
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
                       ` (2 preceding siblings ...)
  2016-06-20 17:12     ` [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
@ 2016-06-20 17:12     ` Helen Koike
  2016-06-20 19:06       ` Helen Koike
  2016-06-20 19:44       ` Lars-Peter Clausen
  2016-06-20 17:12     ` [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
  2016-06-23 19:23     ` [PATCH v3 0/2] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
  5 siblings, 2 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-20 17:12 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Add DAPM support and updated rx51 accordingly.
As a consequence:
- the exported function tpa6130a2_stereo_enable is not needed anymore
- the mutex is dealt in the DAPM
- the power state is tracked by the DAPM

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>

---

Changes since v1:
- Replace
	+	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
	+	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"}

	by

	+       {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
	+       {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
- Add tested-by and reviewed-by from Sebastian
- Add struct device dev* in struct tpa6130a2_data and pass data instead
of dev to tpa6130a2_power function
- remove #include "../codecs/tpa6130a2.h" in rx51.c

 sound/soc/codecs/tpa6130a2.c | 184 ++++++++++++++++++-------------------------
 sound/soc/codecs/tpa6130a2.h |  11 +--
 sound/soc/omap/rx51.c        |  23 ++----
 3 files changed, 88 insertions(+), 130 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 81bf584..cc83870 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -41,79 +41,73 @@ enum tpa_model {
 	TPA6140A2,
 };
 
-static struct i2c_client *tpa6130a2_client;
-
 /* This struct is used to save the context */
 struct tpa6130a2_data {
-	struct mutex mutex;
+	struct device *dev;
 	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
-	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_power(u8 power)
+static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
 {
-	struct	tpa6130a2_data *data;
-	int	ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-	if (power == data->power_state)
-		goto exit;
+	int ret;
 
-	if (power) {
+	if (enable) {
 		ret = regulator_enable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
+			dev_err(data->dev,
 				"Failed to enable supply: %d\n", ret);
-			goto exit;
+			return ret;
 		}
 		/* Power on */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 1);
-
-		data->power_state = 1;
-		ret = regcache_sync(data->regmap);
-		if (ret < 0) {
-			dev_err(&tpa6130a2_client->dev,
-				"Failed to initialize chip\n");
-			if (data->power_gpio >= 0)
-				gpio_set_value(data->power_gpio, 0);
-			regulator_disable(data->supply);
-			data->power_state = 0;
-			goto exit;
-		}
 	} else {
-		/* set SWS */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			TPA6130A2_SWS, TPA6130A2_SWS);
-
 		/* Power off */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 0);
 
 		ret = regulator_disable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
+			dev_err(data->dev,
 				"Failed to disable supply: %d\n", ret);
-			goto exit;
+			return ret;
 		}
 
-		data->power_state = 0;
 		/* device regs does not match the cache state anymore */
 		regcache_mark_dirty(data->regmap);
 	}
 
-exit:
-	mutex_unlock(&data->mutex);
 	return ret;
 }
 
+static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kctrl, int event)
+{
+	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
+	int ret;
+
+	/* before widget power up */
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Turn on the chip */
+		tpa6130a2_power(data, true);
+		/* Sync the registers */
+		ret = regcache_sync(data->regmap);
+		if (ret < 0) {
+			dev_err(c->dev, "Failed to initialize chip\n");
+			tpa6130a2_power(data, false);
+			return ret;
+		}
+	/* after widget power down */
+	} else
+		tpa6130a2_power(data, false);
+
+	return 0;
+}
+
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -149,57 +143,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
 		       tpa6140_tlv),
 };
 
-/*
- * Enable or disable channel (left or right)
- * The bit number for mute and amplifier are the same per channel:
- * bit 6: Right channel
- * bit 7: Left channel
- * in both registers.
- */
-static void tpa6130a2_channel_enable(u8 channel, int enable)
-{
-	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (enable) {
-		/* Enable channel */
-		/* Enable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
-
-		/* Unmute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, 0);
-	} else {
-		/* Disable channel */
-		/* Mute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, channel);
-
-		/* Disable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-				   channel, 0);
-	}
-}
-
-int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
-{
-	int ret = 0;
-	if (enable) {
-		ret = tpa6130a2_power(1);
-		if (ret < 0)
-			return ret;
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 1);
-	} else {
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 0);
-		ret = tpa6130a2_power(0);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
-
 static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
 	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
@@ -212,9 +155,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
 			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
 
+static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("LEFTIN"),
+	SND_SOC_DAPM_INPUT("RIGHTIN"),
+	SND_SOC_DAPM_OUTPUT("HPLEFT"),
+	SND_SOC_DAPM_OUTPUT("HPRIGHT"),
+
+	SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
+			    TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
+	{ "Left PGA", NULL, "LEFTIN" },
+	{ "Right PGA", NULL, "RIGHTIN" },
+
+	{ "Left Mute", NULL, "Left PGA" },
+	{ "Right Mute", NULL, "Right PGA" },
+
+	{ "HPLEFT", NULL, "Left Mute" },
+	{ "HPRIGHT", NULL, "Right Mute" },
+
+	{ "Left PGA", NULL, "Power" },
+	{ "Right PGA", NULL, "Power" },
+};
+
 struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.name = "tpa6130a2",
 	.probe = tpa6130a2_component_probe,
+	.dapm_widgets = tpa6130a2_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
+	.dapm_routes = tpa6130a2_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
 };
 
 static const struct reg_default tpa6130a2_reg_defaults[] = {
@@ -248,6 +229,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (!data)
 		return -ENOMEM;
 
+	data->dev = dev;
+
 	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
 	if (IS_ERR(data->regmap))
 		return PTR_ERR(data->regmap);
@@ -262,14 +245,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	tpa6130a2_client = client;
-
-	i2c_set_clientdata(tpa6130a2_client, data);
+	i2c_set_clientdata(client, data);
 
 	data->id = id->driver_data;
 
-	mutex_init(&data->mutex);
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -300,7 +279,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		goto err_gpio;
 	}
 
-	ret = tpa6130a2_power(1);
+	ret = tpa6130a2_power(data, true);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -312,7 +291,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
-	ret = tpa6130a2_power(0);
+	ret = tpa6130a2_power(data, false);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -320,19 +299,9 @@ static int tpa6130a2_probe(struct i2c_client *client,
 			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
-	tpa6130a2_client = NULL;
-
 	return ret;
 }
 
-static int tpa6130a2_remove(struct i2c_client *client)
-{
-	tpa6130a2_power(0);
-	tpa6130a2_client = NULL;
-
-	return 0;
-}
-
 static const struct i2c_device_id tpa6130a2_id[] = {
 	{ "tpa6130a2", TPA6130A2 },
 	{ "tpa6140a2", TPA6140A2 },
@@ -355,7 +324,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
 		.of_match_table = of_match_ptr(tpa6130a2_of_match),
 	},
 	.probe = tpa6130a2_probe,
-	.remove = tpa6130a2_remove,
 	.id_table = tpa6130a2_id,
 };
 
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index ef05a3f..f19cad5 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -32,15 +32,18 @@
 
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
-#define TPA6130A2_SWS			(0x01 << 0)
+#define TPA6130A2_SWS_SHIFT		0
+#define TPA6130A2_SWS			(0x01 << TPA6130A2_SWS_SHIFT)
 #define TPA6130A2_TERMAL		(0x01 << 1)
 #define TPA6130A2_MODE(x)		(x << 4)
 #define TPA6130A2_MODE_STEREO		(0x00)
 #define TPA6130A2_MODE_DUAL_MONO	(0x01)
 #define TPA6130A2_MODE_BRIDGE		(0x02)
 #define TPA6130A2_MODE_MASK		(0x03)
-#define TPA6130A2_HP_EN_R		(0x01 << 6)
-#define TPA6130A2_HP_EN_L		(0x01 << 7)
+#define TPA6130A2_HP_EN_R_SHIFT		6
+#define TPA6130A2_HP_EN_R		(0x01 << TPA6130A2_HP_EN_R_SHIFT)
+#define TPA6130A2_HP_EN_L_SHIFT		7
+#define TPA6130A2_HP_EN_L		(0x01 << TPA6130A2_HP_EN_L_SHIFT)
 
 /* TPA6130A2_REG_VOL_MUTE (0x02) */
 #define TPA6130A2_VOLUME(x)		((x & 0x3f) << 0)
@@ -54,6 +57,4 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
-
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index b59cf89..a768457 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -33,7 +33,6 @@
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include "../codecs/tpa6130a2.h"
 
 #include <asm/mach-types.h>
 
@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int rx51_hp_event(struct snd_soc_dapm_widget *w,
-			 struct snd_kcontrol *k, int event)
-{
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		tpa6130a2_stereo_enable(codec, 1);
-	else
-		tpa6130a2_stereo_enable(codec, 0);
-
-	return 0;
-}
-
 static int rx51_get_input(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
 static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
 	SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
 	SND_SOC_DAPM_MIC("DMic", NULL),
-	SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 	SND_SOC_DAPM_MIC("HS Mic", NULL),
 	SND_SOC_DAPM_LINE("FM Transmitter", NULL),
 	SND_SOC_DAPM_SPK("Earphone", NULL),
@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Ext Spk", NULL, "HPROUT"},
 	{"Ext Spk", NULL, "HPLCOM"},
 	{"Ext Spk", NULL, "HPRCOM"},
-	{"Headphone Jack", NULL, "LLOUT"},
-	{"Headphone Jack", NULL, "RLOUT"},
 	{"FM Transmitter", NULL, "LLOUT"},
 	{"FM Transmitter", NULL, "RLOUT"},
 
+	{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
+	{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
+	{"TPA6130A2 LEFTIN", NULL, "LLOUT"},
+	{"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
+
 	{"DMic Rate 64", NULL, "DMic"},
 	{"DMic", NULL, "Mic Bias"},
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
                       ` (3 preceding siblings ...)
  2016-06-20 17:12     ` [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support Helen Koike
@ 2016-06-20 17:12     ` Helen Koike
  2016-06-21  1:42       ` Sebastian Reichel
  2016-06-26 12:02       ` Applied "ASoC: tpa6130a2: Remove goto err_gpio" to the asoc tree Mark Brown
  2016-06-23 19:23     ` [PATCH v3 0/2] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
  5 siblings, 2 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-20 17:12 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Replace goto err_gpio by return ret

Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>

---

Changes since v1:
- this is a new patch in the series

 sound/soc/codecs/tpa6130a2.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index cc83870..a919308 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -255,7 +255,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		if (ret < 0) {
 			dev_err(dev, "Failed to request power GPIO (%d)\n",
 				data->power_gpio);
-			goto err_gpio;
+			return ret;
 		}
 		gpio_direction_output(data->power_gpio, 0);
 	}
@@ -276,12 +276,12 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (IS_ERR(data->supply)) {
 		ret = PTR_ERR(data->supply);
 		dev_err(dev, "Failed to request supply: %d\n", ret);
-		goto err_gpio;
+		return ret;
 	}
 
 	ret = tpa6130a2_power(data, true);
 	if (ret != 0)
-		goto err_gpio;
+		return ret;
 
 
 	/* Read version */
@@ -293,13 +293,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	/* Disable the chip */
 	ret = tpa6130a2_power(data, false);
 	if (ret != 0)
-		goto err_gpio;
+		return ret;
 
 	return devm_snd_soc_register_component(&client->dev,
 			&tpa6130a2_component_driver, NULL, 0);
-
-err_gpio:
-	return ret;
 }
 
 static const struct i2c_device_id tpa6130a2_id[] = {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support
  2016-06-20 17:12     ` [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support Helen Koike
@ 2016-06-20 19:06       ` Helen Koike
  2016-06-21  1:45         ` Sebastian Reichel
  2016-06-20 19:44       ` Lars-Peter Clausen
  1 sibling, 1 reply; 36+ messages in thread
From: Helen Koike @ 2016-06-20 19:06 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy

Hi Sebastian,

Thank you for reviewing the patches.

On 20-06-2016 14:12, Helen Koike wrote:
> Add DAPM support and updated rx51 accordingly.
> As a consequence:
> - the exported function tpa6130a2_stereo_enable is not needed anymore
> - the mutex is dealt in the DAPM
> - the power state is tracked by the DAPM
>
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
> Tested-By: Sebastian Reichel <sre@kernel.org>
> Reviewed-By: Sebastian Reichel <sre@kernel.org>
>
> ---
>
> Changes since v1:
> - Replace
> 	+	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
> 	+	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"}
>
> 	by
>
> 	+       {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
> 	+       {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
> - Add tested-by and reviewed-by from Sebastian
> - Add struct device dev* in struct tpa6130a2_data and pass data instead
> of dev to tpa6130a2_power function
> - remove #include "../codecs/tpa6130a2.h" in rx51.c


I added these changes above and kept your tested-by and reviewed-by, 
could you please confirm that I can keep them? As I changed more things 
then you suggested.

Thank you
Helen


>
>   sound/soc/codecs/tpa6130a2.c | 184 ++++++++++++++++++-------------------------
>   sound/soc/codecs/tpa6130a2.h |  11 +--
>   sound/soc/omap/rx51.c        |  23 ++----
>   3 files changed, 88 insertions(+), 130 deletions(-)
>
> diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
> index 81bf584..cc83870 100644
> --- a/sound/soc/codecs/tpa6130a2.c
> +++ b/sound/soc/codecs/tpa6130a2.c
> @@ -41,79 +41,73 @@ enum tpa_model {
>   	TPA6140A2,
>   };
>
> -static struct i2c_client *tpa6130a2_client;
> -
>   /* This struct is used to save the context */
>   struct tpa6130a2_data {
> -	struct mutex mutex;
> +	struct device *dev;
>   	struct regmap *regmap;
>   	struct regulator *supply;
>   	int power_gpio;
> -	u8 power_state:1;
>   	enum tpa_model id;
>   };
>
> -static int tpa6130a2_power(u8 power)
> +static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
>   {
> -	struct	tpa6130a2_data *data;
> -	int	ret = 0;
> -
> -	if (WARN_ON(!tpa6130a2_client))
> -		return -EINVAL;
> -	data = i2c_get_clientdata(tpa6130a2_client);
> -
> -	mutex_lock(&data->mutex);
> -	if (power == data->power_state)
> -		goto exit;
> +	int ret;
>
> -	if (power) {
> +	if (enable) {
>   		ret = regulator_enable(data->supply);
>   		if (ret != 0) {
> -			dev_err(&tpa6130a2_client->dev,
> +			dev_err(data->dev,
>   				"Failed to enable supply: %d\n", ret);
> -			goto exit;
> +			return ret;
>   		}
>   		/* Power on */
>   		if (data->power_gpio >= 0)
>   			gpio_set_value(data->power_gpio, 1);
> -
> -		data->power_state = 1;
> -		ret = regcache_sync(data->regmap);
> -		if (ret < 0) {
> -			dev_err(&tpa6130a2_client->dev,
> -				"Failed to initialize chip\n");
> -			if (data->power_gpio >= 0)
> -				gpio_set_value(data->power_gpio, 0);
> -			regulator_disable(data->supply);
> -			data->power_state = 0;
> -			goto exit;
> -		}
>   	} else {
> -		/* set SWS */
> -		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
> -			TPA6130A2_SWS, TPA6130A2_SWS);
> -
>   		/* Power off */
>   		if (data->power_gpio >= 0)
>   			gpio_set_value(data->power_gpio, 0);
>
>   		ret = regulator_disable(data->supply);
>   		if (ret != 0) {
> -			dev_err(&tpa6130a2_client->dev,
> +			dev_err(data->dev,
>   				"Failed to disable supply: %d\n", ret);
> -			goto exit;
> +			return ret;
>   		}
>
> -		data->power_state = 0;
>   		/* device regs does not match the cache state anymore */
>   		regcache_mark_dirty(data->regmap);
>   	}
>
> -exit:
> -	mutex_unlock(&data->mutex);
>   	return ret;
>   }
>
> +static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
> +				 struct snd_kcontrol *kctrl, int event)
> +{
> +	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
> +	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
> +	int ret;
> +
> +	/* before widget power up */
> +	if (SND_SOC_DAPM_EVENT_ON(event)) {
> +		/* Turn on the chip */
> +		tpa6130a2_power(data, true);
> +		/* Sync the registers */
> +		ret = regcache_sync(data->regmap);
> +		if (ret < 0) {
> +			dev_err(c->dev, "Failed to initialize chip\n");
> +			tpa6130a2_power(data, false);
> +			return ret;
> +		}
> +	/* after widget power down */
> +	} else
> +		tpa6130a2_power(data, false);
> +
> +	return 0;
> +}
> +
>   /*
>    * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
>    * down in gain.
> @@ -149,57 +143,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
>   		       tpa6140_tlv),
>   };
>
> -/*
> - * Enable or disable channel (left or right)
> - * The bit number for mute and amplifier are the same per channel:
> - * bit 6: Right channel
> - * bit 7: Left channel
> - * in both registers.
> - */
> -static void tpa6130a2_channel_enable(u8 channel, int enable)
> -{
> -	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
> -
> -	if (enable) {
> -		/* Enable channel */
> -		/* Enable amplifier */
> -		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
> -			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
> -
> -		/* Unmute channel */
> -		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
> -				   channel, 0);
> -	} else {
> -		/* Disable channel */
> -		/* Mute channel */
> -		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
> -				   channel, channel);
> -
> -		/* Disable amplifier */
> -		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
> -				   channel, 0);
> -	}
> -}
> -
> -int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
> -{
> -	int ret = 0;
> -	if (enable) {
> -		ret = tpa6130a2_power(1);
> -		if (ret < 0)
> -			return ret;
> -		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
> -					 1);
> -	} else {
> -		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
> -					 0);
> -		ret = tpa6130a2_power(0);
> -	}
> -
> -	return ret;
> -}
> -EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
> -
>   static int tpa6130a2_component_probe(struct snd_soc_component *component)
>   {
>   	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
> @@ -212,9 +155,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
>   			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
>   }
>
> +static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
> +	SND_SOC_DAPM_INPUT("LEFTIN"),
> +	SND_SOC_DAPM_INPUT("RIGHTIN"),
> +	SND_SOC_DAPM_OUTPUT("HPLEFT"),
> +	SND_SOC_DAPM_OUTPUT("HPRIGHT"),
> +
> +	SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
> +			 TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
> +	SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
> +			 TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
> +	SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
> +			 TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
> +	SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
> +			 TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
> +
> +	SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
> +			    TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
> +			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
> +};
> +
> +static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
> +	{ "Left PGA", NULL, "LEFTIN" },
> +	{ "Right PGA", NULL, "RIGHTIN" },
> +
> +	{ "Left Mute", NULL, "Left PGA" },
> +	{ "Right Mute", NULL, "Right PGA" },
> +
> +	{ "HPLEFT", NULL, "Left Mute" },
> +	{ "HPRIGHT", NULL, "Right Mute" },
> +
> +	{ "Left PGA", NULL, "Power" },
> +	{ "Right PGA", NULL, "Power" },
> +};
> +
>   struct snd_soc_component_driver tpa6130a2_component_driver = {
>   	.name = "tpa6130a2",
>   	.probe = tpa6130a2_component_probe,
> +	.dapm_widgets = tpa6130a2_dapm_widgets,
> +	.num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
> +	.dapm_routes = tpa6130a2_dapm_routes,
> +	.num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
>   };
>
>   static const struct reg_default tpa6130a2_reg_defaults[] = {
> @@ -248,6 +229,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
>   	if (!data)
>   		return -ENOMEM;
>
> +	data->dev = dev;
> +
>   	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
>   	if (IS_ERR(data->regmap))
>   		return PTR_ERR(data->regmap);
> @@ -262,14 +245,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
>   		return -ENODEV;
>   	}
>
> -	tpa6130a2_client = client;
> -
> -	i2c_set_clientdata(tpa6130a2_client, data);
> +	i2c_set_clientdata(client, data);
>
>   	data->id = id->driver_data;
>
> -	mutex_init(&data->mutex);
> -
>   	if (data->power_gpio >= 0) {
>   		ret = devm_gpio_request(dev, data->power_gpio,
>   					"tpa6130a2 enable");
> @@ -300,7 +279,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
>   		goto err_gpio;
>   	}
>
> -	ret = tpa6130a2_power(1);
> +	ret = tpa6130a2_power(data, true);
>   	if (ret != 0)
>   		goto err_gpio;
>
> @@ -312,7 +291,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
>   		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
>
>   	/* Disable the chip */
> -	ret = tpa6130a2_power(0);
> +	ret = tpa6130a2_power(data, false);
>   	if (ret != 0)
>   		goto err_gpio;
>
> @@ -320,19 +299,9 @@ static int tpa6130a2_probe(struct i2c_client *client,
>   			&tpa6130a2_component_driver, NULL, 0);
>
>   err_gpio:
> -	tpa6130a2_client = NULL;
> -
>   	return ret;
>   }
>
> -static int tpa6130a2_remove(struct i2c_client *client)
> -{
> -	tpa6130a2_power(0);
> -	tpa6130a2_client = NULL;
> -
> -	return 0;
> -}
> -
>   static const struct i2c_device_id tpa6130a2_id[] = {
>   	{ "tpa6130a2", TPA6130A2 },
>   	{ "tpa6140a2", TPA6140A2 },
> @@ -355,7 +324,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
>   		.of_match_table = of_match_ptr(tpa6130a2_of_match),
>   	},
>   	.probe = tpa6130a2_probe,
> -	.remove = tpa6130a2_remove,
>   	.id_table = tpa6130a2_id,
>   };
>
> diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
> index ef05a3f..f19cad5 100644
> --- a/sound/soc/codecs/tpa6130a2.h
> +++ b/sound/soc/codecs/tpa6130a2.h
> @@ -32,15 +32,18 @@
>
>   /* Register bits */
>   /* TPA6130A2_REG_CONTROL (0x01) */
> -#define TPA6130A2_SWS			(0x01 << 0)
> +#define TPA6130A2_SWS_SHIFT		0
> +#define TPA6130A2_SWS			(0x01 << TPA6130A2_SWS_SHIFT)
>   #define TPA6130A2_TERMAL		(0x01 << 1)
>   #define TPA6130A2_MODE(x)		(x << 4)
>   #define TPA6130A2_MODE_STEREO		(0x00)
>   #define TPA6130A2_MODE_DUAL_MONO	(0x01)
>   #define TPA6130A2_MODE_BRIDGE		(0x02)
>   #define TPA6130A2_MODE_MASK		(0x03)
> -#define TPA6130A2_HP_EN_R		(0x01 << 6)
> -#define TPA6130A2_HP_EN_L		(0x01 << 7)
> +#define TPA6130A2_HP_EN_R_SHIFT		6
> +#define TPA6130A2_HP_EN_R		(0x01 << TPA6130A2_HP_EN_R_SHIFT)
> +#define TPA6130A2_HP_EN_L_SHIFT		7
> +#define TPA6130A2_HP_EN_L		(0x01 << TPA6130A2_HP_EN_L_SHIFT)
>
>   /* TPA6130A2_REG_VOL_MUTE (0x02) */
>   #define TPA6130A2_VOLUME(x)		((x & 0x3f) << 0)
> @@ -54,6 +57,4 @@
>   /* TPA6130A2_REG_VERSION (0x04) */
>   #define TPA6130A2_VERSION_MASK		(0x0f)
>
> -extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
> -
>   #endif /* __TPA6130A2_H__ */
> diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
> index b59cf89..a768457 100644
> --- a/sound/soc/omap/rx51.c
> +++ b/sound/soc/omap/rx51.c
> @@ -33,7 +33,6 @@
>   #include <sound/pcm.h>
>   #include <sound/soc.h>
>   #include <linux/platform_data/asoc-ti-mcbsp.h>
> -#include "../codecs/tpa6130a2.h"
>
>   #include <asm/mach-types.h>
>
> @@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
>   	return 0;
>   }
>
> -static int rx51_hp_event(struct snd_soc_dapm_widget *w,
> -			 struct snd_kcontrol *k, int event)
> -{
> -	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
> -
> -	if (SND_SOC_DAPM_EVENT_ON(event))
> -		tpa6130a2_stereo_enable(codec, 1);
> -	else
> -		tpa6130a2_stereo_enable(codec, 0);
> -
> -	return 0;
> -}
> -
>   static int rx51_get_input(struct snd_kcontrol *kcontrol,
>   			  struct snd_ctl_elem_value *ucontrol)
>   {
> @@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
>   static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
>   	SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
>   	SND_SOC_DAPM_MIC("DMic", NULL),
> -	SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
> +	SND_SOC_DAPM_HP("Headphone Jack", NULL),
>   	SND_SOC_DAPM_MIC("HS Mic", NULL),
>   	SND_SOC_DAPM_LINE("FM Transmitter", NULL),
>   	SND_SOC_DAPM_SPK("Earphone", NULL),
> @@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
>   	{"Ext Spk", NULL, "HPROUT"},
>   	{"Ext Spk", NULL, "HPLCOM"},
>   	{"Ext Spk", NULL, "HPRCOM"},
> -	{"Headphone Jack", NULL, "LLOUT"},
> -	{"Headphone Jack", NULL, "RLOUT"},
>   	{"FM Transmitter", NULL, "LLOUT"},
>   	{"FM Transmitter", NULL, "RLOUT"},
>
> +	{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
> +	{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
> +	{"TPA6130A2 LEFTIN", NULL, "LLOUT"},
> +	{"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
> +
>   	{"DMic Rate 64", NULL, "DMic"},
>   	{"DMic", NULL, "Mic Bias"},
>
>

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support
  2016-06-20 17:12     ` [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support Helen Koike
  2016-06-20 19:06       ` Helen Koike
@ 2016-06-20 19:44       ` Lars-Peter Clausen
  2016-06-20 20:12         ` Helen Koike
  1 sibling, 1 reply; 36+ messages in thread
From: Lars-Peter Clausen @ 2016-06-20 19:44 UTC (permalink / raw)
  To: Helen Koike, Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, k.kozlowski,
	alsa-devel, linux-kernel, linux-omap, perex, tiwai, cphealy

> +	/* before widget power up */
> +	if (SND_SOC_DAPM_EVENT_ON(event)) {
> +		/* Turn on the chip */
> +		tpa6130a2_power(data, true);
> +		/* Sync the registers */
> +		ret = regcache_sync(data->regmap);
> +		if (ret < 0) {
> +			dev_err(c->dev, "Failed to initialize chip\n");
> +			tpa6130a2_power(data, false);
> +			return ret;
> +		}
> +	/* after widget power down */
> +	} else
> +		tpa6130a2_power(data, false);

checkpatch.pl should complain about this. Kernel code style is if one branch
has branches the other has to have it as well.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support
  2016-06-20 19:44       ` Lars-Peter Clausen
@ 2016-06-20 20:12         ` Helen Koike
  0 siblings, 0 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-20 20:12 UTC (permalink / raw)
  To: Lars-Peter Clausen, Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, k.kozlowski,
	alsa-devel, linux-kernel, linux-omap, perex, tiwai, cphealy



On 20-06-2016 16:44, Lars-Peter Clausen wrote:
>> +	/* before widget power up */
>> +	if (SND_SOC_DAPM_EVENT_ON(event)) {
>> +		/* Turn on the chip */
>> +		tpa6130a2_power(data, true);
>> +		/* Sync the registers */
>> +		ret = regcache_sync(data->regmap);
>> +		if (ret < 0) {
>> +			dev_err(c->dev, "Failed to initialize chip\n");
>> +			tpa6130a2_power(data, false);
>> +			return ret;
>> +		}
>> +	/* after widget power down */
>> +	} else
>> +		tpa6130a2_power(data, false);
>
> checkpatch.pl should complain about this. Kernel code style is if one branch
> has branches the other has to have it as well.
>

Weird, checkpatch.pl doesn't complain. I'll add the braces in v3, thank 
you for reviewing

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 2/5] ASoC: tap6130a2: Use regmap
  2016-06-20 17:12     ` [PATCH v2 2/5] ASoC: tap6130a2: Use regmap Helen Koike
@ 2016-06-21  1:41       ` Sebastian Reichel
  0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-21  1:41 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy

[-- Attachment #1: Type: text/plain, Size: 406 bytes --]

Hi,

On Mon, Jun 20, 2016 at 02:12:30PM -0300, Helen Koike wrote:
> Use regmap instead of open-coding IO access and caching
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
> [On N900]
> Tested-By: Sebastian Reichel <sre@kernel.org>

Reviewed-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions
  2016-06-20 17:12     ` [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
@ 2016-06-21  1:41       ` Sebastian Reichel
  2016-06-23 14:38       ` Applied "ASoC: tpa6130a2: Use snd soc volsw functions" to the asoc tree Mark Brown
  1 sibling, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-21  1:41 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy

[-- Attachment #1: Type: text/plain, Size: 418 bytes --]

Hi,

On Mon, Jun 20, 2016 at 02:12:31PM -0300, Helen Koike wrote:
> Use snd_soc_{info,get,put}_volsw instead of custom volume functions
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> [koike: port for upstream]
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
> [On N900]
> Tested-By: Sebastian Reichel <sre@kernel.org>

Reviewed-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio
  2016-06-20 17:12     ` [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
@ 2016-06-21  1:42       ` Sebastian Reichel
  2016-06-26 12:02       ` Applied "ASoC: tpa6130a2: Remove goto err_gpio" to the asoc tree Mark Brown
  1 sibling, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-21  1:42 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy

[-- Attachment #1: Type: text/plain, Size: 286 bytes --]

Hi,

On Mon, Jun 20, 2016 at 02:12:33PM -0300, Helen Koike wrote:
> Replace goto err_gpio by return ret
> 
> Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>

Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Re: [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support
  2016-06-20 19:06       ` Helen Koike
@ 2016-06-21  1:45         ` Sebastian Reichel
  0 siblings, 0 replies; 36+ messages in thread
From: Sebastian Reichel @ 2016-06-21  1:45 UTC (permalink / raw)
  To: Helen Koike
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy

[-- Attachment #1: Type: text/plain, Size: 315 bytes --]

Hi Helen,

On Mon, Jun 20, 2016 at 04:06:10PM -0300, Helen Koike wrote:
> I added these changes above and kept your tested-by and reviewed-by, could
> you please confirm that I can keep them? As I changed more things then you
> suggested.

The changes look fine to me, the new patchset works on N900.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 36+ messages in thread

* Applied "ASoC: tpa6130a2: Use snd soc volsw functions" to the asoc tree
  2016-06-20 17:12     ` [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
  2016-06-21  1:41       ` Sebastian Reichel
@ 2016-06-23 14:38       ` Mark Brown
  1 sibling, 0 replies; 36+ messages in thread
From: Mark Brown @ 2016-06-23 14:38 UTC (permalink / raw)
  To: Helen Koike
  Cc: Lars-Peter Clausen, Mark Brown, Sebastian Reichel, k.kozlowski,
	lars, alsa-devel, tiwai, lgirdwood, linux-kernel, peter.ujfalusi,
	broonie, cphealy, linux-omap, jarkko.nikula

The patch

   ASoC: tpa6130a2: Use snd soc volsw functions

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From e01d700c399d8d899850a1e5fad5227a9d976304 Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.co.uk>
Date: Mon, 20 Jun 2016 14:12:31 -0300
Subject: [PATCH] ASoC: tpa6130a2: Use snd soc volsw functions

Use snd_soc_{info,get,put}_volsw instead of custom volume functions

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
[On N900]
Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/tpa6130a2.c | 64 ++------------------------------------------
 1 file changed, 2 insertions(+), 62 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index d90388a38903..81bf5848b743 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -114,64 +114,6 @@ exit:
 	return ret;
 }
 
-static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
-		struct snd_ctl_elem_value *ucontrol)
-{
-	struct soc_mixer_control *mc =
-		(struct soc_mixer_control *)kcontrol->private_value;
-	struct tpa6130a2_data *data;
-	unsigned int reg = mc->reg;
-	unsigned int shift = mc->shift;
-	int max = mc->max, val;
-	unsigned int mask = (1 << fls(max)) - 1;
-	unsigned int invert = mc->invert;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-
-	regmap_read(data->regmap, reg, &val);
-	ucontrol->value.integer.value[0] = (val >> shift) & mask;
-
-	if (invert)
-		ucontrol->value.integer.value[0] =
-			max - ucontrol->value.integer.value[0];
-
-	mutex_unlock(&data->mutex);
-	return 0;
-}
-
-static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
-		struct snd_ctl_elem_value *ucontrol)
-{
-	struct soc_mixer_control *mc =
-		(struct soc_mixer_control *)kcontrol->private_value;
-	struct tpa6130a2_data *data;
-	unsigned int reg = mc->reg;
-	unsigned int shift = mc->shift;
-	int max = mc->max;
-	unsigned int mask = (1 << fls(max)) - 1;
-	unsigned int invert = mc->invert;
-	unsigned int val = (ucontrol->value.integer.value[0] & mask);
-	bool change;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (invert)
-		val = max - val;
-
-	mutex_lock(&data->mutex);
-	regmap_update_bits_check(data->regmap, reg, mask << shift, val << shift,
-				 &change);
-	mutex_unlock(&data->mutex);
-
-	return change;
-}
-
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -190,9 +132,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6130_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6130a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
+	SOC_SINGLE_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
-		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6130_tlv),
 };
 
@@ -203,9 +144,8 @@ static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6140a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
+	SOC_SINGLE_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
-		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6140_tlv),
 };
 
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Applied "ASoC: tap6130a2: Use regmap" to the asoc tree
  2016-06-18  3:26 ` [PATCH 2/4] ASoC: tap6130a2: Use regmap Helen Koike
  2016-06-18 22:33   ` Sebastian Reichel
@ 2016-06-23 14:38   ` Mark Brown
  1 sibling, 0 replies; 36+ messages in thread
From: Mark Brown @ 2016-06-23 14:38 UTC (permalink / raw)
  To: Helen Koike
  Cc: Lars-Peter Clausen, Mark Brown, lgirdwood, broonie, perex, tiwai,
	peter.ujfalusi, jarkko.nikula, lars, k.kozlowski, alsa-devel,
	linux-kernel, linux-omap

The patch

   ASoC: tap6130a2: Use regmap

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From a0d5ff4496dca6e435ae3adb286d6583cf785aca Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.co.uk>
Date: Mon, 20 Jun 2016 14:12:30 -0300
Subject: [PATCH] ASoC: tap6130a2: Use regmap

Use regmap instead of open-coding IO access and caching

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
[On N900]
Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/tpa6130a2.c | 166 ++++++++++++-------------------------------
 sound/soc/codecs/tpa6130a2.h |   2 -
 2 files changed, 46 insertions(+), 122 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index f31326a332fb..d90388a38903 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -32,6 +32,7 @@
 #include <sound/tlv.h>
 #include <linux/of.h>
 #include <linux/of_gpio.h>
+#include <linux/regmap.h>
 
 #include "tpa6130a2.h"
 
@@ -45,92 +46,16 @@ static struct i2c_client *tpa6130a2_client;
 /* This struct is used to save the context */
 struct tpa6130a2_data {
 	struct mutex mutex;
-	unsigned char regs[TPA6130A2_CACHEREGNUM];
+	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
 	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_i2c_read(int reg)
-{
-	struct tpa6130a2_data *data;
-	int val;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	/* If powered off, return the cached value */
-	if (data->power_state) {
-		val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
-		if (val < 0)
-			dev_err(&tpa6130a2_client->dev, "Read failed\n");
-		else
-			data->regs[reg] = val;
-	} else {
-		val = data->regs[reg];
-	}
-
-	return val;
-}
-
-static int tpa6130a2_i2c_write(int reg, u8 value)
-{
-	struct tpa6130a2_data *data;
-	int val = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (data->power_state) {
-		val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
-		if (val < 0) {
-			dev_err(&tpa6130a2_client->dev, "Write failed\n");
-			return val;
-		}
-	}
-
-	/* Either powered on or off, we save the context */
-	data->regs[reg] = value;
-
-	return val;
-}
-
-static u8 tpa6130a2_read(int reg)
-{
-	struct tpa6130a2_data *data;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return 0;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	return data->regs[reg];
-}
-
-static int tpa6130a2_initialize(void)
-{
-	struct tpa6130a2_data *data;
-	int i, ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	for (i = 1; i < TPA6130A2_REG_VERSION; i++) {
-		ret = tpa6130a2_i2c_write(i, data->regs[i]);
-		if (ret < 0)
-			break;
-	}
-
-	return ret;
-}
-
 static int tpa6130a2_power(u8 power)
 {
 	struct	tpa6130a2_data *data;
-	u8	val;
 	int	ret = 0;
 
 	if (WARN_ON(!tpa6130a2_client))
@@ -153,7 +78,7 @@ static int tpa6130a2_power(u8 power)
 			gpio_set_value(data->power_gpio, 1);
 
 		data->power_state = 1;
-		ret = tpa6130a2_initialize();
+		ret = regcache_sync(data->regmap);
 		if (ret < 0) {
 			dev_err(&tpa6130a2_client->dev,
 				"Failed to initialize chip\n");
@@ -165,9 +90,8 @@ static int tpa6130a2_power(u8 power)
 		}
 	} else {
 		/* set SWS */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val |= TPA6130A2_SWS;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+			TPA6130A2_SWS, TPA6130A2_SWS);
 
 		/* Power off */
 		if (data->power_gpio >= 0)
@@ -181,6 +105,8 @@ static int tpa6130a2_power(u8 power)
 		}
 
 		data->power_state = 0;
+		/* device regs does not match the cache state anymore */
+		regcache_mark_dirty(data->regmap);
 	}
 
 exit:
@@ -196,7 +122,7 @@ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
 	struct tpa6130a2_data *data;
 	unsigned int reg = mc->reg;
 	unsigned int shift = mc->shift;
-	int max = mc->max;
+	int max = mc->max, val;
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 
@@ -206,8 +132,8 @@ static int tpa6130a2_get_volsw(struct snd_kcontrol *kcontrol,
 
 	mutex_lock(&data->mutex);
 
-	ucontrol->value.integer.value[0] =
-		(tpa6130a2_read(reg) >> shift) & mask;
+	regmap_read(data->regmap, reg, &val);
+	ucontrol->value.integer.value[0] = (val >> shift) & mask;
 
 	if (invert)
 		ucontrol->value.integer.value[0] =
@@ -229,7 +155,7 @@ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
 	unsigned int mask = (1 << fls(max)) - 1;
 	unsigned int invert = mc->invert;
 	unsigned int val = (ucontrol->value.integer.value[0] & mask);
-	unsigned int val_reg;
+	bool change;
 
 	if (WARN_ON(!tpa6130a2_client))
 		return -EINVAL;
@@ -239,20 +165,11 @@ static int tpa6130a2_put_volsw(struct snd_kcontrol *kcontrol,
 		val = max - val;
 
 	mutex_lock(&data->mutex);
-
-	val_reg = tpa6130a2_read(reg);
-	if (((val_reg >> shift) & mask) == val) {
-		mutex_unlock(&data->mutex);
-		return 0;
-	}
-
-	val_reg &= ~(mask << shift);
-	val_reg |= val << shift;
-	tpa6130a2_i2c_write(reg, val_reg);
-
+	regmap_update_bits_check(data->regmap, reg, mask << shift, val << shift,
+				 &change);
 	mutex_unlock(&data->mutex);
 
-	return 1;
+	return change;
 }
 
 /*
@@ -301,31 +218,26 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
  */
 static void tpa6130a2_channel_enable(u8 channel, int enable)
 {
-	u8	val;
+	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
 
 	if (enable) {
 		/* Enable channel */
 		/* Enable amplifier */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val |= channel;
-		val &= ~TPA6130A2_SWS;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
 
 		/* Unmute channel */
-		val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
-		val &= ~channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
+				   channel, 0);
 	} else {
 		/* Disable channel */
 		/* Mute channel */
-		val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
-		val |= channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
+				   channel, channel);
 
 		/* Disable amplifier */
-		val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
-		val &= ~channel;
-		tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
+		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
+				   channel, 0);
 	}
 }
 
@@ -365,6 +277,20 @@ struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.probe = tpa6130a2_component_probe,
 };
 
+static const struct reg_default tpa6130a2_reg_defaults[] = {
+	{ TPA6130A2_REG_CONTROL, TPA6130A2_SWS },
+	{ TPA6130A2_REG_VOL_MUTE, TPA6130A2_MUTE_R | TPA6130A2_MUTE_L },
+};
+
+static const struct regmap_config tpa6130a2_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TPA6130A2_REG_VERSION,
+	.reg_defaults = tpa6130a2_reg_defaults,
+	.num_reg_defaults = ARRAY_SIZE(tpa6130a2_reg_defaults),
+	.cache_type = REGCACHE_RBTREE,
+};
+
 static int tpa6130a2_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
 {
@@ -373,6 +299,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	struct tpa6130a2_platform_data *pdata = client->dev.platform_data;
 	struct device_node *np = client->dev.of_node;
 	const char *regulator;
+	unsigned int version;
 	int ret;
 
 	dev = &client->dev;
@@ -381,6 +308,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (!data)
 		return -ENOMEM;
 
+	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
+	if (IS_ERR(data->regmap))
+		return PTR_ERR(data->regmap);
+
 	if (pdata) {
 		data->power_gpio = pdata->power_gpio;
 	} else if (np) {
@@ -399,11 +330,6 @@ static int tpa6130a2_probe(struct i2c_client *client,
 
 	mutex_init(&data->mutex);
 
-	/* Set default register values */
-	data->regs[TPA6130A2_REG_CONTROL] =	TPA6130A2_SWS;
-	data->regs[TPA6130A2_REG_VOL_MUTE] =	TPA6130A2_MUTE_R |
-						TPA6130A2_MUTE_L;
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -440,10 +366,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 
 
 	/* Read version */
-	ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
-				 TPA6130A2_VERSION_MASK;
-	if ((ret != 1) && (ret != 2))
-		dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
+	regmap_read(data->regmap, TPA6130A2_REG_VERSION, &version);
+	version &= TPA6130A2_VERSION_MASK;
+	if ((version != 1) && (version != 2))
+		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
 	ret = tpa6130a2_power(0);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 78ee7237568b..ef05a3ff189b 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -30,8 +30,6 @@
 #define TPA6130A2_REG_OUT_IMPEDANCE	0x03
 #define TPA6130A2_REG_VERSION		0x04
 
-#define TPA6130A2_CACHEREGNUM	(TPA6130A2_REG_VERSION + 1)
-
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
 #define TPA6130A2_SWS			(0x01 << 0)
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Applied "ASoC: tpa6130a2: Register component" to the asoc tree
  2016-06-20 17:12     ` [PATCH v2 1/5] ASoC: tpa6130a2: Register component Helen Koike
@ 2016-06-23 14:38       ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2016-06-23 14:38 UTC (permalink / raw)
  To: Helen Koike
  Cc: Lars-Peter Clausen, Mark Brown, Sebastian Reichel, k.kozlowski,
	lars, alsa-devel, tiwai, lgirdwood, linux-kernel, peter.ujfalusi,
	broonie, cphealy, linux-omap, jarkko.nikula

The patch

   ASoC: tpa6130a2: Register component

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From cb7e62256e99d285e415cf75db67558f0f8bb107 Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.co.uk>
Date: Mon, 20 Jun 2016 14:12:29 -0300
Subject: [PATCH] ASoC: tpa6130a2: Register component

Add tpa6130a2 controls by the component API and update rx51 accordingly

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-By: Sebastian Reichel <sre@kernel.org>
Reviewed-By: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/tpa6130a2.c | 30 +++++++++++++++---------------
 sound/soc/codecs/tpa6130a2.h |  1 -
 sound/soc/omap/rx51.c        | 23 ++++++++++++-----------
 3 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 11d85c5c787a..f31326a332fb 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -273,7 +273,7 @@ static const DECLARE_TLV_DB_RANGE(tpa6130_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6130a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
+	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
 		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6130_tlv),
@@ -286,7 +286,7 @@ static const DECLARE_TLV_DB_RANGE(tpa6140_tlv,
 );
 
 static const struct snd_kcontrol_new tpa6140a2_controls[] = {
-	SOC_SINGLE_EXT_TLV("TPA6140A2 Headphone Playback Volume",
+	SOC_SINGLE_EXT_TLV("Headphone Playback Volume",
 		       TPA6130A2_REG_VOL_MUTE, 1, 0x1f, 0,
 		       tpa6130a2_get_volsw, tpa6130a2_put_volsw,
 		       tpa6140_tlv),
@@ -348,23 +348,22 @@ int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
 }
 EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
 
-int tpa6130a2_add_controls(struct snd_soc_codec *codec)
+static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
-	struct	tpa6130a2_data *data;
-
-	if (tpa6130a2_client == NULL)
-		return -ENODEV;
-
-	data = i2c_get_clientdata(tpa6130a2_client);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
 
 	if (data->id == TPA6140A2)
-		return snd_soc_add_codec_controls(codec, tpa6140a2_controls,
-						ARRAY_SIZE(tpa6140a2_controls));
+		return snd_soc_add_component_controls(component,
+			tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls));
 	else
-		return snd_soc_add_codec_controls(codec, tpa6130a2_controls,
-						ARRAY_SIZE(tpa6130a2_controls));
+		return snd_soc_add_component_controls(component,
+			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
-EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
+
+struct snd_soc_component_driver tpa6130a2_component_driver = {
+	.name = "tpa6130a2",
+	.probe = tpa6130a2_component_probe,
+};
 
 static int tpa6130a2_probe(struct i2c_client *client,
 			   const struct i2c_device_id *id)
@@ -451,7 +450,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (ret != 0)
 		goto err_gpio;
 
-	return 0;
+	return devm_snd_soc_register_component(&client->dev,
+			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
 	tpa6130a2_client = NULL;
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 417444020ba6..78ee7237568b 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -56,7 +56,6 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
 extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
 
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 54949242bc70..b59cf89c5cab 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -286,16 +286,10 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
 
 static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
 {
-	struct snd_soc_codec *codec = rtd->codec;
 	struct snd_soc_card *card = rtd->card;
 	struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
 	int err;
 
-	err = tpa6130a2_add_controls(codec);
-	if (err < 0) {
-		dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
-		return err;
-	}
 	snd_soc_limit_volume(card, "TPA6130A2 Headphone Playback Volume", 42);
 
 	err = omap_mcbsp_st_add_controls(rtd, 2);
@@ -357,6 +351,10 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
 		.name = "TLV320AIC34b",
 		.codec_name = "tlv320aic3x-codec.2-0019",
 	},
+	{
+		.name = "TPA61320A2",
+		.codec_name = "tpa6130a2.2-0060",
+	},
 };
 
 static struct snd_soc_codec_conf rx51_codec_conf[] = {
@@ -364,6 +362,10 @@ static struct snd_soc_codec_conf rx51_codec_conf[] = {
 		.dev_name = "tlv320aic3x-codec.2-0019",
 		.name_prefix = "b",
 	},
+	{
+		.dev_name = "tpa6130a2.2-0060",
+		.name_prefix = "TPA6130A2",
+	},
 };
 
 /* Audio card */
@@ -435,11 +437,10 @@ static int rx51_soc_probe(struct platform_device *pdev)
 			dev_err(&pdev->dev, "Headphone amplifier node is not provided\n");
 			return -EINVAL;
 		}
-
-		/* TODO: tpa6130a2a driver supports only a single instance, so
-		 * this driver ignores the headphone-amplifier node for now.
-		 * It's already mandatory in the DT binding to be future proof.
-		 */
+		rx51_aux_dev[1].codec_name = NULL;
+		rx51_aux_dev[1].codec_of_node = dai_node;
+		rx51_codec_conf[1].dev_name = NULL;
+		rx51_codec_conf[1].of_node = dai_node;
 	}
 
 	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 0/2] ASoC: tpa6130a2: Add support for multiple instances
  2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
                       ` (4 preceding siblings ...)
  2016-06-20 17:12     ` [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
@ 2016-06-23 19:23     ` Helen Koike
  2016-06-23 19:23       ` [PATCH v3 1/2] ASoC: tpa6130a2: Add DAPM support Helen Koike
  2016-06-23 19:23       ` [PATCH v3 2/2] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
  5 siblings, 2 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-23 19:23 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

The current tpa6130a2 driver supports only a single instance.
This patch series add support for multiple instances by removing the global
variable that holds the instance.
This is performed by using the component API, regmap, the
snd_soc_{info,put,get}_volsw API and DAPM.

The first 3 pathes of this series were already applied, these two are missing

This patch series is based on git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Available at https://git.collabora.com/cgit/user/koike/linux.git/log/?h=sound/review/tpa6130a2

Helen Koike (2):
  ASoC: tpa6130a2: Add DAPM support
  ASoC: tpa6130a2: Remove goto err_gpio

 sound/soc/codecs/tpa6130a2.c | 196 ++++++++++++++++++-------------------------
 sound/soc/codecs/tpa6130a2.h |  11 +--
 sound/soc/omap/rx51.c        |  23 ++---
 3 files changed, 93 insertions(+), 137 deletions(-)


Changes since v2:
  ASoC: tpa6130a2: Add DAPM support
	- Add braces around else statement in tpa6130a2_power_event
  ASoC: tpa6130a2: Remove goto err_gpio
	- Add tested-by and reviewed-by from Sebastian
-- 
1.9.1

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [PATCH v3 1/2] ASoC: tpa6130a2: Add DAPM support
  2016-06-23 19:23     ` [PATCH v3 0/2] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
@ 2016-06-23 19:23       ` Helen Koike
  2016-06-26 12:02         ` Applied "ASoC: tpa6130a2: Add DAPM support" to the asoc tree Mark Brown
  2016-06-23 19:23       ` [PATCH v3 2/2] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
  1 sibling, 1 reply; 36+ messages in thread
From: Helen Koike @ 2016-06-23 19:23 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Add DAPM support and updated rx51 accordingly.
As a consequence:
- the exported function tpa6130a2_stereo_enable is not needed anymore
- the mutex is dealt in the DAPM
- the power state is tracked by the DAPM

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-by: Sebastian Reichel <sre@kernel.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>

---
Changes since v1:
- Replace
	+	{"TPA6130A2 HPLEFT", NULL, "LLOUT"},
	+	{"TPA6130A2 HPRIGHT", NULL, "RLOUT"}

	by

	+       {"TPA6130A2 LEFTIN", NULL, "LLOUT"},
	+       {"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
- Add tested-by and reviewed-by from Sebastian
- Add struct device dev* in struct tpa6130a2_data and pass data instead
of dev to tpa6130a2_power function
- remove #include "../codecs/tpa6130a2.h" in rx51.c

Changes since v2:
- Add braces around else statement in tpa6130a2_power_event

 sound/soc/codecs/tpa6130a2.c | 185 ++++++++++++++++++-------------------------
 sound/soc/codecs/tpa6130a2.h |  11 +--
 sound/soc/omap/rx51.c        |  23 ++----
 3 files changed, 89 insertions(+), 130 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 81bf584..9da1dd1 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -41,79 +41,74 @@ enum tpa_model {
 	TPA6140A2,
 };
 
-static struct i2c_client *tpa6130a2_client;
-
 /* This struct is used to save the context */
 struct tpa6130a2_data {
-	struct mutex mutex;
+	struct device *dev;
 	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
-	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_power(u8 power)
+static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
 {
-	struct	tpa6130a2_data *data;
-	int	ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-	if (power == data->power_state)
-		goto exit;
+	int ret;
 
-	if (power) {
+	if (enable) {
 		ret = regulator_enable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
+			dev_err(data->dev,
 				"Failed to enable supply: %d\n", ret);
-			goto exit;
+			return ret;
 		}
 		/* Power on */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 1);
-
-		data->power_state = 1;
-		ret = regcache_sync(data->regmap);
-		if (ret < 0) {
-			dev_err(&tpa6130a2_client->dev,
-				"Failed to initialize chip\n");
-			if (data->power_gpio >= 0)
-				gpio_set_value(data->power_gpio, 0);
-			regulator_disable(data->supply);
-			data->power_state = 0;
-			goto exit;
-		}
 	} else {
-		/* set SWS */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			TPA6130A2_SWS, TPA6130A2_SWS);
-
 		/* Power off */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 0);
 
 		ret = regulator_disable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
+			dev_err(data->dev,
 				"Failed to disable supply: %d\n", ret);
-			goto exit;
+			return ret;
 		}
 
-		data->power_state = 0;
 		/* device regs does not match the cache state anymore */
 		regcache_mark_dirty(data->regmap);
 	}
 
-exit:
-	mutex_unlock(&data->mutex);
 	return ret;
 }
 
+static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kctrl, int event)
+{
+	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
+	int ret;
+
+	/* before widget power up */
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Turn on the chip */
+		tpa6130a2_power(data, true);
+		/* Sync the registers */
+		ret = regcache_sync(data->regmap);
+		if (ret < 0) {
+			dev_err(c->dev, "Failed to initialize chip\n");
+			tpa6130a2_power(data, false);
+			return ret;
+		}
+	/* after widget power down */
+	} else {
+		tpa6130a2_power(data, false);
+	}
+
+	return 0;
+}
+
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -149,57 +144,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
 		       tpa6140_tlv),
 };
 
-/*
- * Enable or disable channel (left or right)
- * The bit number for mute and amplifier are the same per channel:
- * bit 6: Right channel
- * bit 7: Left channel
- * in both registers.
- */
-static void tpa6130a2_channel_enable(u8 channel, int enable)
-{
-	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (enable) {
-		/* Enable channel */
-		/* Enable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
-
-		/* Unmute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, 0);
-	} else {
-		/* Disable channel */
-		/* Mute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, channel);
-
-		/* Disable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-				   channel, 0);
-	}
-}
-
-int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
-{
-	int ret = 0;
-	if (enable) {
-		ret = tpa6130a2_power(1);
-		if (ret < 0)
-			return ret;
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 1);
-	} else {
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 0);
-		ret = tpa6130a2_power(0);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
-
 static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
 	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
@@ -212,9 +156,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
 			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
 
+static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("LEFTIN"),
+	SND_SOC_DAPM_INPUT("RIGHTIN"),
+	SND_SOC_DAPM_OUTPUT("HPLEFT"),
+	SND_SOC_DAPM_OUTPUT("HPRIGHT"),
+
+	SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
+			    TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
+	{ "Left PGA", NULL, "LEFTIN" },
+	{ "Right PGA", NULL, "RIGHTIN" },
+
+	{ "Left Mute", NULL, "Left PGA" },
+	{ "Right Mute", NULL, "Right PGA" },
+
+	{ "HPLEFT", NULL, "Left Mute" },
+	{ "HPRIGHT", NULL, "Right Mute" },
+
+	{ "Left PGA", NULL, "Power" },
+	{ "Right PGA", NULL, "Power" },
+};
+
 struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.name = "tpa6130a2",
 	.probe = tpa6130a2_component_probe,
+	.dapm_widgets = tpa6130a2_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
+	.dapm_routes = tpa6130a2_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
 };
 
 static const struct reg_default tpa6130a2_reg_defaults[] = {
@@ -248,6 +230,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (!data)
 		return -ENOMEM;
 
+	data->dev = dev;
+
 	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
 	if (IS_ERR(data->regmap))
 		return PTR_ERR(data->regmap);
@@ -262,14 +246,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	tpa6130a2_client = client;
-
-	i2c_set_clientdata(tpa6130a2_client, data);
+	i2c_set_clientdata(client, data);
 
 	data->id = id->driver_data;
 
-	mutex_init(&data->mutex);
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -300,7 +280,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		goto err_gpio;
 	}
 
-	ret = tpa6130a2_power(1);
+	ret = tpa6130a2_power(data, true);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -312,7 +292,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
-	ret = tpa6130a2_power(0);
+	ret = tpa6130a2_power(data, false);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -320,19 +300,9 @@ static int tpa6130a2_probe(struct i2c_client *client,
 			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
-	tpa6130a2_client = NULL;
-
 	return ret;
 }
 
-static int tpa6130a2_remove(struct i2c_client *client)
-{
-	tpa6130a2_power(0);
-	tpa6130a2_client = NULL;
-
-	return 0;
-}
-
 static const struct i2c_device_id tpa6130a2_id[] = {
 	{ "tpa6130a2", TPA6130A2 },
 	{ "tpa6140a2", TPA6140A2 },
@@ -355,7 +325,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
 		.of_match_table = of_match_ptr(tpa6130a2_of_match),
 	},
 	.probe = tpa6130a2_probe,
-	.remove = tpa6130a2_remove,
 	.id_table = tpa6130a2_id,
 };
 
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index ef05a3f..f19cad5 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -32,15 +32,18 @@
 
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
-#define TPA6130A2_SWS			(0x01 << 0)
+#define TPA6130A2_SWS_SHIFT		0
+#define TPA6130A2_SWS			(0x01 << TPA6130A2_SWS_SHIFT)
 #define TPA6130A2_TERMAL		(0x01 << 1)
 #define TPA6130A2_MODE(x)		(x << 4)
 #define TPA6130A2_MODE_STEREO		(0x00)
 #define TPA6130A2_MODE_DUAL_MONO	(0x01)
 #define TPA6130A2_MODE_BRIDGE		(0x02)
 #define TPA6130A2_MODE_MASK		(0x03)
-#define TPA6130A2_HP_EN_R		(0x01 << 6)
-#define TPA6130A2_HP_EN_L		(0x01 << 7)
+#define TPA6130A2_HP_EN_R_SHIFT		6
+#define TPA6130A2_HP_EN_R		(0x01 << TPA6130A2_HP_EN_R_SHIFT)
+#define TPA6130A2_HP_EN_L_SHIFT		7
+#define TPA6130A2_HP_EN_L		(0x01 << TPA6130A2_HP_EN_L_SHIFT)
 
 /* TPA6130A2_REG_VOL_MUTE (0x02) */
 #define TPA6130A2_VOLUME(x)		((x & 0x3f) << 0)
@@ -54,6 +57,4 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
-
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index b59cf89..a768457 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -33,7 +33,6 @@
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include "../codecs/tpa6130a2.h"
 
 #include <asm/mach-types.h>
 
@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int rx51_hp_event(struct snd_soc_dapm_widget *w,
-			 struct snd_kcontrol *k, int event)
-{
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		tpa6130a2_stereo_enable(codec, 1);
-	else
-		tpa6130a2_stereo_enable(codec, 0);
-
-	return 0;
-}
-
 static int rx51_get_input(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
 static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
 	SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
 	SND_SOC_DAPM_MIC("DMic", NULL),
-	SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 	SND_SOC_DAPM_MIC("HS Mic", NULL),
 	SND_SOC_DAPM_LINE("FM Transmitter", NULL),
 	SND_SOC_DAPM_SPK("Earphone", NULL),
@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Ext Spk", NULL, "HPROUT"},
 	{"Ext Spk", NULL, "HPLCOM"},
 	{"Ext Spk", NULL, "HPRCOM"},
-	{"Headphone Jack", NULL, "LLOUT"},
-	{"Headphone Jack", NULL, "RLOUT"},
 	{"FM Transmitter", NULL, "LLOUT"},
 	{"FM Transmitter", NULL, "RLOUT"},
 
+	{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
+	{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
+	{"TPA6130A2 LEFTIN", NULL, "LLOUT"},
+	{"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
+
 	{"DMic Rate 64", NULL, "DMic"},
 	{"DMic", NULL, "Mic Bias"},
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [PATCH v3 2/2] ASoC: tpa6130a2: Remove goto err_gpio
  2016-06-23 19:23     ` [PATCH v3 0/2] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
  2016-06-23 19:23       ` [PATCH v3 1/2] ASoC: tpa6130a2: Add DAPM support Helen Koike
@ 2016-06-23 19:23       ` Helen Koike
  1 sibling, 0 replies; 36+ messages in thread
From: Helen Koike @ 2016-06-23 19:23 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: lgirdwood, broonie, peter.ujfalusi, jarkko.nikula, lars,
	k.kozlowski, alsa-devel, linux-kernel, linux-omap, perex, tiwai,
	cphealy, Helen Koike

Replace goto err_gpio by return ret

Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-by: Sebastian Reichel <sre@kernel.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>

---
Changes since v1:
- this is a new patch in the series

Changes since v2:
- Add tested-by and reviewed-by from Sebastian

 sound/soc/codecs/tpa6130a2.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 9da1dd1..f1ea052 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -256,7 +256,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		if (ret < 0) {
 			dev_err(dev, "Failed to request power GPIO (%d)\n",
 				data->power_gpio);
-			goto err_gpio;
+			return ret;
 		}
 		gpio_direction_output(data->power_gpio, 0);
 	}
@@ -277,12 +277,12 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (IS_ERR(data->supply)) {
 		ret = PTR_ERR(data->supply);
 		dev_err(dev, "Failed to request supply: %d\n", ret);
-		goto err_gpio;
+		return ret;
 	}
 
 	ret = tpa6130a2_power(data, true);
 	if (ret != 0)
-		goto err_gpio;
+		return ret;
 
 
 	/* Read version */
@@ -294,13 +294,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	/* Disable the chip */
 	ret = tpa6130a2_power(data, false);
 	if (ret != 0)
-		goto err_gpio;
+		return ret;
 
 	return devm_snd_soc_register_component(&client->dev,
 			&tpa6130a2_component_driver, NULL, 0);
-
-err_gpio:
-	return ret;
 }
 
 static const struct i2c_device_id tpa6130a2_id[] = {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Applied "ASoC: tpa6130a2: Remove goto err_gpio" to the asoc tree
  2016-06-20 17:12     ` [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
  2016-06-21  1:42       ` Sebastian Reichel
@ 2016-06-26 12:02       ` Mark Brown
  1 sibling, 0 replies; 36+ messages in thread
From: Mark Brown @ 2016-06-26 12:02 UTC (permalink / raw)
  To: Helen Koike
  Cc: Sebastian Reichel, Mark Brown, Sebastian Reichel, k.kozlowski,
	lars, alsa-devel, tiwai, lgirdwood, linux-kernel, peter.ujfalusi,
	broonie, cphealy, linux-omap, jarkko.nikula

The patch

   ASoC: tpa6130a2: Remove goto err_gpio

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 39088c251c69d3b7b288e30228aed06e1d339da5 Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.co.uk>
Date: Thu, 23 Jun 2016 16:23:14 -0300
Subject: [PATCH] ASoC: tpa6130a2: Remove goto err_gpio

Replace goto err_gpio by return ret

Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-by: Sebastian Reichel <sre@kernel.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/tpa6130a2.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 9da1dd12f839..f1ea052a822e 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -256,7 +256,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		if (ret < 0) {
 			dev_err(dev, "Failed to request power GPIO (%d)\n",
 				data->power_gpio);
-			goto err_gpio;
+			return ret;
 		}
 		gpio_direction_output(data->power_gpio, 0);
 	}
@@ -277,12 +277,12 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (IS_ERR(data->supply)) {
 		ret = PTR_ERR(data->supply);
 		dev_err(dev, "Failed to request supply: %d\n", ret);
-		goto err_gpio;
+		return ret;
 	}
 
 	ret = tpa6130a2_power(data, true);
 	if (ret != 0)
-		goto err_gpio;
+		return ret;
 
 
 	/* Read version */
@@ -294,13 +294,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	/* Disable the chip */
 	ret = tpa6130a2_power(data, false);
 	if (ret != 0)
-		goto err_gpio;
+		return ret;
 
 	return devm_snd_soc_register_component(&client->dev,
 			&tpa6130a2_component_driver, NULL, 0);
-
-err_gpio:
-	return ret;
 }
 
 static const struct i2c_device_id tpa6130a2_id[] = {
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* Applied "ASoC: tpa6130a2: Add DAPM support" to the asoc tree
  2016-06-23 19:23       ` [PATCH v3 1/2] ASoC: tpa6130a2: Add DAPM support Helen Koike
@ 2016-06-26 12:02         ` Mark Brown
  0 siblings, 0 replies; 36+ messages in thread
From: Mark Brown @ 2016-06-26 12:02 UTC (permalink / raw)
  To: Helen Koike
  Cc: Lars-Peter Clausen, Sebastian Reichel, Mark Brown,
	Sebastian Reichel, k.kozlowski, lars, alsa-devel, tiwai,
	lgirdwood, linux-kernel, peter.ujfalusi, broonie, cphealy,
	linux-omap, jarkko.nikula

The patch

   ASoC: tpa6130a2: Add DAPM support

has been applied to the asoc tree at

   git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git 

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.  

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

>From 6d2de5ab4328718302c54b20222c6b1a574c3fce Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.co.uk>
Date: Thu, 23 Jun 2016 16:23:13 -0300
Subject: [PATCH] ASoC: tpa6130a2: Add DAPM support

Add DAPM support and updated rx51 accordingly.
As a consequence:
- the exported function tpa6130a2_stereo_enable is not needed anymore
- the mutex is dealt in the DAPM
- the power state is tracked by the DAPM

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
[koike: port for upstream]
Signed-off-by: Helen Koike <helen.koike@collabora.co.uk>
Tested-by: Sebastian Reichel <sre@kernel.org>
Reviewed-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/codecs/tpa6130a2.c | 185 ++++++++++++++++++-------------------------
 sound/soc/codecs/tpa6130a2.h |  11 +--
 sound/soc/omap/rx51.c        |  23 ++----
 3 files changed, 89 insertions(+), 130 deletions(-)

diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 81bf5848b743..9da1dd12f839 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -41,79 +41,74 @@ enum tpa_model {
 	TPA6140A2,
 };
 
-static struct i2c_client *tpa6130a2_client;
-
 /* This struct is used to save the context */
 struct tpa6130a2_data {
-	struct mutex mutex;
+	struct device *dev;
 	struct regmap *regmap;
 	struct regulator *supply;
 	int power_gpio;
-	u8 power_state:1;
 	enum tpa_model id;
 };
 
-static int tpa6130a2_power(u8 power)
+static int tpa6130a2_power(struct tpa6130a2_data *data, bool enable)
 {
-	struct	tpa6130a2_data *data;
-	int	ret = 0;
-
-	if (WARN_ON(!tpa6130a2_client))
-		return -EINVAL;
-	data = i2c_get_clientdata(tpa6130a2_client);
-
-	mutex_lock(&data->mutex);
-	if (power == data->power_state)
-		goto exit;
+	int ret;
 
-	if (power) {
+	if (enable) {
 		ret = regulator_enable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
+			dev_err(data->dev,
 				"Failed to enable supply: %d\n", ret);
-			goto exit;
+			return ret;
 		}
 		/* Power on */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 1);
-
-		data->power_state = 1;
-		ret = regcache_sync(data->regmap);
-		if (ret < 0) {
-			dev_err(&tpa6130a2_client->dev,
-				"Failed to initialize chip\n");
-			if (data->power_gpio >= 0)
-				gpio_set_value(data->power_gpio, 0);
-			regulator_disable(data->supply);
-			data->power_state = 0;
-			goto exit;
-		}
 	} else {
-		/* set SWS */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			TPA6130A2_SWS, TPA6130A2_SWS);
-
 		/* Power off */
 		if (data->power_gpio >= 0)
 			gpio_set_value(data->power_gpio, 0);
 
 		ret = regulator_disable(data->supply);
 		if (ret != 0) {
-			dev_err(&tpa6130a2_client->dev,
+			dev_err(data->dev,
 				"Failed to disable supply: %d\n", ret);
-			goto exit;
+			return ret;
 		}
 
-		data->power_state = 0;
 		/* device regs does not match the cache state anymore */
 		regcache_mark_dirty(data->regmap);
 	}
 
-exit:
-	mutex_unlock(&data->mutex);
 	return ret;
 }
 
+static int tpa6130a2_power_event(struct snd_soc_dapm_widget *w,
+				 struct snd_kcontrol *kctrl, int event)
+{
+	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
+	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(c);
+	int ret;
+
+	/* before widget power up */
+	if (SND_SOC_DAPM_EVENT_ON(event)) {
+		/* Turn on the chip */
+		tpa6130a2_power(data, true);
+		/* Sync the registers */
+		ret = regcache_sync(data->regmap);
+		if (ret < 0) {
+			dev_err(c->dev, "Failed to initialize chip\n");
+			tpa6130a2_power(data, false);
+			return ret;
+		}
+	/* after widget power down */
+	} else {
+		tpa6130a2_power(data, false);
+	}
+
+	return 0;
+}
+
 /*
  * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
  * down in gain.
@@ -149,57 +144,6 @@ static const struct snd_kcontrol_new tpa6140a2_controls[] = {
 		       tpa6140_tlv),
 };
 
-/*
- * Enable or disable channel (left or right)
- * The bit number for mute and amplifier are the same per channel:
- * bit 6: Right channel
- * bit 7: Left channel
- * in both registers.
- */
-static void tpa6130a2_channel_enable(u8 channel, int enable)
-{
-	struct tpa6130a2_data *data = i2c_get_clientdata(tpa6130a2_client);
-
-	if (enable) {
-		/* Enable channel */
-		/* Enable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-			channel | TPA6130A2_SWS, channel & ~TPA6130A2_SWS);
-
-		/* Unmute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, 0);
-	} else {
-		/* Disable channel */
-		/* Mute channel */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_VOL_MUTE,
-				   channel, channel);
-
-		/* Disable amplifier */
-		regmap_update_bits(data->regmap, TPA6130A2_REG_CONTROL,
-				   channel, 0);
-	}
-}
-
-int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
-{
-	int ret = 0;
-	if (enable) {
-		ret = tpa6130a2_power(1);
-		if (ret < 0)
-			return ret;
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 1);
-	} else {
-		tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
-					 0);
-		ret = tpa6130a2_power(0);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
-
 static int tpa6130a2_component_probe(struct snd_soc_component *component)
 {
 	struct tpa6130a2_data *data = snd_soc_component_get_drvdata(component);
@@ -212,9 +156,47 @@ static int tpa6130a2_component_probe(struct snd_soc_component *component)
 			tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls));
 }
 
+static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
+	SND_SOC_DAPM_INPUT("LEFTIN"),
+	SND_SOC_DAPM_INPUT("RIGHTIN"),
+	SND_SOC_DAPM_OUTPUT("HPLEFT"),
+	SND_SOC_DAPM_OUTPUT("HPRIGHT"),
+
+	SND_SOC_DAPM_PGA("Left Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_L_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Right Mute", TPA6130A2_REG_VOL_MUTE,
+			 TPA6130A2_HP_EN_R_SHIFT, 1, NULL, 0),
+	SND_SOC_DAPM_PGA("Left PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_L_SHIFT, 0, NULL, 0),
+	SND_SOC_DAPM_PGA("Right PGA", TPA6130A2_REG_CONTROL,
+			 TPA6130A2_HP_EN_R_SHIFT, 0, NULL, 0),
+
+	SND_SOC_DAPM_SUPPLY("Power", TPA6130A2_REG_CONTROL,
+			    TPA6130A2_SWS_SHIFT, 1, tpa6130a2_power_event,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_route tpa6130a2_dapm_routes[] = {
+	{ "Left PGA", NULL, "LEFTIN" },
+	{ "Right PGA", NULL, "RIGHTIN" },
+
+	{ "Left Mute", NULL, "Left PGA" },
+	{ "Right Mute", NULL, "Right PGA" },
+
+	{ "HPLEFT", NULL, "Left Mute" },
+	{ "HPRIGHT", NULL, "Right Mute" },
+
+	{ "Left PGA", NULL, "Power" },
+	{ "Right PGA", NULL, "Power" },
+};
+
 struct snd_soc_component_driver tpa6130a2_component_driver = {
 	.name = "tpa6130a2",
 	.probe = tpa6130a2_component_probe,
+	.dapm_widgets = tpa6130a2_dapm_widgets,
+	.num_dapm_widgets = ARRAY_SIZE(tpa6130a2_dapm_widgets),
+	.dapm_routes = tpa6130a2_dapm_routes,
+	.num_dapm_routes = ARRAY_SIZE(tpa6130a2_dapm_routes),
 };
 
 static const struct reg_default tpa6130a2_reg_defaults[] = {
@@ -248,6 +230,8 @@ static int tpa6130a2_probe(struct i2c_client *client,
 	if (!data)
 		return -ENOMEM;
 
+	data->dev = dev;
+
 	data->regmap = devm_regmap_init_i2c(client, &tpa6130a2_regmap_config);
 	if (IS_ERR(data->regmap))
 		return PTR_ERR(data->regmap);
@@ -262,14 +246,10 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		return -ENODEV;
 	}
 
-	tpa6130a2_client = client;
-
-	i2c_set_clientdata(tpa6130a2_client, data);
+	i2c_set_clientdata(client, data);
 
 	data->id = id->driver_data;
 
-	mutex_init(&data->mutex);
-
 	if (data->power_gpio >= 0) {
 		ret = devm_gpio_request(dev, data->power_gpio,
 					"tpa6130a2 enable");
@@ -300,7 +280,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		goto err_gpio;
 	}
 
-	ret = tpa6130a2_power(1);
+	ret = tpa6130a2_power(data, true);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -312,7 +292,7 @@ static int tpa6130a2_probe(struct i2c_client *client,
 		dev_warn(dev, "UNTESTED version detected (%d)\n", version);
 
 	/* Disable the chip */
-	ret = tpa6130a2_power(0);
+	ret = tpa6130a2_power(data, false);
 	if (ret != 0)
 		goto err_gpio;
 
@@ -320,19 +300,9 @@ static int tpa6130a2_probe(struct i2c_client *client,
 			&tpa6130a2_component_driver, NULL, 0);
 
 err_gpio:
-	tpa6130a2_client = NULL;
-
 	return ret;
 }
 
-static int tpa6130a2_remove(struct i2c_client *client)
-{
-	tpa6130a2_power(0);
-	tpa6130a2_client = NULL;
-
-	return 0;
-}
-
 static const struct i2c_device_id tpa6130a2_id[] = {
 	{ "tpa6130a2", TPA6130A2 },
 	{ "tpa6140a2", TPA6140A2 },
@@ -355,7 +325,6 @@ static struct i2c_driver tpa6130a2_i2c_driver = {
 		.of_match_table = of_match_ptr(tpa6130a2_of_match),
 	},
 	.probe = tpa6130a2_probe,
-	.remove = tpa6130a2_remove,
 	.id_table = tpa6130a2_id,
 };
 
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index ef05a3ff189b..f19cad5d4172 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -32,15 +32,18 @@
 
 /* Register bits */
 /* TPA6130A2_REG_CONTROL (0x01) */
-#define TPA6130A2_SWS			(0x01 << 0)
+#define TPA6130A2_SWS_SHIFT		0
+#define TPA6130A2_SWS			(0x01 << TPA6130A2_SWS_SHIFT)
 #define TPA6130A2_TERMAL		(0x01 << 1)
 #define TPA6130A2_MODE(x)		(x << 4)
 #define TPA6130A2_MODE_STEREO		(0x00)
 #define TPA6130A2_MODE_DUAL_MONO	(0x01)
 #define TPA6130A2_MODE_BRIDGE		(0x02)
 #define TPA6130A2_MODE_MASK		(0x03)
-#define TPA6130A2_HP_EN_R		(0x01 << 6)
-#define TPA6130A2_HP_EN_L		(0x01 << 7)
+#define TPA6130A2_HP_EN_R_SHIFT		6
+#define TPA6130A2_HP_EN_R		(0x01 << TPA6130A2_HP_EN_R_SHIFT)
+#define TPA6130A2_HP_EN_L_SHIFT		7
+#define TPA6130A2_HP_EN_L		(0x01 << TPA6130A2_HP_EN_L_SHIFT)
 
 /* TPA6130A2_REG_VOL_MUTE (0x02) */
 #define TPA6130A2_VOLUME(x)		((x & 0x3f) << 0)
@@ -54,6 +57,4 @@
 /* TPA6130A2_REG_VERSION (0x04) */
 #define TPA6130A2_VERSION_MASK		(0x0f)
 
-extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
-
 #endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index b59cf89c5cab..a76845748a10 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -33,7 +33,6 @@
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
-#include "../codecs/tpa6130a2.h"
 
 #include <asm/mach-types.h>
 
@@ -164,19 +163,6 @@ static int rx51_spk_event(struct snd_soc_dapm_widget *w,
 	return 0;
 }
 
-static int rx51_hp_event(struct snd_soc_dapm_widget *w,
-			 struct snd_kcontrol *k, int event)
-{
-	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
-
-	if (SND_SOC_DAPM_EVENT_ON(event))
-		tpa6130a2_stereo_enable(codec, 1);
-	else
-		tpa6130a2_stereo_enable(codec, 0);
-
-	return 0;
-}
-
 static int rx51_get_input(struct snd_kcontrol *kcontrol,
 			  struct snd_ctl_elem_value *ucontrol)
 {
@@ -235,7 +221,7 @@ static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
 static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
 	SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event),
 	SND_SOC_DAPM_MIC("DMic", NULL),
-	SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
+	SND_SOC_DAPM_HP("Headphone Jack", NULL),
 	SND_SOC_DAPM_MIC("HS Mic", NULL),
 	SND_SOC_DAPM_LINE("FM Transmitter", NULL),
 	SND_SOC_DAPM_SPK("Earphone", NULL),
@@ -246,11 +232,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
 	{"Ext Spk", NULL, "HPROUT"},
 	{"Ext Spk", NULL, "HPLCOM"},
 	{"Ext Spk", NULL, "HPRCOM"},
-	{"Headphone Jack", NULL, "LLOUT"},
-	{"Headphone Jack", NULL, "RLOUT"},
 	{"FM Transmitter", NULL, "LLOUT"},
 	{"FM Transmitter", NULL, "RLOUT"},
 
+	{"Headphone Jack", NULL, "TPA6130A2 HPLEFT"},
+	{"Headphone Jack", NULL, "TPA6130A2 HPRIGHT"},
+	{"TPA6130A2 LEFTIN", NULL, "LLOUT"},
+	{"TPA6130A2 RIGHTIN", NULL, "RLOUT"},
+
 	{"DMic Rate 64", NULL, "DMic"},
 	{"DMic", NULL, "Mic Bias"},
 
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2016-06-26 12:04 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-18  3:26 [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
2016-06-18  3:26 ` [PATCH 1/4] ASoC: tpa6130a2: Register component Helen Koike
2016-06-18 22:28   ` Sebastian Reichel
2016-06-18  3:26 ` [PATCH 2/4] ASoC: tap6130a2: Use regmap Helen Koike
2016-06-18 22:33   ` Sebastian Reichel
2016-06-23 14:38   ` Applied "ASoC: tap6130a2: Use regmap" to the asoc tree Mark Brown
2016-06-18  3:26 ` [PATCH 3/4] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
2016-06-18 22:34   ` Sebastian Reichel
2016-06-18  3:26 ` [PATCH 4/4] ASoC: tpa6130a2: Add DAPM support Helen Koike
2016-06-18 23:21   ` Sebastian Reichel
2016-06-19  9:39     ` Lars-Peter Clausen
2016-06-19 20:03       ` Sebastian Reichel
2016-06-20  8:34   ` Peter Ujfalusi
2016-06-18 10:40 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel
2016-06-18 21:33   ` Sebastian Reichel
2016-06-20 17:12   ` [PATCH v2 0/5] " Helen Koike
2016-06-20 17:12     ` [PATCH v2 1/5] ASoC: tpa6130a2: Register component Helen Koike
2016-06-23 14:38       ` Applied "ASoC: tpa6130a2: Register component" to the asoc tree Mark Brown
2016-06-20 17:12     ` [PATCH v2 2/5] ASoC: tap6130a2: Use regmap Helen Koike
2016-06-21  1:41       ` Sebastian Reichel
2016-06-20 17:12     ` [PATCH v2 3/5] ASoC: tpa6130a2: Use snd soc volsw functions Helen Koike
2016-06-21  1:41       ` Sebastian Reichel
2016-06-23 14:38       ` Applied "ASoC: tpa6130a2: Use snd soc volsw functions" to the asoc tree Mark Brown
2016-06-20 17:12     ` [PATCH v2 4/5] ASoC: tpa6130a2: Add DAPM support Helen Koike
2016-06-20 19:06       ` Helen Koike
2016-06-21  1:45         ` Sebastian Reichel
2016-06-20 19:44       ` Lars-Peter Clausen
2016-06-20 20:12         ` Helen Koike
2016-06-20 17:12     ` [PATCH v2 5/5] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
2016-06-21  1:42       ` Sebastian Reichel
2016-06-26 12:02       ` Applied "ASoC: tpa6130a2: Remove goto err_gpio" to the asoc tree Mark Brown
2016-06-23 19:23     ` [PATCH v3 0/2] ASoC: tpa6130a2: Add support for multiple instances Helen Koike
2016-06-23 19:23       ` [PATCH v3 1/2] ASoC: tpa6130a2: Add DAPM support Helen Koike
2016-06-26 12:02         ` Applied "ASoC: tpa6130a2: Add DAPM support" to the asoc tree Mark Brown
2016-06-23 19:23       ` [PATCH v3 2/2] ASoC: tpa6130a2: Remove goto err_gpio Helen Koike
2016-06-19 20:14 ` [PATCH 0/4] ASoC: tpa6130a2: Add support for multiple instances Sebastian Reichel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).