diff options
Diffstat (limited to 'sound/soc/codecs/rt5682.c')
| -rw-r--r-- | sound/soc/codecs/rt5682.c | 140 |
1 files changed, 86 insertions, 54 deletions
diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 415ec564c82e..d39f8e4f3474 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -15,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/mutex.h> #include <sound/core.h> #include <sound/pcm.h> @@ -35,6 +34,8 @@ const char *rt5682_supply_names[RT5682_NUM_SUPPLIES] = { "AVDD", "MICVDD", "VBAT", + "DBVDD", + "LDO1-IN", }; EXPORT_SYMBOL_GPL(rt5682_supply_names); @@ -394,6 +395,7 @@ bool rt5682_volatile_register(struct device *dev, unsigned int reg) case RT5682_4BTN_IL_CMD_1: case RT5682_AJD1_CTRL: case RT5682_HP_CALIB_CTRL_1: + case RT5682_INT_DEVICE_ID: case RT5682_DEVICE_ID: case RT5682_I2C_MODE: case RT5682_HP_CALIB_CTRL_10: @@ -418,6 +420,7 @@ bool rt5682_readable_register(struct device *dev, unsigned int reg) { switch (reg) { case RT5682_RESET: + case RT5682_INT_DEVICE_ID: case RT5682_VERSION_ID: case RT5682_VENDOR_ID: case RT5682_DEVICE_ID: @@ -922,15 +925,13 @@ static void rt5682_enable_push_button_irq(struct snd_soc_component *component, * * Returns detect status. */ -int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) +static int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); - struct snd_soc_dapm_context *dapm = &component->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); unsigned int val, count; if (jack_insert) { - snd_soc_dapm_mutex_lock(dapm); - snd_soc_component_update_bits(component, RT5682_PWR_ANLG_1, RT5682_PWR_VREF2 | RT5682_PWR_MB, RT5682_PWR_VREF2 | RT5682_PWR_MB); @@ -981,8 +982,6 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) snd_soc_component_update_bits(component, RT5682_MICBIAS_2, RT5682_PWR_CLK25M_MASK | RT5682_PWR_CLK1M_MASK, RT5682_PWR_CLK25M_PU | RT5682_PWR_CLK1M_PU); - - snd_soc_dapm_mutex_unlock(dapm); } else { rt5682_enable_push_button_irq(component, false); snd_soc_component_update_bits(component, RT5682_CBJ_CTRL_1, @@ -1011,7 +1010,6 @@ int rt5682_headset_detect(struct snd_soc_component *component, int jack_insert) dev_dbg(component->dev, "jack_type = %d\n", rt5682->jack_type); return rt5682->jack_type; } -EXPORT_SYMBOL_GPL(rt5682_headset_detect); static int rt5682_set_jack_detect(struct snd_soc_component *component, struct snd_soc_jack *hs_jack, void *data) @@ -1020,6 +1018,9 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component, rt5682->hs_jack = hs_jack; + if (rt5682->is_sdw && !rt5682->first_hw_init) + return 0; + if (!hs_jack) { regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2, RT5682_JD1_EN_MASK, RT5682_JD1_DIS); @@ -1094,15 +1095,29 @@ void rt5682_jack_detect_handler(struct work_struct *work) { struct rt5682_priv *rt5682 = container_of(work, struct rt5682_priv, jack_detect_work.work); + struct snd_soc_dapm_context *dapm; int val, btn_type; - while (!rt5682->component) - usleep_range(10000, 15000); + if (!rt5682->component || + !snd_soc_card_is_instantiated(rt5682->component->card)) { + /* card not yet ready, try later */ + mod_delayed_work(system_power_efficient_wq, + &rt5682->jack_detect_work, msecs_to_jiffies(15)); + return; + } + + if (rt5682->is_sdw) { + if (pm_runtime_status_suspended(rt5682->slave->dev.parent)) { + dev_dbg(&rt5682->slave->dev, + "%s: parent device is pm_runtime_status_suspended, skipping jack detection\n", + __func__); + return; + } + } - while (!rt5682->component->card->instantiated) - usleep_range(10000, 15000); + dapm = snd_soc_component_to_dapm(rt5682->component); - mutex_lock(&rt5682->jdet_mutex); + snd_soc_dapm_mutex_lock(dapm); mutex_lock(&rt5682->calibrate_mutex); val = snd_soc_component_read(rt5682->component, RT5682_AJD1_CTRL) @@ -1162,6 +1177,9 @@ void rt5682_jack_detect_handler(struct work_struct *work) rt5682->irq_work_delay_time = 50; } + mutex_unlock(&rt5682->calibrate_mutex); + snd_soc_dapm_mutex_unlock(dapm); + snd_soc_jack_report(rt5682->hs_jack, rt5682->jack_type, SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | @@ -1174,9 +1192,6 @@ void rt5682_jack_detect_handler(struct work_struct *work) else cancel_delayed_work_sync(&rt5682->jd_check_work); } - - mutex_unlock(&rt5682->calibrate_mutex); - mutex_unlock(&rt5682->jdet_mutex); } EXPORT_SYMBOL_GPL(rt5682_jack_detect_handler); @@ -1526,7 +1541,6 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w, { struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); - struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); switch (event) { case SND_SOC_DAPM_PRE_PMU: @@ -1538,17 +1552,12 @@ static int rt5682_hp_event(struct snd_soc_dapm_widget *w, RT5682_DEPOP_1, 0x60, 0x60); snd_soc_component_update_bits(component, RT5682_DAC_ADC_DIG_VOL1, 0x00c0, 0x0080); - - mutex_lock(&rt5682->jdet_mutex); - snd_soc_component_update_bits(component, RT5682_HP_CTRL_2, RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN, RT5682_HP_C2_DAC_L_EN | RT5682_HP_C2_DAC_R_EN); usleep_range(5000, 10000); snd_soc_component_update_bits(component, RT5682_CHARGE_PUMP_1, RT5682_CP_SW_SIZE_MASK, RT5682_CP_SW_SIZE_L); - - mutex_unlock(&rt5682->jdet_mutex); break; case SND_SOC_DAPM_POST_PMD: @@ -2216,10 +2225,10 @@ static int rt5682_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: rt5682->master[dai->id] = 1; break; - case SND_SOC_DAIFMT_CBS_CFS: + case SND_SOC_DAIFMT_CBC_CFC: rt5682->master[dai->id] = 0; break; default: @@ -2586,7 +2595,7 @@ static int rt5682_wclk_prepare(struct clk_hw *hw) return -EINVAL; component = rt5682->component; - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); @@ -2624,7 +2633,7 @@ static void rt5682_wclk_unprepare(struct clk_hw *hw) return; component = rt5682->component; - dapm = snd_soc_component_get_dapm(component); + dapm = snd_soc_component_to_dapm(component); snd_soc_dapm_mutex_lock(dapm); @@ -2666,8 +2675,8 @@ static unsigned long rt5682_wclk_recalc_rate(struct clk_hw *hw, return rt5682->lrck[RT5682_AIF1]; } -static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int rt5682_wclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct rt5682_priv *rt5682 = container_of(hw, struct rt5682_priv, @@ -2680,13 +2689,13 @@ static long rt5682_wclk_round_rate(struct clk_hw *hw, unsigned long rate, * Only accept to set wclk rate to 44.1k or 48kHz. * It will force to 48kHz if not both. */ - if (rate != CLK_48 && rate != CLK_44) { + if (req->rate != CLK_48 && req->rate != CLK_44) { dev_warn(rt5682->i2c_dev, "%s: clk %s only support %d or %d Hz output\n", __func__, clk_name, CLK_44, CLK_48); - rate = CLK_48; + req->rate = CLK_48; } - return rate; + return 0; } static int rt5682_wclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -2786,15 +2795,15 @@ static unsigned long rt5682_bclk_get_factor(unsigned long rate, return 256; } -static long rt5682_bclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int rt5682_bclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct rt5682_priv *rt5682 = container_of(hw, struct rt5682_priv, dai_clks_hw[RT5682_DAI_BCLK_IDX]); unsigned long factor; - if (!*parent_rate || !rt5682_clk_check(rt5682)) + if (!req->best_parent_rate || !rt5682_clk_check(rt5682)) return -EINVAL; /* @@ -2804,9 +2813,11 @@ static long rt5682_bclk_round_rate(struct clk_hw *hw, unsigned long rate, * and find the appropriate multiplier of BCLK to * get the rounded down BCLK value. */ - factor = rt5682_bclk_get_factor(rate, *parent_rate); + factor = rt5682_bclk_get_factor(req->rate, req->best_parent_rate); + + req->rate = req->best_parent_rate * factor; - return *parent_rate * factor; + return 0; } static int rt5682_bclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -2828,14 +2839,11 @@ static int rt5682_bclk_set_rate(struct clk_hw *hw, unsigned long rate, for_each_component_dais(component, dai) if (dai->id == RT5682_AIF1) - break; - if (!dai) { - dev_err(rt5682->i2c_dev, "dai %d not found in component\n", - RT5682_AIF1); - return -ENODEV; - } + return rt5682_set_bclk1_ratio(dai, factor); - return rt5682_set_bclk1_ratio(dai, factor); + dev_err(rt5682->i2c_dev, "dai %d not found in component\n", + RT5682_AIF1); + return -ENODEV; } static const struct clk_ops rt5682_dai_clk_ops[RT5682_DAI_NUM_CLKS] = { @@ -2843,12 +2851,12 @@ static const struct clk_ops rt5682_dai_clk_ops[RT5682_DAI_NUM_CLKS] = { .prepare = rt5682_wclk_prepare, .unprepare = rt5682_wclk_unprepare, .recalc_rate = rt5682_wclk_recalc_rate, - .round_rate = rt5682_wclk_round_rate, + .determine_rate = rt5682_wclk_determine_rate, .set_rate = rt5682_wclk_set_rate, }, [RT5682_DAI_BCLK_IDX] = { .recalc_rate = rt5682_bclk_recalc_rate, - .round_rate = rt5682_bclk_round_rate, + .determine_rate = rt5682_bclk_determine_rate, .set_rate = rt5682_bclk_set_rate, }, }; @@ -2899,8 +2907,10 @@ int rt5682_register_dai_clks(struct rt5682_priv *rt5682) } if (dev->of_node) { - devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, dai_clk_hw); + if (ret) + return ret; } else { ret = devm_clk_hw_register_clkdev(dev, dai_clk_hw, init.name, @@ -2918,9 +2928,9 @@ EXPORT_SYMBOL_GPL(rt5682_register_dai_clks); static int rt5682_probe(struct snd_soc_component *component) { struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component); struct sdw_slave *slave; unsigned long time; - struct snd_soc_dapm_context *dapm = &component->dapm; rt5682->component = component; @@ -2957,6 +2967,9 @@ static int rt5682_suspend(struct snd_soc_component *component) if (rt5682->is_sdw) return 0; + if (rt5682->irq) + disable_irq(rt5682->irq); + cancel_delayed_work_sync(&rt5682->jack_detect_work); cancel_delayed_work_sync(&rt5682->jd_check_work); if (rt5682->hs_jack && (rt5682->jack_type & SND_JACK_HEADSET) == SND_JACK_HEADSET) { @@ -3025,6 +3038,9 @@ static int rt5682_resume(struct snd_soc_component *component) mod_delayed_work(system_power_efficient_wq, &rt5682->jack_detect_work, msecs_to_jiffies(0)); + if (rt5682->irq) + enable_irq(rt5682->irq); + return 0; } #else @@ -3064,7 +3080,6 @@ const struct snd_soc_component_driver rt5682_soc_component_dev = { .set_jack = rt5682_set_jack_detect, .use_pmdown_time = 1, .endianness = 1, - .non_legacy_dai_naming = 1, }; EXPORT_SYMBOL_GPL(rt5682_soc_component_dev); @@ -3084,9 +3099,6 @@ int rt5682_parse_dt(struct rt5682_priv *rt5682, struct device *dev) device_property_read_u32(dev, "realtek,dmic-delay-ms", &rt5682->pdata.dmic_delay); - rt5682->pdata.ldo1_en = of_get_named_gpio(dev->of_node, - "realtek,ldo1-en-gpios", 0); - if (device_property_read_string_array(dev, "clock-output-names", rt5682->pdata.dai_clk_names, RT5682_DAI_NUM_CLKS) < 0) @@ -3101,6 +3113,20 @@ int rt5682_parse_dt(struct rt5682_priv *rt5682, struct device *dev) } EXPORT_SYMBOL_GPL(rt5682_parse_dt); +int rt5682_get_ldo1(struct rt5682_priv *rt5682, struct device *dev) +{ + rt5682->ldo1_en = devm_gpiod_get_optional(dev, + "realtek,ldo1-en", + GPIOD_OUT_HIGH); + if (IS_ERR(rt5682->ldo1_en)) { + dev_err(dev, "Fail gpio request ldo1_en\n"); + return PTR_ERR(rt5682->ldo1_en); + } + + return 0; +} +EXPORT_SYMBOL_GPL(rt5682_get_ldo1); + void rt5682_calibrate(struct rt5682_priv *rt5682) { int value, count; @@ -3117,7 +3143,10 @@ void rt5682_calibrate(struct rt5682_priv *rt5682) regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x0100); regmap_write(rt5682->regmap, RT5682_HP_IMP_SENS_CTRL_19, 0x3800); regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x3000); - regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x7005); + if (rt5682->ve_ic) + regmap_write(rt5682->regmap, RT5682_CHOP_ADC, 0x7005); + else + regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x7005); regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0x686c); regmap_write(rt5682->regmap, RT5682_CAL_REC, 0x0d0d); regmap_write(rt5682->regmap, RT5682_HP_CALIB_CTRL_2, 0x0321); @@ -3146,7 +3175,10 @@ void rt5682_calibrate(struct rt5682_priv *rt5682) regmap_write(rt5682->regmap, RT5682_GLB_CLK, 0x0000); regmap_write(rt5682->regmap, RT5682_PWR_DIG_1, 0x0000); regmap_write(rt5682->regmap, RT5682_CHOP_DAC, 0x2000); - regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005); + if (rt5682->ve_ic) + regmap_write(rt5682->regmap, RT5682_CHOP_ADC, 0x2005); + else + regmap_write(rt5682->regmap, RT5682_CALIB_ADC_CTRL, 0x2005); regmap_write(rt5682->regmap, RT5682_STO1_ADC_MIXER, 0xc0c4); regmap_write(rt5682->regmap, RT5682_CAL_REC, 0x0c0c); |
