ASoC: codecs: tfa989x: Add support for tfa9897 optional rcv-gpios
Some OEM use a GPIO in addition to the tfa9897 RCV bit to switch between loudspeaker and earpiece/receiver mode. Add support for the GPIO switching by specifying rcv-gpios in DT. Signed-off-by: Vincent Knecht <vincent.knecht@mailoo.org> Link: https://lore.kernel.org/r/20211031210956.812101-3-vincent.knecht@mailoo.org Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
77fffb8393
commit
9da52c39b3
|
@ -7,6 +7,7 @@
|
|||
* Copyright (C) 2013 Sony Mobile Communications Inc.
|
||||
*/
|
||||
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
|
@ -56,6 +57,7 @@ struct tfa989x_rev {
|
|||
struct tfa989x {
|
||||
const struct tfa989x_rev *rev;
|
||||
struct regulator *vddd_supply;
|
||||
struct gpio_desc *rcv_gpiod;
|
||||
};
|
||||
|
||||
static bool tfa989x_writeable_reg(struct device *dev, unsigned int reg)
|
||||
|
@ -99,10 +101,20 @@ static const struct snd_soc_dapm_route tfa989x_dapm_routes[] = {
|
|||
{"Amp Input", "Right", "AIFINR"},
|
||||
};
|
||||
|
||||
static int tfa989x_put_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
|
||||
struct tfa989x *tfa989x = snd_soc_component_get_drvdata(component);
|
||||
|
||||
gpiod_set_value_cansleep(tfa989x->rcv_gpiod, ucontrol->value.enumerated.item[0]);
|
||||
|
||||
return snd_soc_put_enum_double(kcontrol, ucontrol);
|
||||
}
|
||||
|
||||
static const char * const mode_text[] = { "Speaker", "Receiver" };
|
||||
static SOC_ENUM_SINGLE_DECL(mode_enum, TFA989X_I2SREG, TFA989X_I2SREG_RCV, mode_text);
|
||||
static const struct snd_kcontrol_new tfa989x_mode_controls[] = {
|
||||
SOC_ENUM("Mode", mode_enum),
|
||||
SOC_ENUM_EXT("Mode", mode_enum, snd_soc_get_enum_double, tfa989x_put_mode),
|
||||
};
|
||||
|
||||
static int tfa989x_probe(struct snd_soc_component *component)
|
||||
|
@ -301,6 +313,12 @@ static int tfa989x_i2c_probe(struct i2c_client *i2c)
|
|||
return dev_err_probe(dev, PTR_ERR(tfa989x->vddd_supply),
|
||||
"Failed to get vddd regulator\n");
|
||||
|
||||
if (tfa989x->rev->rev == TFA9897_REVISION) {
|
||||
tfa989x->rcv_gpiod = devm_gpiod_get_optional(dev, "rcv", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(tfa989x->rcv_gpiod))
|
||||
return PTR_ERR(tfa989x->rcv_gpiod);
|
||||
}
|
||||
|
||||
regmap = devm_regmap_init_i2c(i2c, &tfa989x_regmap);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
|
Loading…
Reference in New Issue