diff options
Diffstat (limited to 'sound/soc/codecs/ts3a227e.c')
-rw-r--r-- | sound/soc/codecs/ts3a227e.c | 86 |
1 files changed, 77 insertions, 9 deletions
diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index 3ed3b45fa7ba..6d9166d9116a 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c @@ -78,12 +78,20 @@ static const int ts3a227e_buttons[] = { #define ADC_COMPLETE_INT_DISABLE 0x04 #define INTB_DISABLE 0x08 +/* TS3A227E_REG_SETTING_1 0x4 */ +#define DEBOUNCE_INSERTION_SETTING_SFT (0) +#define DEBOUNCE_INSERTION_SETTING_MASK (0x7 << DEBOUNCE_PRESS_SETTING_SFT) + /* TS3A227E_REG_SETTING_2 0x05 */ #define KP_ENABLE 0x04 /* TS3A227E_REG_SETTING_3 0x06 */ -#define MICBIAS_SETTING_SFT (3) +#define MICBIAS_SETTING_SFT 3 #define MICBIAS_SETTING_MASK (0x7 << MICBIAS_SETTING_SFT) +#define DEBOUNCE_RELEASE_SETTING_SFT 2 +#define DEBOUNCE_RELEASE_SETTING_MASK (0x1 << DEBOUNCE_RELEASE_SETTING_SFT) +#define DEBOUNCE_PRESS_SETTING_SFT 0 +#define DEBOUNCE_PRESS_SETTING_MASK (0x3 << DEBOUNCE_PRESS_SETTING_SFT) /* TS3A227E_REG_ACCESSORY_STATUS 0x0b */ #define TYPE_3_POLE 0x01 @@ -136,7 +144,7 @@ static bool ts3a227e_volatile_reg(struct device *dev, unsigned int reg) { switch (reg) { case TS3A227E_REG_INTERRUPT ... TS3A227E_REG_INTERRUPT_DISABLE: - case TS3A227E_REG_SETTING_2: + case TS3A227E_REG_SETTING_1 ... TS3A227E_REG_SETTING_2: case TS3A227E_REG_SWITCH_STATUS_1 ... TS3A227E_REG_ADC_OUTPUT: return true; default: @@ -250,7 +258,25 @@ int ts3a227e_enable_jack_detect(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(ts3a227e_enable_jack_detect); -static struct snd_soc_component_driver ts3a227e_soc_driver; +static int ts3a227e_set_jack(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + if (jack == NULL) + return -EINVAL; + + return ts3a227e_enable_jack_detect(component, jack); +} + +static int ts3a227e_get_jack_type(struct snd_soc_component *component) +{ + return SND_JACK_HEADSET; +} + +static const struct snd_soc_component_driver ts3a227e_soc_driver = { + .name = "ti,ts3a227e", + .set_jack = ts3a227e_set_jack, + .get_jack_type = ts3a227e_get_jack_type, +}; static const struct regmap_config ts3a227e_regmap_config = { .val_bits = 8, @@ -269,21 +295,61 @@ static const struct regmap_config ts3a227e_regmap_config = { static int ts3a227e_parse_device_property(struct ts3a227e *ts3a227e, struct device *dev) { - u32 micbias; + u32 value; + u32 value_ms; + u32 setting3_value = 0; + u32 setting3_mask = 0; int err; - err = device_property_read_u32(dev, "ti,micbias", &micbias); + err = device_property_read_u32(dev, "ti,micbias", &value); + if (!err) { + setting3_mask = MICBIAS_SETTING_MASK; + setting3_value = (value << MICBIAS_SETTING_SFT) & + MICBIAS_SETTING_MASK; + } + + err = device_property_read_u32(dev, "ti,debounce-release-ms", + &value_ms); + if (!err) { + value = (value_ms > 10); + setting3_mask |= DEBOUNCE_RELEASE_SETTING_MASK; + setting3_value |= (value << DEBOUNCE_RELEASE_SETTING_SFT) & + DEBOUNCE_RELEASE_SETTING_MASK; + } + + err = device_property_read_u32(dev, "ti,debounce-press-ms", &value_ms); if (!err) { + value = (value_ms + 20) / 40; + if (value > 3) + value = 3; + setting3_mask |= DEBOUNCE_PRESS_SETTING_MASK; + setting3_value |= (value << DEBOUNCE_PRESS_SETTING_SFT) & + DEBOUNCE_PRESS_SETTING_MASK; + } + + if (setting3_mask) regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_3, - MICBIAS_SETTING_MASK, - (micbias & 0x07) << MICBIAS_SETTING_SFT); + setting3_mask, setting3_value); + + err = device_property_read_u32(dev, "ti,debounce-insertion-ms", + &value_ms); + if (!err) { + if (value_ms < 165) + value = (value_ms + 15) / 30; + else if (value_ms < 1500) + value = 6; + else + value = 7; + regmap_update_bits(ts3a227e->regmap, TS3A227E_REG_SETTING_1, + DEBOUNCE_INSERTION_SETTING_MASK, + (value << DEBOUNCE_INSERTION_SETTING_SFT) & + DEBOUNCE_INSERTION_SETTING_MASK); } return 0; } -static int ts3a227e_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int ts3a227e_i2c_probe(struct i2c_client *i2c) { struct ts3a227e *ts3a227e; struct device *dev = &i2c->dev; @@ -366,11 +432,13 @@ static const struct i2c_device_id ts3a227e_i2c_ids[] = { }; MODULE_DEVICE_TABLE(i2c, ts3a227e_i2c_ids); +#ifdef CONFIG_OF static const struct of_device_id ts3a227e_of_match[] = { { .compatible = "ti,ts3a227e", }, { } }; MODULE_DEVICE_TABLE(of, ts3a227e_of_match); +#endif #ifdef CONFIG_ACPI static struct acpi_device_id ts3a227e_acpi_match[] = { |