.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * rt5645.c -- RT5645 ALSA SoC audio codec driver |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright 2013 Realtek Semiconductor Corp. |
---|
5 | 6 | * Author: Bard Liao <bardliao@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 | |
---|
12 | 9 | #include <linux/module.h> |
---|
.. | .. |
---|
401 | 398 | unsigned short val; |
---|
402 | 399 | }; |
---|
403 | 400 | |
---|
| 401 | +struct rt5645_eq_param_s_be16 { |
---|
| 402 | + __be16 reg; |
---|
| 403 | + __be16 val; |
---|
| 404 | +}; |
---|
| 405 | + |
---|
404 | 406 | static const char *const rt5645_supply_names[] = { |
---|
405 | 407 | "avdd", |
---|
406 | 408 | "cpvdd", |
---|
.. | .. |
---|
672 | 674 | { |
---|
673 | 675 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
674 | 676 | struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); |
---|
675 | | - struct rt5645_eq_param_s *eq_param = |
---|
676 | | - (struct rt5645_eq_param_s *)ucontrol->value.bytes.data; |
---|
| 677 | + struct rt5645_eq_param_s_be16 *eq_param = |
---|
| 678 | + (struct rt5645_eq_param_s_be16 *)ucontrol->value.bytes.data; |
---|
677 | 679 | int i; |
---|
678 | 680 | |
---|
679 | 681 | for (i = 0; i < RT5645_HWEQ_NUM; i++) { |
---|
.. | .. |
---|
698 | 700 | { |
---|
699 | 701 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
---|
700 | 702 | struct rt5645_priv *rt5645 = snd_soc_component_get_drvdata(component); |
---|
701 | | - struct rt5645_eq_param_s *eq_param = |
---|
702 | | - (struct rt5645_eq_param_s *)ucontrol->value.bytes.data; |
---|
| 703 | + struct rt5645_eq_param_s_be16 *eq_param = |
---|
| 704 | + (struct rt5645_eq_param_s_be16 *)ucontrol->value.bytes.data; |
---|
703 | 705 | int i; |
---|
704 | 706 | |
---|
705 | 707 | for (i = 0; i < RT5645_HWEQ_NUM; i++) { |
---|
706 | | - eq_param[i].reg = be16_to_cpu(eq_param[i].reg); |
---|
707 | | - eq_param[i].val = be16_to_cpu(eq_param[i].val); |
---|
| 708 | + rt5645->eq_param[i].reg = be16_to_cpu(eq_param[i].reg); |
---|
| 709 | + rt5645->eq_param[i].val = be16_to_cpu(eq_param[i].val); |
---|
708 | 710 | } |
---|
709 | 711 | |
---|
710 | 712 | /* The final setting of the table should be RT5645_EQ_CTRL2 */ |
---|
711 | 713 | for (i = RT5645_HWEQ_NUM - 1; i >= 0; i--) { |
---|
712 | | - if (eq_param[i].reg == 0) |
---|
| 714 | + if (rt5645->eq_param[i].reg == 0) |
---|
713 | 715 | continue; |
---|
714 | | - else if (eq_param[i].reg != RT5645_EQ_CTRL2) |
---|
| 716 | + else if (rt5645->eq_param[i].reg != RT5645_EQ_CTRL2) |
---|
715 | 717 | return 0; |
---|
716 | 718 | else |
---|
717 | 719 | break; |
---|
718 | 720 | } |
---|
719 | 721 | |
---|
720 | 722 | for (i = 0; i < RT5645_HWEQ_NUM; i++) { |
---|
721 | | - if (!rt5645_validate_hweq(eq_param[i].reg) && |
---|
722 | | - eq_param[i].reg != 0) |
---|
| 723 | + if (!rt5645_validate_hweq(rt5645->eq_param[i].reg) && |
---|
| 724 | + rt5645->eq_param[i].reg != 0) |
---|
723 | 725 | return 0; |
---|
724 | | - else if (eq_param[i].reg == 0) |
---|
| 726 | + else if (rt5645->eq_param[i].reg == 0) |
---|
725 | 727 | break; |
---|
726 | 728 | } |
---|
727 | | - |
---|
728 | | - memcpy(rt5645->eq_param, eq_param, |
---|
729 | | - RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s)); |
---|
730 | 729 | |
---|
731 | 730 | return 0; |
---|
732 | 731 | } |
---|
.. | .. |
---|
867 | 866 | struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm); |
---|
868 | 867 | unsigned int val; |
---|
869 | 868 | |
---|
870 | | - val = snd_soc_component_read32(component, RT5645_GLB_CLK); |
---|
| 869 | + val = snd_soc_component_read(component, RT5645_GLB_CLK); |
---|
871 | 870 | val &= RT5645_SCLK_SRC_MASK; |
---|
872 | 871 | if (val == RT5645_SCLK_SRC_PLL1) |
---|
873 | 872 | return 1; |
---|
.. | .. |
---|
910 | 909 | return 0; |
---|
911 | 910 | } |
---|
912 | 911 | |
---|
913 | | - val = (snd_soc_component_read32(component, reg) >> shift) & 0xf; |
---|
| 912 | + val = (snd_soc_component_read(component, reg) >> shift) & 0xf; |
---|
914 | 913 | switch (val) { |
---|
915 | 914 | case 1: |
---|
916 | 915 | case 2: |
---|
.. | .. |
---|
1288 | 1287 | static const struct snd_kcontrol_new rt5645_dac_r2_mux = |
---|
1289 | 1288 | SOC_DAPM_ENUM("DAC2 R source", rt5645_dac2r_enum); |
---|
1290 | 1289 | |
---|
1291 | | - |
---|
1292 | | -/* INL/R source */ |
---|
1293 | | -static const char * const rt5645_inl_src[] = { |
---|
1294 | | - "IN2P", "MonoP" |
---|
1295 | | -}; |
---|
1296 | | - |
---|
1297 | | -static SOC_ENUM_SINGLE_DECL( |
---|
1298 | | - rt5645_inl_enum, RT5645_INL1_INR1_VOL, |
---|
1299 | | - RT5645_INL_SEL_SFT, rt5645_inl_src); |
---|
1300 | | - |
---|
1301 | | -static const struct snd_kcontrol_new rt5645_inl_mux = |
---|
1302 | | - SOC_DAPM_ENUM("INL source", rt5645_inl_enum); |
---|
1303 | | - |
---|
1304 | | -static const char * const rt5645_inr_src[] = { |
---|
1305 | | - "IN2N", "MonoN" |
---|
1306 | | -}; |
---|
1307 | | - |
---|
1308 | | -static SOC_ENUM_SINGLE_DECL( |
---|
1309 | | - rt5645_inr_enum, RT5645_INL1_INR1_VOL, |
---|
1310 | | - RT5645_INR_SEL_SFT, rt5645_inr_src); |
---|
1311 | | - |
---|
1312 | | -static const struct snd_kcontrol_new rt5645_inr_mux = |
---|
1313 | | - SOC_DAPM_ENUM("INR source", rt5645_inr_enum); |
---|
1314 | | - |
---|
1315 | 1290 | /* Stereo1 ADC source */ |
---|
1316 | 1291 | /* MX-27 [12] */ |
---|
1317 | 1292 | static const char * const rt5645_stereo_adc1_src[] = { |
---|
.. | .. |
---|
1610 | 1585 | |
---|
1611 | 1586 | static const struct snd_kcontrol_new rt5645_if2_adc_in_mux = |
---|
1612 | 1587 | SOC_DAPM_ENUM("IF2 ADC IN source", rt5645_if2_adc_in_enum); |
---|
1613 | | - |
---|
1614 | | -/* MX-2F [1:0] */ |
---|
1615 | | -static const char * const rt5645_if3_adc_in_src[] = { |
---|
1616 | | - "IF_ADC1", "IF_ADC2", "VAD_ADC" |
---|
1617 | | -}; |
---|
1618 | | - |
---|
1619 | | -static SOC_ENUM_SINGLE_DECL( |
---|
1620 | | - rt5645_if3_adc_in_enum, RT5645_DIG_INF1_DATA, |
---|
1621 | | - RT5645_IF3_ADC_IN_SFT, rt5645_if3_adc_in_src); |
---|
1622 | | - |
---|
1623 | | -static const struct snd_kcontrol_new rt5645_if3_adc_in_mux = |
---|
1624 | | - SOC_DAPM_ENUM("IF3 ADC IN source", rt5645_if3_adc_in_enum); |
---|
1625 | 1588 | |
---|
1626 | 1589 | /* MX-31 [15] [13] [11] [9] */ |
---|
1627 | 1590 | static const char * const rt5645_pdm_src[] = { |
---|
.. | .. |
---|
3158 | 3121 | RT5645_INT_IRQ_ST, 0x8, 0x8); |
---|
3159 | 3122 | snd_soc_component_update_bits(component, |
---|
3160 | 3123 | RT5650_4BTN_IL_CMD2, 0x8000, 0x8000); |
---|
3161 | | - snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1); |
---|
| 3124 | + snd_soc_component_read(component, RT5650_4BTN_IL_CMD1); |
---|
3162 | 3125 | pr_debug("%s read %x = %x\n", __func__, RT5650_4BTN_IL_CMD1, |
---|
3163 | | - snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1)); |
---|
| 3126 | + snd_soc_component_read(component, RT5650_4BTN_IL_CMD1)); |
---|
3164 | 3127 | } else { |
---|
3165 | 3128 | snd_soc_component_update_bits(component, RT5650_4BTN_IL_CMD2, 0x8000, 0x0); |
---|
3166 | 3129 | snd_soc_component_update_bits(component, RT5645_INT_IRQ_ST, 0x8, 0x0); |
---|
.. | .. |
---|
3253 | 3216 | { |
---|
3254 | 3217 | int btn_type, val; |
---|
3255 | 3218 | |
---|
3256 | | - val = snd_soc_component_read32(component, RT5650_4BTN_IL_CMD1); |
---|
| 3219 | + val = snd_soc_component_read(component, RT5650_4BTN_IL_CMD1); |
---|
3257 | 3220 | pr_debug("val=0x%x\n", val); |
---|
3258 | 3221 | btn_type = val & 0xfff0; |
---|
3259 | 3222 | snd_soc_component_write(component, RT5650_4BTN_IL_CMD1, val); |
---|
.. | .. |
---|
3308 | 3271 | report, SND_JACK_MICROPHONE); |
---|
3309 | 3272 | return; |
---|
3310 | 3273 | case 4: |
---|
3311 | | - val = snd_soc_component_read32(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020; |
---|
| 3274 | + val = snd_soc_component_read(rt5645->component, RT5645_A_JD_CTRL1) & 0x0020; |
---|
3312 | 3275 | break; |
---|
3313 | 3276 | default: /* read rt5645 jd1_1 status */ |
---|
3314 | | - val = snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000; |
---|
| 3277 | + val = snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x1000; |
---|
3315 | 3278 | break; |
---|
3316 | 3279 | |
---|
3317 | 3280 | } |
---|
.. | .. |
---|
3321 | 3284 | } else if (!val && rt5645->jack_type != 0) { |
---|
3322 | 3285 | /* for push button and jack out */ |
---|
3323 | 3286 | btn_type = 0; |
---|
3324 | | - if (snd_soc_component_read32(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) { |
---|
| 3287 | + if (snd_soc_component_read(rt5645->component, RT5645_INT_IRQ_ST) & 0x4) { |
---|
3325 | 3288 | /* button pressed */ |
---|
3326 | 3289 | report = SND_JACK_HEADSET; |
---|
3327 | 3290 | btn_type = rt5645_button_detect(rt5645->component); |
---|
.. | .. |
---|
3456 | 3419 | RT5645_HWEQ_NUM, sizeof(struct rt5645_eq_param_s), |
---|
3457 | 3420 | GFP_KERNEL); |
---|
3458 | 3421 | |
---|
| 3422 | + if (!rt5645->eq_param) |
---|
| 3423 | + return -ENOMEM; |
---|
| 3424 | + |
---|
3459 | 3425 | return 0; |
---|
3460 | 3426 | } |
---|
3461 | 3427 | |
---|
.. | .. |
---|
3562 | 3528 | static const struct regmap_config rt5645_regmap = { |
---|
3563 | 3529 | .reg_bits = 8, |
---|
3564 | 3530 | .val_bits = 16, |
---|
3565 | | - .use_single_rw = true, |
---|
| 3531 | + .use_single_read = true, |
---|
| 3532 | + .use_single_write = true, |
---|
3566 | 3533 | .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) * |
---|
3567 | 3534 | RT5645_PR_SPACING), |
---|
3568 | 3535 | .volatile_reg = rt5645_volatile_register, |
---|
.. | .. |
---|
3578 | 3545 | static const struct regmap_config rt5650_regmap = { |
---|
3579 | 3546 | .reg_bits = 8, |
---|
3580 | 3547 | .val_bits = 16, |
---|
3581 | | - .use_single_rw = true, |
---|
| 3548 | + .use_single_read = true, |
---|
| 3549 | + .use_single_write = true, |
---|
3582 | 3550 | .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) * |
---|
3583 | 3551 | RT5645_PR_SPACING), |
---|
3584 | 3552 | .volatile_reg = rt5645_volatile_register, |
---|
.. | .. |
---|
3595 | 3563 | .name="nocache", |
---|
3596 | 3564 | .reg_bits = 8, |
---|
3597 | 3565 | .val_bits = 16, |
---|
3598 | | - .use_single_rw = true, |
---|
| 3566 | + .use_single_read = true, |
---|
| 3567 | + .use_single_write = true, |
---|
3599 | 3568 | .max_register = RT5645_VENDOR_ID2 + 1, |
---|
3600 | 3569 | .cache_type = REGCACHE_NONE, |
---|
3601 | 3570 | }; |
---|
.. | .. |
---|
3674 | 3643 | static const struct rt5645_platform_data lattepanda_board_platform_data = { |
---|
3675 | 3644 | .jd_mode = 2, |
---|
3676 | 3645 | .inv_jd1_1 = true |
---|
| 3646 | +}; |
---|
| 3647 | + |
---|
| 3648 | +static const struct rt5645_platform_data kahlee_platform_data = { |
---|
| 3649 | + .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, |
---|
| 3650 | + .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, |
---|
| 3651 | + .jd_mode = 3, |
---|
3677 | 3652 | }; |
---|
3678 | 3653 | |
---|
3679 | 3654 | static const struct dmi_system_id dmi_platform_data[] = { |
---|
.. | .. |
---|
3789 | 3764 | DMI_EXACT_MATCH(DMI_BOARD_VERSION, "Default string"), |
---|
3790 | 3765 | }, |
---|
3791 | 3766 | .driver_data = (void *)&lattepanda_board_platform_data, |
---|
| 3767 | + }, |
---|
| 3768 | + { |
---|
| 3769 | + .ident = "Chrome Kahlee", |
---|
| 3770 | + .matches = { |
---|
| 3771 | + DMI_MATCH(DMI_PRODUCT_NAME, "Kahlee"), |
---|
| 3772 | + }, |
---|
| 3773 | + .driver_data = (void *)&kahlee_platform_data, |
---|
| 3774 | + }, |
---|
| 3775 | + { |
---|
| 3776 | + .ident = "Medion E1239T", |
---|
| 3777 | + .matches = { |
---|
| 3778 | + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MEDION"), |
---|
| 3779 | + DMI_MATCH(DMI_PRODUCT_NAME, "E1239T MD60568"), |
---|
| 3780 | + }, |
---|
| 3781 | + .driver_data = (void *)&intel_braswell_platform_data, |
---|
3792 | 3782 | }, |
---|
3793 | 3783 | { } |
---|
3794 | 3784 | }; |
---|
.. | .. |
---|
4105 | 4095 | if (i2c->irq) |
---|
4106 | 4096 | free_irq(i2c->irq, rt5645); |
---|
4107 | 4097 | |
---|
| 4098 | + /* |
---|
| 4099 | + * Since the rt5645_btn_check_callback() can queue jack_detect_work, |
---|
| 4100 | + * the timer need to be delted first |
---|
| 4101 | + */ |
---|
| 4102 | + del_timer_sync(&rt5645->btn_check_timer); |
---|
| 4103 | + |
---|
4108 | 4104 | cancel_delayed_work_sync(&rt5645->jack_detect_work); |
---|
4109 | 4105 | cancel_delayed_work_sync(&rt5645->rcclock_work); |
---|
4110 | | - del_timer_sync(&rt5645->btn_check_timer); |
---|
4111 | 4106 | |
---|
4112 | 4107 | regulator_bulk_disable(ARRAY_SIZE(rt5645->supplies), rt5645->supplies); |
---|
4113 | 4108 | |
---|