diff options
Diffstat (limited to 'sound/soc/codecs/rt5663.c')
| -rw-r--r-- | sound/soc/codecs/rt5663.c | 110 |
1 files changed, 61 insertions, 49 deletions
diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c index da6647015708..e4d8785e64c1 100644 --- a/sound/soc/codecs/rt5663.c +++ b/sound/soc/codecs/rt5663.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * rt5663.c -- RT5663 ALSA SoC audio codec driver * * Copyright 2016 Realtek Semiconductor Corp. * Author: Jack Yu <jack.yu@realtek.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ #include <linux/module.h> #include <linux/moduleparam.h> @@ -77,6 +74,7 @@ struct rt5663_priv { int pll_out; int jack_type; + unsigned int irq; }; static const struct reg_sequence rt5663_patch_list[] = { @@ -1465,7 +1463,7 @@ static void rt5663_enable_push_button_irq(struct snd_soc_component *component, static int rt5663_v2_jack_detect(struct snd_soc_component *component, int jack_insert) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); int val, i = 0, sleep_time[5] = {300, 150, 100, 50, 30}; @@ -1485,7 +1483,7 @@ static int rt5663_v2_jack_detect(struct snd_soc_component *component, int jack_i while (i < 5) { msleep(sleep_time[i]); - val = snd_soc_component_read32(component, RT5663_CBJ_TYPE_2) & 0x0003; + val = snd_soc_component_read(component, RT5663_CBJ_TYPE_2) & 0x0003; if (val == 0x1 || val == 0x2 || val == 0x3) break; dev_dbg(component->dev, "%s: MX-0011 val=%x sleep %d\n", @@ -1598,7 +1596,7 @@ static int rt5663_jack_detect(struct snd_soc_component *component, int jack_inse i++; } - val = snd_soc_component_read32(component, RT5663_EM_JACK_TYPE_2) & 0x0003; + val = snd_soc_component_read(component, RT5663_EM_JACK_TYPE_2) & 0x0003; dev_dbg(component->dev, "%s val = %d\n", __func__, val); snd_soc_component_update_bits(component, RT5663_HP_CHARGE_PUMP_1, @@ -1701,12 +1699,12 @@ static int rt5663_impedance_sensing(struct snd_soc_component *component) rt5663->imp_table[i].dc_offset_r_manual & 0xffff); } - reg84 = snd_soc_component_read32(component, RT5663_ASRC_2); - reg26 = snd_soc_component_read32(component, RT5663_STO1_ADC_MIXER); - reg2fa = snd_soc_component_read32(component, RT5663_DUMMY_1); - reg91 = snd_soc_component_read32(component, RT5663_HP_CHARGE_PUMP_1); - reg10 = snd_soc_component_read32(component, RT5663_RECMIX); - reg80 = snd_soc_component_read32(component, RT5663_GLB_CLK); + reg84 = snd_soc_component_read(component, RT5663_ASRC_2); + reg26 = snd_soc_component_read(component, RT5663_STO1_ADC_MIXER); + reg2fa = snd_soc_component_read(component, RT5663_DUMMY_1); + reg91 = snd_soc_component_read(component, RT5663_HP_CHARGE_PUMP_1); + reg10 = snd_soc_component_read(component, RT5663_RECMIX); + reg80 = snd_soc_component_read(component, RT5663_GLB_CLK); snd_soc_component_update_bits(component, RT5663_STO_DRE_1, 0x8000, 0); snd_soc_component_write(component, RT5663_ASRC_2, 0); @@ -1771,11 +1769,11 @@ static int rt5663_impedance_sensing(struct snd_soc_component *component) for (i = 0; i < 100; i++) { msleep(20); - if (snd_soc_component_read32(component, RT5663_INT_ST_1) & 0x2) + if (snd_soc_component_read(component, RT5663_INT_ST_1) & 0x2) break; } - value = snd_soc_component_read32(component, RT5663_HP_IMP_SEN_4); + value = snd_soc_component_read(component, RT5663_HP_IMP_SEN_4); snd_soc_component_update_bits(component, RT5663_DEPOP_1, 0x3000, 0); snd_soc_component_write(component, RT5663_INT_ST_1, 0); @@ -1846,7 +1844,7 @@ static int rt5663_button_detect(struct snd_soc_component *component) { int btn_type, val; - val = snd_soc_component_read32(component, RT5663_IL_CMD_5); + val = snd_soc_component_read(component, RT5663_IL_CMD_5); dev_dbg(component->dev, "%s: val=0x%x\n", __func__, val); btn_type = val & 0xfff0; snd_soc_component_write(component, RT5663_IL_CMD_5, val); @@ -1861,7 +1859,7 @@ static irqreturn_t rt5663_irq(int irq, void *data) dev_dbg(regmap_get_device(rt5663->regmap), "%s IRQ queue work\n", __func__); - queue_delayed_work(system_wq, &rt5663->jack_detect_work, + queue_delayed_work(system_dfl_wq, &rt5663->jack_detect_work, msecs_to_jiffies(250)); return IRQ_HANDLED; @@ -1882,7 +1880,7 @@ static int rt5663_set_jack_detect(struct snd_soc_component *component, static bool rt5663_check_jd_status(struct snd_soc_component *component) { struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); - int val = snd_soc_component_read32(component, RT5663_INT_ST_1); + int val = snd_soc_component_read(component, RT5663_INT_ST_1); dev_dbg(component->dev, "%s val=%x\n", __func__, val); @@ -1976,7 +1974,7 @@ static void rt5663_jack_detect_work(struct work_struct *work) cancel_delayed_work_sync( &rt5663->jd_unplug_work); } else { - queue_delayed_work(system_wq, + queue_delayed_work(system_dfl_wq, &rt5663->jd_unplug_work, msecs_to_jiffies(500)); } @@ -2026,7 +2024,7 @@ static void rt5663_jd_unplug_work(struct work_struct *work) SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3); } else { - queue_delayed_work(system_wq, &rt5663->jd_unplug_work, + queue_delayed_work(system_dfl_wq, &rt5663->jd_unplug_work, msecs_to_jiffies(500)); } } @@ -2075,7 +2073,7 @@ static int rt5663_is_sys_clk_from_pll(struct snd_soc_dapm_widget *w, unsigned int val; struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - val = snd_soc_component_read32(component, RT5663_GLB_CLK); + val = snd_soc_component_read(component, RT5663_GLB_CLK); val &= RT5663_SCLK_SRC_MASK; if (val == RT5663_SCLK_SRC_PLL1) return 1; @@ -2118,7 +2116,7 @@ static int rt5663_is_using_asrc(struct snd_soc_dapm_widget *w, } } - val = (snd_soc_component_read32(component, reg) >> shift) & 0x7; + val = (snd_soc_component_read(component, reg) >> shift) & 0x7; if (val) return 1; @@ -2133,15 +2131,15 @@ static int rt5663_i2s_use_asrc(struct snd_soc_dapm_widget *source, struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); int da_asrc_en, ad_asrc_en; - da_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) & + da_asrc_en = (snd_soc_component_read(component, RT5663_ASRC_2) & RT5663_DA_STO1_TRACK_MASK) ? 1 : 0; switch (rt5663->codec_ver) { case CODEC_VER_1: - ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_3) & + ad_asrc_en = (snd_soc_component_read(component, RT5663_ASRC_3) & RT5663_V2_AD_STO1_TRACK_MASK) ? 1 : 0; break; case CODEC_VER_0: - ad_asrc_en = (snd_soc_component_read32(component, RT5663_ASRC_2) & + ad_asrc_en = (snd_soc_component_read(component, RT5663_ASRC_2) & RT5663_AD_STO1_TRACK_MASK) ? 1 : 0; break; default: @@ -2816,9 +2814,9 @@ static int rt5663_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: reg_val |= RT5663_I2S_MS_S; break; default: @@ -2944,7 +2942,7 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, ret = rl6231_pll_calc(freq_in, freq_out, &pll_code); if (ret < 0) { - dev_err(component->dev, "Unsupport input clock %d\n", freq_in); + dev_err(component->dev, "Unsupported input clock %d\n", freq_in); return ret; } @@ -2955,8 +2953,8 @@ static int rt5663_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, snd_soc_component_write(component, RT5663_PLL_1, pll_code.n_code << RT5663_PLL_N_SHIFT | pll_code.k_code); snd_soc_component_write(component, RT5663_PLL_2, - (pll_code.m_bp ? 0 : pll_code.m_code) << RT5663_PLL_M_SHIFT | - pll_code.m_bp << RT5663_PLL_M_BP_SHIFT); + ((pll_code.m_bp ? 0 : pll_code.m_code) << RT5663_PLL_M_SHIFT) | + (pll_code.m_bp << RT5663_PLL_M_BP_SHIFT)); rt5663->pll_in = freq_in; rt5663->pll_out = freq_out; @@ -3142,7 +3140,7 @@ static int rt5663_set_bias_level(struct snd_soc_component *component, static int rt5663_probe(struct snd_soc_component *component) { - struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); rt5663->component = component; @@ -3189,6 +3187,12 @@ static int rt5663_suspend(struct snd_soc_component *component) { struct rt5663_priv *rt5663 = snd_soc_component_get_drvdata(component); + if (rt5663->irq) + disable_irq(rt5663->irq); + + cancel_delayed_work_sync(&rt5663->jack_detect_work); + cancel_delayed_work_sync(&rt5663->jd_unplug_work); + regcache_cache_only(rt5663->regmap, true); regcache_mark_dirty(rt5663->regmap); @@ -3204,6 +3208,9 @@ static int rt5663_resume(struct snd_soc_component *component) rt5663_irq(0, rt5663); + if (rt5663->irq) + enable_irq(rt5663->irq); + return 0; } #else @@ -3261,7 +3268,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5663 = { .set_jack = rt5663_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5663_v2_regmap = { @@ -3272,7 +3278,7 @@ static const struct regmap_config rt5663_v2_regmap = { .max_register = 0x07fa, .volatile_reg = rt5663_v2_volatile_register, .readable_reg = rt5663_v2_readable_register, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .reg_defaults = rt5663_v2_reg, .num_reg_defaults = ARRAY_SIZE(rt5663_v2_reg), }; @@ -3285,7 +3291,7 @@ static const struct regmap_config rt5663_regmap = { .max_register = 0x03f3, .volatile_reg = rt5663_volatile_register, .readable_reg = rt5663_readable_register, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .reg_defaults = rt5663_reg, .num_reg_defaults = ARRAY_SIZE(rt5663_reg), }; @@ -3301,7 +3307,7 @@ static const struct regmap_config temp_regmap = { }; static const struct i2c_device_id rt5663_i2c_id[] = { - { "rt5663", 0 }, + { "rt5663" }, {} }; MODULE_DEVICE_TABLE(i2c, rt5663_i2c_id); @@ -3309,15 +3315,15 @@ MODULE_DEVICE_TABLE(i2c, rt5663_i2c_id); #if defined(CONFIG_OF) static const struct of_device_id rt5663_of_match[] = { { .compatible = "realtek,rt5663", }, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5663_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5663_acpi_match[] = { - { "10EC5663", 0}, - {}, + { "10EC5663" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5663_acpi_match); #endif @@ -3464,6 +3470,7 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) { int table_size; + int ret; device_property_read_u32(dev, "realtek,dc_offset_l_manual", &rt5663->pdata.dc_offset_l_manual); @@ -3480,16 +3487,19 @@ static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) table_size = sizeof(struct impedance_mapping_table) * rt5663->pdata.impedance_sensing_num; rt5663->imp_table = devm_kzalloc(dev, table_size, GFP_KERNEL); - device_property_read_u32_array(dev, + if (!rt5663->imp_table) + return -ENOMEM; + ret = device_property_read_u32_array(dev, "realtek,impedance_sensing_table", (u32 *)rt5663->imp_table, table_size); + if (ret) + return ret; } return 0; } -static int rt5663_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5663_i2c_probe(struct i2c_client *i2c) { struct rt5663_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5663_priv *rt5663; @@ -3507,8 +3517,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, if (pdata) rt5663->pdata = *pdata; - else - rt5663_parse_dp(rt5663, &i2c->dev); + else { + ret = rt5663_parse_dp(rt5663, &i2c->dev); + if (ret) + return ret; + } for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) rt5663->supplies[i].supply = rt5663_supply_names[i]; @@ -3647,7 +3660,7 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5663->regmap, RT5663_PWR_ANLG_1, RT5663_LDO1_DVO_MASK | RT5663_AMP_HP_MASK, RT5663_LDO1_DVO_0_9V | RT5663_AMP_HP_3X); - break; + break; case CODEC_VER_0: regmap_update_bits(rt5663->regmap, RT5663_DIG_MISC, RT5663_DIG_GATE_CTRL_MASK, RT5663_DIG_GATE_CTRL_EN); @@ -3666,7 +3679,7 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, regmap_update_bits(rt5663->regmap, RT5663_TDM_2, RT5663_DATA_SWAP_ADCDAT1_MASK, RT5663_DATA_SWAP_ADCDAT1_LL); - break; + break; default: dev_err(&i2c->dev, "%s:Unknown codec type\n", __func__); } @@ -3679,10 +3692,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rt5663", rt5663); if (ret) { - dev_err(&i2c->dev, "%s Failed to reguest IRQ: %d\n", + dev_err(&i2c->dev, "%s Failed to request IRQ: %d\n", __func__, ret); goto err_enable; } + rt5663->irq = i2c->irq; } ret = devm_snd_soc_register_component(&i2c->dev, @@ -3707,7 +3721,7 @@ err_enable: return ret; } -static int rt5663_i2c_remove(struct i2c_client *i2c) +static void rt5663_i2c_remove(struct i2c_client *i2c) { struct rt5663_priv *rt5663 = i2c_get_clientdata(i2c); @@ -3715,8 +3729,6 @@ static int rt5663_i2c_remove(struct i2c_client *i2c) free_irq(i2c->irq, rt5663); regulator_bulk_disable(ARRAY_SIZE(rt5663->supplies), rt5663->supplies); - - return 0; } static void rt5663_i2c_shutdown(struct i2c_client *client) |
