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

ASoC: rt5663: Add the function of impedance sensing

Support the function of impedance sensing. It could be set the matrix row
number of the impedance sensing table and the related parameters in the
DTS.

Signed-off-by: Oder Chiou <oder_chiou@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Oder Chiou and committed by
Mark Brown
457c25ef 2bd6bf03

+233 -4
+16
Documentation/devicetree/bindings/sound/rt5663.txt
··· 19 19 Based on the different PCB layout, add the manual offset value to 20 20 compensate the DC offset for each L and R channel, and they are different 21 21 between headphone and headset. 22 + - "realtek,impedance_sensing_num" 23 + The matrix row number of the impedance sensing table. 24 + If the value is 0, it means the impedance sensing is not supported. 25 + - "realtek,impedance_sensing_table" 26 + The matrix rows of the impedance sensing table are consisted by impedance 27 + minimum, impedance maximun, volume, DC offset w/o and w/ mic of each L and 28 + R channel accordingly. Example is shown as following. 29 + < 0 300 7 0xffd160 0xffd1c0 0xff8a10 0xff8ab0 30 + 301 65535 4 0xffe470 0xffe470 0xffb8e0 0xffb8e0> 31 + The first and second column are defined for the impedance range. If the 32 + detected impedance value is in the range, then the volume value of the 33 + third column will be set to codec. In our codec design, each volume value 34 + should compensate different DC offset to avoid the pop sound, and it is 35 + also different between headphone and headset. In the example, the 36 + "realtek,impedance_sensing_num" is 2. It means that there are 2 ranges of 37 + impedance in the impedance sensing function. 22 38 23 39 Pins on the device (for linking into audio routes) for RT5663: 24 40
+3
include/sound/rt5663.h
··· 16 16 unsigned int dc_offset_r_manual; 17 17 unsigned int dc_offset_l_manual_mic; 18 18 unsigned int dc_offset_r_manual_mic; 19 + 20 + unsigned int impedance_sensing_num; 21 + unsigned int *impedance_sensing_table; 19 22 }; 20 23 21 24 #endif
+214 -4
sound/soc/codecs/rt5663.c
··· 38 38 CODEC_VER_0, 39 39 }; 40 40 41 + struct impedance_mapping_table { 42 + unsigned int imp_min; 43 + unsigned int imp_max; 44 + unsigned int vol; 45 + unsigned int dc_offset_l_manual; 46 + unsigned int dc_offset_r_manual; 47 + unsigned int dc_offset_l_manual_mic; 48 + unsigned int dc_offset_r_manual_mic; 49 + }; 50 + 41 51 struct rt5663_priv { 42 52 struct snd_soc_codec *codec; 43 53 struct rt5663_platform_data pdata; ··· 55 45 struct delayed_work jack_detect_work; 56 46 struct snd_soc_jack *hs_jack; 57 47 struct timer_list btn_check_timer; 48 + struct impedance_mapping_table *imp_table; 58 49 59 50 int codec_ver; 60 51 int sysclk; ··· 1586 1575 rt5663->jack_type = SND_JACK_HEADSET; 1587 1576 rt5663_enable_push_button_irq(codec, true); 1588 1577 1578 + if (rt5663->pdata.impedance_sensing_num) 1579 + break; 1580 + 1589 1581 if (rt5663->pdata.dc_offset_l_manual_mic) { 1590 1582 regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, 1591 1583 rt5663->pdata.dc_offset_l_manual_mic >> ··· 1609 1595 break; 1610 1596 default: 1611 1597 rt5663->jack_type = SND_JACK_HEADPHONE; 1598 + 1599 + if (rt5663->pdata.impedance_sensing_num) 1600 + break; 1612 1601 1613 1602 if (rt5663->pdata.dc_offset_l_manual) { 1614 1603 regmap_write(rt5663->regmap, RT5663_MIC_DECRO_2, ··· 1638 1621 1639 1622 dev_dbg(codec->dev, "jack_type = %d\n", rt5663->jack_type); 1640 1623 return rt5663->jack_type; 1624 + } 1625 + 1626 + static int rt5663_impedance_sensing(struct snd_soc_codec *codec) 1627 + { 1628 + struct rt5663_priv *rt5663 = snd_soc_codec_get_drvdata(codec); 1629 + unsigned int value, i, reg84, reg26, reg2fa, reg91, reg10, reg80; 1630 + 1631 + for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) { 1632 + if (rt5663->imp_table[i].vol == 7) 1633 + break; 1634 + } 1635 + 1636 + if (rt5663->jack_type == SND_JACK_HEADSET) { 1637 + snd_soc_write(codec, RT5663_MIC_DECRO_2, 1638 + rt5663->imp_table[i].dc_offset_l_manual_mic >> 16); 1639 + snd_soc_write(codec, RT5663_MIC_DECRO_3, 1640 + rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff); 1641 + snd_soc_write(codec, RT5663_MIC_DECRO_5, 1642 + rt5663->imp_table[i].dc_offset_r_manual_mic >> 16); 1643 + snd_soc_write(codec, RT5663_MIC_DECRO_6, 1644 + rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff); 1645 + } else { 1646 + snd_soc_write(codec, RT5663_MIC_DECRO_2, 1647 + rt5663->imp_table[i].dc_offset_l_manual >> 16); 1648 + snd_soc_write(codec, RT5663_MIC_DECRO_3, 1649 + rt5663->imp_table[i].dc_offset_l_manual & 0xffff); 1650 + snd_soc_write(codec, RT5663_MIC_DECRO_5, 1651 + rt5663->imp_table[i].dc_offset_r_manual >> 16); 1652 + snd_soc_write(codec, RT5663_MIC_DECRO_6, 1653 + rt5663->imp_table[i].dc_offset_r_manual & 0xffff); 1654 + } 1655 + 1656 + reg84 = snd_soc_read(codec, RT5663_ASRC_2); 1657 + reg26 = snd_soc_read(codec, RT5663_STO1_ADC_MIXER); 1658 + reg2fa = snd_soc_read(codec, RT5663_DUMMY_1); 1659 + reg91 = snd_soc_read(codec, RT5663_HP_CHARGE_PUMP_1); 1660 + reg10 = snd_soc_read(codec, RT5663_RECMIX); 1661 + reg80 = snd_soc_read(codec, RT5663_GLB_CLK); 1662 + 1663 + snd_soc_update_bits(codec, RT5663_STO_DRE_1, 0x8000, 0); 1664 + snd_soc_write(codec, RT5663_ASRC_2, 0); 1665 + snd_soc_write(codec, RT5663_STO1_ADC_MIXER, 0x4040); 1666 + snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, 1667 + RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK | 1668 + RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK, 1669 + RT5663_PWR_VREF1 | RT5663_PWR_VREF2); 1670 + usleep_range(10000, 10005); 1671 + snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, 1672 + RT5663_PWR_FV1_MASK | RT5663_PWR_FV2_MASK, 1673 + RT5663_PWR_FV1 | RT5663_PWR_FV2); 1674 + snd_soc_update_bits(codec, RT5663_GLB_CLK, RT5663_SCLK_SRC_MASK, 1675 + RT5663_SCLK_SRC_RCCLK); 1676 + snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK, 1677 + RT5663_DIG_25M_CLK_EN); 1678 + snd_soc_update_bits(codec, RT5663_ADDA_CLK_1, RT5663_I2S_PD1_MASK, 0); 1679 + snd_soc_write(codec, RT5663_PRE_DIV_GATING_1, 0xff00); 1680 + snd_soc_write(codec, RT5663_PRE_DIV_GATING_2, 0xfffc); 1681 + snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, 0x1232); 1682 + snd_soc_write(codec, RT5663_HP_LOGIC_2, 0x0005); 1683 + snd_soc_write(codec, RT5663_DEPOP_2, 0x3003); 1684 + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0x0030); 1685 + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0x0003); 1686 + snd_soc_update_bits(codec, RT5663_PWR_DIG_2, 1687 + RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F, 1688 + RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F); 1689 + snd_soc_update_bits(codec, RT5663_PWR_DIG_1, 1690 + RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 | 1691 + RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 | 1692 + RT5663_PWR_ADC_R1, 1693 + RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 | 1694 + RT5663_PWR_LDO_DACREF_ON | RT5663_PWR_ADC_L1 | 1695 + RT5663_PWR_ADC_R1); 1696 + msleep(40); 1697 + snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, 1698 + RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2, 1699 + RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2); 1700 + msleep(30); 1701 + snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_2, 0x1371); 1702 + snd_soc_write(codec, RT5663_STO_DAC_MIXER, 0); 1703 + snd_soc_write(codec, RT5663_BYPASS_STO_DAC, 0x000c); 1704 + snd_soc_write(codec, RT5663_HP_BIAS, 0xafaa); 1705 + snd_soc_write(codec, RT5663_CHARGE_PUMP_1, 0x2224); 1706 + snd_soc_write(codec, RT5663_HP_OUT_EN, 0x8088); 1707 + snd_soc_write(codec, RT5663_CHOP_ADC, 0x3000); 1708 + snd_soc_write(codec, RT5663_ADDA_RST, 0xc000); 1709 + snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0x3320); 1710 + snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c9); 1711 + snd_soc_write(codec, RT5663_DUMMY_1, 0x004c); 1712 + snd_soc_write(codec, RT5663_ANA_BIAS_CUR_1, 0x7733); 1713 + snd_soc_write(codec, RT5663_CHARGE_PUMP_2, 0x7777); 1714 + snd_soc_write(codec, RT5663_STO_DRE_9, 0x0007); 1715 + snd_soc_write(codec, RT5663_STO_DRE_10, 0x0007); 1716 + snd_soc_write(codec, RT5663_DUMMY_2, 0x02a4); 1717 + snd_soc_write(codec, RT5663_RECMIX, 0x0005); 1718 + snd_soc_write(codec, RT5663_HP_IMP_SEN_1, 0x4334); 1719 + snd_soc_update_bits(codec, RT5663_IRQ_3, 0x0004, 0x0004); 1720 + snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x2200); 1721 + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0x3000); 1722 + snd_soc_write(codec, RT5663_HP_LOGIC_1, 0x6200); 1723 + 1724 + for (i = 0; i < 100; i++) { 1725 + msleep(20); 1726 + if (snd_soc_read(codec, RT5663_INT_ST_1) & 0x2) 1727 + break; 1728 + } 1729 + 1730 + value = snd_soc_read(codec, RT5663_HP_IMP_SEN_4); 1731 + 1732 + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x3000, 0); 1733 + snd_soc_write(codec, RT5663_INT_ST_1, 0); 1734 + snd_soc_write(codec, RT5663_HP_LOGIC_1, 0); 1735 + snd_soc_update_bits(codec, RT5663_RC_CLK, RT5663_DIG_25M_CLK_MASK, 1736 + RT5663_DIG_25M_CLK_DIS); 1737 + snd_soc_write(codec, RT5663_GLB_CLK, reg80); 1738 + snd_soc_write(codec, RT5663_RECMIX, reg10); 1739 + snd_soc_write(codec, RT5663_DUMMY_2, 0x00a4); 1740 + snd_soc_write(codec, RT5663_DUMMY_1, reg2fa); 1741 + snd_soc_write(codec, RT5663_HP_CALIB_2, 0x00c8); 1742 + snd_soc_write(codec, RT5663_STO1_HPF_ADJ1, 0xb320); 1743 + snd_soc_write(codec, RT5663_ADDA_RST, 0xe400); 1744 + snd_soc_write(codec, RT5663_CHOP_ADC, 0x2000); 1745 + snd_soc_write(codec, RT5663_HP_OUT_EN, 0x0008); 1746 + snd_soc_update_bits(codec, RT5663_PWR_ANLG_2, 1747 + RT5663_PWR_RECMIX1 | RT5663_PWR_RECMIX2, 0); 1748 + snd_soc_update_bits(codec, RT5663_PWR_DIG_1, 1749 + RT5663_PWR_DAC_L1 | RT5663_PWR_DAC_R1 | 1750 + RT5663_PWR_LDO_DACREF_MASK | RT5663_PWR_ADC_L1 | 1751 + RT5663_PWR_ADC_R1, 0); 1752 + snd_soc_update_bits(codec, RT5663_PWR_DIG_2, 1753 + RT5663_PWR_ADC_S1F | RT5663_PWR_DAC_S1F, 0); 1754 + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0003, 0); 1755 + snd_soc_update_bits(codec, RT5663_DEPOP_1, 0x0030, 0); 1756 + snd_soc_write(codec, RT5663_HP_LOGIC_2, 0); 1757 + snd_soc_write(codec, RT5663_HP_CHARGE_PUMP_1, reg91); 1758 + snd_soc_update_bits(codec, RT5663_PWR_ANLG_1, 1759 + RT5663_PWR_VREF1_MASK | RT5663_PWR_VREF2_MASK, 0); 1760 + snd_soc_write(codec, RT5663_STO1_ADC_MIXER, reg26); 1761 + snd_soc_write(codec, RT5663_ASRC_2, reg84); 1762 + 1763 + for (i = 0; i < rt5663->pdata.impedance_sensing_num; i++) { 1764 + if (value >= rt5663->imp_table[i].imp_min && 1765 + value <= rt5663->imp_table[i].imp_max) 1766 + break; 1767 + } 1768 + 1769 + snd_soc_update_bits(codec, RT5663_STO_DRE_9, RT5663_DRE_GAIN_HP_MASK, 1770 + rt5663->imp_table[i].vol); 1771 + snd_soc_update_bits(codec, RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_MASK, 1772 + rt5663->imp_table[i].vol); 1773 + 1774 + if (rt5663->jack_type == SND_JACK_HEADSET) { 1775 + snd_soc_write(codec, RT5663_MIC_DECRO_2, 1776 + rt5663->imp_table[i].dc_offset_l_manual_mic >> 16); 1777 + snd_soc_write(codec, RT5663_MIC_DECRO_3, 1778 + rt5663->imp_table[i].dc_offset_l_manual_mic & 0xffff); 1779 + snd_soc_write(codec, RT5663_MIC_DECRO_5, 1780 + rt5663->imp_table[i].dc_offset_r_manual_mic >> 16); 1781 + snd_soc_write(codec, RT5663_MIC_DECRO_6, 1782 + rt5663->imp_table[i].dc_offset_r_manual_mic & 0xffff); 1783 + } else { 1784 + snd_soc_write(codec, RT5663_MIC_DECRO_2, 1785 + rt5663->imp_table[i].dc_offset_l_manual >> 16); 1786 + snd_soc_write(codec, RT5663_MIC_DECRO_3, 1787 + rt5663->imp_table[i].dc_offset_l_manual & 0xffff); 1788 + snd_soc_write(codec, RT5663_MIC_DECRO_5, 1789 + rt5663->imp_table[i].dc_offset_r_manual >> 16); 1790 + snd_soc_write(codec, RT5663_MIC_DECRO_6, 1791 + rt5663->imp_table[i].dc_offset_r_manual & 0xffff); 1792 + } 1793 + 1794 + return 0; 1641 1795 } 1642 1796 1643 1797 static int rt5663_button_detect(struct snd_soc_codec *codec) ··· 1889 1701 break; 1890 1702 case CODEC_VER_0: 1891 1703 report = rt5663_jack_detect(rt5663->codec, 1); 1704 + if (rt5663->pdata.impedance_sensing_num) 1705 + rt5663_impedance_sensing(rt5663->codec); 1892 1706 break; 1893 1707 default: 1894 1708 dev_err(codec->dev, "Unknown CODEC Version\n"); ··· 1986 1796 }; 1987 1797 1988 1798 static const struct snd_kcontrol_new rt5663_specific_controls[] = { 1989 - /* Headphone Output Volume */ 1990 - SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9, 1991 - RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1, 1992 - rt5663_hp_vol_tlv), 1993 1799 /* Mic Boost Volume*/ 1994 1800 SOC_SINGLE_TLV("IN1 Capture Volume", RT5663_CBJ_2, 1995 1801 RT5663_GAIN_BST1_SHIFT, 8, 0, in_bst_tlv), 1996 1802 /* Data Swap for Slot0/1 in ADCDAT1 */ 1997 1803 SOC_ENUM("IF1 ADC Data Swap", rt5663_if1_adc_enum), 1804 + }; 1805 + 1806 + static const struct snd_kcontrol_new rt5663_hpvol_controls[] = { 1807 + /* Headphone Output Volume */ 1808 + SOC_DOUBLE_R_TLV("Headphone Playback Volume", RT5663_STO_DRE_9, 1809 + RT5663_STO_DRE_10, RT5663_DRE_GAIN_HP_SHIFT, 23, 1, 1810 + rt5663_hp_vol_tlv), 1998 1811 }; 1999 1812 2000 1813 static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w, ··· 3082 2889 ARRAY_SIZE(rt5663_specific_dapm_routes)); 3083 2890 snd_soc_add_codec_controls(codec, rt5663_specific_controls, 3084 2891 ARRAY_SIZE(rt5663_specific_controls)); 2892 + 2893 + if (!rt5663->imp_table) 2894 + snd_soc_add_codec_controls(codec, rt5663_hpvol_controls, 2895 + ARRAY_SIZE(rt5663_hpvol_controls)); 3085 2896 break; 3086 2897 } 3087 2898 ··· 3374 3177 3375 3178 static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) 3376 3179 { 3180 + int table_size; 3181 + 3377 3182 device_property_read_u32(dev, "realtek,dc_offset_l_manual", 3378 3183 &rt5663->pdata.dc_offset_l_manual); 3379 3184 device_property_read_u32(dev, "realtek,dc_offset_r_manual", ··· 3384 3185 &rt5663->pdata.dc_offset_l_manual_mic); 3385 3186 device_property_read_u32(dev, "realtek,dc_offset_r_manual_mic", 3386 3187 &rt5663->pdata.dc_offset_r_manual_mic); 3188 + device_property_read_u32(dev, "realtek,impedance_sensing_num", 3189 + &rt5663->pdata.impedance_sensing_num); 3190 + 3191 + if (rt5663->pdata.impedance_sensing_num) { 3192 + table_size = sizeof(struct impedance_mapping_table) * 3193 + rt5663->pdata.impedance_sensing_num; 3194 + rt5663->imp_table = devm_kzalloc(dev, table_size, GFP_KERNEL); 3195 + device_property_read_u32_array(dev, 3196 + "realtek,impedance_sensing_table", 3197 + (u32 *)rt5663->imp_table, table_size); 3198 + } 3387 3199 3388 3200 return 0; 3389 3201 }