aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt298.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sound/soc/codecs/rt298.c87
1 files changed, 42 insertions, 45 deletions
diff --git a/sound/soc/codecs/rt298.c b/sound/soc/codecs/rt298.c
index f8c0f977206c..a2ce52dafea8 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)
@@ -508,7 +511,7 @@ static int rt298_adc_event(struct snd_soc_dapm_widget *w,
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
0x7080, 0x7000);
/* If MCLK doesn't exist, reset AD filter */
- if (!(snd_soc_component_read32(component, RT298_VAD_CTRL) & 0x200)) {
+ if (!(snd_soc_component_read(component, RT298_VAD_CTRL) & 0x200)) {
pr_info("NO MCLK\n");
switch (nid) {
case RT298_ADC_IN1:
@@ -1006,17 +1009,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 +1022,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 +1082,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 +1102,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 +1113,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 +1122,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 = {
@@ -1145,11 +1143,13 @@ static const struct i2c_device_id rt298_i2c_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rt298_i2c_id);
+#ifdef CONFIG_ACPI
static const struct acpi_device_id rt298_acpi_match[] = {
{ "INT343A", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, rt298_acpi_match);
+#endif
static const struct dmi_system_id force_combo_jack_table[] = {
{
@@ -1169,8 +1169,7 @@ static const struct dmi_system_id force_combo_jack_table[] = {
{ }
};
-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;
@@ -1291,14 +1290,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;
}
@@ -1307,7 +1304,7 @@ static struct i2c_driver rt298_i2c_driver = {
.name = "rt298",
.acpi_match_table = ACPI_PTR(rt298_acpi_match),
},
- .probe = rt298_i2c_probe,
+ .probe_new = rt298_i2c_probe,
.remove = rt298_i2c_remove,
.id_table = rt298_i2c_id,
};