| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * cs42l42.c -- CS42L42 ALSA SoC audio driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 6 | 7 | * Author: James Schulman <james.schulman@cirrus.com> |
|---|
| 7 | 8 | * Author: Brian Austin <brian.austin@cirrus.com> |
|---|
| 8 | 9 | * Author: Michael White <michael.white@cirrus.com> |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 11 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 12 | | - * published by the Free Software Foundation. |
|---|
| 13 | | - * |
|---|
| 14 | 10 | */ |
|---|
| 15 | 11 | |
|---|
| 16 | 12 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 24 | 20 | #include <linux/regmap.h> |
|---|
| 25 | 21 | #include <linux/slab.h> |
|---|
| 26 | 22 | #include <linux/platform_device.h> |
|---|
| 23 | +#include <linux/property.h> |
|---|
| 27 | 24 | #include <linux/regulator/consumer.h> |
|---|
| 28 | 25 | #include <linux/gpio/consumer.h> |
|---|
| 29 | | -#include <linux/of.h> |
|---|
| 30 | | -#include <linux/of_gpio.h> |
|---|
| 31 | 26 | #include <linux/of_device.h> |
|---|
| 32 | 27 | #include <sound/core.h> |
|---|
| 33 | 28 | #include <sound/pcm.h> |
|---|
| .. | .. |
|---|
| 402 | 397 | .reg_defaults = cs42l42_reg_defaults, |
|---|
| 403 | 398 | .num_reg_defaults = ARRAY_SIZE(cs42l42_reg_defaults), |
|---|
| 404 | 399 | .cache_type = REGCACHE_RBTREE, |
|---|
| 400 | + |
|---|
| 401 | + .use_single_read = true, |
|---|
| 402 | + .use_single_write = true, |
|---|
| 405 | 403 | }; |
|---|
| 406 | 404 | |
|---|
| 407 | 405 | static DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 100, true); |
|---|
| .. | .. |
|---|
| 837 | 835 | return 0; |
|---|
| 838 | 836 | } |
|---|
| 839 | 837 | |
|---|
| 840 | | -static int cs42l42_digital_mute(struct snd_soc_dai *dai, int mute) |
|---|
| 838 | +static int cs42l42_mute(struct snd_soc_dai *dai, int mute, int direction) |
|---|
| 841 | 839 | { |
|---|
| 842 | 840 | struct snd_soc_component *component = dai->component; |
|---|
| 843 | 841 | unsigned int regval; |
|---|
| .. | .. |
|---|
| 865 | 863 | CS42L42_PLL_START_MASK, |
|---|
| 866 | 864 | 1 << CS42L42_PLL_START_SHIFT); |
|---|
| 867 | 865 | /* Read the headphone load */ |
|---|
| 868 | | - regval = snd_soc_component_read32(component, CS42L42_LOAD_DET_RCSTAT); |
|---|
| 866 | + regval = snd_soc_component_read(component, CS42L42_LOAD_DET_RCSTAT); |
|---|
| 869 | 867 | if (((regval & CS42L42_RLA_STAT_MASK) >> |
|---|
| 870 | 868 | CS42L42_RLA_STAT_SHIFT) == CS42L42_RLA_STAT_15_OHM) { |
|---|
| 871 | 869 | fullScaleVol = CS42L42_HP_FULL_SCALE_VOL_MASK; |
|---|
| .. | .. |
|---|
| 897 | 895 | .hw_params = cs42l42_pcm_hw_params, |
|---|
| 898 | 896 | .set_fmt = cs42l42_set_dai_fmt, |
|---|
| 899 | 897 | .set_sysclk = cs42l42_set_sysclk, |
|---|
| 900 | | - .digital_mute = cs42l42_digital_mute |
|---|
| 898 | + .mute_stream = cs42l42_mute, |
|---|
| 899 | + .no_capture_mute = 1, |
|---|
| 901 | 900 | }; |
|---|
| 902 | 901 | |
|---|
| 903 | 902 | static struct snd_soc_dai_driver cs42l42_dai = { |
|---|
| .. | .. |
|---|
| 1530 | 1529 | (1 << CS42L42_HS_CLAMP_DISABLE_SHIFT)); |
|---|
| 1531 | 1530 | |
|---|
| 1532 | 1531 | /* Enable the tip sense circuit */ |
|---|
| 1532 | + regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL, |
|---|
| 1533 | + CS42L42_TS_INV_MASK, CS42L42_TS_INV_MASK); |
|---|
| 1534 | + |
|---|
| 1533 | 1535 | regmap_update_bits(cs42l42->regmap, CS42L42_TIPSENSE_CTL, |
|---|
| 1534 | 1536 | CS42L42_TIP_SENSE_CTRL_MASK | |
|---|
| 1535 | 1537 | CS42L42_TIP_SENSE_INV_MASK | |
|---|
| 1536 | 1538 | CS42L42_TIP_SENSE_DEBOUNCE_MASK, |
|---|
| 1537 | 1539 | (3 << CS42L42_TIP_SENSE_CTRL_SHIFT) | |
|---|
| 1538 | | - (0 << CS42L42_TIP_SENSE_INV_SHIFT) | |
|---|
| 1540 | + (!cs42l42->ts_inv << CS42L42_TIP_SENSE_INV_SHIFT) | |
|---|
| 1539 | 1541 | (2 << CS42L42_TIP_SENSE_DEBOUNCE_SHIFT)); |
|---|
| 1540 | 1542 | |
|---|
| 1541 | 1543 | /* Save the initial status of the tip sense */ |
|---|
| .. | .. |
|---|
| 1554 | 1556 | CS42L42_HS_DET_LEVEL_1 |
|---|
| 1555 | 1557 | }; |
|---|
| 1556 | 1558 | |
|---|
| 1557 | | -static int cs42l42_handle_device_data(struct i2c_client *i2c_client, |
|---|
| 1559 | +static int cs42l42_handle_device_data(struct device *dev, |
|---|
| 1558 | 1560 | struct cs42l42_private *cs42l42) |
|---|
| 1559 | 1561 | { |
|---|
| 1560 | | - struct device_node *np = i2c_client->dev.of_node; |
|---|
| 1561 | 1562 | unsigned int val; |
|---|
| 1562 | | - unsigned int thresholds[CS42L42_NUM_BIASES]; |
|---|
| 1563 | + u32 thresholds[CS42L42_NUM_BIASES]; |
|---|
| 1563 | 1564 | int ret; |
|---|
| 1564 | 1565 | int i; |
|---|
| 1565 | 1566 | |
|---|
| 1566 | | - ret = of_property_read_u32(np, "cirrus,ts-inv", &val); |
|---|
| 1567 | | - |
|---|
| 1567 | + ret = device_property_read_u32(dev, "cirrus,ts-inv", &val); |
|---|
| 1568 | 1568 | if (!ret) { |
|---|
| 1569 | 1569 | switch (val) { |
|---|
| 1570 | 1570 | case CS42L42_TS_INV_EN: |
|---|
| .. | .. |
|---|
| 1572 | 1572 | cs42l42->ts_inv = val; |
|---|
| 1573 | 1573 | break; |
|---|
| 1574 | 1574 | default: |
|---|
| 1575 | | - dev_err(&i2c_client->dev, |
|---|
| 1575 | + dev_err(dev, |
|---|
| 1576 | 1576 | "Wrong cirrus,ts-inv DT value %d\n", |
|---|
| 1577 | 1577 | val); |
|---|
| 1578 | 1578 | cs42l42->ts_inv = CS42L42_TS_INV_DIS; |
|---|
| .. | .. |
|---|
| 1581 | 1581 | cs42l42->ts_inv = CS42L42_TS_INV_DIS; |
|---|
| 1582 | 1582 | } |
|---|
| 1583 | 1583 | |
|---|
| 1584 | | - regmap_update_bits(cs42l42->regmap, CS42L42_TSENSE_CTL, |
|---|
| 1585 | | - CS42L42_TS_INV_MASK, |
|---|
| 1586 | | - (cs42l42->ts_inv << CS42L42_TS_INV_SHIFT)); |
|---|
| 1587 | | - |
|---|
| 1588 | | - ret = of_property_read_u32(np, "cirrus,ts-dbnc-rise", &val); |
|---|
| 1589 | | - |
|---|
| 1584 | + ret = device_property_read_u32(dev, "cirrus,ts-dbnc-rise", &val); |
|---|
| 1590 | 1585 | if (!ret) { |
|---|
| 1591 | 1586 | switch (val) { |
|---|
| 1592 | 1587 | case CS42L42_TS_DBNCE_0: |
|---|
| .. | .. |
|---|
| 1600 | 1595 | cs42l42->ts_dbnc_rise = val; |
|---|
| 1601 | 1596 | break; |
|---|
| 1602 | 1597 | default: |
|---|
| 1603 | | - dev_err(&i2c_client->dev, |
|---|
| 1598 | + dev_err(dev, |
|---|
| 1604 | 1599 | "Wrong cirrus,ts-dbnc-rise DT value %d\n", |
|---|
| 1605 | 1600 | val); |
|---|
| 1606 | 1601 | cs42l42->ts_dbnc_rise = CS42L42_TS_DBNCE_1000; |
|---|
| .. | .. |
|---|
| 1614 | 1609 | (cs42l42->ts_dbnc_rise << |
|---|
| 1615 | 1610 | CS42L42_TS_RISE_DBNCE_TIME_SHIFT)); |
|---|
| 1616 | 1611 | |
|---|
| 1617 | | - ret = of_property_read_u32(np, "cirrus,ts-dbnc-fall", &val); |
|---|
| 1618 | | - |
|---|
| 1612 | + ret = device_property_read_u32(dev, "cirrus,ts-dbnc-fall", &val); |
|---|
| 1619 | 1613 | if (!ret) { |
|---|
| 1620 | 1614 | switch (val) { |
|---|
| 1621 | 1615 | case CS42L42_TS_DBNCE_0: |
|---|
| .. | .. |
|---|
| 1629 | 1623 | cs42l42->ts_dbnc_fall = val; |
|---|
| 1630 | 1624 | break; |
|---|
| 1631 | 1625 | default: |
|---|
| 1632 | | - dev_err(&i2c_client->dev, |
|---|
| 1626 | + dev_err(dev, |
|---|
| 1633 | 1627 | "Wrong cirrus,ts-dbnc-fall DT value %d\n", |
|---|
| 1634 | 1628 | val); |
|---|
| 1635 | 1629 | cs42l42->ts_dbnc_fall = CS42L42_TS_DBNCE_0; |
|---|
| .. | .. |
|---|
| 1643 | 1637 | (cs42l42->ts_dbnc_fall << |
|---|
| 1644 | 1638 | CS42L42_TS_FALL_DBNCE_TIME_SHIFT)); |
|---|
| 1645 | 1639 | |
|---|
| 1646 | | - ret = of_property_read_u32(np, "cirrus,btn-det-init-dbnce", &val); |
|---|
| 1647 | | - |
|---|
| 1640 | + ret = device_property_read_u32(dev, "cirrus,btn-det-init-dbnce", &val); |
|---|
| 1648 | 1641 | if (!ret) { |
|---|
| 1649 | | - if ((val >= CS42L42_BTN_DET_INIT_DBNCE_MIN) && |
|---|
| 1650 | | - (val <= CS42L42_BTN_DET_INIT_DBNCE_MAX)) |
|---|
| 1642 | + if (val <= CS42L42_BTN_DET_INIT_DBNCE_MAX) |
|---|
| 1651 | 1643 | cs42l42->btn_det_init_dbnce = val; |
|---|
| 1652 | 1644 | else { |
|---|
| 1653 | | - dev_err(&i2c_client->dev, |
|---|
| 1645 | + dev_err(dev, |
|---|
| 1654 | 1646 | "Wrong cirrus,btn-det-init-dbnce DT value %d\n", |
|---|
| 1655 | 1647 | val); |
|---|
| 1656 | 1648 | cs42l42->btn_det_init_dbnce = |
|---|
| .. | .. |
|---|
| 1661 | 1653 | CS42L42_BTN_DET_INIT_DBNCE_DEFAULT; |
|---|
| 1662 | 1654 | } |
|---|
| 1663 | 1655 | |
|---|
| 1664 | | - ret = of_property_read_u32(np, "cirrus,btn-det-event-dbnce", &val); |
|---|
| 1665 | | - |
|---|
| 1656 | + ret = device_property_read_u32(dev, "cirrus,btn-det-event-dbnce", &val); |
|---|
| 1666 | 1657 | if (!ret) { |
|---|
| 1667 | | - if ((val >= CS42L42_BTN_DET_EVENT_DBNCE_MIN) && |
|---|
| 1668 | | - (val <= CS42L42_BTN_DET_EVENT_DBNCE_MAX)) |
|---|
| 1658 | + if (val <= CS42L42_BTN_DET_EVENT_DBNCE_MAX) |
|---|
| 1669 | 1659 | cs42l42->btn_det_event_dbnce = val; |
|---|
| 1670 | 1660 | else { |
|---|
| 1671 | | - dev_err(&i2c_client->dev, |
|---|
| 1672 | | - "Wrong cirrus,btn-det-event-dbnce DT value %d\n", val); |
|---|
| 1661 | + dev_err(dev, |
|---|
| 1662 | + "Wrong cirrus,btn-det-event-dbnce DT value %d\n", val); |
|---|
| 1673 | 1663 | cs42l42->btn_det_event_dbnce = |
|---|
| 1674 | 1664 | CS42L42_BTN_DET_EVENT_DBNCE_DEFAULT; |
|---|
| 1675 | 1665 | } |
|---|
| .. | .. |
|---|
| 1678 | 1668 | CS42L42_BTN_DET_EVENT_DBNCE_DEFAULT; |
|---|
| 1679 | 1669 | } |
|---|
| 1680 | 1670 | |
|---|
| 1681 | | - ret = of_property_read_u32_array(np, "cirrus,bias-lvls", |
|---|
| 1682 | | - (u32 *)thresholds, CS42L42_NUM_BIASES); |
|---|
| 1683 | | - |
|---|
| 1671 | + ret = device_property_read_u32_array(dev, "cirrus,bias-lvls", |
|---|
| 1672 | + thresholds, ARRAY_SIZE(thresholds)); |
|---|
| 1684 | 1673 | if (!ret) { |
|---|
| 1685 | 1674 | for (i = 0; i < CS42L42_NUM_BIASES; i++) { |
|---|
| 1686 | | - if ((thresholds[i] >= CS42L42_HS_DET_LEVEL_MIN) && |
|---|
| 1687 | | - (thresholds[i] <= CS42L42_HS_DET_LEVEL_MAX)) |
|---|
| 1675 | + if (thresholds[i] <= CS42L42_HS_DET_LEVEL_MAX) |
|---|
| 1688 | 1676 | cs42l42->bias_thresholds[i] = thresholds[i]; |
|---|
| 1689 | 1677 | else { |
|---|
| 1690 | | - dev_err(&i2c_client->dev, |
|---|
| 1691 | | - "Wrong cirrus,bias-lvls[%d] DT value %d\n", i, |
|---|
| 1678 | + dev_err(dev, |
|---|
| 1679 | + "Wrong cirrus,bias-lvls[%d] DT value %d\n", i, |
|---|
| 1692 | 1680 | thresholds[i]); |
|---|
| 1693 | | - cs42l42->bias_thresholds[i] = |
|---|
| 1694 | | - threshold_defaults[i]; |
|---|
| 1681 | + cs42l42->bias_thresholds[i] = threshold_defaults[i]; |
|---|
| 1695 | 1682 | } |
|---|
| 1696 | 1683 | } |
|---|
| 1697 | 1684 | } else { |
|---|
| .. | .. |
|---|
| 1699 | 1686 | cs42l42->bias_thresholds[i] = threshold_defaults[i]; |
|---|
| 1700 | 1687 | } |
|---|
| 1701 | 1688 | |
|---|
| 1702 | | - ret = of_property_read_u32(np, "cirrus,hs-bias-ramp-rate", &val); |
|---|
| 1703 | | - |
|---|
| 1689 | + ret = device_property_read_u32(dev, "cirrus,hs-bias-ramp-rate", &val); |
|---|
| 1704 | 1690 | if (!ret) { |
|---|
| 1705 | 1691 | switch (val) { |
|---|
| 1706 | 1692 | case CS42L42_HSBIAS_RAMP_FAST_RISE_SLOW_FALL: |
|---|
| .. | .. |
|---|
| 1720 | 1706 | cs42l42->hs_bias_ramp_time = CS42L42_HSBIAS_RAMP_TIME3; |
|---|
| 1721 | 1707 | break; |
|---|
| 1722 | 1708 | default: |
|---|
| 1723 | | - dev_err(&i2c_client->dev, |
|---|
| 1709 | + dev_err(dev, |
|---|
| 1724 | 1710 | "Wrong cirrus,hs-bias-ramp-rate DT value %d\n", |
|---|
| 1725 | 1711 | val); |
|---|
| 1726 | 1712 | cs42l42->hs_bias_ramp_rate = CS42L42_HSBIAS_RAMP_SLOW; |
|---|
| .. | .. |
|---|
| 1784 | 1770 | /* Reset the Device */ |
|---|
| 1785 | 1771 | cs42l42->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, |
|---|
| 1786 | 1772 | "reset", GPIOD_OUT_LOW); |
|---|
| 1787 | | - if (IS_ERR(cs42l42->reset_gpio)) |
|---|
| 1788 | | - return PTR_ERR(cs42l42->reset_gpio); |
|---|
| 1773 | + if (IS_ERR(cs42l42->reset_gpio)) { |
|---|
| 1774 | + ret = PTR_ERR(cs42l42->reset_gpio); |
|---|
| 1775 | + goto err_disable; |
|---|
| 1776 | + } |
|---|
| 1789 | 1777 | |
|---|
| 1790 | 1778 | if (cs42l42->reset_gpio) { |
|---|
| 1791 | 1779 | dev_dbg(&i2c_client->dev, "Found reset GPIO\n"); |
|---|
| .. | .. |
|---|
| 1820 | 1808 | dev_err(&i2c_client->dev, |
|---|
| 1821 | 1809 | "CS42L42 Device ID (%X). Expected %X\n", |
|---|
| 1822 | 1810 | devid, CS42L42_CHIP_ID); |
|---|
| 1823 | | - return ret; |
|---|
| 1811 | + goto err_disable; |
|---|
| 1824 | 1812 | } |
|---|
| 1825 | 1813 | |
|---|
| 1826 | 1814 | ret = regmap_read(cs42l42->regmap, CS42L42_REVID, ®); |
|---|
| 1827 | 1815 | if (ret < 0) { |
|---|
| 1828 | 1816 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); |
|---|
| 1829 | | - return ret; |
|---|
| 1817 | + goto err_disable; |
|---|
| 1830 | 1818 | } |
|---|
| 1831 | 1819 | |
|---|
| 1832 | 1820 | dev_info(&i2c_client->dev, |
|---|
| .. | .. |
|---|
| 1849 | 1837 | (1 << CS42L42_ADC_PDN_SHIFT) | |
|---|
| 1850 | 1838 | (0 << CS42L42_PDN_ALL_SHIFT)); |
|---|
| 1851 | 1839 | |
|---|
| 1852 | | - if (i2c_client->dev.of_node) { |
|---|
| 1853 | | - ret = cs42l42_handle_device_data(i2c_client, cs42l42); |
|---|
| 1854 | | - if (ret != 0) |
|---|
| 1855 | | - return ret; |
|---|
| 1856 | | - } |
|---|
| 1840 | + ret = cs42l42_handle_device_data(&i2c_client->dev, cs42l42); |
|---|
| 1841 | + if (ret != 0) |
|---|
| 1842 | + goto err_disable; |
|---|
| 1857 | 1843 | |
|---|
| 1858 | 1844 | /* Setup headset detection */ |
|---|
| 1859 | 1845 | cs42l42_setup_hs_type_detect(cs42l42); |
|---|