diff options
Diffstat (limited to 'sound/soc/codecs/rt5668.c')
| -rw-r--r-- | sound/soc/codecs/rt5668.c | 126 |
1 files changed, 39 insertions, 87 deletions
diff --git a/sound/soc/codecs/rt5668.c b/sound/soc/codecs/rt5668.c index 230a21c93b6b..5fcdb50d5184 100644 --- a/sound/soc/codecs/rt5668.c +++ b/sound/soc/codecs/rt5668.c @@ -1,12 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * rt5668.c -- RT5668B ALSA SoC audio component driver * * Copyright 2018 Realtek Semiconductor Corp. * Author: Bard Liao <bardliao@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> @@ -18,8 +15,7 @@ #include <linux/platform_device.h> #include <linux/spi/spi.h> #include <linux/acpi.h> -#include <linux/gpio.h> -#include <linux/of_gpio.h> +#include <linux/gpio/consumer.h> #include <linux/regulator/consumer.h> #include <linux/mutex.h> #include <sound/core.h> @@ -46,6 +42,7 @@ static const char *rt5668_supply_names[RT5668_NUM_SUPPLIES] = { struct rt5668_priv { struct snd_soc_component *component; struct rt5668_platform_data pdata; + struct gpio_desc *ldo1_en; struct regmap *regmap; struct snd_soc_jack *hs_jack; struct regulator_bulk_data supplies[RT5668_NUM_SUPPLIES]; @@ -802,55 +799,12 @@ static void rt5668_reset(struct regmap *regmap) regmap_write(regmap, RT5668_RESET, 0); regmap_write(regmap, RT5668_I2C_MODE, 1); } -/** - * rt5668_sel_asrc_clk_src - select ASRC clock source for a set of filters - * @component: SoC audio component device. - * @filter_mask: mask of filters. - * @clk_src: clock source - * - * The ASRC function is for asynchronous MCLK and LRCK. Also, since RT5668 can - * only support standard 32fs or 64fs i2s format, ASRC should be enabled to - * support special i2s clock format such as Intel's 100fs(100 * sampling rate). - * ASRC function will track i2s clock and generate a corresponding system clock - * for codec. This function provides an API to select the clock source for a - * set of filters specified by the mask. And the component driver will turn on - * ASRC for these filters if ASRC is selected as their clock source. - */ -int rt5668_sel_asrc_clk_src(struct snd_soc_component *component, - unsigned int filter_mask, unsigned int clk_src) -{ - - switch (clk_src) { - case RT5668_CLK_SEL_SYS: - case RT5668_CLK_SEL_I2S1_ASRC: - case RT5668_CLK_SEL_I2S2_ASRC: - break; - - default: - return -EINVAL; - } - - if (filter_mask & RT5668_DA_STEREO1_FILTER) { - snd_soc_component_update_bits(component, RT5668_PLL_TRACK_2, - RT5668_FILTER_CLK_SEL_MASK, - clk_src << RT5668_FILTER_CLK_SEL_SFT); - } - - if (filter_mask & RT5668_AD_STEREO1_FILTER) { - snd_soc_component_update_bits(component, RT5668_PLL_TRACK_3, - RT5668_FILTER_CLK_SEL_MASK, - clk_src << RT5668_FILTER_CLK_SEL_SFT); - } - - return 0; -} -EXPORT_SYMBOL_GPL(rt5668_sel_asrc_clk_src); static int rt5668_button_detect(struct snd_soc_component *component) { int btn_type, val; - val = snd_soc_component_read32(component, RT5668_4BTN_IL_CMD_1); + val = snd_soc_component_read(component, RT5668_4BTN_IL_CMD_1); btn_type = val & 0xfff0; snd_soc_component_write(component, RT5668_4BTN_IL_CMD_1, val); pr_debug("%s btn_type=%x\n", __func__, btn_type); @@ -899,8 +853,7 @@ static int rt5668_headset_detect(struct snd_soc_component *component, int jack_insert) { struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(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); unsigned int val, count; if (jack_insert) { @@ -910,11 +863,11 @@ static int rt5668_headset_detect(struct snd_soc_component *component, RT5668_TRIG_JD_MASK, RT5668_TRIG_JD_HIGH); count = 0; - val = snd_soc_component_read32(component, RT5668_CBJ_CTRL_2) + val = snd_soc_component_read(component, RT5668_CBJ_CTRL_2) & RT5668_JACK_TYPE_MASK; while (val == 0 && count < 50) { usleep_range(10000, 15000); - val = snd_soc_component_read32(component, + val = snd_soc_component_read(component, RT5668_CBJ_CTRL_2) & RT5668_JACK_TYPE_MASK; count++; } @@ -958,7 +911,7 @@ static void rt5668_jd_check_handler(struct work_struct *work) struct rt5668_priv *rt5668 = container_of(work, struct rt5668_priv, jd_check_work.work); - if (snd_soc_component_read32(rt5668->component, RT5668_AJD1_CTRL) + if (snd_soc_component_read(rt5668->component, RT5668_AJD1_CTRL) & RT5668_JDH_RS_MASK) { /* jack out */ rt5668->jack_type = rt5668_headset_detect(rt5668->component, 0); @@ -1025,15 +978,17 @@ static void rt5668_jack_detect_handler(struct work_struct *work) container_of(work, struct rt5668_priv, jack_detect_work.work); int val, btn_type; - while (!rt5668->component) - usleep_range(10000, 15000); - - while (!rt5668->component->card->instantiated) - usleep_range(10000, 15000); + if (!rt5668->component || + !snd_soc_card_is_instantiated(rt5668->component->card)) { + /* card not yet ready, try later */ + mod_delayed_work(system_power_efficient_wq, + &rt5668->jack_detect_work, msecs_to_jiffies(15)); + return; + } mutex_lock(&rt5668->calibrate_mutex); - val = snd_soc_component_read32(rt5668->component, RT5668_AJD1_CTRL) + val = snd_soc_component_read(rt5668->component, RT5668_AJD1_CTRL) & RT5668_JDH_RS_MASK; if (!val) { /* jack in */ @@ -1174,7 +1129,7 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component); - int idx = -EINVAL; + int idx; static const int div[] = {2, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128}; idx = rt5668_div_sel(rt5668, 1500000, div, ARRAY_SIZE(div)); @@ -1191,10 +1146,10 @@ static int set_filter_clk(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); struct rt5668_priv *rt5668 = snd_soc_component_get_drvdata(component); - int ref, val, reg, idx = -EINVAL; + int ref, val, reg, idx; static const int div[] = {1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48}; - val = snd_soc_component_read32(component, RT5668_GPIO_CTRL_1) & + val = snd_soc_component_read(component, RT5668_GPIO_CTRL_1) & RT5668_GP4_PIN_MASK; if (w->shift == RT5668_PWR_ADC_S1F_BIT && val == RT5668_GP4_PIN_ADCDAT2) @@ -1222,7 +1177,7 @@ static int is_sys_clk_from_pll1(struct snd_soc_dapm_widget *w, struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - val = snd_soc_component_read32(component, RT5668_GLB_CLK); + val = snd_soc_component_read(component, RT5668_GLB_CLK); val &= RT5668_SCLK_SRC_MASK; if (val == RT5668_SCLK_SRC_PLL1) return 1; @@ -1250,7 +1205,7 @@ static int is_using_asrc(struct snd_soc_dapm_widget *w, return 0; } - val = (snd_soc_component_read32(component, reg) >> shift) & 0xf; + val = (snd_soc_component_read(component, reg) >> shift) & 0xf; switch (val) { case RT5668_CLK_SEL_I2S1_ASRC: case RT5668_CLK_SEL_I2S2_ASRC: @@ -2011,10 +1966,10 @@ static int rt5668_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) unsigned int reg_val = 0, tdm_ctrl = 0; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: + case SND_SOC_DAIFMT_CBP_CFP: rt5668->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: rt5668->master[dai->id] = 0; break; default: @@ -2174,7 +2129,7 @@ static int rt5668_set_component_pll(struct snd_soc_component *component, 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; } @@ -2185,8 +2140,8 @@ static int rt5668_set_component_pll(struct snd_soc_component *component, snd_soc_component_write(component, RT5668_PLL_CTRL_1, pll_code.n_code << RT5668_PLL_N_SFT | pll_code.k_code); snd_soc_component_write(component, RT5668_PLL_CTRL_2, - (pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SFT | - pll_code.m_bp << RT5668_PLL_M_BP_SFT); + ((pll_code.m_bp ? 0 : pll_code.m_code) << RT5668_PLL_M_SFT) | + (pll_code.m_bp << RT5668_PLL_M_BP_SFT)); rt5668->pll_in = freq_in; rt5668->pll_out = freq_out; @@ -2363,7 +2318,6 @@ static const struct snd_soc_component_driver soc_component_dev_rt5668 = { .set_jack = rt5668_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; static const struct regmap_config rt5668_regmap = { @@ -2372,7 +2326,7 @@ static const struct regmap_config rt5668_regmap = { .max_register = RT5668_I2C_MODE, .volatile_reg = rt5668_volatile_register, .readable_reg = rt5668_readable_register, - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, .reg_defaults = rt5668_reg, .num_reg_defaults = ARRAY_SIZE(rt5668_reg), .use_single_read = true, @@ -2380,7 +2334,7 @@ static const struct regmap_config rt5668_regmap = { }; static const struct i2c_device_id rt5668_i2c_id[] = { - {"rt5668b", 0}, + {"rt5668b"}, {} }; MODULE_DEVICE_TABLE(i2c, rt5668_i2c_id); @@ -2395,9 +2349,6 @@ static int rt5668_parse_dt(struct rt5668_priv *rt5668, struct device *dev) of_property_read_u32(dev->of_node, "realtek,jd-src", &rt5668->pdata.jd_src); - rt5668->pdata.ldo1_en = of_get_named_gpio(dev->of_node, - "realtek,ldo1-en-gpios", 0); - return 0; } @@ -2454,8 +2405,7 @@ static void rt5668_calibrate(struct rt5668_priv *rt5668) } -static int rt5668_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) +static int rt5668_i2c_probe(struct i2c_client *i2c) { struct rt5668_platform_data *pdata = dev_get_platdata(&i2c->dev); struct rt5668_priv *rt5668; @@ -2500,10 +2450,12 @@ static int rt5668_i2c_probe(struct i2c_client *i2c, return ret; } - if (gpio_is_valid(rt5668->pdata.ldo1_en)) { - if (devm_gpio_request_one(&i2c->dev, rt5668->pdata.ldo1_en, - GPIOF_OUT_INIT_HIGH, "rt5668")) - dev_err(&i2c->dev, "Fail gpio_request gpio_ldo\n"); + rt5668->ldo1_en = devm_gpiod_get_optional(&i2c->dev, + "realtek,ldo1-en", + GPIOD_OUT_HIGH); + if (IS_ERR(rt5668->ldo1_en)) { + dev_err(&i2c->dev, "Fail gpio request ldo1_en\n"); + return PTR_ERR(rt5668->ldo1_en); } /* Sleep for 300 ms miniumum */ @@ -2584,7 +2536,7 @@ static int rt5668_i2c_probe(struct i2c_client *i2c, rt5668_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "rt5668", rt5668); if (ret) - dev_err(&i2c->dev, "Failed to reguest IRQ: %d\n", ret); + dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret); } @@ -2602,15 +2554,15 @@ static void rt5668_i2c_shutdown(struct i2c_client *client) #ifdef CONFIG_OF static const struct of_device_id rt5668_of_match[] = { {.compatible = "realtek,rt5668b"}, - {}, + { } }; MODULE_DEVICE_TABLE(of, rt5668_of_match); #endif #ifdef CONFIG_ACPI static const struct acpi_device_id rt5668_acpi_match[] = { - {"10EC5668", 0,}, - {}, + { "10EC5668" }, + { } }; MODULE_DEVICE_TABLE(acpi, rt5668_acpi_match); #endif |
