Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Carlo Caione and committed by
Mark Brown
80bbe4a3 be96fc54

+178 -2
+8
include/sound/rt5651.h
··· 11 11 #ifndef __LINUX_SND_RT5651_H 12 12 #define __LINUX_SND_RT5651_H 13 13 14 + enum rt5651_jd_src { 15 + RT5651_JD_NULL, 16 + RT5651_JD1_1, 17 + RT5651_JD1_2, 18 + RT5651_JD2, 19 + }; 20 + 14 21 struct rt5651_platform_data { 15 22 /* IN2 can optionally be differential */ 16 23 bool in2_diff; 17 24 18 25 bool dmic_en; 26 + enum rt5651_jd_src jd_src; 19 27 }; 20 28 21 29 #endif
+166 -2
sound/soc/codecs/rt5651.c
··· 26 26 #include <sound/soc-dapm.h> 27 27 #include <sound/initval.h> 28 28 #include <sound/tlv.h> 29 + #include <sound/jack.h> 29 30 30 31 #include "rl6231.h" 31 32 #include "rt5651.h" ··· 881 880 SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2, 882 881 RT5651_PWR_PLL_BIT, 0, NULL, 0), 883 882 /* Input Side */ 883 + SND_SOC_DAPM_SUPPLY("JD Power", RT5651_PWR_ANLG2, 884 + RT5651_PWM_JD_M_BIT, 0, NULL, 0), 885 + 884 886 /* micbias */ 885 887 SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1, 886 888 RT5651_PWR_LDO_BIT, 0, NULL, 0), ··· 1532 1528 static int rt5651_set_bias_level(struct snd_soc_codec *codec, 1533 1529 enum snd_soc_bias_level level) 1534 1530 { 1531 + struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); 1532 + 1535 1533 switch (level) { 1536 1534 case SND_SOC_BIAS_PREPARE: 1537 1535 if (SND_SOC_BIAS_STANDBY == snd_soc_codec_get_bias_level(codec)) { ··· 1562 1556 snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000); 1563 1557 snd_soc_write(codec, RT5651_PWR_VOL, 0x0000); 1564 1558 snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000); 1565 - snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000); 1566 - snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000); 1559 + if (rt5651->pdata.jd_src) { 1560 + snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0204); 1561 + snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0002); 1562 + } else { 1563 + snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000); 1564 + snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000); 1565 + } 1567 1566 break; 1568 1567 1569 1568 default: ··· 1581 1570 static int rt5651_probe(struct snd_soc_codec *codec) 1582 1571 { 1583 1572 struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); 1573 + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 1584 1574 1585 1575 rt5651->codec = codec; 1586 1576 ··· 1596 1584 RT5651_PWR_FV1 | RT5651_PWR_FV2); 1597 1585 1598 1586 snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); 1587 + 1588 + if (rt5651->pdata.jd_src) { 1589 + snd_soc_dapm_force_enable_pin(dapm, "JD Power"); 1590 + snd_soc_dapm_force_enable_pin(dapm, "LDO"); 1591 + snd_soc_dapm_sync(dapm); 1592 + 1593 + regmap_update_bits(rt5651->regmap, RT5651_MICBIAS, 1594 + 0x38, 0x38); 1595 + } 1599 1596 1600 1597 return 0; 1601 1598 } ··· 1749 1728 return 0; 1750 1729 } 1751 1730 1731 + static irqreturn_t rt5651_irq(int irq, void *data) 1732 + { 1733 + struct rt5651_priv *rt5651 = data; 1734 + 1735 + queue_delayed_work(system_power_efficient_wq, 1736 + &rt5651->jack_detect_work, msecs_to_jiffies(250)); 1737 + 1738 + return IRQ_HANDLED; 1739 + } 1740 + 1741 + static int rt5651_jack_detect(struct snd_soc_codec *codec, int jack_insert) 1742 + { 1743 + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 1744 + int jack_type; 1745 + 1746 + if (jack_insert) { 1747 + snd_soc_dapm_force_enable_pin(dapm, "LDO"); 1748 + snd_soc_dapm_sync(dapm); 1749 + 1750 + snd_soc_update_bits(codec, RT5651_MICBIAS, 1751 + RT5651_MIC1_OVCD_MASK | 1752 + RT5651_MIC1_OVTH_MASK | 1753 + RT5651_PWR_CLK12M_MASK | 1754 + RT5651_PWR_MB_MASK, 1755 + RT5651_MIC1_OVCD_EN | 1756 + RT5651_MIC1_OVTH_600UA | 1757 + RT5651_PWR_MB_PU | 1758 + RT5651_PWR_CLK12M_PU); 1759 + msleep(100); 1760 + if (snd_soc_read(codec, RT5651_IRQ_CTRL2) & RT5651_MB1_OC_CLR) 1761 + jack_type = SND_JACK_HEADPHONE; 1762 + else 1763 + jack_type = SND_JACK_HEADSET; 1764 + snd_soc_update_bits(codec, RT5651_IRQ_CTRL2, 1765 + RT5651_MB1_OC_CLR, 0); 1766 + } else { /* jack out */ 1767 + jack_type = 0; 1768 + 1769 + snd_soc_update_bits(codec, RT5651_MICBIAS, 1770 + RT5651_MIC1_OVCD_MASK, 1771 + RT5651_MIC1_OVCD_DIS); 1772 + } 1773 + 1774 + return jack_type; 1775 + } 1776 + 1777 + static void rt5651_jack_detect_work(struct work_struct *work) 1778 + { 1779 + struct rt5651_priv *rt5651 = 1780 + container_of(work, struct rt5651_priv, jack_detect_work.work); 1781 + 1782 + int report, val = 0; 1783 + 1784 + if (!rt5651->codec) 1785 + return; 1786 + 1787 + switch (rt5651->pdata.jd_src) { 1788 + case RT5651_JD1_1: 1789 + val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x1000; 1790 + break; 1791 + case RT5651_JD1_2: 1792 + val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x2000; 1793 + break; 1794 + case RT5651_JD2: 1795 + val = snd_soc_read(rt5651->codec, RT5651_INT_IRQ_ST) & 0x4000; 1796 + break; 1797 + default: 1798 + break; 1799 + } 1800 + 1801 + report = rt5651_jack_detect(rt5651->codec, !val); 1802 + 1803 + snd_soc_jack_report(rt5651->hp_jack, report, SND_JACK_HEADSET); 1804 + } 1805 + 1806 + int rt5651_set_jack_detect(struct snd_soc_codec *codec, 1807 + struct snd_soc_jack *hp_jack) 1808 + { 1809 + struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); 1810 + 1811 + rt5651->hp_jack = hp_jack; 1812 + rt5651_irq(0, rt5651); 1813 + 1814 + return 0; 1815 + } 1816 + EXPORT_SYMBOL_GPL(rt5651_set_jack_detect); 1817 + 1752 1818 static int rt5651_i2c_probe(struct i2c_client *i2c, 1753 1819 const struct i2c_device_id *id) 1754 1820 { ··· 1887 1779 1888 1780 rt5651->hp_mute = 1; 1889 1781 1782 + if (rt5651->pdata.jd_src) { 1783 + 1784 + /* IRQ output on GPIO1 */ 1785 + regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1, 1786 + RT5651_GP1_PIN_MASK, RT5651_GP1_PIN_IRQ); 1787 + 1788 + switch (rt5651->pdata.jd_src) { 1789 + case RT5651_JD1_1: 1790 + regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2, 1791 + RT5651_JD_TRG_SEL_MASK, 1792 + RT5651_JD_TRG_SEL_JD1_1); 1793 + regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1, 1794 + RT5651_JD1_1_IRQ_EN, 1795 + RT5651_JD1_1_IRQ_EN); 1796 + break; 1797 + case RT5651_JD1_2: 1798 + regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2, 1799 + RT5651_JD_TRG_SEL_MASK, 1800 + RT5651_JD_TRG_SEL_JD1_2); 1801 + regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1, 1802 + RT5651_JD1_2_IRQ_EN, 1803 + RT5651_JD1_2_IRQ_EN); 1804 + break; 1805 + case RT5651_JD2: 1806 + regmap_update_bits(rt5651->regmap, RT5651_JD_CTRL2, 1807 + RT5651_JD_TRG_SEL_MASK, 1808 + RT5651_JD_TRG_SEL_JD2); 1809 + regmap_update_bits(rt5651->regmap, RT5651_IRQ_CTRL1, 1810 + RT5651_JD2_IRQ_EN, 1811 + RT5651_JD2_IRQ_EN); 1812 + break; 1813 + case RT5651_JD_NULL: 1814 + break; 1815 + default: 1816 + dev_warn(&i2c->dev, "Currently only JD1_1 / JD1_2 / JD2 are supported\n"); 1817 + break; 1818 + } 1819 + } 1820 + 1821 + INIT_DELAYED_WORK(&rt5651->jack_detect_work, rt5651_jack_detect_work); 1822 + 1823 + if (i2c->irq) { 1824 + ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL, 1825 + rt5651_irq, 1826 + IRQF_TRIGGER_RISING | 1827 + IRQF_TRIGGER_FALLING | 1828 + IRQF_ONESHOT, "rt5651", rt5651); 1829 + if (ret) { 1830 + dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); 1831 + return ret; 1832 + } 1833 + } 1834 + 1890 1835 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651, 1891 1836 rt5651_dai, ARRAY_SIZE(rt5651_dai)); 1892 1837 ··· 1948 1787 1949 1788 static int rt5651_i2c_remove(struct i2c_client *i2c) 1950 1789 { 1790 + struct rt5651_priv *rt5651 = i2c_get_clientdata(i2c); 1791 + 1792 + cancel_delayed_work_sync(&rt5651->jack_detect_work); 1951 1793 snd_soc_unregister_codec(&i2c->dev); 1952 1794 1953 1795 return 0;
+4
sound/soc/codecs/rt5651.h
··· 2062 2062 struct snd_soc_codec *codec; 2063 2063 struct rt5651_platform_data pdata; 2064 2064 struct regmap *regmap; 2065 + struct snd_soc_jack *hp_jack; 2066 + struct delayed_work jack_detect_work; 2065 2067 2066 2068 int sysclk; 2067 2069 int sysclk_src; ··· 2079 2077 bool hp_mute; 2080 2078 }; 2081 2079 2080 + int rt5651_set_jack_detect(struct snd_soc_codec *codec, 2081 + struct snd_soc_jack *hp_jack); 2082 2082 #endif /* __RT5651_H__ */