aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt286.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt286.c')
-rw-r--r--sound/soc/codecs/rt286.c82
1 files changed, 42 insertions, 40 deletions
diff --git a/sound/soc/codecs/rt286.c b/sound/soc/codecs/rt286.c
index 1d1c7f8a9af2..f374840a5a7c 100644
--- a/sound/soc/codecs/rt286.c
+++ b/sound/soc/codecs/rt286.c
@@ -34,6 +34,7 @@
34#include "rt286.h" 34#include "rt286.h"
35 35
36#define RT286_VENDOR_ID 0x10ec0286 36#define RT286_VENDOR_ID 0x10ec0286
37#define RT288_VENDOR_ID 0x10ec0288
37 38
38struct rt286_priv { 39struct rt286_priv {
39 struct regmap *regmap; 40 struct regmap *regmap;
@@ -305,6 +306,8 @@ static int rt286_jack_detect(struct rt286_priv *rt286, bool *hp, bool *mic)
305 *hp = false; 306 *hp = false;
306 *mic = false; 307 *mic = false;
307 308
309 if (!rt286->codec)
310 return -EINVAL;
308 if (rt286->pdata.cbj_en) { 311 if (rt286->pdata.cbj_en) {
309 regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf); 312 regmap_read(rt286->regmap, RT286_GET_HP_SENSE, &buf);
310 *hp = buf & 0x80000000; 313 *hp = buf & 0x80000000;
@@ -403,7 +406,8 @@ EXPORT_SYMBOL_GPL(rt286_mic_detect);
403static int is_mclk_mode(struct snd_soc_dapm_widget *source, 406static int is_mclk_mode(struct snd_soc_dapm_widget *source,
404 struct snd_soc_dapm_widget *sink) 407 struct snd_soc_dapm_widget *sink)
405{ 408{
406 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(source->codec); 409 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm);
410 struct rt286_priv *rt286 = snd_soc_codec_get_drvdata(codec);
407 411
408 if (rt286->clk_id == RT286_SCLK_S_MCLK) 412 if (rt286->clk_id == RT286_SCLK_S_MCLK)
409 return 1; 413 return 1;
@@ -417,6 +421,8 @@ static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
417static const struct snd_kcontrol_new rt286_snd_controls[] = { 421static const struct snd_kcontrol_new rt286_snd_controls[] = {
418 SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT286_DACL_GAIN, 422 SOC_DOUBLE_R_TLV("DAC0 Playback Volume", RT286_DACL_GAIN,
419 RT286_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv), 423 RT286_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv),
424 SOC_DOUBLE_R("ADC0 Capture Switch", RT286_ADCL_GAIN,
425 RT286_ADCR_GAIN, 7, 1, 1),
420 SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT286_ADCL_GAIN, 426 SOC_DOUBLE_R_TLV("ADC0 Capture Volume", RT286_ADCL_GAIN,
421 RT286_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), 427 RT286_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv),
422 SOC_SINGLE_TLV("AMIC Volume", RT286_MIC_GAIN, 428 SOC_SINGLE_TLV("AMIC Volume", RT286_MIC_GAIN,
@@ -500,7 +506,7 @@ SOC_DAPM_ENUM("SPO source", rt286_spo_enum);
500static int rt286_spk_event(struct snd_soc_dapm_widget *w, 506static int rt286_spk_event(struct snd_soc_dapm_widget *w,
501 struct snd_kcontrol *kcontrol, int event) 507 struct snd_kcontrol *kcontrol, int event)
502{ 508{
503 struct snd_soc_codec *codec = w->codec; 509 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
504 510
505 switch (event) { 511 switch (event) {
506 case SND_SOC_DAPM_POST_PMU: 512 case SND_SOC_DAPM_POST_PMU:
@@ -522,7 +528,7 @@ static int rt286_spk_event(struct snd_soc_dapm_widget *w,
522static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w, 528static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
523 struct snd_kcontrol *kcontrol, int event) 529 struct snd_kcontrol *kcontrol, int event)
524{ 530{
525 struct snd_soc_codec *codec = w->codec; 531 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
526 532
527 switch (event) { 533 switch (event) {
528 case SND_SOC_DAPM_POST_PMU: 534 case SND_SOC_DAPM_POST_PMU:
@@ -538,36 +544,10 @@ static int rt286_set_dmic1_event(struct snd_soc_dapm_widget *w,
538 return 0; 544 return 0;
539} 545}
540 546
541static int rt286_adc_event(struct snd_soc_dapm_widget *w,
542 struct snd_kcontrol *kcontrol, int event)
543{
544 struct snd_soc_codec *codec = w->codec;
545 unsigned int nid;
546
547 nid = (w->reg >> 20) & 0xff;
548
549 switch (event) {
550 case SND_SOC_DAPM_POST_PMU:
551 snd_soc_update_bits(codec,
552 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
553 0x7080, 0x7000);
554 break;
555 case SND_SOC_DAPM_PRE_PMD:
556 snd_soc_update_bits(codec,
557 VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
558 0x7080, 0x7080);
559 break;
560 default:
561 return 0;
562 }
563
564 return 0;
565}
566
567static int rt286_vref_event(struct snd_soc_dapm_widget *w, 547static int rt286_vref_event(struct snd_soc_dapm_widget *w,
568 struct snd_kcontrol *kcontrol, int event) 548 struct snd_kcontrol *kcontrol, int event)
569{ 549{
570 struct snd_soc_codec *codec = w->codec; 550 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
571 551
572 switch (event) { 552 switch (event) {
573 case SND_SOC_DAPM_PRE_PMU: 553 case SND_SOC_DAPM_PRE_PMU:
@@ -585,7 +565,7 @@ static int rt286_vref_event(struct snd_soc_dapm_widget *w,
585static int rt286_ldo2_event(struct snd_soc_dapm_widget *w, 565static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
586 struct snd_kcontrol *kcontrol, int event) 566 struct snd_kcontrol *kcontrol, int event)
587{ 567{
588 struct snd_soc_codec *codec = w->codec; 568 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
589 569
590 switch (event) { 570 switch (event) {
591 case SND_SOC_DAPM_POST_PMU: 571 case SND_SOC_DAPM_POST_PMU:
@@ -604,7 +584,7 @@ static int rt286_ldo2_event(struct snd_soc_dapm_widget *w,
604static int rt286_mic1_event(struct snd_soc_dapm_widget *w, 584static int rt286_mic1_event(struct snd_soc_dapm_widget *w,
605 struct snd_kcontrol *kcontrol, int event) 585 struct snd_kcontrol *kcontrol, int event)
606{ 586{
607 struct snd_soc_codec *codec = w->codec; 587 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
608 588
609 switch (event) { 589 switch (event) {
610 case SND_SOC_DAPM_PRE_PMU: 590 case SND_SOC_DAPM_PRE_PMU:
@@ -667,12 +647,10 @@ static const struct snd_soc_dapm_widget rt286_dapm_widgets[] = {
667 SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0), 647 SND_SOC_DAPM_ADC("ADC 1", NULL, SND_SOC_NOPM, 0, 0),
668 648
669 /* ADC Mux */ 649 /* ADC Mux */
670 SND_SOC_DAPM_MUX_E("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1, 650 SND_SOC_DAPM_MUX("ADC 0 Mux", RT286_SET_POWER(RT286_ADC_IN1), 0, 1,
671 &rt286_adc0_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD | 651 &rt286_adc0_mux),
672 SND_SOC_DAPM_POST_PMU), 652 SND_SOC_DAPM_MUX("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1,
673 SND_SOC_DAPM_MUX_E("ADC 1 Mux", RT286_SET_POWER(RT286_ADC_IN2), 0, 1, 653 &rt286_adc1_mux),
674 &rt286_adc1_mux, rt286_adc_event, SND_SOC_DAPM_PRE_PMD |
675 SND_SOC_DAPM_POST_PMU),
676 654
677 /* Audio Interface */ 655 /* Audio Interface */
678 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 656 SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
@@ -1194,6 +1172,7 @@ static const struct regmap_config rt286_regmap = {
1194 1172
1195static const struct i2c_device_id rt286_i2c_id[] = { 1173static const struct i2c_device_id rt286_i2c_id[] = {
1196 {"rt286", 0}, 1174 {"rt286", 0},
1175 {"rt288", 0},
1197 {} 1176 {}
1198}; 1177};
1199MODULE_DEVICE_TABLE(i2c, rt286_i2c_id); 1178MODULE_DEVICE_TABLE(i2c, rt286_i2c_id);
@@ -1214,6 +1193,17 @@ static struct dmi_system_id force_combo_jack_table[] = {
1214 { } 1193 { }
1215}; 1194};
1216 1195
1196static struct dmi_system_id dmi_dell_dino[] = {
1197 {
1198 .ident = "Dell Dino",
1199 .matches = {
1200 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
1201 DMI_MATCH(DMI_BOARD_NAME, "0144P8")
1202 }
1203 },
1204 { }
1205};
1206
1217static int rt286_i2c_probe(struct i2c_client *i2c, 1207static int rt286_i2c_probe(struct i2c_client *i2c,
1218 const struct i2c_device_id *id) 1208 const struct i2c_device_id *id)
1219{ 1209{
@@ -1236,7 +1226,7 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1236 1226
1237 regmap_read(rt286->regmap, 1227 regmap_read(rt286->regmap,
1238 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret); 1228 RT286_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), &ret);
1239 if (ret != RT286_VENDOR_ID) { 1229 if (ret != RT286_VENDOR_ID && ret != RT288_VENDOR_ID) {
1240 dev_err(&i2c->dev, 1230 dev_err(&i2c->dev,
1241 "Device with ID register %x is not rt286\n", ret); 1231 "Device with ID register %x is not rt286\n", ret);
1242 return -ENODEV; 1232 return -ENODEV;
@@ -1249,7 +1239,8 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1249 if (pdata) 1239 if (pdata)
1250 rt286->pdata = *pdata; 1240 rt286->pdata = *pdata;
1251 1241
1252 if (dmi_check_system(force_combo_jack_table)) 1242 if (dmi_check_system(force_combo_jack_table) ||
1243 dmi_check_system(dmi_dell_dino))
1253 rt286->pdata.cbj_en = true; 1244 rt286->pdata.cbj_en = true;
1254 1245
1255 regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3); 1246 regmap_write(rt286->regmap, RT286_SET_AUDIO_POWER, AC_PWRST_D3);
@@ -1288,6 +1279,17 @@ static int rt286_i2c_probe(struct i2c_client *i2c,
1288 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737); 1279 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL3, 0xf777, 0x4737);
1289 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f); 1280 regmap_update_bits(rt286->regmap, RT286_DEPOP_CTRL4, 0x00ff, 0x003f);
1290 1281
1282 if (dmi_check_system(dmi_dell_dino)) {
1283 regmap_update_bits(rt286->regmap,
1284 RT286_SET_GPIO_MASK, 0x40, 0x40);
1285 regmap_update_bits(rt286->regmap,
1286 RT286_SET_GPIO_DIRECTION, 0x40, 0x40);
1287 regmap_update_bits(rt286->regmap,
1288 RT286_SET_GPIO_DATA, 0x40, 0x40);
1289 regmap_update_bits(rt286->regmap,
1290 RT286_GPIO_CTRL, 0xc, 0x8);
1291 }
1292
1291 if (rt286->i2c->irq) { 1293 if (rt286->i2c->irq) {
1292 ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq, 1294 ret = request_threaded_irq(rt286->i2c->irq, NULL, rt286_irq,
1293 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286); 1295 IRQF_TRIGGER_HIGH | IRQF_ONESHOT, "rt286", rt286);