summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/rt5670.h1
-rw-r--r--sound/soc/codecs/rt5670.c176
-rw-r--r--sound/soc/codecs/rt5670.h4
3 files changed, 179 insertions, 2 deletions
diff --git a/include/sound/rt5670.h b/include/sound/rt5670.h
index bd311197a3b5..b7d60510819b 100644
--- a/include/sound/rt5670.h
+++ b/include/sound/rt5670.h
@@ -14,6 +14,7 @@
14struct rt5670_platform_data { 14struct rt5670_platform_data {
15 int jd_mode; 15 int jd_mode;
16 bool in2_diff; 16 bool in2_diff;
17 bool dev_gpio;
17 18
18 bool dmic_en; 19 bool dmic_en;
19 unsigned int dmic1_data_pin; 20 unsigned int dmic1_data_pin;
diff --git a/sound/soc/codecs/rt5670.c b/sound/soc/codecs/rt5670.c
index 1a6a9c4dc879..a900db5fb1d9 100644
--- a/sound/soc/codecs/rt5670.c
+++ b/sound/soc/codecs/rt5670.c
@@ -403,6 +403,171 @@ static bool rt5670_readable_register(struct device *dev, unsigned int reg)
403 } 403 }
404} 404}
405 405
406/**
407 * rt5670_headset_detect - Detect headset.
408 * @codec: SoC audio codec device.
409 * @jack_insert: Jack insert or not.
410 *
411 * Detect whether is headset or not when jack inserted.
412 *
413 * Returns detect status.
414 */
415
416static int rt5670_headset_detect(struct snd_soc_codec *codec, int jack_insert)
417{
418 int val;
419 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
420
421 if (jack_insert) {
422 snd_soc_dapm_force_enable_pin(&codec->dapm,
423 "Mic Det Power");
424 snd_soc_dapm_sync(&codec->dapm);
425 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x0);
426 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
427 RT5670_CBJ_DET_MODE | RT5670_CBJ_MN_JD,
428 RT5670_CBJ_MN_JD);
429 snd_soc_write(codec, RT5670_GPIO_CTRL2, 0x0004);
430 snd_soc_update_bits(codec, RT5670_GPIO_CTRL1,
431 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
432 snd_soc_update_bits(codec, RT5670_CJ_CTRL1,
433 RT5670_CBJ_BST1_EN, RT5670_CBJ_BST1_EN);
434 snd_soc_write(codec, RT5670_JD_CTRL3, 0x00f0);
435 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
436 RT5670_CBJ_MN_JD, RT5670_CBJ_MN_JD);
437 snd_soc_update_bits(codec, RT5670_CJ_CTRL2,
438 RT5670_CBJ_MN_JD, 0);
439 msleep(300);
440 val = snd_soc_read(codec, RT5670_CJ_CTRL3) & 0x7;
441 if (val == 0x1 || val == 0x2) {
442 rt5670->jack_type = SND_JACK_HEADSET;
443 /* for push button */
444 snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x8);
445 snd_soc_update_bits(codec, RT5670_IL_CMD, 0x40, 0x40);
446 snd_soc_read(codec, RT5670_IL_CMD);
447 } else {
448 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
449 rt5670->jack_type = SND_JACK_HEADPHONE;
450 snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
451 snd_soc_dapm_sync(&codec->dapm);
452 }
453 } else {
454 snd_soc_update_bits(codec, RT5670_INT_IRQ_ST, 0x8, 0x0);
455 snd_soc_update_bits(codec, RT5670_GEN_CTRL3, 0x4, 0x4);
456 rt5670->jack_type = 0;
457 snd_soc_dapm_disable_pin(&codec->dapm, "Mic Det Power");
458 snd_soc_dapm_sync(&codec->dapm);
459 }
460
461 return rt5670->jack_type;
462}
463
464static int rt5670_button_detect(struct snd_soc_codec *codec)
465{
466 int btn_type, val;
467
468 val = snd_soc_read(codec, RT5670_IL_CMD);
469 btn_type = val & 0xff80;
470 snd_soc_write(codec, RT5670_IL_CMD, val);
471 if (btn_type != 0) {
472 msleep(20);
473 val = snd_soc_read(codec, RT5670_IL_CMD);
474 snd_soc_write(codec, RT5670_IL_CMD, val);
475 }
476
477 return btn_type;
478}
479
480static int rt5670_irq_detection(void *data)
481{
482 struct rt5670_priv *rt5670 = (struct rt5670_priv *)data;
483 struct snd_soc_jack_gpio *gpio = &rt5670->hp_gpio;
484 struct snd_soc_jack *jack = rt5670->jack;
485 int val, btn_type, report = jack->status;
486
487 if (rt5670->pdata.jd_mode == 1) /* 2 port */
488 val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0070;
489 else
490 val = snd_soc_read(rt5670->codec, RT5670_A_JD_CTRL1) & 0x0020;
491
492 switch (val) {
493 /* jack in */
494 case 0x30: /* 2 port */
495 case 0x0: /* 1 port or 2 port */
496 if (rt5670->jack_type == 0) {
497 report = rt5670_headset_detect(rt5670->codec, 1);
498 /* for push button and jack out */
499 gpio->debounce_time = 25;
500 break;
501 }
502 btn_type = 0;
503 if (snd_soc_read(rt5670->codec, RT5670_INT_IRQ_ST) & 0x4) {
504 /* button pressed */
505 report = SND_JACK_HEADSET;
506 btn_type = rt5670_button_detect(rt5670->codec);
507 switch (btn_type) {
508 case 0x2000: /* up */
509 report |= SND_JACK_BTN_1;
510 break;
511 case 0x0400: /* center */
512 report |= SND_JACK_BTN_0;
513 break;
514 case 0x0080: /* down */
515 report |= SND_JACK_BTN_2;
516 break;
517 default:
518 dev_err(rt5670->codec->dev,
519 "Unexpected button code 0x%04x\n",
520 btn_type);
521 break;
522 }
523 }
524 if (btn_type == 0)/* button release */
525 report = rt5670->jack_type;
526
527 break;
528 /* jack out */
529 case 0x70: /* 2 port */
530 case 0x10: /* 2 port */
531 case 0x20: /* 1 port */
532 report = 0;
533 snd_soc_update_bits(rt5670->codec, RT5670_INT_IRQ_ST, 0x1, 0x0);
534 rt5670_headset_detect(rt5670->codec, 0);
535 gpio->debounce_time = 150; /* for jack in */
536 break;
537 default:
538 break;
539 }
540
541 return report;
542}
543
544int rt5670_set_jack_detect(struct snd_soc_codec *codec,
545 struct snd_soc_jack *jack)
546{
547 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
548 int ret;
549
550 rt5670->jack = jack;
551 rt5670->hp_gpio.gpiod_dev = codec->dev;
552 rt5670->hp_gpio.name = "headphone detect";
553 rt5670->hp_gpio.report = SND_JACK_HEADSET |
554 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2;
555 rt5670->hp_gpio.debounce_time = 150;
556 rt5670->hp_gpio.wake = true;
557 rt5670->hp_gpio.data = (struct rt5670_priv *)rt5670;
558 rt5670->hp_gpio.jack_status_check = rt5670_irq_detection;
559
560 ret = snd_soc_jack_add_gpios(rt5670->jack, 1,
561 &rt5670->hp_gpio);
562 if (ret) {
563 dev_err(codec->dev, "Adding jack GPIO failed\n");
564 return ret;
565 }
566
567 return 0;
568}
569EXPORT_SYMBOL_GPL(rt5670_set_jack_detect);
570
406static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); 571static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
407static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); 572static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
408static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); 573static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
@@ -2506,6 +2671,7 @@ static int rt5670_remove(struct snd_soc_codec *codec)
2506 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec); 2671 struct rt5670_priv *rt5670 = snd_soc_codec_get_drvdata(codec);
2507 2672
2508 regmap_write(rt5670->regmap, RT5670_RESET, 0); 2673 regmap_write(rt5670->regmap, RT5670_RESET, 0);
2674 snd_soc_jack_free_gpios(rt5670->jack, 1, &rt5670->hp_gpio);
2509 return 0; 2675 return 0;
2510} 2676}
2511 2677
@@ -2665,6 +2831,7 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
2665 if (dmi_check_system(dmi_platform_intel_braswell)) { 2831 if (dmi_check_system(dmi_platform_intel_braswell)) {
2666 rt5670->pdata.dmic_en = true; 2832 rt5670->pdata.dmic_en = true;
2667 rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P; 2833 rt5670->pdata.dmic1_data_pin = RT5670_DMIC_DATA_IN2P;
2834 rt5670->pdata.dev_gpio = true;
2668 rt5670->pdata.jd_mode = 1; 2835 rt5670->pdata.jd_mode = 1;
2669 } 2836 }
2670 2837
@@ -2706,12 +2873,17 @@ static int rt5670_i2c_probe(struct i2c_client *i2c,
2706 regmap_update_bits(rt5670->regmap, RT5670_IN2, 2873 regmap_update_bits(rt5670->regmap, RT5670_IN2,
2707 RT5670_IN_DF2, RT5670_IN_DF2); 2874 RT5670_IN_DF2, RT5670_IN_DF2);
2708 2875
2709 if (i2c->irq) { 2876 if (rt5670->pdata.dev_gpio) {
2877 /* for push button */
2878 regmap_write(rt5670->regmap, RT5670_IL_CMD, 0x0000);
2879 regmap_write(rt5670->regmap, RT5670_IL_CMD2, 0x0010);
2880 regmap_write(rt5670->regmap, RT5670_IL_CMD3, 0x0014);
2881 /* for irq */
2710 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1, 2882 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL1,
2711 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ); 2883 RT5670_GP1_PIN_MASK, RT5670_GP1_PIN_IRQ);
2712 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2, 2884 regmap_update_bits(rt5670->regmap, RT5670_GPIO_CTRL2,
2713 RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT); 2885 RT5670_GP1_PF_MASK, RT5670_GP1_PF_OUT);
2714 2886 regmap_update_bits(rt5670->regmap, RT5670_DIG_MISC, 0x8, 0x8);
2715 } 2887 }
2716 2888
2717 if (rt5670->pdata.jd_mode) { 2889 if (rt5670->pdata.jd_mode) {
diff --git a/sound/soc/codecs/rt5670.h b/sound/soc/codecs/rt5670.h
index 0a67adbcfbc3..0f3255aeeb9b 100644
--- a/sound/soc/codecs/rt5670.h
+++ b/sound/soc/codecs/rt5670.h
@@ -1988,6 +1988,8 @@ struct rt5670_priv {
1988 struct snd_soc_codec *codec; 1988 struct snd_soc_codec *codec;
1989 struct rt5670_platform_data pdata; 1989 struct rt5670_platform_data pdata;
1990 struct regmap *regmap; 1990 struct regmap *regmap;
1991 struct snd_soc_jack *jack;
1992 struct snd_soc_jack_gpio hp_gpio;
1991 1993
1992 int sysclk; 1994 int sysclk;
1993 int sysclk_src; 1995 int sysclk_src;
@@ -2004,4 +2006,6 @@ struct rt5670_priv {
2004 int jack_type; 2006 int jack_type;
2005}; 2007};
2006 2008
2009int rt5670_set_jack_detect(struct snd_soc_codec *codec,
2010 struct snd_soc_jack *jack);
2007#endif /* __RT5670_H__ */ 2011#endif /* __RT5670_H__ */