From d13e4362dec91304143875d9b8e1348bdfe69e63 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 13 Jun 2016 17:39:43 +0200 Subject: ASoC: fix ABE_TWL6040 dependency The TWL6040 ASoC support has recently started turning on CLK_TWL6040, but that fails to build when CONFIG_COMMON_CLK is disabled: warning: (SND_OMAP_SOC_OMAP_ABE_TWL6040) selects CLK_TWL6040 which has unmet direct dependencies (COMMON_CLK && TWL6040_CORE) 0xF18E38F6 Thu Jun 9 18:57:32 CEST 2016 failed In file included from ../include/linux/clocksource.h:18:0, from ../drivers/clocksource/timer-nps.c:34: ../include/linux/of.h:1005:20: error: comparison of distinct pointer types lacks a cast [-Werror] .data = (fn == (fn_type)NULL) ? fn : fn } ^ This adds a dependency to avoid the invalid configuration. Signed-off-by: Arnd Bergmann Fixes: 443500a3927a ("ASoC: omap: Kconfig: SND_OMAP_SOC_OMAP_ABE_TWL6040 to select CLK_TWL6040") Signed-off-by: Mark Brown --- sound/soc/omap/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/soc/omap') diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index 5185a3844da9..c82fa542c9e7 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig @@ -100,7 +100,7 @@ config SND_OMAP_SOC_OMAP_TWL4030 config SND_OMAP_SOC_OMAP_ABE_TWL6040 tristate "SoC Audio support for OMAP boards using ABE and twl6040 codec" - depends on TWL6040_CORE && SND_OMAP_SOC + depends on TWL6040_CORE && SND_OMAP_SOC && COMMON_CLK depends on ARCH_OMAP4 || (SOC_OMAP5 && MFD_PALMAS) || COMPILE_TEST select SND_OMAP_SOC_DMIC select SND_OMAP_SOC_MCPDM -- cgit v1.2.3-55-g7522 From cb7e62256e99d285e415cf75db67558f0f8bb107 Mon Sep 17 00:00:00 2001 From: Helen Koike Date: Mon, 20 Jun 2016 14:12:29 -0300 Subject: ASoC: tpa6130a2: Register component Add tpa6130a2 controls by the component API and update rx51 accordingly Signed-off-by: Lars-Peter Clausen [koike: port for upstream] Signed-off-by: Helen Koike Tested-By: Sebastian Reichel Reviewed-By: Sebastian Reichel Signed-off-by: Mark Brown --- 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(-) (limited to 'sound/soc/omap') 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); -- cgit v1.2.3-55-g7522 From 6d2de5ab4328718302c54b20222c6b1a574c3fce Mon Sep 17 00:00:00 2001 From: Helen Koike Date: Thu, 23 Jun 2016 16:23:13 -0300 Subject: 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 [koike: port for upstream] Signed-off-by: Helen Koike Tested-by: Sebastian Reichel Reviewed-by: Sebastian Reichel Signed-off-by: Mark Brown --- 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(-) (limited to 'sound/soc/omap') 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 #include #include -#include "../codecs/tpa6130a2.h" #include @@ -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"}, -- cgit v1.2.3-55-g7522