aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCarlo Caione <carlo@endlessm.com>2017-10-20 07:18:55 -0400
committerMark Brown <broonie@kernel.org>2017-10-26 10:15:02 -0400
commit80bbe4a30bc6b119df86c280c91cde2034309bf1 (patch)
tree9ac5b6c85c47f343bbeb7fad269478695d841d9d
parentbe96fc54d2ed8eae6683b71d2dc5d1a939a10a1e (diff)
ASoC: rt5651: Enable jack detection on JD* pins
Enable jack detection for the RT5651 codec on the JD* pins. Signed-off-by: Carlo Caione <carlo@endlessm.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--include/sound/rt5651.h8
-rw-r--r--sound/soc/codecs/rt5651.c168
-rw-r--r--sound/soc/codecs/rt5651.h4
3 files changed, 178 insertions, 2 deletions
diff --git a/include/sound/rt5651.h b/include/sound/rt5651.h
index d35de758dfb5..18b79a761f10 100644
--- a/include/sound/rt5651.h
+++ b/include/sound/rt5651.h
@@ -11,11 +11,19 @@
11#ifndef __LINUX_SND_RT5651_H 11#ifndef __LINUX_SND_RT5651_H
12#define __LINUX_SND_RT5651_H 12#define __LINUX_SND_RT5651_H
13 13
14enum rt5651_jd_src {
15 RT5651_JD_NULL,
16 RT5651_JD1_1,
17 RT5651_JD1_2,
18 RT5651_JD2,
19};
20
14struct rt5651_platform_data { 21struct rt5651_platform_data {
15 /* IN2 can optionally be differential */ 22 /* IN2 can optionally be differential */
16 bool in2_diff; 23 bool in2_diff;
17 24
18 bool dmic_en; 25 bool dmic_en;
26 enum rt5651_jd_src jd_src;
19}; 27};
20 28
21#endif 29#endif
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c
index 28f7210cec91..91f254391452 100644
--- a/sound/soc/codecs/rt5651.c
+++ b/sound/soc/codecs/rt5651.c
@@ -26,6 +26,7 @@
26#include <sound/soc-dapm.h> 26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <sound/jack.h>
29 30
30#include "rl6231.h" 31#include "rl6231.h"
31#include "rt5651.h" 32#include "rt5651.h"
@@ -880,6 +881,9 @@ static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = {
880 SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2, 881 SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2,
881 RT5651_PWR_PLL_BIT, 0, NULL, 0), 882 RT5651_PWR_PLL_BIT, 0, NULL, 0),
882 /* Input Side */ 883 /* Input Side */
884 SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2,
885 RT5651_PWM_JD_M_BIT, 0, NULL, 0),
886
883 /* micbias */ 887 /* micbias */
884 SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1, 888 SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1,
885 RT5651_PWR_LDO_BIT, 0, NULL, 0), 889 RT5651_PWR_LDO_BIT, 0, NULL, 0),
@@ -1528,6 +1532,8 @@ static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
1528static int rt5651_set_bias_level(struct snd_soc_codec *codec, 1532static int rt5651_set_bias_level(struct snd_soc_codec *codec,
1529 enum snd_soc_bias_level level) 1533 enum snd_soc_bias_level level)
1530{ 1534{
1535 struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
1536
1531 switch (level) { 1537 switch (level) {
1532 case SND_SOC_BIAS_PREPARE: 1538 case SND_SOC_BIAS_PREPARE:
1533 if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) { 1539 if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) {
@@ -1556,8 +1562,13 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
1556 snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000); 1562 snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000);
1557 snd_soc_write(codec, RT5651_PWR_VOL, 0x0000); 1563 snd_soc_write(codec, RT5651_PWR_VOL, 0x0000);
1558 snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000); 1564 snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000);
1559 snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000); 1565 if (rt5651->pdata.jd_src) {
1560 snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000); 1566 snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204);
1567 snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002);
1568 } else {
1569 snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000);
1570 snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000);
1571 }
1561 break; 1572 break;
1562 1573
1563 default: 1574 default:
@@ -1570,6 +1581,7 @@ static int rt5651_set_bias_level(struct snd_soc_codec *codec,
1570static int rt5651_probe(struct snd_soc_codec *codec) 1581static int rt5651_probe(struct snd_soc_codec *codec)
1571{ 1582{
1572 struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); 1583 struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
1584 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1573 1585
1574 rt5651->codec = codec; 1586 rt5651->codec = codec;
1575 1587
@@ -1585,6 +1597,15 @@ static int rt5651_probe(struct snd_soc_codec *codec)
1585 1597
1586 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); 1598 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF);
1587 1599
1600 if (rt5651->pdata.jd_src) {
1601 snd_soc_dapm_force_enable_pin(dapm, "JD Power");
1602 snd_soc_dapm_force_enable_pin(dapm, "LDO");
1603 snd_soc_dapm_sync(dapm);
1604
1605 regmap_update_bits(rt5651->regmap, RT5651_MICBIAS,
1606 0x38, 0x38);
1607 }
1608
1588 return 0; 1609 return 0;
1589} 1610}
1590 1611
@@ -1728,6 +1749,93 @@ static int rt5651_parse_dt(struct rt5651_priv *rt5651, struct device_node *np)
1728 return 0; 1749 return 0;
1729} 1750}
1730 1751
1752static irqreturn_t rt5651_irq(int irq, void *data)
1753{
1754 struct rt5651_priv *rt5651 = data;
1755
1756 queue_delayed_work(system_power_efficient_wq,
1757 &rt5651->jack_detect_work, msecs_to_jiffies(250));
1758
1759 return IRQ_HANDLED;
1760}
1761
1762static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert)
1763{
1764 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
1765 int jack_type;
1766
1767 if (jack_insert) {
1768 snd_soc_dapm_force_enable_pin(dapm, "LDO");
1769 snd_soc_dapm_sync(dapm);
1770
1771 snd_soc_update_bits(codec, RT5651_MICBIAS,
1772 RT5651_MIC1_OVCD_MASK |
1773 RT5651_MIC1_OVTH_MASK |
1774 RT5651_PWR_CLK12M_MASK |
1775 RT5651_PWR_MB_MASK,
1776 RT5651_MIC1_OVCD_EN |
1777 RT5651_MIC1_OVTH_600UA |
1778 RT5651_PWR_MB_PU |
1779 RT5651_PWR_CLK12M_PU);
1780 msleep(100);
1781 if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR)
1782 jack_type = SND_JACK_HEADPHONE;
1783 else
1784 jack_type = SND_JACK_HEADSET;
1785 snd_soc_update_bits(codec, RT5651_IRQ_CTRL2,
1786 RT5651_MB1_OC_CLR, 0);
1787 } else { /* jack out */
1788 jack_type = 0;
1789
1790 snd_soc_update_bits(codec, RT5651_MICBIAS,
1791 RT5651_MIC1_OVCD_MASK,
1792 RT5651_MIC1_OVCD_DIS);
1793 }
1794
1795 return jack_type;
1796}
1797
1798static void rt5651_jack_detect_work(struct work_struct *work)
1799{
1800 struct rt5651_priv *rt5651 =
1801 container_of(work, struct rt5651_priv, jack_detect_work.work);
1802
1803 int report, val = 0;
1804
1805 if (!rt5651->codec)
1806 return;
1807
1808 switch (rt5651->pdata.jd_src) {
1809 case RT5651_JD1_1:
1810 val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000;
1811 break;
1812 case RT5651_JD1_2:
1813 val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000;
1814 break;
1815 case RT5651_JD2:
1816 val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000;
1817 break;
1818 default:
1819 break;
1820 }
1821
1822 report = rt5651_jack_detect(rt5651->codec, !val);
1823
1824 snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET);
1825}
1826
1827int rt5651_set_jack_detect(struct snd_soc_codec *codec,
1828 struct snd_soc_jack *hp_jack)
1829{
1830 struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
1831
1832 rt5651->hp_jack = hp_jack;
1833 rt5651_irq(0, rt5651);
1834
1835 return 0;
1836}
1837EXPORT_SYMBOL_GPL(rt5651_set_jack_detect);
1838
1731static int rt5651_i2c_probe(struct i2c_client *i2c, 1839static int rt5651_i2c_probe(struct i2c_client *i2c,
1732 const struct i2c_device_id *id) 1840 const struct i2c_device_id *id)
1733{ 1841{
@@ -1779,6 +1887,59 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
1779 1887
1780 rt5651->hp_mute = 1; 1888 rt5651->hp_mute = 1;
1781 1889
1890 if (rt5651->pdata.jd_src) {
1891
1892 /* IRQ output on GPIO1 */
1893 regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1,
1894 RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ);
1895
1896 switch (rt5651->pdata.jd_src) {
1897 case RT5651_JD1_1:
1898 regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
1899 RT5651_JD_TRG_SEL_MASK,
1900 RT5651_JD_TRG_SEL_JD1_1);
1901 regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
1902 RT5651_JD1_1_IRQ_EN,
1903 RT5651_JD1_1_IRQ_EN);
1904 break;
1905 case RT5651_JD1_2:
1906 regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
1907 RT5651_JD_TRG_SEL_MASK,
1908 RT5651_JD_TRG_SEL_JD1_2);
1909 regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
1910 RT5651_JD1_2_IRQ_EN,
1911 RT5651_JD1_2_IRQ_EN);
1912 break;
1913 case RT5651_JD2:
1914 regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2,
1915 RT5651_JD_TRG_SEL_MASK,
1916 RT5651_JD_TRG_SEL_JD2);
1917 regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1,
1918 RT5651_JD2_IRQ_EN,
1919 RT5651_JD2_IRQ_EN);
1920 break;
1921 case RT5651_JD_NULL:
1922 break;
1923 default:
1924 dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n");
1925 break;
1926 }
1927 }
1928
1929 INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work);
1930
1931 if (i2c->irq) {
1932 ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
1933 rt5651_irq,
1934 IRQF_TRIGGER_RISING |
1935 IRQF_TRIGGER_FALLING |
1936 IRQF_ONESHOT, "rt5651", rt5651);
1937 if (ret) {
1938 dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret);
1939 return ret;
1940 }
1941 }
1942
1782 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651, 1943 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651,
1783 rt5651_dai, ARRAY_SIZE(rt5651_dai)); 1944 rt5651_dai, ARRAY_SIZE(rt5651_dai));
1784 1945
@@ -1787,6 +1948,9 @@ static int rt5651_i2c_probe(struct i2c_client *i2c,
1787 1948
1788static int rt5651_i2c_remove(struct i2c_client *i2c) 1949static int rt5651_i2c_remove(struct i2c_client *i2c)
1789{ 1950{
1951 struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c);
1952
1953 cancel_delayed_work_sync(&rt5651->jack_detect_work);
1790 snd_soc_unregister_codec(&i2c->dev); 1954 snd_soc_unregister_codec(&i2c->dev);
1791 1955
1792 return 0; 1956 return 0;
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h
index 1bd33cfa6411..4f8b202121d7 100644
--- a/sound/soc/codecs/rt5651.h
+++ b/sound/soc/codecs/rt5651.h
@@ -2062,6 +2062,8 @@ struct rt5651_priv {
2062 struct snd_soc_codec *codec; 2062 struct snd_soc_codec *codec;
2063 struct rt5651_platform_data pdata; 2063 struct rt5651_platform_data pdata;
2064 struct regmap *regmap; 2064 struct regmap *regmap;
2065 struct snd_soc_jack *hp_jack;
2066 struct delayed_work jack_detect_work;
2065 2067
2066 int sysclk; 2068 int sysclk;
2067 int sysclk_src; 2069 int sysclk_src;
@@ -2077,4 +2079,6 @@ struct rt5651_priv {
2077 bool hp_mute; 2079 bool hp_mute;
2078}; 2080};
2079 2081
2082int rt5651_set_jack_detect(struct snd_soc_codec *codec,
2083 struct snd_soc_jack *hp_jack);
2080#endif /* __RT5651_H__ */ 2084#endif /* __RT5651_H__ */