Lines Matching +full:int +full:- +full:vref +full:- +full:microvolt
1 // SPDX-License-Identifier: GPL-2.0-only
3 // nau8325.c -- Nuvoton NAU8325 audio codec driver
30 #define CLK_PROC_BYPASS (-1)
119 static bool nau8325_readable_reg(struct device *dev, unsigned int reg) in nau8325_readable_reg()
142 static bool nau8325_writeable_reg(struct device *dev, unsigned int reg) in nau8325_writeable_reg()
162 static bool nau8325_volatile_reg(struct device *dev, unsigned int reg) in nau8325_volatile_reg()
181 static const unsigned int nau8325_dac_oversampl_values[] = {
192 static const DECLARE_TLV_DB_MINMAX_MUTE(dac_vol_tlv, -8000, 600);
215 static int nau8325_dac_event(struct snd_soc_dapm_widget *w, in nau8325_dac_event()
216 struct snd_kcontrol *kcontrol, int event) in nau8325_dac_event()
219 snd_soc_dapm_to_component(w->dapm); in nau8325_dac_event()
224 regmap_update_bits(nau8325->regmap, NAU8325_R12_MUTE_CTRL, in nau8325_dac_event()
230 regmap_update_bits(nau8325->regmap, NAU8325_R12_MUTE_CTRL, in nau8325_dac_event()
235 return -EINVAL; in nau8325_dac_event()
241 static int nau8325_powerup_event(struct snd_soc_dapm_widget *w, in nau8325_powerup_event()
242 struct snd_kcontrol *kcontrol, int event) in nau8325_powerup_event()
245 snd_soc_dapm_to_component(w->dapm); in nau8325_powerup_event()
248 if (nau8325->clock_detection) in nau8325_powerup_event()
253 regmap_update_bits(nau8325->regmap, NAU8325_R40_CLK_DET_CTRL, in nau8325_powerup_event()
257 regmap_update_bits(nau8325->regmap, NAU8325_R40_CLK_DET_CTRL, in nau8325_powerup_event()
261 return -EINVAL; in nau8325_powerup_event()
293 static int nau8325_srate_clk_apply(struct nau8325 *nau8325, in nau8325_srate_clk_apply()
295 int n1_sel, int mclk_mult_sel, int n2_sel) in nau8325_srate_clk_apply()
299 dev_dbg(nau8325->dev, "The CLK isn't supported."); in nau8325_srate_clk_apply()
300 return -EINVAL; in nau8325_srate_clk_apply()
303 regmap_update_bits(nau8325->regmap, NAU8325_R40_CLK_DET_CTRL, in nau8325_srate_clk_apply()
305 (srate_table->range << NAU8325_REG_SRATE_SFT) | in nau8325_srate_clk_apply()
306 (srate_table->max ? NAU8325_REG_DIV_MAX : 0)); in nau8325_srate_clk_apply()
307 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL, in nau8325_srate_clk_apply()
309 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL, in nau8325_srate_clk_apply()
314 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL, in nau8325_srate_clk_apply()
319 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL, in nau8325_srate_clk_apply()
325 regmap_update_bits(nau8325->regmap, NAU8325_R65_ANALOG_CONTROL_5, in nau8325_srate_clk_apply()
329 regmap_update_bits(nau8325->regmap, NAU8325_R65_ANALOG_CONTROL_5, in nau8325_srate_clk_apply()
334 regmap_update_bits(nau8325->regmap, NAU8325_R65_ANALOG_CONTROL_5, in nau8325_srate_clk_apply()
342 static int nau8325_clksrc_n2(struct nau8325 *nau8325, in nau8325_clksrc_n2()
344 int mclk, int *n2_sel) in nau8325_clksrc_n2()
346 int i, mclk_src, ratio; in nau8325_clksrc_n2()
351 if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_256] == mclk_src) { in nau8325_clksrc_n2()
354 } else if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_400] == mclk_src) { in nau8325_clksrc_n2()
357 } else if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_500] == mclk_src) { in nau8325_clksrc_n2()
368 static const struct nau8325_srate_attr *target_srate_attribute(int srate) in target_srate_attribute()
370 int i; in target_srate_attribute()
385 static int nau8325_clksrc_choose(struct nau8325 *nau8325, in nau8325_clksrc_choose()
387 int *n1_sel, int *mult_sel, int *n2_sel) in nau8325_clksrc_choose()
389 int i, j, mclk, mclk_max, ratio, ratio_sel, n2_max; in nau8325_clksrc_choose()
391 if (!nau8325->mclk || !nau8325->fs) in nau8325_clksrc_choose()
395 *srate_table = target_srate_attribute(nau8325->fs); in nau8325_clksrc_choose()
402 ratio = nau8325_clksrc_n2(nau8325, *srate_table, nau8325->mclk, n2_sel); in nau8325_clksrc_choose()
414 mclk = nau8325->mclk << mclk_n3_mult[j].param; in nau8325_clksrc_choose()
436 dev_dbg(nau8325->dev, "The MCLK %d is invalid. It can't get MCLK_SRC of 256/400/500 FS (%d)", in nau8325_clksrc_choose()
437 nau8325->mclk, nau8325->fs); in nau8325_clksrc_choose()
438 return -EINVAL; in nau8325_clksrc_choose()
440 …dev_dbg(nau8325->dev, "nau8325->fs=%d,range=0x%x, %s, (n1,mu,n2,dmu):(%d,%d,%d), MCLK_SRC=%uHz (%d… in nau8325_clksrc_choose()
441 nau8325->fs, (*srate_table)->range, in nau8325_clksrc_choose()
442 (*srate_table)->max ? "MAX" : "MIN", in nau8325_clksrc_choose()
448 (*srate_table)->mclk_src[ratio], in nau8325_clksrc_choose()
449 (*srate_table)->mclk_src[ratio] / nau8325->fs); in nau8325_clksrc_choose()
454 static int nau8325_clock_config(struct nau8325 *nau8325) in nau8325_clock_config()
457 int ret, n1_sel, mult_sel, n2_sel; in nau8325_clock_config()
476 unsigned int osr; in nau8325_get_osr()
478 regmap_read(nau8325->regmap, NAU8325_R29_DAC_CTRL1, &osr); in nau8325_get_osr()
486 static int nau8325_dai_startup(struct snd_pcm_substream *substream, in nau8325_dai_startup()
489 struct snd_soc_component *component = dai->component; in nau8325_dai_startup()
494 if (!osr || !osr->osr) in nau8325_dai_startup()
495 return -EINVAL; in nau8325_dai_startup()
497 return snd_pcm_hw_constraint_minmax(substream->runtime, in nau8325_dai_startup()
499 0, CLK_DA_AD_MAX / osr->osr); in nau8325_dai_startup()
502 static int nau8325_hw_params(struct snd_pcm_substream *substream, in nau8325_hw_params()
506 struct snd_soc_component *component = dai->component; in nau8325_hw_params()
508 unsigned int val_len = 0; in nau8325_hw_params()
510 int ret; in nau8325_hw_params()
512 nau8325->fs = params_rate(params); in nau8325_hw_params()
514 if (!osr || !osr->osr || nau8325->fs * osr->osr > CLK_DA_AD_MAX) { in nau8325_hw_params()
515 ret = -EINVAL; in nau8325_hw_params()
518 regmap_update_bits(nau8325->regmap, NAU8325_R03_CLK_CTRL, in nau8325_hw_params()
520 osr->clk_src << NAU8325_CLK_DAC_SRC_SFT); in nau8325_hw_params()
540 ret = -EINVAL; in nau8325_hw_params()
544 regmap_update_bits(nau8325->regmap, NAU8325_R0D_I2S_PCM_CTRL1, in nau8325_hw_params()
553 static int nau8325_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) in nau8325_set_fmt()
555 struct snd_soc_component *component = dai->component; in nau8325_set_fmt()
557 unsigned int ctrl1_val = 0; in nau8325_set_fmt()
563 return -EINVAL; in nau8325_set_fmt()
573 return -EINVAL; in nau8325_set_fmt()
594 return -EINVAL; in nau8325_set_fmt()
597 regmap_update_bits(nau8325->regmap, NAU8325_R0D_I2S_PCM_CTRL1, in nau8325_set_fmt()
604 static int nau8325_set_sysclk(struct snd_soc_component *component, int clk_id, in nau8325_set_sysclk()
605 int source, unsigned int freq, int dir) in nau8325_set_sysclk()
610 dev_dbg(nau8325->dev, "MCLK exceeds the range, MCLK:%d", freq); in nau8325_set_sysclk()
611 return -EINVAL; in nau8325_set_sysclk()
614 nau8325->mclk = freq; in nau8325_set_sysclk()
615 dev_dbg(nau8325->dev, "MCLK %dHz", nau8325->mclk); in nau8325_set_sysclk()
675 struct regmap *regmap = nau8325->regmap; in nau8325_init_regs()
676 struct device *dev = nau8325->dev; in nau8325_init_regs()
688 if (nau8325->alc_enable) in nau8325_init_regs()
691 if (nau8325->clock_detection) in nau8325_init_regs()
699 if (nau8325->clock_det_data) in nau8325_init_regs()
707 switch (nau8325->dac_vref_microvolt) { in nau8325_init_regs()
725 dev_dbg(dev, "Invalid dac-vref-microvolt %d", nau8325->dac_vref_microvolt); in nau8325_init_regs()
732 /* Auto-Att Min Gain 0dB, Class-D N Driver Slew Rate -25%. */ in nau8325_init_regs()
737 switch (nau8325->vref_impedance_ohms) { in nau8325_init_regs()
755 dev_dbg(dev, "Invalid vref-impedance-ohms %d", nau8325->vref_impedance_ohms); in nau8325_init_regs()
775 if (nau8325->alc_enable) in nau8325_init_regs()
778 if (nau8325->clock_det_data) in nau8325_init_regs()
784 if (nau8325->clock_detection) in nau8325_init_regs()
799 struct device *dev = nau8325->dev; in nau8325_print_device_properties()
801 dev_dbg(dev, "vref-impedance-ohms: %d", nau8325->vref_impedance_ohms); in nau8325_print_device_properties()
802 dev_dbg(dev, "dac-vref-microvolt: %d", nau8325->dac_vref_microvolt); in nau8325_print_device_properties()
803 dev_dbg(dev, "alc-enable: %d", nau8325->alc_enable); in nau8325_print_device_properties()
804 dev_dbg(dev, "clock-det-data: %d", nau8325->clock_det_data); in nau8325_print_device_properties()
805 dev_dbg(dev, "clock-detection-disable: %d", nau8325->clock_detection); in nau8325_print_device_properties()
808 static int nau8325_read_device_properties(struct device *dev, in nau8325_read_device_properties()
811 int ret; in nau8325_read_device_properties()
813 nau8325->alc_enable = in nau8325_read_device_properties()
814 device_property_read_bool(dev, "nuvoton,alc-enable"); in nau8325_read_device_properties()
815 nau8325->clock_det_data = in nau8325_read_device_properties()
816 device_property_read_bool(dev, "nuvoton,clock-det-data"); in nau8325_read_device_properties()
817 nau8325->clock_detection = in nau8325_read_device_properties()
818 !device_property_read_bool(dev, "nuvoton,clock-detection-disable"); in nau8325_read_device_properties()
820 ret = device_property_read_u32(dev, "nuvoton,vref-impedance-ohms", in nau8325_read_device_properties()
821 &nau8325->vref_impedance_ohms); in nau8325_read_device_properties()
823 nau8325->vref_impedance_ohms = 125000; in nau8325_read_device_properties()
824 ret = device_property_read_u32(dev, "nuvoton,dac-vref-microvolt", in nau8325_read_device_properties()
825 &nau8325->dac_vref_microvolt); in nau8325_read_device_properties()
827 nau8325->dac_vref_microvolt = 2880000; in nau8325_read_device_properties()
832 static int nau8325_i2c_probe(struct i2c_client *i2c, in nau8325_i2c_probe()
835 struct device *dev = &i2c->dev; in nau8325_i2c_probe()
837 int ret, value; in nau8325_i2c_probe()
842 ret = -ENOMEM; in nau8325_i2c_probe()
851 nau8325->regmap = devm_regmap_init_i2c(i2c, &nau8325_regmap_config); in nau8325_i2c_probe()
852 if (IS_ERR(nau8325->regmap)) { in nau8325_i2c_probe()
853 ret = PTR_ERR(nau8325->regmap); in nau8325_i2c_probe()
856 nau8325->dev = dev; in nau8325_i2c_probe()
859 nau8325_reset_chip(nau8325->regmap); in nau8325_i2c_probe()
860 ret = regmap_read(nau8325->regmap, NAU8325_R02_DEVICE_ID, &value); in nau8325_i2c_probe()