diff options
Diffstat (limited to 'sound/soc/codecs/rt298.c')
-rw-r--r-- | sound/soc/codecs/rt298.c | 91 |
1 files changed, 46 insertions, 45 deletions
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c index dc0273a5a11f..03d9839a5de3 100644 --- a/sound/soc/codecs/rt298.c +++ b/sound/soc/codecs/rt298.c @@ -267,11 +267,16 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic) msleep(300); regmap_read(rt298->regmap, RT298_CBJ_CTRL2, &val); - if (0x0070 == (val & 0x0070)) + if (0x0070 == (val & 0x0070)) { *mic = true; - else + } else { *mic = false; + regmap_update_bits(rt298->regmap, + RT298_CBJ_CTRL1, + 0xfcc0, 0xc400); + } } + regmap_update_bits(rt298->regmap, RT298_DC_GAIN, 0x200, 0x0); @@ -321,39 +326,37 @@ static void rt298_jack_detect_work(struct work_struct *work) SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); } -int rt298_mic_detect(struct snd_soc_component *component, struct snd_soc_jack *jack) +static int rt298_mic_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm; - bool hp = false; - bool mic = false; - int status = 0; - /* If jack in NULL, disable HS jack */ - if (!jack) { + rt298->jack = jack; + + if (jack) { + /* Enable IRQ */ + if (rt298->jack->status & SND_JACK_HEADPHONE) + snd_soc_dapm_force_enable_pin(dapm, "LDO1"); + if (rt298->jack->status & SND_JACK_MICROPHONE) { + snd_soc_dapm_force_enable_pin(dapm, "HV"); + snd_soc_dapm_force_enable_pin(dapm, "VREF"); + } + regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); + /* Send an initial empty report */ + snd_soc_jack_report(rt298->jack, rt298->jack->status, + SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + } else { + /* Disable IRQ */ regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x0); - dapm = snd_soc_component_get_dapm(component); + snd_soc_dapm_disable_pin(dapm, "HV"); + snd_soc_dapm_disable_pin(dapm, "VREF"); snd_soc_dapm_disable_pin(dapm, "LDO1"); - snd_soc_dapm_sync(dapm); - return 0; } - - rt298->jack = jack; - regmap_update_bits(rt298->regmap, RT298_IRQ_CTRL, 0x2, 0x2); - - rt298_jack_detect(rt298, &hp, &mic); - if (hp) - status |= SND_JACK_HEADPHONE; - - if (mic) - status |= SND_JACK_MICROPHONE; - - snd_soc_jack_report(rt298->jack, status, - SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); + snd_soc_dapm_sync(dapm); return 0; } -EXPORT_SYMBOL_GPL(rt298_mic_detect); static int is_mclk_mode(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) @@ -786,7 +789,6 @@ static int rt298_hw_params(struct snd_pcm_substream *substream, return -EINVAL; } - d_len_code = 0; switch (params_width(params)) { /* bit 6:4 Bits per Sample */ case 16: @@ -1006,17 +1008,11 @@ static int rt298_probe(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); rt298->component = component; + INIT_DELAYED_WORK(&rt298->jack_detect_work, rt298_jack_detect_work); - if (rt298->i2c->irq) { - regmap_update_bits(rt298->regmap, - RT298_IRQ_CTRL, 0x2, 0x2); - - INIT_DELAYED_WORK(&rt298->jack_detect_work, - rt298_jack_detect_work); + if (rt298->i2c->irq) schedule_delayed_work(&rt298->jack_detect_work, - msecs_to_jiffies(1250)); - } - + msecs_to_jiffies(1250)); return 0; } @@ -1025,6 +1021,7 @@ static void rt298_remove(struct snd_soc_component *component) struct rt298_priv *rt298 = snd_soc_component_get_drvdata(component); cancel_delayed_work_sync(&rt298->jack_detect_work); + rt298->component = NULL; } #ifdef CONFIG_PM @@ -1084,7 +1081,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { .formats = RT298_FORMATS, }, .ops = &rt298_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, { .name = "rt298-aif2", @@ -1104,7 +1101,7 @@ static struct snd_soc_dai_driver rt298_dai[] = { .formats = RT298_FORMATS, }, .ops = &rt298_aif_dai_ops, - .symmetric_rates = 1, + .symmetric_rate = 1, }, }; @@ -1115,6 +1112,7 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .suspend = rt298_suspend, .resume = rt298_resume, .set_bias_level = rt298_set_bias_level, + .set_jack = rt298_mic_detect, .controls = rt298_snd_controls, .num_controls = ARRAY_SIZE(rt298_snd_controls), .dapm_widgets = rt298_dapm_widgets, @@ -1123,7 +1121,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt298 = { .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt298_regmap = { @@ -1168,11 +1165,17 @@ static const struct dmi_system_id force_combo_jack_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake") } }, + { + .ident = "Intel Kabylake R RVP", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform") + } + }, { } }; -static int rt298_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt298_i2c_probe(struct i2c_client *i2c) { struct rt298_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt298_priv *rt298; @@ -1281,7 +1284,7 @@ static int rt298_i2c_probe(struct i2c_client *i2c, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt298", rt298); if (ret != 0) { dev_err(&i2c->dev, - "Failed to reguest IRQ: %d\n", ret); + "Failed to request IRQ: %d\n", ret); return ret; } } @@ -1293,14 +1296,12 @@ static int rt298_i2c_probe(struct i2c_client *i2c, return ret; } -static int rt298_i2c_remove(struct i2c_client *i2c) +static void rt298_i2c_remove(struct i2c_client *i2c) { struct rt298_priv *rt298 = i2c_get_clientdata(i2c); if (i2c->irq) free_irq(i2c->irq, rt298); - - return 0; } |