| .. | .. |
|---|
| 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 | |
|---|