diff options
Diffstat (limited to 'sound/soc/codecs')
81 files changed, 1517 insertions, 727 deletions
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 126f897312d4..6d7e4725d89c 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -238,6 +238,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_RT1320_SDW imply SND_SOC_RT9120 imply SND_SOC_RT9123 + imply SND_SOC_RTQ9124 imply SND_SOC_RTQ9128 imply SND_SOC_SDW_MOCKUP imply SND_SOC_SGTL5000 @@ -263,9 +264,6 @@ config SND_SOC_ALL_CODECS imply SND_SOC_TAS2764 imply SND_SOC_TAS2770 imply SND_SOC_TAS2780 - imply SND_SOC_TAS2781_COMLIB - imply SND_SOC_TAS2781_COMLIB_I2C - imply SND_SOC_TAS2781_FMWLIB imply SND_SOC_TAS2781_I2C imply SND_SOC_TAS5086 imply SND_SOC_TAS571X @@ -1858,6 +1856,14 @@ config SND_SOC_RT9123P Enable support for the HW control mode of Richtek RT9123P 3.2W mono Class-D audio amplifier. +config SND_SOC_RTQ9124 + tristate "Richtek RTQ9124 Mono Class-D Amplifier" + depends on I2C + select REGMAP + help + Enable support for Richtek RTQ9124 1x30W digital input automotive + audio amplifier with current sense and real-time load diagnostics. + config SND_SOC_RTQ9128 tristate "Richtek RTQ9128 45W Digital Input Amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 6d7aa109ede7..a68c3d192a1b 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -275,6 +275,7 @@ snd-soc-rt722-sdca-y := rt722-sdca.o rt722-sdca-sdw.o snd-soc-rt9120-y := rt9120.o snd-soc-rt9123-y := rt9123.o snd-soc-rt9123p-y := rt9123p.o +snd-soc-rtq9124-y := rtq9124.o snd-soc-rtq9128-y := rtq9128.o snd-soc-sdw-mockup-y := sdw-mockup.o snd-soc-sgtl5000-y := sgtl5000.o @@ -695,6 +696,7 @@ obj-$(CONFIG_SND_SOC_RT722_SDCA_SDW) += snd-soc-rt722-sdca.o obj-$(CONFIG_SND_SOC_RT9120) += snd-soc-rt9120.o obj-$(CONFIG_SND_SOC_RT9123) += snd-soc-rt9123.o obj-$(CONFIG_SND_SOC_RT9123P) += snd-soc-rt9123p.o +obj-$(CONFIG_SND_SOC_RTQ9124) += snd-soc-rtq9124.o obj-$(CONFIG_SND_SOC_RTQ9128) += snd-soc-rtq9128.o obj-$(CONFIG_SND_SOC_SDW_MOCKUP) += snd-soc-sdw-mockup.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o @@ -853,4 +855,4 @@ obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o # Mux -obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o
\ No newline at end of file +obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/arizona-jack.c b/sound/soc/codecs/arizona-jack.c index 9c15ddba6008..22f9c431a0e5 100644 --- a/sound/soc/codecs/arizona-jack.c +++ b/sound/soc/codecs/arizona-jack.c @@ -319,7 +319,6 @@ static void arizona_stop_mic(struct arizona_priv *info) if (change) { regulator_disable(info->micvdd); - pm_runtime_mark_last_busy(arizona->dev); pm_runtime_put_autosuspend(arizona->dev); } } @@ -1127,7 +1126,6 @@ out: mutex_unlock(&info->lock); - pm_runtime_mark_last_busy(arizona->dev); pm_runtime_put_autosuspend(arizona->dev); return IRQ_HANDLED; diff --git a/sound/soc/codecs/aw88395/aw88395_device.h b/sound/soc/codecs/aw88395/aw88395_device.h index 0f750f654f3e..6f8b30b475da 100644 --- a/sound/soc/codecs/aw88395/aw88395_device.h +++ b/sound/soc/codecs/aw88395/aw88395_device.h @@ -102,6 +102,11 @@ struct aw_profctrl_desc { unsigned int cur_mode; }; +enum { + CALI_RESULT_NORMAL, + CALI_RESULT_ERROR, +}; + struct aw_volume_desc { unsigned int init_volume; unsigned int mute_volume; @@ -124,9 +129,25 @@ struct aw_cali_delay_desc { unsigned int delay; }; +#define AW_CALI_CFG_NUM (4) +struct cali_cfg { + uint32_t data[AW_CALI_CFG_NUM]; +}; + +struct aw_cali_backup_desc { + unsigned int dsp_ng_cfg; + unsigned int dsp_lp_cfg; +}; + struct aw_cali_desc { u32 cali_re; u32 ra; + bool cali_switch; + bool cali_running; + uint16_t cali_result; + uint16_t store_vol; + struct cali_cfg cali_cfg; + struct aw_cali_backup_desc backup_info; }; struct aw_container { diff --git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c index 4b90133e5ab4..bad3ad6b8c0e 100644 --- a/sound/soc/codecs/aw88399.c +++ b/sound/soc/codecs/aw88399.c @@ -13,6 +13,7 @@ #include <linux/firmware.h> #include <linux/minmax.h> #include <linux/regmap.h> +#include <linux/sort.h> #include <sound/soc.h> #include "aw88399.h" #include "aw88395/aw88395_device.h" @@ -45,6 +46,67 @@ static int aw_dev_dsp_write_16bit(struct aw_device *aw_dev, return 0; } +static int aw_dev_dsp_write_32bit(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data) +{ + unsigned int temp_data; + int ret; + + ret = regmap_write(aw_dev->regmap, AW88399_DSPMADD_REG, dsp_addr); + if (ret) { + dev_err(aw_dev->dev, "%s write addr error, ret=%d", __func__, ret); + return ret; + } + + temp_data = dsp_data & AW88395_DSP_16_DATA_MASK; + ret = regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, temp_data); + if (ret) { + dev_err(aw_dev->dev, "%s write datal error, ret=%d", __func__, ret); + return ret; + } + + temp_data = dsp_data >> 16; + ret = regmap_write(aw_dev->regmap, AW88399_DSPMDAT_REG, temp_data); + if (ret) + dev_err(aw_dev->dev, "%s write datah error, ret=%d", __func__, ret); + + return ret; +} + +static int aw_dev_dsp_write(struct aw_device *aw_dev, + unsigned short dsp_addr, unsigned int dsp_data, unsigned char data_type) +{ + unsigned int reg_value; + int ret; + + mutex_lock(&aw_dev->dsp_lock); + switch (data_type) { + case AW88395_DSP_16_DATA: + ret = aw_dev_dsp_write_16bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "write dsp_addr[0x%x] 16-bit dsp_data[0x%x] failed", + dsp_addr, dsp_data); + break; + case AW88395_DSP_32_DATA: + ret = aw_dev_dsp_write_32bit(aw_dev, dsp_addr, dsp_data); + if (ret) + dev_err(aw_dev->dev, "write dsp_addr[0x%x] 32-bit dsp_data[0x%x] failed", + dsp_addr, dsp_data); + break; + default: + dev_err(aw_dev->dev, "data type[%d] unsupported", data_type); + ret = -EINVAL; + break; + } + + /* clear dsp chip select state */ + if (regmap_read(aw_dev->regmap, 0x00, ®_value)) + dev_err(aw_dev->dev, "%s fail to clear chip state. Err=%d\n", __func__, ret); + mutex_unlock(&aw_dev->dsp_lock); + + return ret; +} + static int aw_dev_dsp_read_16bit(struct aw_device *aw_dev, unsigned short dsp_addr, unsigned int *dsp_data) { @@ -452,14 +514,14 @@ static int aw_dev_set_vcalb(struct aw88399 *aw88399) case AW88399_DEV_VDSEL_VSENSE: ret = aw88399_dev_get_vcalk(aw88399, &vcalk); vcal_k = vcalk * AW88399_VCABLK_FACTOR + AW88399_CABL_BASE_VALUE; - vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_FACTOR / AW88399_ISCAL_FACTOR / + vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_FACTOR / AW88399_ISCAL_FACTOR * ical_k / vcal_k * aw88399->vcalb_init_val; break; case AW88399_DEV_VDSEL_DAC: ret = aw88399_dev_get_internal_vcalk(aw88399, &vcalk); vcal_k = vcalk * AW88399_VCABLK_DAC_FACTOR + AW88399_CABL_BASE_VALUE; vcalb = AW88399_VCALB_ACCURACY * AW88399_VSCAL_DAC_FACTOR / - AW88399_ISCAL_DAC_FACTOR / ical_k / + AW88399_ISCAL_DAC_FACTOR * ical_k / vcal_k * aw88399->vcalb_init_val; break; default: @@ -1356,6 +1418,329 @@ static struct snd_soc_dai_driver aw88399_dai[] = { }, }; +static void aw_cali_svc_run_mute(struct aw_device *aw_dev, uint16_t cali_result) +{ + if (cali_result == CALI_RESULT_ERROR) + aw88399_dev_mute(aw_dev, true); + else if (cali_result == CALI_RESULT_NORMAL) + aw88399_dev_mute(aw_dev, false); +} + +static int aw_cali_svc_get_cali_cfg(struct aw_device *aw_dev) +{ + struct cali_cfg *cali_cfg = &aw_dev->cali_desc.cali_cfg; + int ret; + + ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH, + &cali_cfg->data[0], AW88399_DSP_32_DATA); + if (ret) + return ret; + + ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH, + &cali_cfg->data[1], AW88399_DSP_32_DATA); + if (ret) + return ret; + + ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_ADPZ_USTEPN, + &cali_cfg->data[2], AW88399_DSP_16_DATA); + if (ret) + return ret; + + ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CFG_RE_ALPHA, + &cali_cfg->data[3], AW88399_DSP_16_DATA); + + return ret; +} + +static int aw_cali_svc_set_cali_cfg(struct aw_device *aw_dev, + struct cali_cfg cali_cfg) +{ + int ret; + + ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH, + cali_cfg.data[0], AW88399_DSP_32_DATA); + if (ret) + return ret; + + ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH, + cali_cfg.data[1], AW88399_DSP_32_DATA); + if (ret) + return ret; + + ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_ADPZ_USTEPN, + cali_cfg.data[2], AW88399_DSP_16_DATA); + if (ret) + return ret; + + ret = aw_dev_dsp_write(aw_dev, AW88399_DSP_REG_CFG_RE_ALPHA, + cali_cfg.data[3], AW88399_DSP_16_DATA); + + return ret; +} + +static int aw_cali_svc_cali_en(struct aw_device *aw_dev, bool cali_en) +{ + struct cali_cfg set_cfg; + int ret; + + aw_dev_dsp_enable(aw_dev, false); + if (cali_en) { + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW883XX_DSP_NG_EN_MASK, AW883XX_DSP_NG_EN_DISABLE_VALUE); + aw_dev_dsp_write(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, + AW88399_DSP_LOW_POWER_SWITCH_DISABLE, AW88399_DSP_16_DATA); + + ret = aw_cali_svc_get_cali_cfg(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "get cali cfg failed\n"); + aw_dev_dsp_enable(aw_dev, true); + return ret; + } + set_cfg.data[0] = 0; + set_cfg.data[1] = 0; + set_cfg.data[2] = -1; + set_cfg.data[3] = 1; + + ret = aw_cali_svc_set_cali_cfg(aw_dev, set_cfg); + if (ret) { + dev_err(aw_dev->dev, "set cali cfg failed\n"); + aw_cali_svc_set_cali_cfg(aw_dev, aw_dev->cali_desc.cali_cfg); + aw_dev_dsp_enable(aw_dev, true); + return ret; + } + } else { + aw_cali_svc_set_cali_cfg(aw_dev, aw_dev->cali_desc.cali_cfg); + } + + aw_dev_dsp_enable(aw_dev, true); + + return 0; +} + +static int aw_cali_svc_cali_run_dsp_vol(struct aw_device *aw_dev, bool enable) +{ + unsigned int reg_val; + int ret; + + if (enable) { + ret = regmap_read(aw_dev->regmap, AW88399_DSPCFG_REG, ®_val); + if (ret) { + dev_err(aw_dev->dev, "read reg 0x%x failed\n", AW88399_DSPCFG_REG); + return ret; + } + + aw_dev->cali_desc.store_vol = reg_val & (~AW88399_DSP_VOL_MASK); + ret = regmap_update_bits(aw_dev->regmap, AW88399_DSPCFG_REG, + ~AW88399_DSP_VOL_MASK, AW88399_DSP_VOL_MUTE); + } else { + ret = regmap_update_bits(aw_dev->regmap, AW88399_DSPCFG_REG, + ~AW88399_DSP_VOL_MASK, aw_dev->cali_desc.store_vol); + } + + return ret; +} + +static void aw_cali_svc_backup_info(struct aw_device *aw_dev) +{ + struct aw_cali_backup_desc *backup_desc = &aw_dev->cali_desc.backup_info; + unsigned int reg_val, dsp_val; + + regmap_read(aw_dev->regmap, AW88399_DBGCTRL_REG, ®_val); + backup_desc->dsp_ng_cfg = reg_val & (~AW883XX_DSP_NG_EN_MASK); + + aw_dev_dsp_read(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, + &dsp_val, AW88399_DSP_16_DATA); + + backup_desc->dsp_lp_cfg = dsp_val; +} + +static void aw_cali_svc_recover_info(struct aw_device *aw_dev) +{ + struct aw_cali_backup_desc *backup_desc = &aw_dev->cali_desc.backup_info; + + regmap_update_bits(aw_dev->regmap, AW88399_DBGCTRL_REG, + ~AW883XX_DSP_NG_EN_MASK, backup_desc->dsp_ng_cfg); + + aw_dev_dsp_write(aw_dev, AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR, + backup_desc->dsp_lp_cfg, AW88399_DSP_16_DATA); +} + +static int aw_cali_svc_cali_re_mode_enable(struct aw_device *aw_dev, bool is_enable) +{ + int ret; + + if (is_enable) { + ret = aw_dev_check_syspll(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "pll check failed cannot start\n"); + return ret; + } + + ret = aw_dev_get_dsp_status(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "dsp status error\n"); + return ret; + } + + aw_cali_svc_backup_info(aw_dev); + ret = aw_cali_svc_cali_en(aw_dev, true); + if (ret) { + dev_err(aw_dev->dev, "aw_cali_svc_cali_en failed\n"); + return ret; + } + + ret = aw_cali_svc_cali_run_dsp_vol(aw_dev, true); + if (ret) { + aw_cali_svc_cali_en(aw_dev, false); + return ret; + } + + } else { + aw_cali_svc_cali_run_dsp_vol(aw_dev, false); + aw_cali_svc_recover_info(aw_dev); + aw_cali_svc_cali_en(aw_dev, false); + } + + return 0; +} + +static int aw_cali_svc_get_dev_re(struct aw_device *aw_dev, uint32_t *re) +{ + uint32_t dsp_re, show_re; + int ret; + + ret = aw_dev_dsp_read(aw_dev, AW88399_DSP_REG_CALRE, &dsp_re, AW88399_DSP_16_DATA); + if (ret) + return ret; + + show_re = AW88399_DSP_RE_TO_SHOW_RE(dsp_re, AW88399_DSP_REG_CALRE_SHIFT); + + *re = (uint32_t)(show_re - aw_dev->cali_desc.ra); + + return 0; +} + +static void aw_cali_svc_del_max_min_ave_algo(uint32_t *data, int data_size, uint32_t *dsp_re) +{ + int sum = 0, i; + + for (i = 1; i < data_size - 1; i++) + sum += data[i]; + + *dsp_re = sum / (data_size - AW_CALI_DATA_SUM_RM); +} + +static int aw_cali_svc_get_iv_st(struct aw_device *aw_dev) +{ + unsigned int reg_data; + int ret, i; + + for (i = 0; i < AW_GET_IV_CNT_MAX; i++) { + ret = regmap_read(aw_dev->regmap, AW88399_ASR1_REG, ®_data); + if (ret) { + dev_err(aw_dev->dev, "read 0x%x failed\n", AW88399_ASR1_REG); + return ret; + } + + reg_data &= (~AW88399_REABS_MASK); + if (!reg_data) + return 0; + msleep(30); + } + + dev_err(aw_dev->dev, "IV data abnormal, please check\n"); + + return -EINVAL; +} + +static int compare_ints(const void *a, const void *b) +{ + return *(int *)a - *(int *)b; +} + +static int aw_cali_svc_get_smooth_cali_re(struct aw_device *aw_dev) +{ + uint32_t re_temp[AW_CALI_READ_CNT_MAX]; + uint32_t dsp_re; + int ret, i; + + for (i = 0; i < AW_CALI_READ_CNT_MAX; i++) { + ret = aw_cali_svc_get_dev_re(aw_dev, &re_temp[i]); + if (ret) + goto cali_re_fail; + msleep(30); + } + + sort(re_temp, AW_CALI_READ_CNT_MAX, sizeof(uint32_t), compare_ints, NULL); + + aw_cali_svc_del_max_min_ave_algo(re_temp, AW_CALI_READ_CNT_MAX, &dsp_re); + + ret = aw_cali_svc_get_iv_st(aw_dev); + if (ret) { + dev_err(aw_dev->dev, "get iv data failed"); + goto cali_re_fail; + } + + if (dsp_re < AW88399_CALI_RE_MIN || dsp_re > AW88399_CALI_RE_MAX) { + dev_err(aw_dev->dev, "out range re value: [%d]mohm\n", dsp_re); + aw_dev->cali_desc.cali_re = dsp_re; + aw_dev->cali_desc.cali_result = CALI_RESULT_ERROR; + aw_cali_svc_run_mute(aw_dev, aw_dev->cali_desc.cali_result); + + return 0; + } + + aw_dev->cali_desc.cali_result = CALI_RESULT_NORMAL; + + aw_dev->cali_desc.cali_re = dsp_re; + dev_dbg(aw_dev->dev, "re[%d]mohm\n", aw_dev->cali_desc.cali_re); + + aw_dev_dsp_enable(aw_dev, false); + aw_dev_update_cali_re(&aw_dev->cali_desc); + aw_dev_dsp_enable(aw_dev, true); + + return 0; + +cali_re_fail: + aw_dev->cali_desc.cali_result = CALI_RESULT_ERROR; + aw_cali_svc_run_mute(aw_dev, aw_dev->cali_desc.cali_result); + return -EINVAL; +} + +static int aw_cali_svc_dev_cali_re(struct aw88399 *aw88399) +{ + struct aw_device *aw_dev = aw88399->aw_pa; + struct aw_cali_desc *cali_desc = &aw_dev->cali_desc; + int ret; + + if (cali_desc->cali_running) { + dev_err(aw_dev->dev, "calibration in progress\n"); + return -EINVAL; + } + + cali_desc->cali_running = true; + aw_cali_svc_run_mute(aw_dev, CALI_RESULT_NORMAL); + + ret = aw_cali_svc_cali_re_mode_enable(aw_dev, true); + if (ret) { + dev_err(aw_dev->dev, "start cali re failed\n"); + goto re_mode_err; + } + + msleep(1000); + + ret = aw_cali_svc_get_smooth_cali_re(aw_dev); + if (ret) + dev_err(aw_dev->dev, "get cali re failed\n"); + + aw_cali_svc_cali_re_mode_enable(aw_dev, false); + +re_mode_err: + cali_desc->cali_running = false; + + return ret; +} + static int aw88399_get_fade_in_time(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1616,6 +2001,53 @@ static int aw88399_re_set(struct snd_kcontrol *kcontrol, return 0; } +static int aw88399_calib_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec); + struct aw_device *aw_dev = aw88399->aw_pa; + + ucontrol->value.integer.value[0] = aw_dev->cali_desc.cali_switch; + + return 0; +} + +static int aw88399_calib_switch_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec); + struct aw_device *aw_dev = aw88399->aw_pa; + + if (aw_dev->cali_desc.cali_switch == ucontrol->value.integer.value[0]) + return 0; + + aw_dev->cali_desc.cali_switch = ucontrol->value.integer.value[0]; + + return 1; +} + +static int aw88399_calib_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* do nothing */ + return 0; +} + +static int aw88399_calib_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); + struct aw88399 *aw88399 = snd_soc_component_get_drvdata(codec); + struct aw_device *aw_dev = aw88399->aw_pa; + + if (aw_dev->status && aw_dev->cali_desc.cali_switch) + aw_cali_svc_dev_cali_re(aw88399); + + return 0; +} + static int aw88399_dev_init(struct aw88399 *aw88399, struct aw_container *aw_cfg) { struct aw_device *aw_dev = aw88399->aw_pa; @@ -1708,6 +2140,10 @@ static const struct snd_kcontrol_new aw88399_controls[] = { aw88399_get_fade_out_time, aw88399_set_fade_out_time), SOC_SINGLE_EXT("Calib", 0, 0, AW88399_CALI_RE_MAX, 0, aw88399_re_get, aw88399_re_set), + SOC_SINGLE_BOOL_EXT("Calib Switch", 0, + aw88399_calib_switch_get, aw88399_calib_switch_set), + SOC_SINGLE_EXT("Trigger Calib", SND_SOC_NOPM, 0, 1, 0, + aw88399_calib_get, aw88399_calib_set), AW88399_PROFILE_EXT("AW88399 Profile Set", aw88399_profile_info, aw88399_profile_get, aw88399_profile_set), }; diff --git a/sound/soc/codecs/aw88399.h b/sound/soc/codecs/aw88399.h index 5e9cdf725d3d..cacc03b1eefa 100644 --- a/sound/soc/codecs/aw88399.h +++ b/sound/soc/codecs/aw88399.h @@ -451,6 +451,24 @@ #define AW88399_WDT_CNT_MASK \ (~(((1<<AW88399_WDT_CNT_BITS_LEN)-1) << AW88399_WDT_CNT_START_BIT)) +#define AW88399_REABS_START_BIT (3) +#define AW88399_REABS_BITS_LEN (1) +#define AW88399_REABS_MASK \ + (~(((1<<AW88399_REABS_BITS_LEN)-1) << AW88399_REABS_START_BIT)) + +#define AW88399_DSP_VOL_START_BIT (8) +#define AW88399_DSP_VOL_BITS_LEN (8) +#define AW88399_DSP_VOL_MASK \ + (~(((1<<AW88399_DSP_VOL_BITS_LEN)-1) << AW88399_DSP_VOL_START_BIT)) + +#define AW883XX_DSP_NG_EN_START (13) +#define AW883XX_DSP_NG_EN_LEN (1) +#define AW883XX_DSP_NG_EN_MASK \ + (~(((1 << AW883XX_DSP_NG_EN_LEN) - 1) << AW883XX_DSP_NG_EN_START)) +#define AW883XX_DSP_NG_EN_DISABLE (0) +#define AW883XX_DSP_NG_EN_DISABLE_VALUE \ + (AW883XX_DSP_NG_EN_DISABLE << AW883XX_DSP_NG_EN_START) + #define AW88399_VOLUME_STEP_DB (64) #define AW88399_VOL_DEFAULT_VALUE (0) #define AW88399_DSP_ODD_NUM_BIT_TEST (0x5555) @@ -507,6 +525,22 @@ #define FADE_TIME_MAX 100000 #define FADE_TIME_MIN 0 +#define AW_CALI_READ_CNT_MAX (8) +#define AW88399_DSP_REG_CALRE (0x8141) +#define AW88399_DSP_REG_CALRE_SHIFT (10) +#define AW_CALI_DATA_SUM_RM (2) + +#define AW88399_DSP_REG_CFG_MBMEC_ACTAMPTH (0x9B4C) +#define AW88399_DSP_REG_CFG_MBMEC_NOISEAMPTH (0x9B4E) +#define AW88399_DSP_REG_CFG_ADPZ_USTEPN (0x9B6E) +#define AW88399_DSP_REG_CFG_RE_ALPHA (0x9BD4) +#define AW_GET_IV_CNT_MAX (6) + +#define AW88399_DSP_VOL_MUTE (0XFF00) + +#define AW88399_DSP_LOW_POWER_SWITCH_CFG_ADDR (0x9BEC) +#define AW88399_DSP_LOW_POWER_SWITCH_DISABLE (0x110b) + #define AW88399_PROFILE_EXT(xname, profile_info, profile_get, profile_set) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 571222ec520c..937c8cec682a 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -18,6 +18,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/of_reserved_mem.h> #include <linux/platform_data/cros_ec_commands.h> #include <linux/platform_data/cros_ec_proto.h> #include <linux/platform_device.h> @@ -961,7 +962,6 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) struct ec_response_ec_codec_get_capabilities r; int ret; #ifdef CONFIG_OF - struct device_node *node; struct resource res; u64 ec_shm_size; const __be32 *regaddr_p; @@ -981,22 +981,18 @@ static int cros_ec_codec_platform_probe(struct platform_device *pdev) priv->ec_shm_addr, priv->ec_shm_len); } - node = of_parse_phandle(dev->of_node, "memory-region", 0); - if (node) { - ret = of_address_to_resource(node, 0, &res); - if (!ret) { - priv->ap_shm_phys_addr = res.start; - priv->ap_shm_len = resource_size(&res); - priv->ap_shm_addr = - (uint64_t)(uintptr_t)devm_ioremap_wc( - dev, priv->ap_shm_phys_addr, - priv->ap_shm_len); - priv->ap_shm_last_alloc = priv->ap_shm_phys_addr; - - dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", - priv->ap_shm_phys_addr, priv->ap_shm_len); - } - of_node_put(node); + ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res); + if (!ret) { + priv->ap_shm_phys_addr = res.start; + priv->ap_shm_len = resource_size(&res); + priv->ap_shm_addr = + (uint64_t)(uintptr_t)devm_ioremap_wc( + dev, priv->ap_shm_phys_addr, + priv->ap_shm_len); + priv->ap_shm_last_alloc = priv->ap_shm_phys_addr; + + dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", + priv->ap_shm_phys_addr, priv->ap_shm_len); } #endif diff --git a/sound/soc/codecs/cs35l36.c b/sound/soc/codecs/cs35l36.c index b49c6905e872..b60697ff7a50 100644 --- a/sound/soc/codecs/cs35l36.c +++ b/sound/soc/codecs/cs35l36.c @@ -129,7 +129,7 @@ static const struct cs35l36_pll_config cs35l36_pll_sysclk[] = { {27000000, 0x3F, 0x0A}, }; -static struct reg_default cs35l36_reg[] = { +static const struct reg_default cs35l36_reg[] = { {CS35L36_TESTKEY_CTRL, 0x00000000}, {CS35L36_USERKEY_CTL, 0x00000000}, {CS35L36_OTP_CTRL1, 0x00002460}, diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index ff4134bee858..224d65987a8d 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -483,7 +483,6 @@ static irqreturn_t cs35l41_irq(int irq, void *data) } done: - pm_runtime_mark_last_busy(cs35l41->dev); pm_runtime_put_autosuspend(cs35l41->dev); return ret; @@ -1328,7 +1327,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg * pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000); pm_runtime_use_autosuspend(cs35l41->dev); - pm_runtime_mark_last_busy(cs35l41->dev); pm_runtime_set_active(cs35l41->dev); pm_runtime_get_noresume(cs35l41->dev); pm_runtime_enable(cs35l41->dev); diff --git a/sound/soc/codecs/cs35l45.c b/sound/soc/codecs/cs35l45.c index 432a19f4de2b..d4dcdf37bb70 100644 --- a/sound/soc/codecs/cs35l45.c +++ b/sound/soc/codecs/cs35l45.c @@ -1427,7 +1427,6 @@ int cs35l45_probe(struct cs35l45_private *cs35l45) pm_runtime_set_autosuspend_delay(cs35l45->dev, 3000); pm_runtime_use_autosuspend(cs35l45->dev); - pm_runtime_mark_last_busy(cs35l45->dev); pm_runtime_set_active(cs35l45->dev); pm_runtime_get_noresume(cs35l45->dev); pm_runtime_enable(cs35l45->dev); diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c index 13f602f51bf3..ee14031695a1 100644 --- a/sound/soc/codecs/cs35l56-sdw.c +++ b/sound/soc/codecs/cs35l56-sdw.c @@ -238,16 +238,15 @@ static const struct regmap_bus cs35l56_regmap_bus_sdw = { .val_format_endian_default = REGMAP_ENDIAN_BIG, }; -static int cs35l56_sdw_set_cal_index(struct cs35l56_private *cs35l56) +static int cs35l56_sdw_get_unique_id(struct cs35l56_private *cs35l56) { int ret; - /* SoundWire UniqueId is used to index the calibration array */ ret = sdw_read_no_pm(cs35l56->sdw_peripheral, SDW_SCP_DEVID_0); if (ret < 0) return ret; - cs35l56->base.cal_index = ret & 0xf; + cs35l56->sdw_unique_id = ret & 0xf; return 0; } @@ -259,11 +258,13 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral) pm_runtime_get_noresume(cs35l56->base.dev); - if (cs35l56->base.cal_index < 0) { - ret = cs35l56_sdw_set_cal_index(cs35l56); - if (ret < 0) - goto out; - } + ret = cs35l56_sdw_get_unique_id(cs35l56); + if (ret) + goto out; + + /* SoundWire UniqueId is used to index the calibration array */ + if (cs35l56->base.cal_index < 0) + cs35l56->base.cal_index = cs35l56->sdw_unique_id; ret = cs35l56_init(cs35l56); if (ret < 0) { @@ -282,7 +283,6 @@ static void cs35l56_sdw_init(struct sdw_slave *peripheral) } out: - pm_runtime_mark_last_busy(cs35l56->base.dev); pm_runtime_put_autosuspend(cs35l56->base.dev); } @@ -587,6 +587,7 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi cs35l56->base.dev = dev; cs35l56->sdw_peripheral = peripheral; + cs35l56->sdw_link_num = peripheral->bus->link_id; INIT_WORK(&cs35l56->sdw_irq_work, cs35l56_sdw_irq_work); dev_set_drvdata(dev, cs35l56); diff --git a/sound/soc/codecs/cs35l56-shared.c b/sound/soc/codecs/cs35l56-shared.c index d0831d609584..ba653f6ccfae 100644 --- a/sound/soc/codecs/cs35l56-shared.c +++ b/sound/soc/codecs/cs35l56-shared.c @@ -980,7 +980,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base) break; default: dev_err(cs35l56_base->dev, "Unknown device %x\n", devid); - return ret; + return -ENODEV; } cs35l56_base->type = devid & 0xFF; diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c index c78e4746e428..b1c65d8331e7 100644 --- a/sound/soc/codecs/cs35l56.c +++ b/sound/soc/codecs/cs35l56.c @@ -706,17 +706,41 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56) return ret; } -static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56) +static int cs35l56_dsp_download_and_power_up(struct cs35l56_private *cs35l56, + bool load_firmware) { int ret; - /* Use wm_adsp to load and apply the firmware patch and coefficient files */ - ret = wm_adsp_power_up(&cs35l56->dsp, true); + /* + * Abort the first load if it didn't find the suffixed bins and + * we have an alternate fallback suffix. + */ + cs35l56->dsp.bin_mandatory = (load_firmware && cs35l56->fallback_fw_suffix); + + ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware); + if ((ret == -ENOENT) && cs35l56->dsp.bin_mandatory) { + cs35l56->dsp.fwf_suffix = cs35l56->fallback_fw_suffix; + cs35l56->fallback_fw_suffix = NULL; + cs35l56->dsp.bin_mandatory = false; + ret = wm_adsp_power_up(&cs35l56->dsp, load_firmware); + } + if (ret) { - dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret); - return; + dev_dbg(cs35l56->base.dev, "wm_adsp_power_up ret %d\n", ret); + return ret; } + return 0; +} + +static void cs35l56_reinit_patch(struct cs35l56_private *cs35l56) +{ + int ret; + + ret = cs35l56_dsp_download_and_power_up(cs35l56, true); + if (ret) + return; + cs35l56_write_cal(cs35l56); /* Always REINIT after applying patch or coefficients */ @@ -750,11 +774,9 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing * but only if firmware is missing. If firmware is already patched just * power-up wm_adsp without downloading firmware. */ - ret = wm_adsp_power_up(&cs35l56->dsp, !!firmware_missing); - if (ret) { - dev_dbg(cs35l56->base.dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret); + ret = cs35l56_dsp_download_and_power_up(cs35l56, firmware_missing); + if (ret) goto err; - } mutex_lock(&cs35l56->base.irq_lock); @@ -849,10 +871,37 @@ static void cs35l56_dsp_work(struct work_struct *work) cs35l56_log_tuning(&cs35l56->base, &cs35l56->dsp.cs_dsp); err: - pm_runtime_mark_last_busy(cs35l56->base.dev); pm_runtime_put_autosuspend(cs35l56->base.dev); } +static int cs35l56_set_fw_suffix(struct cs35l56_private *cs35l56) +{ + if (cs35l56->dsp.fwf_suffix) + return 0; + + if (!cs35l56->sdw_peripheral) + return 0; + + cs35l56->dsp.fwf_suffix = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, + "l%uu%u", + cs35l56->sdw_link_num, + cs35l56->sdw_unique_id); + if (!cs35l56->dsp.fwf_suffix) + return -ENOMEM; + + /* + * There are published firmware files for L56 B0 silicon using + * the ALSA prefix as the filename suffix. Default to trying these + * first, with the new name as an alternate. + */ + if ((cs35l56->base.type == 0x56) && (cs35l56->base.rev == 0xb0)) { + cs35l56->fallback_fw_suffix = cs35l56->dsp.fwf_suffix; + cs35l56->dsp.fwf_suffix = cs35l56->component->name_prefix; + } + + return 0; +} + static int cs35l56_component_probe(struct snd_soc_component *component) { struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component); @@ -892,6 +941,10 @@ static int cs35l56_component_probe(struct snd_soc_component *component) return -ENOMEM; cs35l56->component = component; + ret = cs35l56_set_fw_suffix(cs35l56); + if (ret) + return ret; + wm_adsp2_component_probe(&cs35l56->dsp, component); debugfs_create_bool("init_done", 0444, debugfs_root, &cs35l56->base.init_done); diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h index 200f695efca3..bd77a57249d7 100644 --- a/sound/soc/codecs/cs35l56.h +++ b/sound/soc/codecs/cs35l56.h @@ -38,6 +38,7 @@ struct cs35l56_private { struct snd_soc_component *component; struct regulator_bulk_data supplies[CS35L56_NUM_BULK_SUPPLIES]; struct sdw_slave *sdw_peripheral; + const char *fallback_fw_suffix; struct work_struct sdw_irq_work; bool sdw_irq_no_unmask; bool soft_resetting; @@ -52,6 +53,8 @@ struct cs35l56_private { bool tdm_mode; bool sysclk_set; u8 old_sdw_clock_scale; + u8 sdw_link_num; + u8 sdw_unique_id; }; extern const struct dev_pm_ops cs35l56_pm_ops_i2c_spi; diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 56668c392063..78bb093fa0cc 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1775,7 +1775,6 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data) } mutex_unlock(&cs42l42->irq_lock); - pm_runtime_mark_last_busy(cs42l42->dev); pm_runtime_put_autosuspend(cs42l42->dev); return IRQ_HANDLED; diff --git a/sound/soc/codecs/cs42l43-jack.c b/sound/soc/codecs/cs42l43-jack.c index 6165ac16c3a9..f5c5150c25e5 100644 --- a/sound/soc/codecs/cs42l43-jack.c +++ b/sound/soc/codecs/cs42l43-jack.c @@ -242,7 +242,6 @@ done: error: mutex_unlock(&priv->jack_lock); - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); return ret; @@ -423,7 +422,6 @@ void cs42l43_button_press_work(struct work_struct *work) error: mutex_unlock(&priv->jack_lock); - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); } @@ -462,7 +460,6 @@ void cs42l43_button_release_work(struct work_struct *work) mutex_unlock(&priv->jack_lock); - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); } @@ -504,7 +501,6 @@ void cs42l43_bias_sense_timeout(struct work_struct *work) mutex_unlock(&priv->jack_lock); - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); } @@ -776,7 +772,6 @@ error: priv->suspend_jack_debounce = false; - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); } diff --git a/sound/soc/codecs/cs42l43.c b/sound/soc/codecs/cs42l43.c index ea84ac64c775..d84ad8d43438 100644 --- a/sound/soc/codecs/cs42l43.c +++ b/sound/soc/codecs/cs42l43.c @@ -1088,7 +1088,6 @@ static int cs42l43_shutter_get(struct cs42l43_codec *priv, unsigned int shift) ret ? "open" : "closed"); error: - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); return ret; @@ -2370,7 +2369,6 @@ static int cs42l43_codec_probe(struct platform_device *pdev) goto err_clk; } - pm_runtime_mark_last_busy(priv->dev); pm_runtime_put_autosuspend(priv->dev); return 0; diff --git a/sound/soc/codecs/cs48l32.c b/sound/soc/codecs/cs48l32.c index 90a795230d27..a306af4289ad 100644 --- a/sound/soc/codecs/cs48l32.c +++ b/sound/soc/codecs/cs48l32.c @@ -1385,7 +1385,6 @@ static irqreturn_t cs48l32_irq(int irq, void *data) result = IRQ_HANDLED; out: - pm_runtime_mark_last_busy(cs48l32_codec->core.dev); pm_runtime_put_autosuspend(cs48l32_codec->core.dev); return result; @@ -2162,6 +2161,10 @@ static int cs48l32_hw_params(struct snd_pcm_substream *substream, n_slots_multiple = 1; sclk_target = snd_soc_tdm_params_to_bclk(params, slotw, n_slots, n_slots_multiple); + if (sclk_target < 0) { + cs48l32_asp_err(dai, "Invalid parameters\n"); + return sclk_target; + } for (i = 0; i < ARRAY_SIZE(cs48l32_sclk_rates); i++) { if ((cs48l32_sclk_rates[i].freq >= sclk_target) && diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 5f2f67e3bd29..a7539e1a1893 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c @@ -3033,7 +3033,7 @@ static const struct snd_soc_component_driver soc_component_dev_da7218 = { * Regmap configs */ -static struct reg_default da7218_reg_defaults[] = { +static const struct reg_default da7218_reg_defaults[] = { { DA7218_SYSTEM_ACTIVE, 0x00 }, { DA7218_CIF_CTRL, 0x00 }, { DA7218_SPARE1, 0x00 }, diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c index 3958e88a2445..1742f91c788c 100644 --- a/sound/soc/codecs/da7219.c +++ b/sound/soc/codecs/da7219.c @@ -1982,8 +1982,8 @@ static unsigned long da7219_wclk_recalc_rate(struct clk_hw *hw, } } -static long da7219_wclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int da7219_wclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct da7219_priv *da7219 = container_of(hw, struct da7219_priv, @@ -1992,28 +1992,30 @@ static long da7219_wclk_round_rate(struct clk_hw *hw, unsigned long rate, if (!da7219->master) return -EINVAL; - if (rate < 11025) - return 8000; - else if (rate < 12000) - return 11025; - else if (rate < 16000) - return 12000; - else if (rate < 22050) - return 16000; - else if (rate < 24000) - return 22050; - else if (rate < 32000) - return 24000; - else if (rate < 44100) - return 32000; - else if (rate < 48000) - return 44100; - else if (rate < 88200) - return 48000; - else if (rate < 96000) - return 88200; + if (req->rate < 11025) + req->rate = 8000; + else if (req->rate < 12000) + req->rate = 11025; + else if (req->rate < 16000) + req->rate = 12000; + else if (req->rate < 22050) + req->rate = 16000; + else if (req->rate < 24000) + req->rate = 22050; + else if (req->rate < 32000) + req->rate = 24000; + else if (req->rate < 44100) + req->rate = 32000; + else if (req->rate < 48000) + req->rate = 44100; + else if (req->rate < 88200) + req->rate = 48000; + else if (req->rate < 96000) + req->rate = 88200; else - return 96000; + req->rate = 96000; + + return 0; } static int da7219_wclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -2070,15 +2072,15 @@ static unsigned long da7219_bclk_get_factor(unsigned long rate, return 256; } -static long da7219_bclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int da7219_bclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct da7219_priv *da7219 = container_of(hw, struct da7219_priv, dai_clks_hw[DA7219_DAI_BCLK_IDX]); unsigned long factor; - if (!*parent_rate || !da7219->master) + if (!req->best_parent_rate || !da7219->master) return -EINVAL; /* @@ -2088,9 +2090,11 @@ static long da7219_bclk_round_rate(struct clk_hw *hw, unsigned long rate, * parent WCLK rate set and find the appropriate multiplier of BCLK to * get the rounded down BCLK value. */ - factor = da7219_bclk_get_factor(rate, *parent_rate); + factor = da7219_bclk_get_factor(req->rate, req->best_parent_rate); + + req->rate = req->best_parent_rate * factor; - return *parent_rate * factor; + return 0; } static int da7219_bclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -2116,12 +2120,12 @@ static const struct clk_ops da7219_dai_clk_ops[DA7219_DAI_NUM_CLKS] = { .unprepare = da7219_wclk_unprepare, .is_prepared = da7219_wclk_is_prepared, .recalc_rate = da7219_wclk_recalc_rate, - .round_rate = da7219_wclk_round_rate, + .determine_rate = da7219_wclk_determine_rate, .set_rate = da7219_wclk_set_rate, }, [DA7219_DAI_BCLK_IDX] = { .recalc_rate = da7219_bclk_recalc_rate, - .round_rate = da7219_bclk_round_rate, + .determine_rate = da7219_bclk_determine_rate, .set_rate = da7219_bclk_set_rate, }, }; @@ -2312,7 +2316,7 @@ static void da7219_handle_pdata(struct snd_soc_component *component) * Regmap configs */ -static struct reg_default da7219_reg_defaults[] = { +static const struct reg_default da7219_reg_defaults[] = { { DA7219_MIC_1_SELECT, 0x00 }, { DA7219_CIF_TIMEOUT_CTRL, 0x01 }, { DA7219_SR_24_48, 0x00 }, @@ -2443,7 +2447,7 @@ static const struct regmap_config da7219_regmap_config = { .cache_type = REGCACHE_RBTREE, }; -static struct reg_sequence da7219_rev_aa_patch[] = { +static const struct reg_sequence da7219_rev_aa_patch[] = { { DA7219_REFERENCES, 0x08 }, }; diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 066d92b54312..78c4e68f6002 100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -1079,8 +1079,7 @@ static void es8326_init(struct snd_soc_component *component) regmap_update_bits(es8326->regmap, ES8326_HPDET_TYPE, 0x03, 0x00); regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk); - regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, - (ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT)); + regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT); regmap_write(es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT); regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00); diff --git a/sound/soc/codecs/es8375.c b/sound/soc/codecs/es8375.c index 009259632107..36b0ebdce514 100644 --- a/sound/soc/codecs/es8375.c +++ b/sound/soc/codecs/es8375.c @@ -620,7 +620,7 @@ static bool es8375_writeable_register(struct device *dev, unsigned int reg) } } -static struct regmap_config es8375_regmap_config = { +static const struct regmap_config es8375_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = ES8375_REG_MAX, diff --git a/sound/soc/codecs/hda.c b/sound/soc/codecs/hda.c index dc7794c9ac44..ede980cc6050 100644 --- a/sound/soc/codecs/hda.c +++ b/sound/soc/codecs/hda.c @@ -162,7 +162,6 @@ int hda_codec_probe_complete(struct hda_codec *codec) snd_hda_codec_register(codec); /* Complement pm_runtime_get_sync(bus) in probe */ - pm_runtime_mark_last_busy(bus->dev); pm_runtime_put_autosuspend(bus->dev); return ret; @@ -173,10 +172,10 @@ EXPORT_SYMBOL_GPL(hda_codec_probe_complete); static int hda_codec_probe(struct snd_soc_component *component) { struct hda_codec *codec = dev_to_hda_codec(component->dev); + struct hda_codec_driver *driver = hda_codec_to_driver(codec); struct hdac_device *hdev = &codec->core; struct hdac_bus *bus = hdev->bus; struct hdac_ext_link *hlink; - hda_codec_patch_t patch; int ret; #ifdef CONFIG_PM @@ -214,14 +213,12 @@ static int hda_codec_probe(struct snd_soc_component *component) goto err; } - patch = (hda_codec_patch_t)codec->preset->driver_data; - if (!patch) { - dev_err(&hdev->dev, "no patch specified\n"); + if (WARN_ON(!(driver->ops && driver->ops->probe))) { ret = -EINVAL; goto err; } - ret = patch(codec); + ret = driver->ops->probe(codec, codec->preset); if (ret < 0) { dev_err(&hdev->dev, "codec init failed: %d\n", ret); goto err; @@ -252,8 +249,8 @@ static int hda_codec_probe(struct snd_soc_component *component) complete_err: hda_codec_unregister_dais(codec, component); parse_pcms_err: - if (codec->patch_ops.free) - codec->patch_ops.free(codec); + if (driver->ops->remove) + driver->ops->remove(codec); err: snd_hda_codec_cleanup_for_unbind(codec); device_new_err: @@ -262,7 +259,6 @@ device_new_err: snd_hdac_ext_bus_link_put(bus, hlink); - pm_runtime_mark_last_busy(bus->dev); pm_runtime_put_autosuspend(bus->dev); return ret; } @@ -271,6 +267,7 @@ device_new_err: static void hda_codec_remove(struct snd_soc_component *component) { struct hda_codec *codec = dev_to_hda_codec(component->dev); + struct hda_codec_driver *driver = hda_codec_to_driver(codec); struct hdac_device *hdev = &codec->core; struct hdac_bus *bus = hdev->bus; struct hdac_ext_link *hlink; @@ -281,8 +278,8 @@ static void hda_codec_remove(struct snd_soc_component *component) hda_codec_unregister_dais(codec, component); - if (codec->patch_ops.free) - codec->patch_ops.free(codec); + if (driver->ops->remove) + driver->ops->remove(codec); snd_hda_codec_cleanup_for_unbind(codec); pm_runtime_put_noidle(&hdev->dev); @@ -300,7 +297,6 @@ static void hda_codec_remove(struct snd_soc_component *component) * not be called due to early error, leaving bus uc unbalanced */ if (!was_registered) { - pm_runtime_mark_last_busy(bus->dev); pm_runtime_put_autosuspend(bus->dev); } diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c index 29c88de5508b..afd8edf10fdc 100644 --- a/sound/soc/codecs/hdac_hda.c +++ b/sound/soc/codecs/hdac_hda.c @@ -409,8 +409,8 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) snd_soc_component_get_dapm(component); struct hdac_device *hdev = &hda_pvt->codec->core; struct hda_codec *hcodec = hda_pvt->codec; + struct hda_codec_driver *driver = hda_codec_to_driver(hcodec); struct hdac_ext_link *hlink; - hda_codec_patch_t patch; int ret; hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); @@ -484,15 +484,15 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) goto error_pm; } - patch = (hda_codec_patch_t)hcodec->preset->driver_data; - if (patch) { - ret = patch(hcodec); - if (ret < 0) { - dev_err(&hdev->dev, "%s: patch failed %d\n", __func__, ret); - goto error_regmap; - } - } else { - dev_dbg(&hdev->dev, "%s: no patch file found\n", __func__); + if (WARN_ON(!(driver->ops && driver->ops->probe))) { + ret = -EINVAL; + goto error_regmap; + } + + ret = driver->ops->probe(hcodec, hcodec->preset); + if (ret < 0) { + dev_err(&hdev->dev, "%s: probe failed %d\n", __func__, ret); + goto error_regmap; } ret = snd_hda_codec_parse_pcms(hcodec); @@ -531,8 +531,8 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component) return 0; error_patch: - if (hcodec->patch_ops.free) - hcodec->patch_ops.free(hcodec); + if (driver->ops->remove) + driver->ops->remove(hcodec); error_regmap: snd_hdac_regmap_exit(hdev); error_pm: @@ -548,6 +548,7 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component) snd_soc_component_get_drvdata(component); struct hdac_device *hdev = &hda_pvt->codec->core; struct hda_codec *codec = hda_pvt->codec; + struct hda_codec_driver *driver = hda_codec_to_driver(codec); struct hdac_ext_link *hlink = NULL; hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev)); @@ -559,8 +560,8 @@ static void hdac_hda_codec_remove(struct snd_soc_component *component) pm_runtime_disable(&hdev->dev); snd_hdac_ext_bus_link_put(hdev->bus, hlink); - if (codec->patch_ops.free) - codec->patch_ops.free(codec); + if (driver->ops->remove) + driver->ops->remove(codec); snd_hda_codec_cleanup_for_unbind(codec); } diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 1139a2754ca3..e50afd0bfcec 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -24,8 +24,6 @@ #include <sound/hda_i915.h> #include <sound/pcm_drm_eld.h> #include <sound/hda_chmap.h> -#include "../../hda/local.h" -#include "hdac_hdmi.h" #define NAME_SIZE 32 @@ -221,8 +219,8 @@ static int hdac_hdmi_get_port_len(struct hdac_device *hdev, hda_nid_t nid) unsigned int caps; unsigned int type, param; - caps = get_wcaps(hdev, nid); - type = get_wcaps_type(caps); + caps = snd_hdac_get_wcaps(hdev, nid); + type = snd_hdac_get_wcaps_type(caps); if (!(caps & AC_WCAP_DIGITAL) || (type != AC_WID_PIN)) return 0; @@ -492,10 +490,10 @@ static int hdac_hdmi_query_port_connlist(struct hdac_device *hdev, struct hdac_hdmi_pin *pin, struct hdac_hdmi_port *port) { - if (!(get_wcaps(hdev, pin->nid) & AC_WCAP_CONN_LIST)) { + if (!(snd_hdac_get_wcaps(hdev, pin->nid) & AC_WCAP_CONN_LIST)) { dev_warn(&hdev->dev, "HDMI: pin %d wcaps %#x does not support connection list\n", - pin->nid, get_wcaps(hdev, pin->nid)); + pin->nid, snd_hdac_get_wcaps(hdev, pin->nid)); return -EINVAL; } @@ -660,8 +658,8 @@ hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt) struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); int err; - chans = get_wcaps(hdev, cvt->nid); - chans = get_wcaps_channels(chans); + chans = snd_hdac_get_wcaps(hdev, cvt->nid); + chans = snd_hdac_get_wcaps_channels(chans); cvt->params.channels_min = 2; @@ -743,7 +741,7 @@ static void hdac_hdmi_set_power_state(struct hdac_device *hdev, int count; unsigned int state; - if (get_wcaps(hdev, nid) & AC_WCAP_POWER) { + if (snd_hdac_get_wcaps(hdev, nid) & AC_WCAP_POWER) { if (!snd_hdac_check_power_state(hdev, nid, pwr_state)) { for (count = 0; count < 10; count++) { snd_hdac_codec_read(hdev, nid, 0, @@ -761,7 +759,7 @@ static void hdac_hdmi_set_power_state(struct hdac_device *hdev, static void hdac_hdmi_set_amp(struct hdac_device *hdev, hda_nid_t nid, int val) { - if (get_wcaps(hdev, nid) & AC_WCAP_OUT_AMP) + if (snd_hdac_get_wcaps(hdev, nid) & AC_WCAP_OUT_AMP) snd_hdac_codec_write(hdev, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, val); } @@ -1232,7 +1230,8 @@ static int hdac_hdmi_parse_eld(struct hdac_device *hdev, >> DRM_ELD_VER_SHIFT; if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) { - dev_err(&hdev->dev, "HDMI: Unknown ELD version %d\n", ver); + dev_err_ratelimited(&hdev->dev, + "HDMI: Unknown ELD version %d\n", ver); return -EINVAL; } @@ -1240,7 +1239,8 @@ static int hdac_hdmi_parse_eld(struct hdac_device *hdev, DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT; if (mnl > ELD_MAX_MNL) { - dev_err(&hdev->dev, "HDMI: MNL Invalid %d\n", mnl); + dev_err_ratelimited(&hdev->dev, + "HDMI: MNL Invalid %d\n", mnl); return -EINVAL; } @@ -1299,8 +1299,8 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, if (!port->eld.monitor_present || !port->eld.eld_valid) { - dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n", - __func__, pin->nid, port->id); + dev_dbg(&hdev->dev, "%s: disconnect for pin:port %d:%d\n", + __func__, pin->nid, port->id); /* * PCMs are not registered during device probe, so don't @@ -1431,122 +1431,6 @@ static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdev) } -static int hdac_hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component); - struct hdac_hdmi_pcm *pcm; - struct hdac_hdmi_port *port; - struct hdac_hdmi_eld *eld; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; - uinfo->count = 0; - - pcm = get_hdmi_pcm_from_id(hdmi, kcontrol->id.device); - if (!pcm) { - dev_dbg(component->dev, "%s: no pcm, device %d\n", __func__, - kcontrol->id.device); - return 0; - } - - if (list_empty(&pcm->port_list)) { - dev_dbg(component->dev, "%s: empty port list, device %d\n", - __func__, kcontrol->id.device); - return 0; - } - - mutex_lock(&hdmi->pin_mutex); - - list_for_each_entry(port, &pcm->port_list, head) { - eld = &port->eld; - - if (eld->eld_valid) { - uinfo->count = eld->eld_size; - break; - } - } - - mutex_unlock(&hdmi->pin_mutex); - - return 0; -} - -static int hdac_hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); - struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component); - struct hdac_hdmi_pcm *pcm; - struct hdac_hdmi_port *port; - struct hdac_hdmi_eld *eld; - - memset(ucontrol->value.bytes.data, 0, sizeof(ucontrol->value.bytes.data)); - - pcm = get_hdmi_pcm_from_id(hdmi, kcontrol->id.device); - if (!pcm) { - dev_dbg(component->dev, "%s: no pcm, device %d\n", __func__, - kcontrol->id.device); - return 0; - } - - if (list_empty(&pcm->port_list)) { - dev_dbg(component->dev, "%s: empty port list, device %d\n", - __func__, kcontrol->id.device); - return 0; - } - - mutex_lock(&hdmi->pin_mutex); - - list_for_each_entry(port, &pcm->port_list, head) { - eld = &port->eld; - - if (!eld->eld_valid) - continue; - - if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) || - eld->eld_size > ELD_MAX_SIZE) { - mutex_unlock(&hdmi->pin_mutex); - - dev_err(component->dev, "%s: buffer too small, device %d eld_size %d\n", - __func__, kcontrol->id.device, eld->eld_size); - snd_BUG(); - return -EINVAL; - } - - memcpy(ucontrol->value.bytes.data, eld->eld_buffer, - eld->eld_size); - break; - } - - mutex_unlock(&hdmi->pin_mutex); - - return 0; -} - -static int hdac_hdmi_create_eld_ctl(struct snd_soc_component *component, struct hdac_hdmi_pcm *pcm) -{ - struct snd_kcontrol *kctl; - struct snd_kcontrol_new hdmi_eld_ctl = { - .access = SNDRV_CTL_ELEM_ACCESS_READ | - SNDRV_CTL_ELEM_ACCESS_VOLATILE, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = "ELD", - .info = hdac_hdmi_eld_ctl_info, - .get = hdac_hdmi_eld_ctl_get, - .device = pcm->pcm_id, - }; - - /* add ELD ctl with the device number corresponding to the PCM stream */ - kctl = snd_ctl_new1(&hdmi_eld_ctl, component); - if (!kctl) - return -ENOMEM; - - pcm->eld_ctl = kctl; - - return snd_ctl_add(component->card->snd_card, kctl); -} - static const struct snd_soc_dai_ops hdmi_dai_ops = { .startup = hdac_hdmi_pcm_open, .shutdown = hdac_hdmi_pcm_close, @@ -1648,8 +1532,8 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_device *hdev, unsigned int caps; unsigned int type; - caps = get_wcaps(hdev, nid); - type = get_wcaps_type(caps); + caps = snd_hdac_get_wcaps(hdev, nid); + type = snd_hdac_get_wcaps_type(caps); if (!(caps & AC_WCAP_DIGITAL)) continue; @@ -1754,186 +1638,6 @@ static struct drm_audio_component_audio_ops aops = { .pin_eld_notify = hdac_hdmi_eld_notify_cb, }; -static struct snd_pcm *hdac_hdmi_get_pcm_from_id(struct snd_soc_card *card, - int device) -{ - struct snd_soc_pcm_runtime *rtd; - - for_each_card_rtds(card, rtd) { - if (rtd->pcm && (rtd->pcm->device == device)) - return rtd->pcm; - } - - return NULL; -} - -/* create jack pin kcontrols */ -static int create_fill_jack_kcontrols(struct snd_soc_card *card, - struct hdac_device *hdev) -{ - struct hdac_hdmi_pin *pin; - struct snd_kcontrol_new *kc; - char *name; - int i = 0, j; - struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); - struct snd_soc_component *component = hdmi->component; - - kc = devm_kcalloc(component->dev, hdmi->num_ports, - sizeof(*kc), GFP_KERNEL); - - if (!kc) - return -ENOMEM; - - list_for_each_entry(pin, &hdmi->pin_list, head) { - for (j = 0; j < pin->num_ports; j++) { - name = devm_kasprintf(component->dev, GFP_KERNEL, - "hif%d-%d Jack", - pin->nid, pin->ports[j].id); - if (!name) - return -ENOMEM; - - kc[i].name = devm_kasprintf(component->dev, GFP_KERNEL, - "%s Switch", name); - if (!kc[i].name) - return -ENOMEM; - - kc[i].private_value = (unsigned long)name; - kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER; - kc[i].access = 0; - kc[i].info = snd_soc_dapm_info_pin_switch; - kc[i].put = snd_soc_dapm_put_pin_switch; - kc[i].get = snd_soc_dapm_get_pin_switch; - i++; - } - } - - return snd_soc_add_card_controls(card, kc, i); -} - -int hdac_hdmi_jack_port_init(struct snd_soc_component *component, - struct snd_soc_dapm_context *dapm) -{ - struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component); - struct hdac_device *hdev = hdmi->hdev; - struct hdac_hdmi_pin *pin; - struct snd_soc_dapm_widget *widgets; - struct snd_soc_dapm_route *route; - char w_name[NAME_SIZE]; - int i = 0, j, ret; - - widgets = devm_kcalloc(dapm->dev, hdmi->num_ports, - sizeof(*widgets), GFP_KERNEL); - - if (!widgets) - return -ENOMEM; - - route = devm_kcalloc(dapm->dev, hdmi->num_ports, - sizeof(*route), GFP_KERNEL); - if (!route) - return -ENOMEM; - - /* create Jack DAPM widget */ - list_for_each_entry(pin, &hdmi->pin_list, head) { - for (j = 0; j < pin->num_ports; j++) { - snprintf(w_name, sizeof(w_name), "hif%d-%d Jack", - pin->nid, pin->ports[j].id); - - ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i], - snd_soc_dapm_spk, NULL, - w_name, NULL, NULL, 0, NULL, 0); - if (ret < 0) - return ret; - - pin->ports[j].jack_pin = widgets[i].name; - pin->ports[j].dapm = dapm; - - /* add to route from Jack widget to output */ - hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin, - NULL, pin->ports[j].output_pin, NULL); - - i++; - } - } - - /* Add Route from Jack widget to the output widget */ - ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi->num_ports); - if (ret < 0) - return ret; - - ret = snd_soc_dapm_add_routes(dapm, route, hdmi->num_ports); - if (ret < 0) - return ret; - - ret = snd_soc_dapm_new_widgets(dapm->card); - if (ret < 0) - return ret; - - /* Add Jack Pin switch Kcontrol */ - ret = create_fill_jack_kcontrols(dapm->card, hdev); - - if (ret < 0) - return ret; - - /* default set the Jack Pin switch to OFF */ - list_for_each_entry(pin, &hdmi->pin_list, head) { - for (j = 0; j < pin->num_ports; j++) - snd_soc_dapm_disable_pin(pin->ports[j].dapm, - pin->ports[j].jack_pin); - } - - return 0; -} -EXPORT_SYMBOL_GPL(hdac_hdmi_jack_port_init); - -int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device, - struct snd_soc_jack *jack) -{ - struct snd_soc_component *component = dai->component; - struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component); - struct hdac_device *hdev = hdmi->hdev; - struct hdac_hdmi_pcm *pcm; - struct snd_pcm *snd_pcm; - int err; - - /* - * this is a new PCM device, create new pcm and - * add to the pcm list - */ - pcm = devm_kzalloc(&hdev->dev, sizeof(*pcm), GFP_KERNEL); - if (!pcm) - return -ENOMEM; - pcm->pcm_id = device; - pcm->cvt = hdmi->dai_map[dai->id].cvt; - pcm->jack_event = 0; - pcm->jack = jack; - mutex_init(&pcm->lock); - INIT_LIST_HEAD(&pcm->port_list); - snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device); - if (snd_pcm) { - err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap); - if (err < 0) { - dev_err(&hdev->dev, - "chmap control add failed with err: %d for pcm: %d\n", - err, device); - return err; - } - } - - /* add control for ELD Bytes */ - err = hdac_hdmi_create_eld_ctl(component, pcm); - if (err < 0) { - dev_err(&hdev->dev, - "eld control add failed with err: %d for pcm: %d\n", - err, device); - return err; - } - - list_add_tail(&pcm->head, &hdmi->pcm_list); - - return 0; -} -EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init); - static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev, struct hdac_hdmi_priv *hdmi, bool detect_pin_caps) { diff --git a/sound/soc/codecs/hdac_hdmi.h b/sound/soc/codecs/hdac_hdmi.h deleted file mode 100644 index 493fa3b4ef75..000000000000 --- a/sound/soc/codecs/hdac_hdmi.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __HDAC_HDMI_H__ -#define __HDAC_HDMI_H__ - -int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device, - struct snd_soc_jack *jack); - -int hdac_hdmi_jack_port_init(struct snd_soc_component *component, - struct snd_soc_dapm_context *dapm); -#endif /* __HDAC_HDMI_H__ */ diff --git a/sound/soc/codecs/hdmi-codec.c b/sound/soc/codecs/hdmi-codec.c index 31121f9c18c9..e1933f733af1 100644 --- a/sound/soc/codecs/hdmi-codec.c +++ b/sound/soc/codecs/hdmi-codec.c @@ -943,7 +943,7 @@ static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp, { if (jack_status != hcp->jack_status) { if (hcp->jack) - snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT); + snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_AVOUT); hcp->jack_status = jack_status; } } @@ -964,7 +964,7 @@ static void plugged_cb(struct device *dev, bool plugged) else snd_show_eld(dev, &hcp->eld_parsed); } - hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT); + hdmi_codec_jack_report(hcp, SND_JACK_AVOUT); } else { hdmi_codec_jack_report(hcp, 0); memset(hcp->eld, 0, sizeof(hcp->eld)); @@ -984,7 +984,7 @@ static int hdmi_codec_set_jack(struct snd_soc_component *component, * Report the initial jack status which may have been provided * by the parent hdmi driver while the hpd hook was registered. */ - snd_soc_jack_report(jack, hcp->jack_status, SND_JACK_LINEOUT); + snd_soc_jack_report(jack, hcp->jack_status, SND_JACK_AVOUT); return 0; } diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c index 45a6b83808b2..238dbdb46c18 100644 --- a/sound/soc/codecs/lpass-rx-macro.c +++ b/sound/soc/codecs/lpass-rx-macro.c @@ -619,7 +619,6 @@ static struct interp_sample_rate sr_val_tbl[] = { }; enum { - RX_MACRO_AIF_INVALID = 0, RX_MACRO_AIF1_PB, RX_MACRO_AIF2_PB, RX_MACRO_AIF3_PB, diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c index 27bae58f4072..40d79bee4584 100644 --- a/sound/soc/codecs/lpass-tx-macro.c +++ b/sound/soc/codecs/lpass-tx-macro.c @@ -208,7 +208,6 @@ #define MCLK_FREQ 19200000 enum { - TX_MACRO_AIF_INVALID = 0, TX_MACRO_AIF1_CAP, TX_MACRO_AIF2_CAP, TX_MACRO_AIF3_CAP, diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c index 74ada6e77526..a49551f3fb29 100644 --- a/sound/soc/codecs/lpass-va-macro.c +++ b/sound/soc/codecs/lpass-va-macro.c @@ -165,7 +165,6 @@ static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400); enum { - VA_MACRO_AIF_INVALID = 0, VA_MACRO_AIF1_CAP, VA_MACRO_AIF2_CAP, VA_MACRO_AIF3_CAP, diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c index c1fb71cfb5d0..da6adb3de21d 100644 --- a/sound/soc/codecs/lpass-wsa-macro.c +++ b/sound/soc/codecs/lpass-wsa-macro.c @@ -369,7 +369,6 @@ static struct interp_sample_rate int_mix_sample_rate_val[] = { }; enum { - WSA_MACRO_AIF_INVALID = 0, WSA_MACRO_AIF1_PB, WSA_MACRO_AIF_MIX1_PB, WSA_MACRO_AIF_VI, diff --git a/sound/soc/codecs/max98363.c b/sound/soc/codecs/max98363.c index 950105e5bffd..25af78ab30d5 100644 --- a/sound/soc/codecs/max98363.c +++ b/sound/soc/codecs/max98363.c @@ -14,7 +14,7 @@ #include "max98363.h" -static struct reg_default max98363_reg[] = { +static const struct reg_default max98363_reg[] = { {MAX98363_R2021_ERR_MON_CTRL, 0x0}, {MAX98363_R2022_SPK_MON_THRESH, 0x0}, {MAX98363_R2023_SPK_MON_DURATION, 0x0}, @@ -188,7 +188,6 @@ static int max98363_io_init(struct sdw_slave *slave) max98363->hw_init = true; out: - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return ret; diff --git a/sound/soc/codecs/max98373-i2c.c b/sound/soc/codecs/max98373-i2c.c index 56c4ba1f3782..f58b8c8625a7 100644 --- a/sound/soc/codecs/max98373-i2c.c +++ b/sound/soc/codecs/max98373-i2c.c @@ -23,7 +23,7 @@ static const u32 max98373_i2c_cache_reg[] = { MAX98373_R20B6_BDE_CUR_STATE_READBACK, }; -static struct reg_default max98373_reg[] = { +static const struct reg_default max98373_reg[] = { {MAX98373_R2000_SW_RESET, 0x00}, {MAX98373_R2001_INT_RAW1, 0x00}, {MAX98373_R2002_INT_RAW2, 0x00}, diff --git a/sound/soc/codecs/max98373-sdw.c b/sound/soc/codecs/max98373-sdw.c index 6088278e6503..88ff215f52b3 100644 --- a/sound/soc/codecs/max98373-sdw.c +++ b/sound/soc/codecs/max98373-sdw.c @@ -26,7 +26,7 @@ static const u32 max98373_sdw_cache_reg[] = { MAX98373_R20B6_BDE_CUR_STATE_READBACK, }; -static struct reg_default max98373_reg[] = { +static const struct reg_default max98373_reg[] = { {MAX98373_R0040_SCP_INIT_STAT_1, 0x00}, {MAX98373_R0041_SCP_INIT_MASK_1, 0x00}, {MAX98373_R0042_SCP_INIT_STAT_2, 0x00}, @@ -458,7 +458,6 @@ static int max98373_io_init(struct sdw_slave *slave) max98373->first_hw_init = true; max98373->hw_init = true; - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return 0; diff --git a/sound/soc/codecs/max98388.c b/sound/soc/codecs/max98388.c index 99986090b4a6..076f15a9867e 100644 --- a/sound/soc/codecs/max98388.c +++ b/sound/soc/codecs/max98388.c @@ -18,7 +18,7 @@ #include <sound/tlv.h> #include "max98388.h" -static struct reg_default max98388_reg[] = { +static const struct reg_default max98388_reg[] = { {MAX98388_R2000_SW_RESET, 0x00}, {MAX98388_R2001_INT_RAW1, 0x00}, {MAX98388_R2002_INT_RAW2, 0x00}, diff --git a/sound/soc/codecs/max98390.c b/sound/soc/codecs/max98390.c index 76296176f948..a8a282ff9fc5 100644 --- a/sound/soc/codecs/max98390.c +++ b/sound/soc/codecs/max98390.c @@ -23,7 +23,7 @@ #include "max98390.h" -static struct reg_default max98390_reg_defaults[] = { +static const struct reg_default max98390_reg_defaults[] = { {MAX98390_INT_EN1, 0xf0}, {MAX98390_INT_EN2, 0x00}, {MAX98390_INT_EN3, 0x00}, diff --git a/sound/soc/codecs/max98396.c b/sound/soc/codecs/max98396.c index c1888cd83dbc..4b4e1fc98a6d 100644 --- a/sound/soc/codecs/max98396.c +++ b/sound/soc/codecs/max98396.c @@ -16,7 +16,7 @@ static const char * const max98396_core_supplies[MAX98396_NUM_CORE_SUPPLIES] = { "dvddio", }; -static struct reg_default max98396_reg[] = { +static const struct reg_default max98396_reg[] = { {MAX98396_R2000_SW_RESET, 0x00}, {MAX98396_R2001_INT_RAW1, 0x00}, {MAX98396_R2002_INT_RAW2, 0x00}, @@ -174,7 +174,7 @@ static struct reg_default max98396_reg[] = { {MAX98396_R21FF_REVISION_ID, 0x00}, }; -static struct reg_default max98397_reg[] = { +static const struct reg_default max98397_reg[] = { {MAX98396_R2000_SW_RESET, 0x00}, {MAX98396_R2001_INT_RAW1, 0x00}, {MAX98396_R2002_INT_RAW2, 0x00}, diff --git a/sound/soc/codecs/max98504.c b/sound/soc/codecs/max98504.c index 6b6a7ece4cec..c94142768c81 100644 --- a/sound/soc/codecs/max98504.c +++ b/sound/soc/codecs/max98504.c @@ -35,7 +35,7 @@ struct max98504_priv { unsigned int brownout_release_rate; }; -static struct reg_default max98504_reg_defaults[] = { +static const struct reg_default max98504_reg_defaults[] = { { 0x01, 0}, { 0x02, 0}, { 0x03, 0}, diff --git a/sound/soc/codecs/max98520.c b/sound/soc/codecs/max98520.c index adf5a898c6df..2bf8976c1828 100644 --- a/sound/soc/codecs/max98520.c +++ b/sound/soc/codecs/max98520.c @@ -16,7 +16,7 @@ #include <sound/tlv.h> #include "max98520.h" -static struct reg_default max98520_reg[] = { +static const struct reg_default max98520_reg[] = { {MAX98520_R2000_SW_RESET, 0x00}, {MAX98520_R2001_STATUS_1, 0x00}, {MAX98520_R2002_STATUS_2, 0x00}, diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index 55cc18451a2d..0e9b8970997c 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c @@ -19,7 +19,7 @@ #include <sound/tlv.h> #include "max98927.h" -static struct reg_default max98927_reg[] = { +static const struct reg_default max98927_reg[] = { {MAX98927_R0001_INT_RAW1, 0x00}, {MAX98927_R0002_INT_RAW2, 0x00}, {MAX98927_R0003_INT_RAW3, 0x00}, diff --git a/sound/soc/codecs/rt1017-sdca-sdw.c b/sound/soc/codecs/rt1017-sdca-sdw.c index 88fc23a4999f..a9c000876be8 100644 --- a/sound/soc/codecs/rt1017-sdca-sdw.c +++ b/sound/soc/codecs/rt1017-sdca-sdw.c @@ -362,7 +362,6 @@ static int rt1017_sdca_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt1017->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "hw_init complete\n"); diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c index ea708068f0e8..b6c224832a43 100644 --- a/sound/soc/codecs/rt1308-sdw.c +++ b/sound/soc/codecs/rt1308-sdw.c @@ -291,7 +291,6 @@ _preset_ready_: /* Mark Slave initialization complete */ rt1308->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt1316-sdw.c b/sound/soc/codecs/rt1316-sdw.c index 960b6c4f5a66..01a977398864 100644 --- a/sound/soc/codecs/rt1316-sdw.c +++ b/sound/soc/codecs/rt1316-sdw.c @@ -302,7 +302,6 @@ static int rt1316_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt1316->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt1318-sdw.c b/sound/soc/codecs/rt1318-sdw.c index 4eb636e0c9ed..70db5450d6d2 100644 --- a/sound/soc/codecs/rt1318-sdw.c +++ b/sound/soc/codecs/rt1318-sdw.c @@ -434,7 +434,6 @@ static int rt1318_io_init(struct device *dev, struct sdw_slave *slave) rt1318->first_hw_init = true; rt1318->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c index 015cc710e6dc..b13d7a99bf63 100644 --- a/sound/soc/codecs/rt1320-sdw.c +++ b/sound/soc/codecs/rt1320-sdw.c @@ -763,7 +763,6 @@ static int rt1320_io_init(struct device *dev, struct sdw_slave *slave) rt1320->first_hw_init = true; rt1320->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 21a18012b4c0..f50e771db24b 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c @@ -193,7 +193,7 @@ static bool rt5640_volatile_register(struct device *dev, unsigned int reg) case RT5640_PRIV_DATA: case RT5640_PGM_REG_ARR1: case RT5640_PGM_REG_ARR3: - case RT5640_DUMMY2: + case RT5640_GCTL2: case RT5640_VENDOR_ID: case RT5640_VENDOR_ID1: case RT5640_VENDOR_ID2: @@ -325,8 +325,8 @@ static bool rt5640_readable_register(struct device *dev, unsigned int reg) case RT5640_HP_CALIB2: case RT5640_SV_ZCD1: case RT5640_SV_ZCD2: - case RT5640_DUMMY1: - case RT5640_DUMMY2: + case RT5640_GCTL1: + case RT5640_GCTL2: case RT5640_DUMMY3: case RT5640_VENDOR_ID: case RT5640_VENDOR_ID1: @@ -423,7 +423,7 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { SOC_DOUBLE_TLV("ADC Capture Volume", RT5640_ADC_DIG_VOL, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 127, 0, adc_vol_tlv), - SOC_DOUBLE("Mono ADC Capture Switch", RT5640_DUMMY1, + SOC_DOUBLE("Mono ADC Capture Switch", RT5640_GCTL1, RT5640_M_MONO_ADC_L_SFT, RT5640_M_MONO_ADC_R_SFT, 1, 1), SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5640_ADC_DATA, RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, @@ -1969,7 +1969,7 @@ static int rt5640_set_bias_level(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5640_PWR_ANLG1, RT5640_PWR_FV1 | RT5640_PWR_FV2, RT5640_PWR_FV1 | RT5640_PWR_FV2); - snd_soc_component_update_bits(component, RT5640_DUMMY1, + snd_soc_component_update_bits(component, RT5640_GCTL1, 0x1, 0x1); snd_soc_component_update_bits(component, RT5640_MICBIAS, 0x0030, 0x0030); @@ -1979,7 +1979,7 @@ static int rt5640_set_bias_level(struct snd_soc_component *component, case SND_SOC_BIAS_OFF: snd_soc_component_write(component, RT5640_DEPOP_M1, 0x0004); snd_soc_component_write(component, RT5640_DEPOP_M2, 0x1100); - snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x1, 0); + snd_soc_component_update_bits(component, RT5640_GCTL1, 0x1, 0); snd_soc_component_write(component, RT5640_PWR_DIG1, 0x0000); snd_soc_component_write(component, RT5640_PWR_DIG2, 0x0000); snd_soc_component_write(component, RT5640_PWR_VOL, 0x0000); @@ -2328,12 +2328,12 @@ static void rt5640_jack_work(struct work_struct *work) jack_type |= SND_JACK_MICROPHONE; /* headphone jack */ - val = snd_soc_component_read(component, RT5640_DUMMY2); + val = snd_soc_component_read(component, RT5640_GCTL2); hda_hp_plugged = !(val & (0x1 << 11)); dev_dbg(component->dev, "headphone jack status %d\n", hda_hp_plugged); - snd_soc_component_update_bits(component, RT5640_DUMMY2, + snd_soc_component_update_bits(component, RT5640_GCTL2, (0x1 << 10), !hda_hp_plugged << 10); if (hda_hp_plugged) @@ -2504,7 +2504,7 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, snd_soc_component_update_bits(component, RT5640_GPIO_CTRL3, RT5640_GP1_PF_MASK, RT5640_GP1_PF_OUT); - snd_soc_component_write(component, RT5640_DUMMY1, 0x3f41); + snd_soc_component_write(component, RT5640_GCTL1, 0x3f41); rt5640_set_ovcd_params(component); @@ -2519,7 +2519,7 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, snd_soc_component_write(component, RT5640_IRQ_CTRL1, RT5640_IRQ_JD_NOR); else if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N) - snd_soc_component_update_bits(component, RT5640_DUMMY2, + snd_soc_component_update_bits(component, RT5640_GCTL2, RT5640_IRQ_JD2_MASK | RT5640_JD2_MASK, RT5640_IRQ_JD2_NOR | RT5640_JD2_EN); } else { @@ -2527,7 +2527,7 @@ static void rt5640_enable_jack_detect(struct snd_soc_component *component, snd_soc_component_write(component, RT5640_IRQ_CTRL1, RT5640_IRQ_JD_NOR | RT5640_JD_P_INV); else if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N) - snd_soc_component_update_bits(component, RT5640_DUMMY2, + snd_soc_component_update_bits(component, RT5640_GCTL2, RT5640_IRQ_JD2_MASK | RT5640_JD2_P_MASK | RT5640_JD2_MASK, RT5640_IRQ_JD2_NOR | RT5640_JD2_P_INV | @@ -2596,7 +2596,7 @@ static void rt5640_enable_hda_jack_detect( snd_soc_component_write(component, RT5640_IRQ_CTRL1, RT5640_IRQ_JD_NOR); /* Select JD2 for Headphone */ - snd_soc_component_update_bits(component, RT5640_DUMMY2, 0x1100, 0x1100); + snd_soc_component_update_bits(component, RT5640_GCTL2, 0x1100, 0x1100); /* Selecting GPIO01 as an interrupt */ snd_soc_component_update_bits(component, RT5640_GPIO_CTRL1, @@ -2606,7 +2606,7 @@ static void rt5640_enable_hda_jack_detect( snd_soc_component_update_bits(component, RT5640_GPIO_CTRL3, RT5640_GP1_PF_MASK, RT5640_GP1_PF_OUT); - snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x400, 0x0); + snd_soc_component_update_bits(component, RT5640_GCTL1, 0x400, 0x0); snd_soc_component_update_bits(component, RT5640_PWR_ANLG1, RT5640_PWR_VREF2 | RT5640_PWR_MB | RT5640_PWR_BG, @@ -2668,7 +2668,7 @@ static int rt5640_probe(struct snd_soc_component *component) snd_soc_component_force_bias_level(component, SND_SOC_BIAS_OFF); - snd_soc_component_update_bits(component, RT5640_DUMMY1, 0x0301, 0x0301); + snd_soc_component_update_bits(component, RT5640_GCTL1, 0x0301, 0x0301); snd_soc_component_update_bits(component, RT5640_MICBIAS, 0x0030, 0x0030); snd_soc_component_update_bits(component, RT5640_DSP_PATH2, 0xfc00, 0x0c00); @@ -2719,7 +2719,7 @@ static int rt5640_probe(struct snd_soc_component *component) RT5640_IN_DF2, RT5640_IN_DF2); if (device_property_read_bool(component->dev, "realtek,lout-differential")) - snd_soc_component_update_bits(component, RT5640_DUMMY1, + snd_soc_component_update_bits(component, RT5640_GCTL1, RT5640_EN_LOUT_DF, RT5640_EN_LOUT_DF); if (device_property_read_u32(component->dev, "realtek,dmic1-data-pin", @@ -2829,12 +2829,12 @@ static int rt5640_resume(struct snd_soc_component *component) if (rt5640->jack) { if (rt5640->jd_src == RT5640_JD_SRC_HDA_HEADER) { snd_soc_component_update_bits(component, - RT5640_DUMMY2, 0x1100, 0x1100); + RT5640_GCTL2, 0x1100, 0x1100); } else { if (rt5640->jd_inverted) { if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N) snd_soc_component_update_bits( - component, RT5640_DUMMY2, + component, RT5640_GCTL2, RT5640_IRQ_JD2_MASK | RT5640_JD2_MASK, RT5640_IRQ_JD2_NOR | @@ -2843,7 +2843,7 @@ static int rt5640_resume(struct snd_soc_component *component) } else { if (rt5640->jd_src == RT5640_JD_SRC_JD2_IN4N) snd_soc_component_update_bits( - component, RT5640_DUMMY2, + component, RT5640_GCTL2, RT5640_IRQ_JD2_MASK | RT5640_JD2_P_MASK | RT5640_JD2_MASK, @@ -3014,6 +3014,11 @@ static int rt5640_i2c_probe(struct i2c_client *i2c) regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); if (val != RT5640_DEVICE_ID) { + usleep_range(60000, 100000); + regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); + } + + if (val != RT5640_DEVICE_ID) { dev_err(&i2c->dev, "Device with ID register %#x is not rt5640/39\n", val); return -ENODEV; @@ -3026,7 +3031,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c) if (ret != 0) dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); - regmap_update_bits(rt5640->regmap, RT5640_DUMMY1, + regmap_update_bits(rt5640->regmap, RT5640_GCTL1, RT5640_MCLK_DET, RT5640_MCLK_DET); rt5640->hp_mute = true; diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 94b9a502f7f9..8a12cee76bdc 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h @@ -139,8 +139,8 @@ #define RT5640_SV_ZCD1 0xd9 #define RT5640_SV_ZCD2 0xda /* Dummy Register */ -#define RT5640_DUMMY1 0xfa -#define RT5640_DUMMY2 0xfb +#define RT5640_GCTL1 0xfa +#define RT5640_GCTL2 0xfb #define RT5640_DUMMY3 0xfc @@ -1986,7 +1986,7 @@ #define RT5640_M_MONO_ADC_R_SFT 12 #define RT5640_MCLK_DET (0x1 << 11) -/* General Control 1 (0xfb) */ +/* General Control 2 (0xfb) */ #define RT5640_IRQ_JD2_MASK (0x1 << 12) #define RT5640_IRQ_JD2_SFT 12 #define RT5640_IRQ_JD2_BP (0x0 << 12) diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index 08df87238eee..29a403526cd9 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c @@ -82,6 +82,7 @@ static const struct reg_sequence rt5650_init_list[] = { {0xf6, 0x0100}, {RT5645_PWR_ANLG1, 0x02}, {RT5645_IL_CMD3, 0x6728}, + {RT5645_PR_BASE + 0x3a, 0x0000}, }; static const struct reg_default rt5645_reg[] = { diff --git a/sound/soc/codecs/rt5660.c b/sound/soc/codecs/rt5660.c index 82b92e83be4c..44c3a3b92f98 100644 --- a/sound/soc/codecs/rt5660.c +++ b/sound/soc/codecs/rt5660.c @@ -1315,14 +1315,17 @@ static int rt5660_i2c_probe(struct i2c_client *i2c) regmap_update_bits(rt5660->regmap, RT5660_GPIO_CTRL1, RT5660_GP1_PIN_MASK, RT5660_GP1_PIN_DMIC1_SCL); - if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_GPIO2) + if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_GPIO2) { regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1, RT5660_SEL_DMIC_DATA_MASK, RT5660_SEL_DMIC_DATA_GPIO2); - else if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_IN1P) + regmap_update_bits(rt5660->regmap, RT5660_GPIO_CTRL1, + RT5660_GP2_PIN_MASK, RT5660_GP2_PIN_DMIC1_SDA); + } else if (rt5660->pdata.dmic1_data_pin == RT5660_DMIC1_DATA_IN1P) { regmap_update_bits(rt5660->regmap, RT5660_DMIC_CTRL1, RT5660_SEL_DMIC_DATA_MASK, RT5660_SEL_DMIC_DATA_IN1P); + } } return devm_snd_soc_register_component(&i2c->dev, diff --git a/sound/soc/codecs/rt5682-sdw.c b/sound/soc/codecs/rt5682-sdw.c index aa229894129b..055bea0a4a3b 100644 --- a/sound/soc/codecs/rt5682-sdw.c +++ b/sound/soc/codecs/rt5682-sdw.c @@ -474,7 +474,6 @@ reinit: rt5682->first_hw_init = true; err_nodev: - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete: %d\n", __func__, ret); diff --git a/sound/soc/codecs/rt5682.c b/sound/soc/codecs/rt5682.c index 7c88370e2dee..a0abd2ce0c1e 100644 --- a/sound/soc/codecs/rt5682.c +++ b/sound/soc/codecs/rt5682.c @@ -2675,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, @@ -2689,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, @@ -2795,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; /* @@ -2813,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, @@ -2849,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, }, }; diff --git a/sound/soc/codecs/rt5682s.c b/sound/soc/codecs/rt5682s.c index 73c4b3c31f8c..80b921695e7d 100644 --- a/sound/soc/codecs/rt5682s.c +++ b/sound/soc/codecs/rt5682s.c @@ -2610,8 +2610,8 @@ static unsigned long rt5682s_wclk_recalc_rate(struct clk_hw *hw, return rt5682s->lrck[RT5682S_AIF1]; } -static long rt5682s_wclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int rt5682s_wclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct rt5682s_priv *rt5682s = container_of(hw, struct rt5682s_priv, dai_clks_hw[RT5682S_DAI_WCLK_IDX]); @@ -2624,13 +2624,13 @@ static long rt5682s_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(component->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 rt5682s_wclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -2719,14 +2719,14 @@ static unsigned long rt5682s_bclk_get_factor(unsigned long rate, return 256; } -static long rt5682s_bclk_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) +static int rt5682s_bclk_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) { struct rt5682s_priv *rt5682s = container_of(hw, struct rt5682s_priv, dai_clks_hw[RT5682S_DAI_BCLK_IDX]); unsigned long factor; - if (!*parent_rate || !rt5682s_clk_check(rt5682s)) + if (!req->best_parent_rate || !rt5682s_clk_check(rt5682s)) return -EINVAL; /* @@ -2736,9 +2736,11 @@ static long rt5682s_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 = rt5682s_bclk_get_factor(rate, *parent_rate); + factor = rt5682s_bclk_get_factor(req->rate, req->best_parent_rate); + + req->rate = req->best_parent_rate * factor; - return *parent_rate * factor; + return 0; } static int rt5682s_bclk_set_rate(struct clk_hw *hw, unsigned long rate, @@ -2769,12 +2771,12 @@ static const struct clk_ops rt5682s_dai_clk_ops[RT5682S_DAI_NUM_CLKS] = { .prepare = rt5682s_wclk_prepare, .unprepare = rt5682s_wclk_unprepare, .recalc_rate = rt5682s_wclk_recalc_rate, - .round_rate = rt5682s_wclk_round_rate, + .determine_rate = rt5682s_wclk_determine_rate, .set_rate = rt5682s_wclk_set_rate, }, [RT5682S_DAI_BCLK_IDX] = { .recalc_rate = rt5682s_bclk_recalc_rate, - .round_rate = rt5682s_bclk_round_rate, + .determine_rate = rt5682s_bclk_determine_rate, .set_rate = rt5682s_bclk_set_rate, }, }; diff --git a/sound/soc/codecs/rt700.c b/sound/soc/codecs/rt700.c index 434b926f96c8..816117c13aea 100644 --- a/sound/soc/codecs/rt700.c +++ b/sound/soc/codecs/rt700.c @@ -338,7 +338,6 @@ static int rt700_set_jack_detect(struct snd_soc_component *component, rt700_jack_init(rt700); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -862,7 +861,7 @@ static int rt700_set_bias_level(struct snd_soc_component *component, default: break; } - dapm->bias_level = level; + return 0; } @@ -1230,7 +1229,6 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt700->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt711-sdca.c b/sound/soc/codecs/rt711-sdca.c index dd6ccf17afd4..16c351779243 100644 --- a/sound/soc/codecs/rt711-sdca.c +++ b/sound/soc/codecs/rt711-sdca.c @@ -545,7 +545,6 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component, rt711_sdca_jack_init(rt711); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -1662,7 +1661,6 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt711->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt711.c b/sound/soc/codecs/rt711.c index 5446f9506a16..af3a49aee618 100644 --- a/sound/soc/codecs/rt711.c +++ b/sound/soc/codecs/rt711.c @@ -480,7 +480,6 @@ static int rt711_set_jack_detect(struct snd_soc_component *component, rt711_jack_init(rt711); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -1331,7 +1330,6 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt711->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt712-sdca-dmic.c b/sound/soc/codecs/rt712-sdca-dmic.c index 4d044dfa3136..42f8f7b8bed0 100644 --- a/sound/soc/codecs/rt712-sdca-dmic.c +++ b/sound/soc/codecs/rt712-sdca-dmic.c @@ -236,7 +236,6 @@ static int rt712_sdca_dmic_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt712->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt712-sdca.c b/sound/soc/codecs/rt712-sdca.c index 570c2af1245d..5b298db5f0f6 100644 --- a/sound/soc/codecs/rt712-sdca.c +++ b/sound/soc/codecs/rt712-sdca.c @@ -479,7 +479,6 @@ static int rt712_sdca_set_jack_detect(struct snd_soc_component *component, rt712_sdca_jack_init(rt712); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -1925,7 +1924,6 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave) dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); suspend: - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); return 0; diff --git a/sound/soc/codecs/rt715-sdca.c b/sound/soc/codecs/rt715-sdca.c index 7fb02654c16b..db7d43349d7d 100644 --- a/sound/soc/codecs/rt715-sdca.c +++ b/sound/soc/codecs/rt715-sdca.c @@ -1065,7 +1065,6 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt715->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); return 0; diff --git a/sound/soc/codecs/rt715.c b/sound/soc/codecs/rt715.c index 2cf461852091..7e1628a5c9d1 100644 --- a/sound/soc/codecs/rt715.c +++ b/sound/soc/codecs/rt715.c @@ -775,7 +775,7 @@ static int rt715_set_bias_level(struct snd_soc_component *component, default: break; } - dapm->bias_level = level; + return 0; } @@ -1129,7 +1129,6 @@ int rt715_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt715->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); return 0; diff --git a/sound/soc/codecs/rt721-sdca.c b/sound/soc/codecs/rt721-sdca.c index 1c9f32e405cf..f6f7c2ffde1c 100644 --- a/sound/soc/codecs/rt721-sdca.c +++ b/sound/soc/codecs/rt721-sdca.c @@ -327,7 +327,6 @@ static int rt721_sdca_set_jack_detect(struct snd_soc_component *component, rt721_sdca_jack_init(rt721); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -430,6 +429,7 @@ static int rt721_sdca_set_gain_get(struct snd_kcontrol *kcontrol, unsigned int read_l, read_r, ctl_l = 0, ctl_r = 0; unsigned int adc_vol_flag = 0; const unsigned int interval_offset = 0xc0; + const unsigned int tendA = 0x200; const unsigned int tendB = 0xa00; if (strstr(ucontrol->id.name, "FU1E Capture Volume") || @@ -439,9 +439,16 @@ static int rt721_sdca_set_gain_get(struct snd_kcontrol *kcontrol, regmap_read(rt721->mbq_regmap, mc->reg, &read_l); regmap_read(rt721->mbq_regmap, mc->rreg, &read_r); - if (mc->shift == 8) /* boost gain */ + if (mc->shift == 8) { + /* boost gain */ ctl_l = read_l / tendB; - else { + } else if (mc->shift == 1) { + /* FU33 boost gain */ + if (read_l == 0x8000 || read_l == 0xfe00) + ctl_l = 0; + else + ctl_l = read_l / tendA + 1; + } else { if (adc_vol_flag) ctl_l = mc->max - (((0x1e00 - read_l) & 0xffff) / interval_offset); else @@ -449,9 +456,16 @@ static int rt721_sdca_set_gain_get(struct snd_kcontrol *kcontrol, } if (read_l != read_r) { - if (mc->shift == 8) /* boost gain */ + if (mc->shift == 8) { + /* boost gain */ ctl_r = read_r / tendB; - else { /* ADC/DAC gain */ + } else if (mc->shift == 1) { + /* FU33 boost gain */ + if (read_r == 0x8000 || read_r == 0xfe00) + ctl_r = 0; + else + ctl_r = read_r / tendA + 1; + } else { /* ADC/DAC gain */ if (adc_vol_flag) ctl_r = mc->max - (((0x1e00 - read_r) & 0xffff) / interval_offset); else @@ -1533,7 +1547,6 @@ int rt721_sdca_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt721->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt722-sdca-sdw.c b/sound/soc/codecs/rt722-sdca-sdw.c index 609ca0d6c83a..70700bdb80a1 100644 --- a/sound/soc/codecs/rt722-sdca-sdw.c +++ b/sound/soc/codecs/rt722-sdca-sdw.c @@ -147,7 +147,7 @@ static int rt722_sdca_mbq_size(struct device *dev, unsigned int reg) } } -static struct regmap_sdw_mbq_cfg rt722_mbq_config = { +static const struct regmap_sdw_mbq_cfg rt722_mbq_config = { .mbq_size = rt722_sdca_mbq_size, }; diff --git a/sound/soc/codecs/rt722-sdca.c b/sound/soc/codecs/rt722-sdca.c index ac9588284a95..333611490ae3 100644 --- a/sound/soc/codecs/rt722-sdca.c +++ b/sound/soc/codecs/rt722-sdca.c @@ -339,7 +339,6 @@ static int rt722_sdca_set_jack_detect(struct snd_soc_component *component, rt722_sdca_jack_init(rt722); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -1559,7 +1558,6 @@ int rt722_sdca_io_init(struct device *dev, struct sdw_slave *slave) /* Mark Slave initialization complete */ rt722->hw_init = true; - pm_runtime_mark_last_busy(&slave->dev); pm_runtime_put_autosuspend(&slave->dev); dev_dbg(&slave->dev, "%s hw_init complete\n", __func__); diff --git a/sound/soc/codecs/rt9123.c b/sound/soc/codecs/rt9123.c index 242e8c975a62..b162824526d6 100644 --- a/sound/soc/codecs/rt9123.c +++ b/sound/soc/codecs/rt9123.c @@ -77,7 +77,6 @@ static int rt9123_enable_event(struct snd_soc_dapm_widget *w, struct snd_kcontro /* AMPON bit is located in volatile RG, use pm_runtime to guarantee the RG access */ snd_soc_component_write_field(comp, RT9123_REG_AMPCTRL, RT9123_MASK_AMPON, enable); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return 0; @@ -140,7 +139,6 @@ static int rt9123_xhandler_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ele if (ret < 0) dev_err(dev, "Failed to get control (%d)\n", ret); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return ret; } @@ -168,7 +166,6 @@ static int rt9123_xhandler_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele if (ret < 0) dev_err(dev, "Failed to put control (%d)\n", ret); - pm_runtime_mark_last_busy(dev); pm_runtime_put_autosuspend(dev); return ret; } diff --git a/sound/soc/codecs/rtq9124.c b/sound/soc/codecs/rtq9124.c new file mode 100644 index 000000000000..186904b31434 --- /dev/null +++ b/sound/soc/codecs/rtq9124.c @@ -0,0 +1,543 @@ +// SPDX-License-Identifier: GPL-2.0-only +// +// rtq9124.c -- RTQ9124 ALSA SoC Codec driver +// +// Author: ChiYuan Huang <cy_huang@richtek.com> + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/byteorder/generic.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/kernel.h> +#include <linux/mod_devicetable.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pm_runtime.h> +#include <linux/property.h> +#include <linux/regmap.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <sound/soc-dai.h> +#include <sound/soc-dapm.h> +#include <sound/tlv.h> + +#define RTQ9124_REG_SDI_SEL 0x00 +#define RTQ9124_REG_SDO_SEL 0x01 +#define RTQ9124_REG_I2S_OPT 0x02 +#define RTQ9124_REG_AMP_OPT 0x03 +#define RTQ9124_REG_STATE_CTRL 0x04 +#define RTQ9124_REG_PWM_PHASE 0x05 +#define RTQ9124_REG_SIL_CTRL 0x06 +#define RTQ9124_REG_PWM_SS_OPT 0x07 +#define RTQ9124_REG_ERR_INT_0 0x10 +#define RTQ9124_REG_ERR_MASK6 0x26 +#define RTQ9124_REG_TDM_TX_CH0 0x32 +#define RTQ9124_REG_TDM_RX_CH0 0x34 +#define RTQ9124_REG_VOL_OPT 0x38 +#define RTQ9124_REG_DCR_TH 0x4B +#define RTQ9124_REG_ERR_TH 0x4C +#define RTQ9124_REG_PROT_EN 0x5B +#define RTQ9124_REG_PRJ_CODE 0xF9 + +#define RTQ9124_MASK_CS_DATA_INV BIT(9) +#define RTQ9124_MASK_VDDIO_SDO_SEL BIT(8) +#define RTQ9124_MASK_AUD_BITS GENMASK(5, 4) +#define RTQ9124_MASK_AUD_FMT GENMASK(3, 0) +#define RTQ9124_MASK_CH_STATE GENMASK(1, 0) +#define RTQ9124_MASK_SF_RESET BIT(15) + +#define RTQ9124_FIXED_VENID 0x9124 + +struct rtq9124_priv { + struct gpio_desc *enable; + unsigned int dai_fmt; + int tdm_slots; + int tdm_slot_width; +}; + +static int rtq9124_enable_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); + unsigned int i, chan_state; + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Change state to normal */ + chan_state = 0; + break; + case SND_SOC_DAPM_POST_PMD: + /* Change state to HiZ */ + chan_state = 1; + break; + default: + return -EINVAL; + } + + /* Before amp turn on, clear old events first */ + for (i = 0; !chan_state && i < 8; i++) + snd_soc_component_write(comp, RTQ9124_REG_ERR_INT_0 + i, 0xffff); + + snd_soc_component_write_field(comp, RTQ9124_REG_STATE_CTRL, RTQ9124_MASK_CH_STATE, + chan_state); + + return 0; +} + +static const struct snd_soc_dapm_widget rtq9124_dapm_widgets[] = { + SND_SOC_DAPM_OUTPUT("SPK"), + SND_SOC_DAPM_OUT_DRV_E("Amp Drv", SND_SOC_NOPM, 0, 0, NULL, 0, rtq9124_enable_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), +}; + +static const struct snd_soc_dapm_route rtq9124_dapm_routes[] = { + { "Amp Drv", NULL, "HiFi Playback" }, + { "SPK", NULL, "Amp Drv" }, +}; + +static const DECLARE_TLV_DB_SCALE(dig_tlv, -10375, 25, 0); +static const DECLARE_TLV_DB_RANGE(ana_tlv, + 0, 3, TLV_DB_SCALE_ITEM(-600, 600, 0), + 4, 6, TLV_DB_SCALE_ITEM(1400, 200, 0)); +static const char * const i2sch_text[] = { "(L+R)/2", "LCH", "RCH", "(L+R)/2" }; +static const struct soc_enum rtq9124_i2sch_select_enum = + SOC_ENUM_SINGLE(RTQ9124_REG_SDI_SEL, 0, ARRAY_SIZE(i2sch_text), i2sch_text); +static const char * const sdo_vsel_text[] = { "1.8V", "3.3V" }; +static const struct soc_enum rtq9124_sdo_vselect_enum = + SOC_ENUM_SINGLE(RTQ9124_REG_SDO_SEL, 8, ARRAY_SIZE(sdo_vsel_text), sdo_vsel_text); +static const char * const pwmfreq_text[] = { "8*fs", "10*fs", "40*fs", "44*fs", "48*fs" }; +static const struct soc_enum rtq9124_pwm_freq_enum = + SOC_ENUM_SINGLE(RTQ9124_REG_AMP_OPT, 4, ARRAY_SIZE(pwmfreq_text), pwmfreq_text); +static const char * const out_angle_text[] = { "0", "45", "90", "135", "180", "225", "270", "315" }; +static const struct soc_enum rtq9124_out_angle_enum = + SOC_ENUM_SINGLE(RTQ9124_REG_PWM_PHASE, 0, ARRAY_SIZE(out_angle_text), out_angle_text); +static const char * const sdo_select_text[] = { + "None", "I2S DataI", "Interface", "DSP", "DF", "ISense", "ACLoad Cos", "ACLoad Sin", + "DCR", +}; +static const struct soc_enum rtq9124_sdo_select_enum = + SOC_ENUM_DOUBLE(RTQ9124_REG_SDO_SEL, 4, 0, ARRAY_SIZE(sdo_select_text), sdo_select_text); +static const char * const ulqm_dcvt_text[] = { "Disable", "DC", "VT", "DC+VT" }; +static const struct soc_enum rtq9124_ulqm_dcvt_select_enum = + SOC_ENUM_SINGLE(RTQ9124_REG_STATE_CTRL, 10, ARRAY_SIZE(ulqm_dcvt_text), ulqm_dcvt_text); + +static const struct snd_kcontrol_new rtq9124_controls[] = { + SOC_SINGLE_TLV("Master Volume", RTQ9124_REG_VOL_OPT, 2, 511, 1, dig_tlv), + SOC_SINGLE_TLV("Speaker Volume", RTQ9124_REG_AMP_OPT, 0, 6, 0, ana_tlv), + SOC_ENUM("I2S CH Select", rtq9124_i2sch_select_enum), + SOC_ENUM("SDO VDDIO Select", rtq9124_sdo_vselect_enum), + SOC_ENUM("PWM Frequency Select", rtq9124_pwm_freq_enum), + SOC_ENUM("PWM Output Phase Select", rtq9124_out_angle_enum), + SOC_ENUM("SDO Select", rtq9124_sdo_select_enum), + SOC_ENUM("ULQM DCVT Select", rtq9124_ulqm_dcvt_select_enum), + SOC_SINGLE("Silence Detect Enable Switch", RTQ9124_REG_SIL_CTRL, 7, 1, 0), + SOC_SINGLE("Spread Spectrum Enable Switch", RTQ9124_REG_PWM_SS_OPT, 7, 1, 0), +}; + +static int rtq9124_comp_probe(struct snd_soc_component *comp) +{ + /* CS Data INV */ + snd_soc_component_write_field(comp, RTQ9124_REG_SDO_SEL, RTQ9124_MASK_CS_DATA_INV, 1); + + /* RTLD */ + snd_soc_component_write(comp, RTQ9124_REG_DCR_TH, 0x5e30); + snd_soc_component_write(comp, RTQ9124_REG_ERR_TH, 0x3ff); + snd_soc_component_write(comp, RTQ9124_REG_PROT_EN, 0x3fc); + snd_soc_component_write(comp, RTQ9124_REG_ERR_MASK6, 0); + + return 0; +} + +static const struct snd_soc_component_driver rtq9124_comp_driver = { + .probe = rtq9124_comp_probe, + .controls = rtq9124_controls, + .num_controls = ARRAY_SIZE(rtq9124_controls), + .dapm_widgets = rtq9124_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(rtq9124_dapm_widgets), + .dapm_routes = rtq9124_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(rtq9124_dapm_routes), + .use_pmdown_time = 1, + .endianness = 1, +}; + +static int rtq9124_dai_set_format(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct rtq9124_priv *rtq9124 = snd_soc_dai_get_drvdata(dai); + + rtq9124->dai_fmt = fmt; + return 0; +} + +static int rtq9124_dai_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, + unsigned int rx_mask, int slots, int slot_width) +{ + struct rtq9124_priv *rtq9124 = snd_soc_dai_get_drvdata(dai); + struct snd_soc_component *comp = dai->component; + struct device *dev = dai->dev; + unsigned int byte_loc, i; + + dev_dbg(dev, "(slots, slot_width) = (%d, %d), (txmask, rxmask) = 0x%x, 0x%x\n", slots, + slot_width, tx_mask, rx_mask); + + if (slots <= 0 || slots > 16 || slot_width <= 0 || slots % 2 || slot_width % 8) { + dev_err(dev, "Invalid slot parameter (%d, %d)\n", slots, slot_width); + return -EINVAL; + } + + if (tx_mask && (hweight_long(tx_mask) > 2 || fls(tx_mask) > slots)) { + dev_err(dev, "Invalid tx_mask 0x%08x, slots = %d\n", tx_mask, slots); + return -EINVAL; + } + + if (!rx_mask || hweight_long(rx_mask) > 1 || fls(rx_mask) > slots) { + dev_err(dev, "Invalid rx_mask 0x%08x, slots = %d\n", rx_mask, slots); + return -EINVAL; + } + + /* Configure tx channel data location */ + for (i = 0; tx_mask; i++, tx_mask ^= BIT(ffs(tx_mask) - 1)) { + byte_loc = (ffs(tx_mask) - 1) * slot_width / 8; + snd_soc_component_write(comp, RTQ9124_REG_TDM_TX_CH0 + i, byte_loc); + } + + /* Configure rx channel data location */ + byte_loc = (ffs(rx_mask) - 1) * slot_width / 8; + snd_soc_component_write(comp, RTQ9124_REG_TDM_RX_CH0, byte_loc); + + rtq9124->tdm_slots = slots; + rtq9124->tdm_slot_width = slot_width; + + return 0; +} + +static int rtq9124_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *param, struct snd_soc_dai *dai) +{ + struct rtq9124_priv *rtq9124 = snd_soc_dai_get_drvdata(dai); + struct snd_soc_component *comp = dai->component; + unsigned int fmtval, width, slot_width, bitrate; + struct device *dev = dai->dev; + unsigned int audfmt, audbit; + + fmtval = FIELD_GET(SND_SOC_DAIFMT_FORMAT_MASK, rtq9124->dai_fmt); + if (rtq9124->tdm_slots && fmtval != SND_SOC_DAIFMT_DSP_A && + fmtval != SND_SOC_DAIFMT_DSP_B) { + dev_err(dev, "TDM only can support DSP_A or DSP_B format\n"); + return -EINVAL; + } + + switch (fmtval) { + case SND_SOC_DAIFMT_I2S: + audfmt = 0; + break; + case SND_SOC_DAIFMT_LEFT_J: + audfmt = 1; + break; + case SND_SOC_DAIFMT_RIGHT_J: + audfmt = 2; + break; + case SND_SOC_DAIFMT_DSP_B: + audfmt = rtq9124->tdm_slots ? 7 : 3; + break; + case SND_SOC_DAIFMT_DSP_A: + audfmt = rtq9124->tdm_slots ? 15 : 11; + break; + default: + dev_err(dev, "Unsupported format %d\n", fmtval); + return -EINVAL; + } + + switch (width = params_width(param)) { + case 16: + audbit = 0; + break; + case 20: + audbit = 1; + break; + case 24: + case 32: + audbit = 3; + break; + default: + dev_err(dev, "Unsupported width %d\n", width); + return -EINVAL; + } + + if (rtq9124->tdm_slots) { + slot_width = params_physical_width(param); + if (slot_width > rtq9124->tdm_slot_width) { + dev_err(dev, "Slot width is larger than TDM slot width\n"); + return -EINVAL; + } + + bitrate = rtq9124->tdm_slots * rtq9124->tdm_slot_width * params_rate(param); + if (bitrate > 24576000) { + dev_err(dev, "Bitrate exceed the internal PLL 24.576MHz (%d)\n", bitrate); + return -EINVAL; + } + } + + snd_soc_component_write_field(comp, RTQ9124_REG_I2S_OPT, RTQ9124_MASK_AUD_FMT, audfmt); + snd_soc_component_write_field(comp, RTQ9124_REG_I2S_OPT, RTQ9124_MASK_AUD_BITS, audbit); + + return 0; +} + +static const struct snd_soc_dai_ops rtq9124_dai_ops = { + .set_fmt = rtq9124_dai_set_format, + .set_tdm_slot = rtq9124_dai_set_tdm_slot, + .hw_params = rtq9124_dai_hw_params, +}; + +static struct snd_soc_dai_driver rtq9124_dai_driver = { + .name = "HiFi", + .playback = { + .stream_name = "HiFi Playback", + .formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_24000 | + SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .rate_min = 8000, + .rate_max = 192000, + .channels_min = 1, + .channels_max = 2, + }, + .ops = &rtq9124_dai_ops, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, +}; + +static bool rtq9124_readable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0x00 ... 0x17: + case 0x20 ... 0x27: + case 0x30 ... 0x3D: + case 0x40 ... 0x68: + case 0x80 ... 0xBC: + case 0xC0 ... 0xDE: + case 0xE0 ... 0xE7: + case 0xF0 ... 0xFD: + return true; + default: + return false; + } +} + +static bool rtq9124_writeable_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0x00 ... 0x09: + case 0x0C ... 0x0E: + case 0x10 ... 0x17: + case 0x20 ... 0x27: + case 0x30: + case 0x32 ... 0x3D: + case 0x40 ... 0x4E: + case 0x50 ... 0x68: + case 0x80 ... 0xBC: + case 0xC0 ... 0xDE: + case 0xE0 ... 0xE7: + case 0xF0 ... 0xFD: + return true; + default: + return false; + } +} + +static bool rtq9124_volatile_reg(struct device *dev, unsigned int reg) +{ + switch (reg) { + case 0x0A ... 0x0B: + case 0x0F ... 0x17: + case 0x31: + case 0x4F: + case 0x51: + case 0x53 ... 0x57: + case 0x80 ... 0xBC: + case 0xC0 ... 0xDE: + case 0xE0 ... 0xE7: + case 0xF0 ... 0xFD: + return true; + default: + return false; + } +} + +static inline u8 rtq9124_get_reg_len(unsigned int reg) +{ + return (reg >= 0x40 && reg <= 0x47) ? 4 : 2; +} + +static int rtq9124_regmap_read(void *context, const void *reg_buf, size_t reg_size, void *val_buf, + size_t val_size) +{ + struct i2c_client *i2c = context; + u8 reg = *(u8 *)reg_buf; + u8 size = rtq9124_get_reg_len(reg); + u32 *val = val_buf; + int ret; + + ret = i2c_smbus_read_i2c_block_data(i2c, reg, size, val_buf); + if (ret < 0) + return ret; + else if (ret != size) + return -EIO; + + *val = size == 4 ? be32_to_cpup(val_buf) : be16_to_cpup(val_buf); + + return 0; +} + +static int rtq9124_regmap_write(void *context, const void *data, size_t count) +{ + struct i2c_client *i2c = context; + u8 reg = *(u8 *)data, *vbuf; + u8 size = rtq9124_get_reg_len(reg); + __be16 val16 = cpu_to_be16p(data + 1); + __be32 val32 = cpu_to_be32p(data + 1); + + vbuf = size == 4 ? (u8 *)&val32 : (u8 *)&val16; + return i2c_smbus_write_i2c_block_data(i2c, reg, size, vbuf); +} + +static const struct regmap_config rtq9124_regmap_config = { + .name = "rtq9124", + .reg_bits = 8, + .val_bits = 32, + .read = rtq9124_regmap_read, + .write = rtq9124_regmap_write, + .readable_reg = rtq9124_readable_reg, + .writeable_reg = rtq9124_writeable_reg, + .volatile_reg = rtq9124_volatile_reg, + .cache_type = REGCACHE_MAPLE, + .num_reg_defaults_raw = 0xFD + 1, + .use_single_read = 1, + .use_single_write = 1, +}; + +static const struct reg_sequence rtq9124_init_regs[] = { + { 0xfb, 0x0065 }, + { 0x93, 0x2000 }, + { 0xfb, 0x0000 }, +}; + +static int rtq9124_probe(struct i2c_client *i2c) +{ + struct device *dev = &i2c->dev; + struct rtq9124_priv *rtq9124; + struct regmap *regmap; + int ret; + + rtq9124 = devm_kzalloc(dev, sizeof(*rtq9124), GFP_KERNEL); + if (!rtq9124) + return -ENOMEM; + + rtq9124->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(rtq9124->enable)) + return PTR_ERR(rtq9124->enable); + else if (rtq9124->enable) + usleep_range(6000, 7000); + else + dev_dbg(dev, "No 'enable' GPIO specified, treat it as default on\n"); + + /* Check vendor id information */ + ret = i2c_smbus_read_word_swapped(i2c, RTQ9124_REG_PRJ_CODE); + if (ret < 0) + return dev_err_probe(dev, ret, "Failed to read project code\n"); + else if (ret != RTQ9124_FIXED_VENID) + return dev_err_probe(dev, -ENODEV, "Incorrect project-code 0x%04x\n", ret); + + /* Trigger RG reset before regmap init */ + ret = i2c_smbus_write_word_swapped(i2c, RTQ9124_REG_STATE_CTRL, RTQ9124_MASK_SF_RESET); + if (ret) + return dev_err_probe(dev, ret, "Failed to trigger RG reset\n"); + + /* Need to wait 10ms for the reset to complete */ + usleep_range(10000, 11000); + + regmap = devm_regmap_init(dev, NULL, i2c, &rtq9124_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to init regmap\n"); + + ret = regmap_register_patch(regmap, rtq9124_init_regs, ARRAY_SIZE(rtq9124_init_regs)); + if (ret) + return dev_err_probe(dev, ret, "Failed to register regmap patch\n"); + + i2c_set_clientdata(i2c, rtq9124); + + pm_runtime_set_autosuspend_delay(dev, 1000); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + ret = devm_pm_runtime_enable(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable pm runtime\n"); + + return devm_snd_soc_register_component(dev, &rtq9124_comp_driver, &rtq9124_dai_driver, 1); +} + +#ifdef CONFIG_PM +static int rtq9124_runtime_suspend(struct device *dev) +{ + struct rtq9124_priv *rtq9124 = dev_get_drvdata(dev); + struct regmap *regmap = dev_get_regmap(dev, NULL); + + if (rtq9124->enable) { + regcache_cache_only(regmap, true); + regcache_mark_dirty(regmap); + gpiod_set_value(rtq9124->enable, 0); + } + + return 0; +} + +static int rtq9124_runtime_resume(struct device *dev) +{ + struct rtq9124_priv *rtq9124 = dev_get_drvdata(dev); + struct regmap *regmap = dev_get_regmap(dev, NULL); + int ret; + + if (rtq9124->enable) { + gpiod_set_value(rtq9124->enable, 1); + usleep_range(6000, 7000); + + regcache_cache_only(regmap, false); + ret = regcache_sync(regmap); + if (ret) + return ret; + } + + return 0; +} +#endif + +static const struct dev_pm_ops rtq9124_dev_pm_ops = { + SET_RUNTIME_PM_OPS(rtq9124_runtime_suspend, rtq9124_runtime_resume, NULL) +}; + +#ifdef CONFIG_OF +static const struct of_device_id rtq9124_device_id[] = { + { .compatible = "richtek,rtq9124" }, + {} +}; +MODULE_DEVICE_TABLE(of, rtq9124_device_id); +#endif + +static struct i2c_driver rtq9124_driver = { + .driver = { + .name = "rtq9124", + .of_match_table = of_match_ptr(rtq9124_device_id), + .pm = pm_ptr(&rtq9124_dev_pm_ops), + }, + .probe = rtq9124_probe, +}; +module_i2c_driver(rtq9124_driver); + +MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>"); +MODULE_DESCRIPTION("ASoC RTQ9124 Driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tas2552.c b/sound/soc/codecs/tas2552.c index b56dd279d90a..43449d7c2584 100644 --- a/sound/soc/codecs/tas2552.c +++ b/sound/soc/codecs/tas2552.c @@ -724,7 +724,6 @@ static int tas2552_probe(struct i2c_client *client) pm_runtime_set_autosuspend_delay(&client->dev, 1000); pm_runtime_use_autosuspend(&client->dev); pm_runtime_enable(&client->dev); - pm_runtime_mark_last_busy(&client->dev); pm_runtime_put_sync_autosuspend(&client->dev); dev_set_drvdata(&client->dev, data); diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c index c40d8f754d89..9f4d965a1335 100644 --- a/sound/soc/codecs/tas2781-i2c.c +++ b/sound/soc/codecs/tas2781-i2c.c @@ -14,9 +14,6 @@ // #include <linux/crc8.h> -#ifdef CONFIG_SND_SOC_TAS2781_ACOUST_I2C -#include <linux/debugfs.h> -#endif #include <linux/firmware.h> #include <linux/gpio/consumer.h> #include <linux/i2c.h> diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c index 6bf37c77f0a7..41d73f470f8b 100644 --- a/sound/soc/codecs/tas571x.c +++ b/sound/soc/codecs/tas571x.c @@ -839,6 +839,56 @@ static const struct tas571x_chip tas5733_chip = { .vol_reg_size = 2, }; +static const struct reg_default tas5753_reg_defaults[] = { + {TAS571X_CLK_CTRL_REG, 0x6c}, + {TAS571X_DEV_ID_REG, 0x41}, + {TAS571X_ERR_STATUS_REG, 0x00}, + {TAS571X_SYS_CTRL_1_REG, 0xa0}, + {TAS571X_SDI_REG, 0x05}, + {TAS571X_SYS_CTRL_2_REG, 0x40}, + {TAS571X_SOFT_MUTE_REG, 0x00}, + {TAS571X_MVOL_REG, 0x03ff}, + {TAS571X_CH1_VOL_REG, 0x00c0}, + {TAS571X_CH2_VOL_REG, 0x00c0}, + {TAS571X_CH3_VOL_REG, 0x00c0}, + {TAS571X_VOL_CFG_REG, 0xf0}, + {TAS571X_MODULATION_LIMIT_REG, 0x01}, + {TAS571X_IC_DELAY_CH1_REG, 0xac}, + {TAS571X_IC_DELAY_CH2_REG, 0x54}, + {TAS571X_IC_DELAY_CH3_REG, 0xac}, + {TAS571X_IC_DELAY_CH4_REG, 0x54}, + {TAS571X_OSC_TRIM_REG, 0x82}, + {TAS571X_BKND_ERR_REG, 0x57}, + {TAS571X_INPUT_MUX_REG, 0x00017772}, + {TAS571X_PWM_MUX_REG, 0x01021345}, + {TAS5717_CH1_RIGHT_CH_MIX_REG, 0x00}, + {TAS5717_CH1_LEFT_CH_MIX_REG, 0x800000}, + {TAS5717_CH2_LEFT_CH_MIX_REG, 0x00}, + {TAS5717_CH2_RIGHT_CH_MIX_REG, 0x800000}, +}; + +static const struct regmap_config tas5753_regmap_config = { + .reg_bits = 8, + .val_bits = 32, + .max_register = 0xff, + .reg_read = tas571x_reg_read, + .reg_write = tas571x_reg_write, + .reg_defaults = tas5753_reg_defaults, + .num_reg_defaults = ARRAY_SIZE(tas5753_reg_defaults), + .cache_type = REGCACHE_RBTREE, + .wr_table = &tas571x_write_regs, + .volatile_table = &tas571x_volatile_regs, +}; + +static const struct tas571x_chip tas5753_chip = { + .supply_names = tas5721_supply_names, + .num_supply_names = ARRAY_SIZE(tas5721_supply_names), + .controls = tas5733_controls, + .num_controls = ARRAY_SIZE(tas5733_controls), + .regmap_config = &tas5753_regmap_config, + .vol_reg_size = 2, +}; + static const struct tas571x_chip tas5721_chip = { .supply_names = tas5721_supply_names, .num_supply_names = ARRAY_SIZE(tas5721_supply_names), @@ -1007,6 +1057,7 @@ static const struct of_device_id tas571x_of_match[] __maybe_unused = { { .compatible = "ti,tas5719", .data = &tas5717_chip, }, { .compatible = "ti,tas5721", .data = &tas5721_chip, }, { .compatible = "ti,tas5733", .data = &tas5733_chip, }, + { .compatible = "ti,tas5753", .data = &tas5753_chip, }, { } }; MODULE_DEVICE_TABLE(of, tas571x_of_match); @@ -1018,6 +1069,7 @@ static const struct i2c_device_id tas571x_i2c_id[] = { { "tas5719", (kernel_ulong_t) &tas5717_chip }, { "tas5721", (kernel_ulong_t) &tas5721_chip }, { "tas5733", (kernel_ulong_t) &tas5733_chip }, + { "tas5753", (kernel_ulong_t) &tas5753_chip }, { } }; MODULE_DEVICE_TABLE(i2c, tas571x_i2c_id); diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index 54ea4bc58c27..7399080f8580 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c @@ -9,27 +9,26 @@ * Based on sound/soc/codecs/wm8974 and TI driver for kernel 2.6.27. */ -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/pm.h> -#include <linux/gpio.h> -#include <linux/of_gpio.h> #include <linux/cdev.h> -#include <linux/slab.h> #include <linux/clk.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/of_clk.h> +#include <linux/pm.h> #include <linux/regulator/consumer.h> +#include <linux/slab.h> -#include <sound/tlv320aic32x4.h> #include <sound/core.h> +#include <sound/initval.h> #include <sound/pcm.h> #include <sound/pcm_params.h> #include <sound/soc.h> #include <sound/soc-dapm.h> -#include <sound/initval.h> #include <sound/tlv.h> +#include <sound/tlv320aic32x4.h> #include "tlv320aic32x4.h" @@ -38,7 +37,7 @@ struct aic32x4_priv { u32 power_cfg; u32 micpga_routing; bool swapdacs; - int rstn_gpio; + struct gpio_desc *rstn_gpio; const char *mclk_name; struct regulator *supply_ldo; @@ -1236,7 +1235,14 @@ static int aic32x4_parse_dt(struct aic32x4_priv *aic32x4, aic32x4->swapdacs = false; aic32x4->micpga_routing = 0; - aic32x4->rstn_gpio = of_get_named_gpio(np, "reset-gpios", 0); + /* Assert reset using GPIOD_OUT_HIGH, because reset is GPIO_ACTIVE_LOW */ + aic32x4->rstn_gpio = devm_gpiod_get_optional(aic32x4->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(aic32x4->rstn_gpio)) { + return dev_err_probe(aic32x4->dev, PTR_ERR(aic32x4->rstn_gpio), + "Failed to get reset gpio\n"); + } else { + gpiod_set_consumer_name(aic32x4->rstn_gpio, "tlv320aic32x4_rstn"); + } if (of_property_read_u32_array(np, "aic32x4-gpio-func", aic32x4_setup->gpio_func, 5) >= 0) @@ -1346,7 +1352,6 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap, enum aic32x4_type type) { struct aic32x4_priv *aic32x4; - struct aic32x4_pdata *pdata = dev->platform_data; struct device_node *np = dev->of_node; int ret; @@ -1363,13 +1368,7 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap, dev_set_drvdata(dev, aic32x4); - if (pdata) { - aic32x4->power_cfg = pdata->power_cfg; - aic32x4->swapdacs = pdata->swapdacs; - aic32x4->micpga_routing = pdata->micpga_routing; - aic32x4->rstn_gpio = pdata->rstn_gpio; - aic32x4->mclk_name = "mclk"; - } else if (np) { + if (np) { ret = aic32x4_parse_dt(aic32x4, np); if (ret) { dev_err(dev, "Failed to parse DT node\n"); @@ -1379,26 +1378,20 @@ int aic32x4_probe(struct device *dev, struct regmap *regmap, aic32x4->power_cfg = 0; aic32x4->swapdacs = false; aic32x4->micpga_routing = 0; - aic32x4->rstn_gpio = -1; + aic32x4->rstn_gpio = NULL; aic32x4->mclk_name = "mclk"; } - if (gpio_is_valid(aic32x4->rstn_gpio)) { - ret = devm_gpio_request_one(dev, aic32x4->rstn_gpio, - GPIOF_OUT_INIT_LOW, "tlv320aic32x4 rstn"); - if (ret != 0) - return ret; - } - ret = aic32x4_setup_regulators(dev, aic32x4); if (ret) { dev_err(dev, "Failed to setup regulators\n"); return ret; } - if (gpio_is_valid(aic32x4->rstn_gpio)) { + if (aic32x4->rstn_gpio) { ndelay(10); - gpio_set_value_cansleep(aic32x4->rstn_gpio, 1); + /* deassert reset */ + gpiod_set_value_cansleep(aic32x4->rstn_gpio, 0); mdelay(1); } diff --git a/sound/soc/codecs/wcd-mbhc-v2.c b/sound/soc/codecs/wcd-mbhc-v2.c index 4b7c3d6080a1..26ebcdadeb7d 100644 --- a/sound/soc/codecs/wcd-mbhc-v2.c +++ b/sound/soc/codecs/wcd-mbhc-v2.c @@ -825,7 +825,6 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc) mutex_unlock(&mbhc->lock); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); return 0; @@ -1319,7 +1318,6 @@ exit: if (mbhc->mbhc_cb->hph_pull_down_ctrl) mbhc->mbhc_cb->hph_pull_down_ctrl(component, true); - pm_runtime_mark_last_busy(component->dev); pm_runtime_put_autosuspend(component->dev); } diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 5e19e813748d..1c050b8c19de 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -312,7 +312,6 @@ struct wcd9335_codec { u32 num_rx_port; u32 num_tx_port; - int sido_input_src; enum wcd9335_sido_voltage sido_voltage; struct wcd_slim_codec_dai_data dai[NUM_CODEC_DAIS]; @@ -4725,8 +4724,6 @@ static const struct snd_soc_dapm_widget wcd9335_dapm_widgets[] = { static void wcd9335_enable_sido_buck(struct snd_soc_component *component) { - struct wcd9335_codec *wcd = dev_get_drvdata(component->dev); - snd_soc_component_update_bits(component, WCD9335_ANA_RCO, WCD9335_ANA_RCO_BG_EN_MASK, WCD9335_ANA_RCO_BG_ENABLE); @@ -4740,7 +4737,6 @@ static void wcd9335_enable_sido_buck(struct snd_soc_component *component) WCD9335_ANA_BUCK_CTL_VOUT_D_VREF_EXT); /* 100us sleep needed after VREF settings */ usleep_range(100, 110); - wcd->sido_input_src = SIDO_SOURCE_RCO_BG; } static int wcd9335_enable_efuse_sensing(struct snd_soc_component *comp) @@ -4871,7 +4867,6 @@ static int wcd9335_probe(struct wcd9335_codec *wcd) memcpy(wcd->rx_chs, wcd9335_rx_chs, sizeof(wcd9335_rx_chs)); memcpy(wcd->tx_chs, wcd9335_tx_chs, sizeof(wcd9335_tx_chs)); - wcd->sido_input_src = SIDO_SOURCE_INTERNAL; wcd->sido_voltage = SIDO_VOLTAGE_NOMINAL_MV; return devm_snd_soc_register_component(dev, &wcd9335_component_drv, diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index fa69817c97ea..1bb7e1dc7e6b 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -537,8 +537,6 @@ struct wcd934x_codec { int rate; u32 version; u32 hph_mode; - int num_rx_port; - int num_tx_port; u32 tx_port_value[WCD934X_TX_MAX]; u32 rx_port_value[WCD934X_RX_MAX]; int sido_input_src; @@ -1928,13 +1926,11 @@ static int wcd934x_set_channel_map(struct snd_soc_dai *dai, return -EINVAL; } - wcd->num_rx_port = rx_num; for (i = 0; i < rx_num; i++) { wcd->rx_chs[i].ch_num = rx_slot[i]; INIT_LIST_HEAD(&wcd->rx_chs[i].list); } - wcd->num_tx_port = tx_num; for (i = 0; i < tx_num; i++) { wcd->tx_chs[i].ch_num = tx_slot[i]; INIT_LIST_HEAD(&wcd->tx_chs[i].list); diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c index b9df58b86ce9..3b0a8cc314e0 100644 --- a/sound/soc/codecs/wcd937x.c +++ b/sound/soc/codecs/wcd937x.c @@ -24,10 +24,8 @@ #include "wcd-mbhc-v2.h" #include "wcd937x.h" -enum { - CHIPID_WCD9370 = 0, - CHIPID_WCD9375 = 5, -}; +#define CHIPID_WCD9370 0x0 +#define CHIPID_WCD9375 0x5 /* Z value defined in milliohm */ #define WCD937X_ZDET_VAL_32 (32000) @@ -88,9 +86,7 @@ struct wcd937x_priv { struct wcd_mbhc_intr intr_ids; struct wcd_clsh_ctrl *clsh_info; struct irq_domain *virq; - struct regmap_irq_chip *wcd_regmap_irq_chip; struct regmap_irq_chip_data *irq_chip; - struct regulator_bulk_data supplies[WCD937X_MAX_BULK_SUPPLY]; struct snd_soc_jack *jack; unsigned long status_mask; s32 micb_ref[WCD937X_MAX_MICBIAS]; @@ -113,6 +109,10 @@ struct wcd937x_priv { atomic_t ana_clk_count; }; +static const char * const wcd937x_supplies[] = { + "vdd-rxtx", "vdd-px", "vdd-mic-bias", "vdd-buck", +}; + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); @@ -2934,18 +2934,10 @@ static int wcd937x_probe(struct platform_device *pdev) cfg = &wcd937x->mbhc_cfg; cfg->swap_gnd_mic = wcd937x_swap_gnd_mic; - wcd937x->supplies[0].supply = "vdd-rxtx"; - wcd937x->supplies[1].supply = "vdd-px"; - wcd937x->supplies[2].supply = "vdd-mic-bias"; - wcd937x->supplies[3].supply = "vdd-buck"; - - ret = devm_regulator_bulk_get(dev, WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies); - if (ret) - return dev_err_probe(dev, ret, "Failed to get supplies\n"); - - ret = regulator_bulk_enable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd937x_supplies), + wcd937x_supplies); if (ret) - return dev_err_probe(dev, ret, "Failed to enable supplies\n"); + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); wcd937x_dt_parse_micbias_info(dev, wcd937x); @@ -2962,13 +2954,13 @@ static int wcd937x_probe(struct platform_device *pdev) ret = wcd937x_add_slave_components(wcd937x, dev, &match); if (ret) - goto err_disable_regulators; + return ret; wcd937x_reset(wcd937x); ret = component_master_add_with_match(dev, &wcd937x_comp_ops, match); if (ret) - goto err_disable_regulators; + return ret; pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_use_autosuspend(dev); @@ -2978,25 +2970,17 @@ static int wcd937x_probe(struct platform_device *pdev) pm_runtime_idle(dev); return 0; - -err_disable_regulators: - regulator_bulk_disable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies); - - return ret; } static void wcd937x_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct wcd937x_priv *wcd937x = dev_get_drvdata(dev); component_master_del(&pdev->dev, &wcd937x_comp_ops); pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_dont_use_autosuspend(dev); - - regulator_bulk_disable(WCD937X_MAX_BULK_SUPPLY, wcd937x->supplies); } #if defined(CONFIG_OF) diff --git a/sound/soc/codecs/wcd937x.h b/sound/soc/codecs/wcd937x.h index 4ef57c496c37..3ab21bb5846e 100644 --- a/sound/soc/codecs/wcd937x.h +++ b/sound/soc/codecs/wcd937x.h @@ -487,7 +487,6 @@ #define WCD937X_MAX_REGISTER (WCD937X_DIGITAL_EFUSE_REG_31) #define WCD937X_MAX_MICBIAS 3 -#define WCD937X_MAX_BULK_SUPPLY 4 #define WCD937X_MAX_SWR_CH_IDS 15 #define WCD937X_SWRM_CH_MASK(ch_idx) BIT(ch_idx - 1) diff --git a/sound/soc/codecs/wcd938x.c b/sound/soc/codecs/wcd938x.c index d9b61eab029a..711f373ece24 100644 --- a/sound/soc/codecs/wcd938x.c +++ b/sound/soc/codecs/wcd938x.c @@ -25,8 +25,10 @@ #include "wcd-mbhc-v2.h" #include "wcd938x.h" +#define CHIPID_WCD9380 0x0 +#define CHIPID_WCD9385 0x5 + #define WCD938X_MAX_MICBIAS (4) -#define WCD938X_MAX_SUPPLY (4) #define WCD938X_MBHC_MAX_BUTTONS (8) #define TX_ADC_MAX (4) @@ -74,11 +76,6 @@ wcd938x_ear_pa_put_gain, tlv_array) enum { - WCD9380 = 0, - WCD9385 = 5, -}; - -enum { /* INTR_CTRL_INT_MASK_0 */ WCD938X_IRQ_MBHC_BUTTON_PRESS_DET = 0, WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET, @@ -159,9 +156,7 @@ struct wcd938x_priv { struct wcd_mbhc_intr intr_ids; struct wcd_clsh_ctrl *clsh_info; struct irq_domain *virq; - struct regmap_irq_chip *wcd_regmap_irq_chip; struct regmap_irq_chip_data *irq_chip; - struct regulator_bulk_data supplies[WCD938X_MAX_SUPPLY]; struct snd_soc_jack *jack; unsigned long status_mask; s32 micb_ref[WCD938X_MAX_MICBIAS]; @@ -170,7 +165,6 @@ struct wcd938x_priv { u32 tx_mode[TX_ADC_MAX]; int flyback_cur_det_disable; int ear_rx_path; - int variant; struct gpio_desc *reset_gpio; struct gpio_desc *us_euro_gpio; struct mux_control *us_euro_mux; @@ -188,6 +182,10 @@ struct wcd938x_priv { bool mux_setup_done; }; +static const char * const wcd938x_supplies[] = { + "vdd-rxtx", "vdd-io", "vdd-buck", "vdd-mic-bias", +}; + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); static const DECLARE_TLV_DB_SCALE(line_gain, -3000, 150, 0); static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(analog_gain, 0, 3000); @@ -275,7 +273,7 @@ static const struct regmap_irq wcd938x_irqs[WCD938X_NUM_IRQS] = { REGMAP_IRQ_REG(WCD938X_IRQ_HPHR_SURGE_DET_INT, 2, 0x08), }; -static struct regmap_irq_chip wcd938x_regmap_irq_chip = { +static const struct regmap_irq_chip wcd938x_regmap_irq_chip = { .name = "wcd938x", .irqs = wcd938x_irqs, .num_irqs = ARRAY_SIZE(wcd938x_irqs), @@ -3046,6 +3044,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) struct sdw_slave *tx_sdw_dev = wcd938x->tx_sdw_dev; struct device *dev = component->dev; unsigned long time_left; + unsigned int variant; int ret, i; time_left = wait_for_completion_timeout(&tx_sdw_dev->initialization_complete, @@ -3061,9 +3060,9 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) if (ret < 0) return ret; - wcd938x->variant = snd_soc_component_read_field(component, - WCD938X_DIGITAL_EFUSE_REG_0, - WCD938X_ID_MASK); + variant = snd_soc_component_read_field(component, + WCD938X_DIGITAL_EFUSE_REG_0, + WCD938X_ID_MASK); wcd938x->clsh_info = wcd_clsh_ctrl_alloc(component, WCD938X); if (IS_ERR(wcd938x->clsh_info)) { @@ -3117,24 +3116,24 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) disable_irq_nosync(wcd938x->hphl_pdm_wd_int); disable_irq_nosync(wcd938x->aux_pdm_wd_int); - switch (wcd938x->variant) { - case WCD9380: + switch (variant) { + case CHIPID_WCD9380: ret = snd_soc_add_component_controls(component, wcd9380_snd_controls, ARRAY_SIZE(wcd9380_snd_controls)); if (ret < 0) { dev_err(component->dev, "%s: Failed to add snd ctrls for variant: %d\n", - __func__, wcd938x->variant); + __func__, variant); goto err_free_aux_pdm_wd_int; } break; - case WCD9385: + case CHIPID_WCD9385: ret = snd_soc_add_component_controls(component, wcd9385_snd_controls, ARRAY_SIZE(wcd9385_snd_controls)); if (ret < 0) { dev_err(component->dev, "%s: Failed to add snd ctrls for variant: %d\n", - __func__, wcd938x->variant); + __func__, variant); goto err_free_aux_pdm_wd_int; } break; @@ -3292,20 +3291,10 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device cfg->swap_gnd_mic = wcd938x_swap_gnd_mic; - wcd938x->supplies[0].supply = "vdd-rxtx"; - wcd938x->supplies[1].supply = "vdd-io"; - wcd938x->supplies[2].supply = "vdd-buck"; - wcd938x->supplies[3].supply = "vdd-mic-bias"; - - ret = regulator_bulk_get(dev, WCD938X_MAX_SUPPLY, wcd938x->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd938x_supplies), + wcd938x_supplies); if (ret) - return dev_err_probe(dev, ret, "Failed to get supplies\n"); - - ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - if (ret) { - regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); - return dev_err_probe(dev, ret, "Failed to enable supplies\n"); - } + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); wcd938x_dt_parse_micbias_info(dev, wcd938x); @@ -3569,13 +3558,13 @@ static int wcd938x_probe(struct platform_device *pdev) ret = wcd938x_add_slave_components(wcd938x, dev, &match); if (ret) - goto err_disable_regulators; + return ret; wcd938x_reset(wcd938x); ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match); if (ret) - goto err_disable_regulators; + return ret; pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_use_autosuspend(dev); @@ -3585,12 +3574,6 @@ static int wcd938x_probe(struct platform_device *pdev) pm_runtime_idle(dev); return 0; - -err_disable_regulators: - regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); - - return ret; } static void wcd938x_remove(struct platform_device *pdev) @@ -3606,9 +3589,6 @@ static void wcd938x_remove(struct platform_device *pdev) if (wcd938x->us_euro_mux && wcd938x->mux_setup_done) mux_control_deselect(wcd938x->us_euro_mux); - - regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies); - regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies); } #if defined(CONFIG_OF) diff --git a/sound/soc/codecs/wcd939x.c b/sound/soc/codecs/wcd939x.c index 067d23c7ecf9..64f082e474c1 100644 --- a/sound/soc/codecs/wcd939x.c +++ b/sound/soc/codecs/wcd939x.c @@ -32,11 +32,18 @@ #include "wcd939x.h" #define WCD939X_MAX_MICBIAS (4) -#define WCD939X_MAX_SUPPLY (4) #define WCD939X_MBHC_MAX_BUTTONS (8) #define TX_ADC_MAX (4) #define WCD_MBHC_HS_V_MAX 1600 +#define CHIPID_WCD9390 0x0 +#define CHIPID_WCD9395 0x5 + +/* Version major: 1.x */ +#define CHIPID_WCD939X_VER_MAJOR_1 0x0 +/* Version minor: x.1 */ +#define CHIPID_WCD939X_VER_MINOR_1 0x3 + enum { WCD939X_VERSION_1_0 = 0, WCD939X_VERSION_1_1, @@ -87,11 +94,6 @@ enum { #define WCD939X_ANA_MBHC_ZDET_CONST (1018 * 1024) enum { - WCD9390 = 0, - WCD9395 = 5, -}; - -enum { /* INTR_CTRL_INT_MASK_0 */ WCD939X_IRQ_MBHC_BUTTON_PRESS_DET = 0, WCD939X_IRQ_MBHC_BUTTON_RELEASE_DET, @@ -190,9 +192,7 @@ struct wcd939x_priv { struct wcd_mbhc_intr intr_ids; struct wcd_clsh_ctrl *clsh_info; struct irq_domain *virq; - struct regmap_irq_chip *wcd_regmap_irq_chip; struct regmap_irq_chip_data *irq_chip; - struct regulator_bulk_data supplies[WCD939X_MAX_SUPPLY]; struct snd_soc_jack *jack; unsigned long status_mask; s32 micb_ref[WCD939X_MAX_MICBIAS]; @@ -213,6 +213,10 @@ struct wcd939x_priv { bool ldoh; }; +static const char * const wcd939x_supplies[] = { + "vdd-rxtx", "vdd-io", "vdd-buck", "vdd-mic-bias", "vdd-px", +}; + static const SNDRV_CTL_TLVD_DECLARE_DB_MINMAX(ear_pa_gain, 600, -1800); static const DECLARE_TLV_DB_SCALE(line_gain, 0, 7, 1); static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); @@ -1482,7 +1486,7 @@ static int wcd939x_rx_hph_mode_put(struct snd_kcontrol *kcontrol, if (mode_val == wcd939x->hph_mode) return 0; - if (wcd939x->variant == WCD9390) { + if (wcd939x->variant == CHIPID_WCD9390) { switch (mode_val) { case CLS_H_NORMAL: case CLS_H_LP: @@ -3064,7 +3068,7 @@ static int wcd939x_soc_codec_probe(struct snd_soc_component *component) disable_irq_nosync(wcd939x->ear_pdm_wd_int); switch (wcd939x->variant) { - case WCD9390: + case CHIPID_WCD9390: ret = snd_soc_add_component_controls(component, wcd9390_snd_controls, ARRAY_SIZE(wcd9390_snd_controls)); if (ret < 0) { @@ -3074,7 +3078,7 @@ static int wcd939x_soc_codec_probe(struct snd_soc_component *component) goto err_free_ear_pdm_wd_int; } break; - case WCD9395: + case CHIPID_WCD9395: ret = snd_soc_add_component_controls(component, wcd9395_snd_controls, ARRAY_SIZE(wcd9395_snd_controls)); if (ret < 0) { @@ -3239,25 +3243,14 @@ static int wcd939x_populate_dt_data(struct wcd939x_priv *wcd939x, struct device int ret; wcd939x->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(wcd939x->reset_gpio)) { - ret = PTR_ERR(wcd939x->reset_gpio); - return dev_err_probe(dev, ret, "Failed to get reset gpio\n"); - } + if (IS_ERR(wcd939x->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(wcd939x->reset_gpio), + "Failed to get reset gpio\n"); - wcd939x->supplies[0].supply = "vdd-rxtx"; - wcd939x->supplies[1].supply = "vdd-io"; - wcd939x->supplies[2].supply = "vdd-buck"; - wcd939x->supplies[3].supply = "vdd-mic-bias"; - - ret = regulator_bulk_get(dev, WCD939X_MAX_SUPPLY, wcd939x->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd939x_supplies), + wcd939x_supplies); if (ret) - return dev_err_probe(dev, ret, "Failed to get supplies\n"); - - ret = regulator_bulk_enable(WCD939X_MAX_SUPPLY, wcd939x->supplies); - if (ret) { - regulator_bulk_free(WCD939X_MAX_SUPPLY, wcd939x->supplies); - return dev_err_probe(dev, ret, "Failed to enable supplies\n"); - } + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n"); wcd939x_dt_parse_micbias_info(dev, wcd939x); @@ -3461,8 +3454,8 @@ static int wcd939x_bind(struct device *dev) regmap_read(wcd939x->regmap, WCD939X_DIGITAL_CHIP_ID1, &id1); regmap_read(wcd939x->regmap, WCD939X_EAR_STATUS_REG_1, &status1); - if (id1 == 0) - version = ((status1 & 0x3) ? WCD939X_VERSION_1_1 : WCD939X_VERSION_1_0); + if (id1 == CHIPID_WCD939X_VER_MAJOR_1) + version = ((status1 & CHIPID_WCD939X_VER_MINOR_1) ? WCD939X_VERSION_1_1 : WCD939X_VERSION_1_0); else version = WCD939X_VERSION_2_0; @@ -3629,17 +3622,17 @@ static int wcd939x_probe(struct platform_device *pdev) ret = wcd939x_add_typec(wcd939x, dev); if (ret) - goto err_disable_regulators; + return ret; ret = wcd939x_add_slave_components(wcd939x, dev, &match); if (ret) - goto err_disable_regulators; + return ret; wcd939x_reset(wcd939x); ret = component_master_add_with_match(dev, &wcd939x_comp_ops, match); if (ret) - goto err_disable_regulators; + return ret; pm_runtime_set_autosuspend_delay(dev, 1000); pm_runtime_use_autosuspend(dev); @@ -3649,27 +3642,17 @@ static int wcd939x_probe(struct platform_device *pdev) pm_runtime_idle(dev); return 0; - -err_disable_regulators: - regulator_bulk_disable(WCD939X_MAX_SUPPLY, wcd939x->supplies); - regulator_bulk_free(WCD939X_MAX_SUPPLY, wcd939x->supplies); - - return ret; } static void wcd939x_remove(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct wcd939x_priv *wcd939x = dev_get_drvdata(dev); component_master_del(dev, &wcd939x_comp_ops); pm_runtime_disable(dev); pm_runtime_set_suspended(dev); pm_runtime_dont_use_autosuspend(dev); - - regulator_bulk_disable(WCD939X_MAX_SUPPLY, wcd939x->supplies); - regulator_bulk_free(WCD939X_MAX_SUPPLY, wcd939x->supplies); } #if defined(CONFIG_OF) diff --git a/sound/soc/codecs/wm8524.c b/sound/soc/codecs/wm8524.c index 403e513f3fa8..6b1a7450b0ac 100644 --- a/sound/soc/codecs/wm8524.c +++ b/sound/soc/codecs/wm8524.c @@ -21,7 +21,7 @@ #include <sound/soc.h> #include <sound/initval.h> -#define WM8524_NUM_RATES 7 +#define WM8524_NUM_RATES 12 /* codec private data */ struct wm8524_priv { @@ -46,7 +46,7 @@ static const struct snd_soc_dapm_route wm8524_dapm_routes[] = { static const struct { int value; int ratio; -} lrclk_ratios[WM8524_NUM_RATES] = { +} lrclk_ratios[] = { { 1, 128 }, { 2, 192 }, { 3, 256 }, @@ -63,17 +63,12 @@ static int wm8524_startup(struct snd_pcm_substream *substream, struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component); /* The set of sample rates that can be supported depends on the - * MCLK supplied to the CODEC - enforce this. + * MCLK supplied to the CODEC. */ - if (!wm8524->sysclk) { - dev_err(component->dev, - "No MCLK configured, call set_sysclk() on init\n"); - return -EINVAL; - } - - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &wm8524->rate_constraint); + if (wm8524->sysclk) + snd_pcm_hw_constraint_list(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &wm8524->rate_constraint); gpiod_set_value_cansleep(wm8524->mute, 1); @@ -97,9 +92,11 @@ static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai, unsigned int val; int i, j = 0; + wm8524->rate_constraint.count = 0; wm8524->sysclk = freq; + if (!wm8524->sysclk) + return 0; - wm8524->rate_constraint.count = 0; for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) { val = freq / lrclk_ratios[i].ratio; /* Check that it's a standard rate since core can't @@ -108,9 +105,13 @@ static int wm8524_set_dai_sysclk(struct snd_soc_dai *codec_dai, */ switch (val) { case 8000: + case 11025: + case 16000: + case 22050: case 32000: case 44100: case 48000: + case 64000: case 88200: case 96000: case 176400: @@ -157,6 +158,33 @@ static int wm8524_mute_stream(struct snd_soc_dai *dai, int mute, int stream) return 0; } +static int wm8524_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct wm8524_priv *wm8524 = snd_soc_component_get_drvdata(component); + int i; + + /* If sysclk is not configured, no need to check the rate */ + if (!wm8524->sysclk) + return 0; + + /* Find a supported LRCLK rate */ + for (i = 0; i < wm8524->rate_constraint.count; i++) { + if (wm8524->rate_constraint.list[i] == params_rate(params)) + break; + } + + if (i == wm8524->rate_constraint.count) { + dev_err(component->dev, "LRCLK %d unsupported with MCLK %d\n", + params_rate(params), wm8524->sysclk); + return -EINVAL; + } + + return 0; +} + #define WM8524_RATES SNDRV_PCM_RATE_8000_192000 #define WM8524_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ @@ -169,6 +197,7 @@ static const struct snd_soc_dai_ops wm8524_dai_ops = { .set_sysclk = wm8524_set_dai_sysclk, .set_fmt = wm8524_set_fmt, .mute_stream = wm8524_mute_stream, + .hw_params = wm8524_hw_params, }; static struct snd_soc_dai_driver wm8524_dai = { diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 3c580faab3b7..8a1d5cc75d6c 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -783,16 +783,19 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, char **coeff_filename) { const char *system_name = dsp->system_name; - const char *asoc_component_prefix = dsp->component->name_prefix; + const char *suffix = dsp->component->name_prefix; int ret = 0; - if (system_name && asoc_component_prefix) { + if (dsp->fwf_suffix) + suffix = dsp->fwf_suffix; + + if (system_name && suffix) { if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, cirrus_dir, system_name, - asoc_component_prefix, "wmfw")) { + suffix, "wmfw")) { wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, cirrus_dir, system_name, - asoc_component_prefix, "bin"); + suffix, "bin"); return 0; } } @@ -801,10 +804,10 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename, cirrus_dir, system_name, NULL, "wmfw")) { - if (asoc_component_prefix) + if (suffix) wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, cirrus_dir, system_name, - asoc_component_prefix, "bin"); + suffix, "bin"); if (!*coeff_firmware) wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, @@ -816,10 +819,10 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, /* Check system-specific bin without wmfw before falling back to generic */ if (dsp->wmfw_optional && system_name) { - if (asoc_component_prefix) + if (suffix) wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, cirrus_dir, system_name, - asoc_component_prefix, "bin"); + suffix, "bin"); if (!*coeff_firmware) wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename, @@ -850,7 +853,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp, adsp_err(dsp, "Failed to request firmware <%s>%s-%s-%s<-%s<%s>>.wmfw\n", cirrus_dir, dsp->part, dsp->fwf_name ? dsp->fwf_name : dsp->cs_dsp.name, - wm_adsp_fw[dsp->fw].file, system_name, asoc_component_prefix); + wm_adsp_fw[dsp->fw].file, system_name, suffix); return -ENOENT; } @@ -997,11 +1000,17 @@ int wm_adsp_power_up(struct wm_adsp *dsp, bool load_firmware) return ret; } + if (dsp->bin_mandatory && !coeff_firmware) { + ret = -ENOENT; + goto err; + } + ret = cs_dsp_power_up(&dsp->cs_dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename, wm_adsp_fw_text[dsp->fw]); +err: wm_adsp_release_firmware_files(dsp, wmfw_firmware, wmfw_filename, coeff_firmware, coeff_filename); diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index edc5b02ae765..25210d404bf1 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -29,12 +29,14 @@ struct wm_adsp { const char *part; const char *fwf_name; const char *system_name; + const char *fwf_suffix; struct snd_soc_component *component; unsigned int sys_config_size; int fw; bool wmfw_optional; + bool bin_mandatory; struct work_struct boot_work; int (*control_add)(struct wm_adsp *dsp, struct cs_dsp_coeff_ctl *cs_ctl); diff --git a/sound/soc/codecs/wsa881x.c b/sound/soc/codecs/wsa881x.c index 6627d2da3722..636e59abc377 100644 --- a/sound/soc/codecs/wsa881x.c +++ b/sound/soc/codecs/wsa881x.c @@ -202,7 +202,7 @@ SOC_SINGLE_EXT_TLV(xname, reg, shift, max, invert, \ snd_soc_get_volsw, wsa881x_put_pa_gain, tlv_array) -static struct reg_default wsa881x_defaults[] = { +static const struct reg_default wsa881x_defaults[] = { { WSA881X_CHIP_ID0, 0x00 }, { WSA881X_CHIP_ID1, 0x00 }, { WSA881X_CHIP_ID2, 0x00 }, @@ -346,7 +346,7 @@ static const struct reg_sequence wsa881x_vi_txfe_en_2_0[] = { }; /* Default register reset values for WSA881x rev 2.0 */ -static struct reg_sequence wsa881x_rev_2_0[] = { +static const struct reg_sequence wsa881x_rev_2_0[] = { { WSA881X_RESET_CTL, 0x00, 0x00 }, { WSA881X_TADC_VALUE_CTL, 0x01, 0x00 }, { WSA881X_INTR_MASK, 0x1B, 0x00 }, @@ -775,7 +775,6 @@ static int wsa881x_put_pa_gain(struct snd_kcontrol *kc, usleep_range(1000, 1010); } - pm_runtime_mark_last_busy(comp->dev); pm_runtime_put_autosuspend(comp->dev); return 1; diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index f04d99c66f33..188363b03b93 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -572,7 +572,7 @@ static const struct sdw_port_config wsa883x_pconfig[WSA883X_MAX_SWR_PORTS] = { }, }; -static struct reg_default wsa883x_defaults[] = { +static const struct reg_default wsa883x_defaults[] = { { WSA883X_REF_CTRL, 0xD5 }, { WSA883X_TEST_CTL_0, 0x06 }, { WSA883X_BIAS_0, 0xD2 }, @@ -1491,7 +1491,6 @@ static int wsa883x_get_temp(struct wsa883x_priv *wsa883x, long *temp) ret = -EAGAIN; } out: - pm_runtime_mark_last_busy(wsa883x->dev); pm_runtime_put_autosuspend(wsa883x->dev); return ret; diff --git a/sound/soc/codecs/wsa884x.c b/sound/soc/codecs/wsa884x.c index fd6ebc25fe89..2484d4b8e2d9 100644 --- a/sound/soc/codecs/wsa884x.c +++ b/sound/soc/codecs/wsa884x.c @@ -899,7 +899,7 @@ static const struct sdw_port_config wsa884x_pconfig[WSA884X_MAX_SWR_PORTS] = { }, }; -static struct reg_default wsa884x_defaults[] = { +static const struct reg_default wsa884x_defaults[] = { { WSA884X_BG_CTRL, 0xa5 }, { WSA884X_ADC_CTRL, 0x00 }, { WSA884X_BOP1_PROG, 0x22 }, @@ -1941,7 +1941,6 @@ static int wsa884x_get_temp(struct wsa884x_priv *wsa884x, long *temp) } out: - pm_runtime_mark_last_busy(wsa884x->dev); pm_runtime_put_autosuspend(wsa884x->dev); return ret; |