.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * rt5663.c -- RT5663 ALSA SoC audio codec driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2016 Realtek Semiconductor Corp. |
---|
5 | 6 | * Author: Jack Yu <jack.yu@realtek.com> |
---|
6 | | - * |
---|
7 | | - * This program is free software; you can redistribute it and/or modify |
---|
8 | | - * it under the terms of the GNU General Public License version 2 as |
---|
9 | | - * published by the Free Software Foundation. |
---|
10 | 7 | */ |
---|
11 | 8 | #include <linux/module.h> |
---|
12 | 9 | #include <linux/moduleparam.h> |
---|
.. | .. |
---|
17 | 14 | #include <linux/platform_device.h> |
---|
18 | 15 | #include <linux/spi/spi.h> |
---|
19 | 16 | #include <linux/acpi.h> |
---|
| 17 | +#include <linux/regulator/consumer.h> |
---|
20 | 18 | #include <linux/workqueue.h> |
---|
21 | 19 | #include <sound/core.h> |
---|
22 | 20 | #include <sound/pcm.h> |
---|
.. | .. |
---|
33 | 31 | #define RT5663_DEVICE_ID_2 0x6451 |
---|
34 | 32 | #define RT5663_DEVICE_ID_1 0x6406 |
---|
35 | 33 | |
---|
| 34 | +#define RT5663_POWER_ON_DELAY_MS 300 |
---|
| 35 | +#define RT5663_SUPPLY_CURRENT_UA 500000 |
---|
| 36 | + |
---|
36 | 37 | enum { |
---|
37 | 38 | CODEC_VER_1, |
---|
38 | 39 | CODEC_VER_0, |
---|
.. | .. |
---|
48 | 49 | unsigned int dc_offset_r_manual_mic; |
---|
49 | 50 | }; |
---|
50 | 51 | |
---|
| 52 | +static const char *const rt5663_supply_names[] = { |
---|
| 53 | + "avdd", |
---|
| 54 | + "cpvdd", |
---|
| 55 | +}; |
---|
| 56 | + |
---|
51 | 57 | struct rt5663_priv { |
---|
52 | 58 | struct snd_soc_component *component; |
---|
53 | 59 | struct rt5663_platform_data pdata; |
---|
.. | .. |
---|
56 | 62 | struct snd_soc_jack *hs_jack; |
---|
57 | 63 | struct timer_list btn_check_timer; |
---|
58 | 64 | struct impedance_mapping_table *imp_table; |
---|
| 65 | + struct regulator_bulk_data supplies[ARRAY_SIZE(rt5663_supply_names)]; |
---|
59 | 66 | |
---|
60 | 67 | int codec_ver; |
---|
61 | 68 | int sysclk; |
---|
.. | .. |
---|
72 | 79 | static const struct reg_sequence rt5663_patch_list[] = { |
---|
73 | 80 | { 0x002a, 0x8020 }, |
---|
74 | 81 | { 0x0086, 0x0028 }, |
---|
| 82 | + { 0x0100, 0xa020 }, |
---|
75 | 83 | { 0x0117, 0x0f28 }, |
---|
76 | 84 | { 0x02fb, 0x8089 }, |
---|
77 | 85 | }; |
---|
.. | .. |
---|
580 | 588 | { 0x00fd, 0x0001 }, |
---|
581 | 589 | { 0x00fe, 0x10ec }, |
---|
582 | 590 | { 0x00ff, 0x6406 }, |
---|
583 | | - { 0x0100, 0xa0a0 }, |
---|
| 591 | + { 0x0100, 0xa020 }, |
---|
584 | 592 | { 0x0108, 0x4444 }, |
---|
585 | 593 | { 0x0109, 0x4444 }, |
---|
586 | 594 | { 0x010a, 0xaaaa }, |
---|
.. | .. |
---|
1474 | 1482 | |
---|
1475 | 1483 | while (i < 5) { |
---|
1476 | 1484 | msleep(sleep_time[i]); |
---|
1477 | | - val = snd_soc_component_read32(component, RT5663_CBJ_TYPE_2) & 0x0003; |
---|
| 1485 | + val = snd_soc_component_read(component, RT5663_CBJ_TYPE_2) & 0x0003; |
---|
1478 | 1486 | if (val == 0x1 || val == 0x2 || val == 0x3) |
---|
1479 | 1487 | break; |
---|
1480 | 1488 | dev_dbg(component->dev, "%s: MX-0011 val=%x sleep %d\n", |
---|
.. | .. |
---|
1587 | 1595 | i++; |
---|
1588 | 1596 | } |
---|
1589 | 1597 | |
---|
1590 | | - val = snd_soc_component_read32(component, RT5663_EM_JACK_TYPE_2) & 0x0003; |
---|
| 1598 | + val = snd_soc_component_read(component, RT5663_EM_JACK_TYPE_2) & 0x0003; |
---|
1591 | 1599 | dev_dbg(component->dev, "%s val = %d\n", __func__, val); |
---|
1592 | 1600 | |
---|
1593 | 1601 | snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1, |
---|
.. | .. |
---|
1690 | 1698 | rt5663->imp_table[i].dc_offset_r_manual & 0xffff); |
---|
1691 | 1699 | } |
---|
1692 | 1700 | |
---|
1693 | | - reg84 = snd_soc_component_read32(component, RT5663_ASRC_2); |
---|
1694 | | - reg26 = snd_soc_component_read32(component, RT5663_STO1_ADC_MIXER); |
---|
1695 | | - reg2fa = snd_soc_component_read32(component, RT5663_DUMMY_1); |
---|
1696 | | - reg91 = snd_soc_component_read32(component, RT5663_HP_CHARGE_PUMP_1); |
---|
1697 | | - reg10 = snd_soc_component_read32(component, RT5663_RECMIX); |
---|
1698 | | - reg80 = snd_soc_component_read32(component, RT5663_GLB_CLK); |
---|
| 1701 | + reg84 = snd_soc_component_read(component, RT5663_ASRC_2); |
---|
| 1702 | + reg26 = snd_soc_component_read(component, RT5663_STO1_ADC_MIXER); |
---|
| 1703 | + reg2fa = snd_soc_component_read(component, RT5663_DUMMY_1); |
---|
| 1704 | + reg91 = snd_soc_component_read(component, RT5663_HP_CHARGE_PUMP_1); |
---|
| 1705 | + reg10 = snd_soc_component_read(component, RT5663_RECMIX); |
---|
| 1706 | + reg80 = snd_soc_component_read(component, RT5663_GLB_CLK); |
---|
1699 | 1707 | |
---|
1700 | 1708 | snd_soc_component_update_bits(component, RT5663_STO_DRE_1, 0x8000, 0); |
---|
1701 | 1709 | snd_soc_component_write(component, RT5663_ASRC_2, 0); |
---|
.. | .. |
---|
1760 | 1768 | |
---|
1761 | 1769 | for (i = 0; i < 100; i++) { |
---|
1762 | 1770 | msleep(20); |
---|
1763 | | - if (snd_soc_component_read32(component, RT5663_INT_ST_1) & 0x2) |
---|
| 1771 | + if (snd_soc_component_read(component, RT5663_INT_ST_1) & 0x2) |
---|
1764 | 1772 | break; |
---|
1765 | 1773 | } |
---|
1766 | 1774 | |
---|
1767 | | - value = snd_soc_component_read32(component, RT5663_HP_IMP_SEN_4); |
---|
| 1775 | + value = snd_soc_component_read(component, RT5663_HP_IMP_SEN_4); |
---|
1768 | 1776 | |
---|
1769 | 1777 | snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0); |
---|
1770 | 1778 | snd_soc_component_write(component, RT5663_INT_ST_1, 0); |
---|
.. | .. |
---|
1835 | 1843 | { |
---|
1836 | 1844 | int btn_type, val; |
---|
1837 | 1845 | |
---|
1838 | | - val = snd_soc_component_read32(component, RT5663_IL_CMD_5); |
---|
| 1846 | + val = snd_soc_component_read(component, RT5663_IL_CMD_5); |
---|
1839 | 1847 | dev_dbg(component->dev, "%s: val=0x%x\n", __func__, val); |
---|
1840 | 1848 | btn_type = val & 0xfff0; |
---|
1841 | 1849 | snd_soc_component_write(component, RT5663_IL_CMD_5, val); |
---|
.. | .. |
---|
1871 | 1879 | static bool rt5663_check_jd_status(struct snd_soc_component *component) |
---|
1872 | 1880 | { |
---|
1873 | 1881 | struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); |
---|
1874 | | - int val = snd_soc_component_read32(component, RT5663_INT_ST_1); |
---|
| 1882 | + int val = snd_soc_component_read(component, RT5663_INT_ST_1); |
---|
1875 | 1883 | |
---|
1876 | 1884 | dev_dbg(component->dev, "%s val=%x\n", __func__, val); |
---|
1877 | 1885 | |
---|
.. | .. |
---|
2064 | 2072 | unsigned int val; |
---|
2065 | 2073 | struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); |
---|
2066 | 2074 | |
---|
2067 | | - val = snd_soc_component_read32(component, RT5663_GLB_CLK); |
---|
| 2075 | + val = snd_soc_component_read(component, RT5663_GLB_CLK); |
---|
2068 | 2076 | val &= RT5663_SCLK_SRC_MASK; |
---|
2069 | 2077 | if (val == RT5663_SCLK_SRC_PLL1) |
---|
2070 | 2078 | return 1; |
---|
.. | .. |
---|
2107 | 2115 | } |
---|
2108 | 2116 | } |
---|
2109 | 2117 | |
---|
2110 | | - val = (snd_soc_component_read32(component, reg) >> shift) & 0x7; |
---|
| 2118 | + val = (snd_soc_component_read(component, reg) >> shift) & 0x7; |
---|
2111 | 2119 | |
---|
2112 | 2120 | if (val) |
---|
2113 | 2121 | return 1; |
---|
.. | .. |
---|
2122 | 2130 | struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); |
---|
2123 | 2131 | int da_asrc_en, ad_asrc_en; |
---|
2124 | 2132 | |
---|
2125 | | - da_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) & |
---|
| 2133 | + da_asrc_en = (snd_soc_component_read(component, RT5663_ASRC_2) & |
---|
2126 | 2134 | RT5663_DA_STO1_TRACK_MASK) ? 1 : 0; |
---|
2127 | 2135 | switch (rt5663->codec_ver) { |
---|
2128 | 2136 | case CODEC_VER_1: |
---|
2129 | | - ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_3) & |
---|
| 2137 | + ad_asrc_en = (snd_soc_component_read(component, RT5663_ASRC_3) & |
---|
2130 | 2138 | RT5663_V2_AD_STO1_TRACK_MASK) ? 1 : 0; |
---|
2131 | 2139 | break; |
---|
2132 | 2140 | case CODEC_VER_0: |
---|
2133 | | - ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) & |
---|
| 2141 | + ad_asrc_en = (snd_soc_component_read(component, RT5663_ASRC_2) & |
---|
2134 | 2142 | RT5663_AD_STO1_TRACK_MASK) ? 1 : 0; |
---|
2135 | 2143 | break; |
---|
2136 | 2144 | default: |
---|
.. | .. |
---|
2337 | 2345 | 0x8000); |
---|
2338 | 2346 | snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, |
---|
2339 | 2347 | 0x3000); |
---|
| 2348 | + snd_soc_component_update_bits(component, |
---|
| 2349 | + RT5663_DIG_VOL_ZCD, 0x00c0, 0x0080); |
---|
2340 | 2350 | } |
---|
2341 | 2351 | break; |
---|
2342 | 2352 | |
---|
.. | .. |
---|
2351 | 2361 | RT5663_OVCD_HP_MASK, RT5663_OVCD_HP_EN); |
---|
2352 | 2362 | snd_soc_component_update_bits(component, |
---|
2353 | 2363 | RT5663_DACREF_LDO, 0x3e0e, 0); |
---|
| 2364 | + snd_soc_component_update_bits(component, |
---|
| 2365 | + RT5663_DIG_VOL_ZCD, 0x00c0, 0); |
---|
2354 | 2366 | } |
---|
2355 | 2367 | break; |
---|
2356 | 2368 | |
---|
.. | .. |
---|
3252 | 3264 | static const struct regmap_config rt5663_v2_regmap = { |
---|
3253 | 3265 | .reg_bits = 16, |
---|
3254 | 3266 | .val_bits = 16, |
---|
3255 | | - .use_single_rw = true, |
---|
| 3267 | + .use_single_read = true, |
---|
| 3268 | + .use_single_write = true, |
---|
3256 | 3269 | .max_register = 0x07fa, |
---|
3257 | 3270 | .volatile_reg = rt5663_v2_volatile_register, |
---|
3258 | 3271 | .readable_reg = rt5663_v2_readable_register, |
---|
.. | .. |
---|
3264 | 3277 | static const struct regmap_config rt5663_regmap = { |
---|
3265 | 3278 | .reg_bits = 16, |
---|
3266 | 3279 | .val_bits = 16, |
---|
3267 | | - .use_single_rw = true, |
---|
| 3280 | + .use_single_read = true, |
---|
| 3281 | + .use_single_write = true, |
---|
3268 | 3282 | .max_register = 0x03f3, |
---|
3269 | 3283 | .volatile_reg = rt5663_volatile_register, |
---|
3270 | 3284 | .readable_reg = rt5663_readable_register, |
---|
.. | .. |
---|
3277 | 3291 | .name = "nocache", |
---|
3278 | 3292 | .reg_bits = 16, |
---|
3279 | 3293 | .val_bits = 16, |
---|
3280 | | - .use_single_rw = true, |
---|
| 3294 | + .use_single_read = true, |
---|
| 3295 | + .use_single_write = true, |
---|
3281 | 3296 | .max_register = 0x03f3, |
---|
3282 | 3297 | .cache_type = REGCACHE_NONE, |
---|
3283 | 3298 | }; |
---|
.. | .. |
---|
3463 | 3478 | table_size = sizeof(struct impedance_mapping_table) * |
---|
3464 | 3479 | rt5663->pdata.impedance_sensing_num; |
---|
3465 | 3480 | rt5663->imp_table = devm_kzalloc(dev, table_size, GFP_KERNEL); |
---|
| 3481 | + if (!rt5663->imp_table) |
---|
| 3482 | + return -ENOMEM; |
---|
3466 | 3483 | ret = device_property_read_u32_array(dev, |
---|
3467 | 3484 | "realtek,impedance_sensing_table", |
---|
3468 | 3485 | (u32 *)rt5663->imp_table, table_size); |
---|
.. | .. |
---|
3478 | 3495 | { |
---|
3479 | 3496 | struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); |
---|
3480 | 3497 | struct rt5663_priv *rt5663; |
---|
3481 | | - int ret; |
---|
| 3498 | + int ret, i; |
---|
3482 | 3499 | unsigned int val; |
---|
3483 | 3500 | struct regmap *regmap; |
---|
3484 | 3501 | |
---|
.. | .. |
---|
3498 | 3515 | return ret; |
---|
3499 | 3516 | } |
---|
3500 | 3517 | |
---|
| 3518 | + for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) |
---|
| 3519 | + rt5663->supplies[i].supply = rt5663_supply_names[i]; |
---|
| 3520 | + |
---|
| 3521 | + ret = devm_regulator_bulk_get(&i2c->dev, |
---|
| 3522 | + ARRAY_SIZE(rt5663->supplies), |
---|
| 3523 | + rt5663->supplies); |
---|
| 3524 | + if (ret) { |
---|
| 3525 | + dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); |
---|
| 3526 | + return ret; |
---|
| 3527 | + } |
---|
| 3528 | + |
---|
| 3529 | + /* Set load for regulator. */ |
---|
| 3530 | + for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) { |
---|
| 3531 | + ret = regulator_set_load(rt5663->supplies[i].consumer, |
---|
| 3532 | + RT5663_SUPPLY_CURRENT_UA); |
---|
| 3533 | + if (ret < 0) { |
---|
| 3534 | + dev_err(&i2c->dev, |
---|
| 3535 | + "Failed to set regulator load on %s, ret: %d\n", |
---|
| 3536 | + rt5663->supplies[i].supply, ret); |
---|
| 3537 | + return ret; |
---|
| 3538 | + } |
---|
| 3539 | + } |
---|
| 3540 | + |
---|
| 3541 | + ret = regulator_bulk_enable(ARRAY_SIZE(rt5663->supplies), |
---|
| 3542 | + rt5663->supplies); |
---|
| 3543 | + |
---|
| 3544 | + if (ret) { |
---|
| 3545 | + dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); |
---|
| 3546 | + return ret; |
---|
| 3547 | + } |
---|
| 3548 | + msleep(RT5663_POWER_ON_DELAY_MS); |
---|
| 3549 | + |
---|
3501 | 3550 | regmap = devm_regmap_init_i2c(i2c, &temp_regmap); |
---|
3502 | 3551 | if (IS_ERR(regmap)) { |
---|
3503 | 3552 | ret = PTR_ERR(regmap); |
---|
3504 | 3553 | dev_err(&i2c->dev, "Failed to allocate temp register map: %d\n", |
---|
3505 | 3554 | ret); |
---|
3506 | | - return ret; |
---|
| 3555 | + goto err_enable; |
---|
3507 | 3556 | } |
---|
3508 | 3557 | |
---|
3509 | 3558 | ret = regmap_read(regmap, RT5663_VENDOR_ID_2, &val); |
---|
.. | .. |
---|
3528 | 3577 | dev_err(&i2c->dev, |
---|
3529 | 3578 | "Device with ID register %#x is not rt5663\n", |
---|
3530 | 3579 | val); |
---|
3531 | | - return -ENODEV; |
---|
| 3580 | + ret = -ENODEV; |
---|
| 3581 | + goto err_enable; |
---|
3532 | 3582 | } |
---|
3533 | 3583 | |
---|
3534 | 3584 | if (IS_ERR(rt5663->regmap)) { |
---|
3535 | 3585 | ret = PTR_ERR(rt5663->regmap); |
---|
3536 | 3586 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
---|
3537 | 3587 | ret); |
---|
3538 | | - return ret; |
---|
| 3588 | + goto err_enable; |
---|
3539 | 3589 | } |
---|
3540 | 3590 | |
---|
3541 | 3591 | /* reset and calibrate */ |
---|
.. | .. |
---|
3602 | 3652 | regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_1, |
---|
3603 | 3653 | RT5663_LDO1_DVO_MASK | RT5663_AMP_HP_MASK, |
---|
3604 | 3654 | RT5663_LDO1_DVO_0_9V | RT5663_AMP_HP_3X); |
---|
3605 | | - break; |
---|
| 3655 | + break; |
---|
3606 | 3656 | case CODEC_VER_0: |
---|
3607 | 3657 | regmap_update_bits(rt5663->regmap, RT5663_DIG_MISC, |
---|
3608 | 3658 | RT5663_DIG_GATE_CTRL_MASK, RT5663_DIG_GATE_CTRL_EN); |
---|
.. | .. |
---|
3621 | 3671 | regmap_update_bits(rt5663->regmap, RT5663_TDM_2, |
---|
3622 | 3672 | RT5663_DATA_SWAP_ADCDAT1_MASK, |
---|
3623 | 3673 | RT5663_DATA_SWAP_ADCDAT1_LL); |
---|
3624 | | - break; |
---|
| 3674 | + break; |
---|
3625 | 3675 | default: |
---|
3626 | 3676 | dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); |
---|
3627 | 3677 | } |
---|
.. | .. |
---|
3633 | 3683 | ret = request_irq(i2c->irq, rt5663_irq, |
---|
3634 | 3684 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
---|
3635 | 3685 | | IRQF_ONESHOT, "rt5663", rt5663); |
---|
3636 | | - if (ret) |
---|
| 3686 | + if (ret) { |
---|
3637 | 3687 | dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n", |
---|
3638 | 3688 | __func__, ret); |
---|
| 3689 | + goto err_enable; |
---|
| 3690 | + } |
---|
3639 | 3691 | } |
---|
3640 | 3692 | |
---|
3641 | 3693 | ret = devm_snd_soc_register_component(&i2c->dev, |
---|
3642 | 3694 | &soc_component_dev_rt5663, |
---|
3643 | 3695 | rt5663_dai, ARRAY_SIZE(rt5663_dai)); |
---|
3644 | 3696 | |
---|
3645 | | - if (ret) { |
---|
3646 | | - if (i2c->irq) |
---|
3647 | | - free_irq(i2c->irq, rt5663); |
---|
3648 | | - } |
---|
| 3697 | + if (ret) |
---|
| 3698 | + goto err_enable; |
---|
3649 | 3699 | |
---|
| 3700 | + return 0; |
---|
| 3701 | + |
---|
| 3702 | + |
---|
| 3703 | + /* |
---|
| 3704 | + * Error after enabling regulators should goto err_enable |
---|
| 3705 | + * to disable regulators. |
---|
| 3706 | + */ |
---|
| 3707 | +err_enable: |
---|
| 3708 | + if (i2c->irq) |
---|
| 3709 | + free_irq(i2c->irq, rt5663); |
---|
| 3710 | + |
---|
| 3711 | + regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies); |
---|
3650 | 3712 | return ret; |
---|
3651 | 3713 | } |
---|
3652 | 3714 | |
---|
.. | .. |
---|
3657 | 3719 | if (i2c->irq) |
---|
3658 | 3720 | free_irq(i2c->irq, rt5663); |
---|
3659 | 3721 | |
---|
| 3722 | + regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies); |
---|
| 3723 | + |
---|
3660 | 3724 | return 0; |
---|
3661 | 3725 | } |
---|
3662 | 3726 | |
---|