Lines Matching +full:core +full:- +full:vcc +full:- +full:supplies

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system
30 #include <sound/core.h>
34 #include <sound/soc-dapm.h>
54 /* Power-up register defaults */
155 "vdd-dig", /* digital supply, 3.3V */
156 "vdd-pll", /* pll supply, 3.3V */
157 "vcc" /* power amp supply, 5V - 26V */
163 struct regulator_bulk_data supplies[ARRAY_SIZE(sta350_supply_names)]; member
178 static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12750, 50, 1);
179 static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1);
180 static const DECLARE_TLV_DB_SCALE(tone_tlv, -1200, 200, 0);
183 "Anti-Clipping", "Dynamic Range Compression"
195 "FFX 3-state output - normal operation", "Binary output"
215 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0),
221 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0),
222 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0),
223 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0),
224 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0),
228 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0),
229 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0),
230 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0),
235 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0),
236 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0),
237 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0),
238 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0),
295 int numcoef = kcontrol->private_value >> 16; in sta350_coefficient_info()
296 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; in sta350_coefficient_info()
297 uinfo->count = 3 * numcoef; in sta350_coefficient_info()
306 int numcoef = kcontrol->private_value >> 16; in sta350_coefficient_get()
307 int index = kcontrol->private_value & 0xffff; in sta350_coefficient_get()
311 mutex_lock(&sta350->coeff_lock); in sta350_coefficient_get()
314 regmap_read(sta350->regmap, STA350_CFUD, &cfud); in sta350_coefficient_get()
320 regmap_write(sta350->regmap, STA350_CFUD, cfud); in sta350_coefficient_get()
322 regmap_write(sta350->regmap, STA350_CFADDR2, index); in sta350_coefficient_get()
324 regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x04); in sta350_coefficient_get()
326 regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x08); in sta350_coefficient_get()
328 ret = -EINVAL; in sta350_coefficient_get()
333 regmap_read(sta350->regmap, STA350_B1CF1 + i, &val); in sta350_coefficient_get()
334 ucontrol->value.bytes.data[i] = val; in sta350_coefficient_get()
338 mutex_unlock(&sta350->coeff_lock); in sta350_coefficient_get()
348 int numcoef = kcontrol->private_value >> 16; in sta350_coefficient_put()
349 int index = kcontrol->private_value & 0xffff; in sta350_coefficient_put()
354 regmap_read(sta350->regmap, STA350_CFUD, &cfud); in sta350_coefficient_put()
360 regmap_write(sta350->regmap, STA350_CFUD, cfud); in sta350_coefficient_put()
362 regmap_write(sta350->regmap, STA350_CFADDR2, index); in sta350_coefficient_put()
364 sta350->coef_shadow[index + i] = in sta350_coefficient_put()
365 (ucontrol->value.bytes.data[3 * i] << 16) in sta350_coefficient_put()
366 | (ucontrol->value.bytes.data[3 * i + 1] << 8) in sta350_coefficient_put()
367 | (ucontrol->value.bytes.data[3 * i + 2]); in sta350_coefficient_put()
369 regmap_write(sta350->regmap, STA350_B1CF1 + i, in sta350_coefficient_put()
370 ucontrol->value.bytes.data[i]); in sta350_coefficient_put()
372 regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); in sta350_coefficient_put()
374 regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x02); in sta350_coefficient_put()
376 return -EINVAL; in sta350_coefficient_put()
388 regmap_read(sta350->regmap, STA350_CFUD, &cfud); in sta350_sync_coef_shadow()
392 regmap_write(sta350->regmap, STA350_CFADDR2, i); in sta350_sync_coef_shadow()
393 regmap_write(sta350->regmap, STA350_B1CF1, in sta350_sync_coef_shadow()
394 (sta350->coef_shadow[i] >> 16) & 0xff); in sta350_sync_coef_shadow()
395 regmap_write(sta350->regmap, STA350_B1CF2, in sta350_sync_coef_shadow()
396 (sta350->coef_shadow[i] >> 8) & 0xff); in sta350_sync_coef_shadow()
397 regmap_write(sta350->regmap, STA350_B1CF3, in sta350_sync_coef_shadow()
398 (sta350->coef_shadow[i]) & 0xff); in sta350_sync_coef_shadow()
401 * self-clearing, so do it explicitly in sta350_sync_coef_shadow()
403 regmap_write(sta350->regmap, STA350_CFUD, cfud); in sta350_sync_coef_shadow()
404 regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); in sta350_sync_coef_shadow()
416 regmap_read(sta350->regmap, STA350_CFUD, &mute); in sta350_cache_sync()
417 regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE); in sta350_cache_sync()
419 rc = regcache_sync(sta350->regmap); in sta350_cache_sync()
420 regmap_write(sta350->regmap, STA350_MMUTE, mute); in sta350_cache_sync()
447 SOC_SINGLE("De-emphasis Filter Switch",
451 SOC_SINGLE("Post-scale Link Switch",
457 SOC_SINGLE("Zero-detect Mute Enable Switch",
532 BIQUAD_COEFS("Ch1 - Biquad 1", 0),
533 BIQUAD_COEFS("Ch1 - Biquad 2", 5),
534 BIQUAD_COEFS("Ch1 - Biquad 3", 10),
535 BIQUAD_COEFS("Ch1 - Biquad 4", 15),
536 BIQUAD_COEFS("Ch2 - Biquad 1", 20),
537 BIQUAD_COEFS("Ch2 - Biquad 2", 25),
538 BIQUAD_COEFS("Ch2 - Biquad 3", 30),
539 BIQUAD_COEFS("Ch2 - Biquad 4", 35),
540 BIQUAD_COEFS("High-pass", 40),
541 BIQUAD_COEFS("Low-pass", 45),
542 SINGLE_COEF("Ch1 - Prescale", 50),
543 SINGLE_COEF("Ch2 - Prescale", 51),
544 SINGLE_COEF("Ch1 - Postscale", 52),
545 SINGLE_COEF("Ch2 - Postscale", 53),
546 SINGLE_COEF("Ch3 - Postscale", 54),
547 SINGLE_COEF("Thermal warning - Postscale", 55),
548 SINGLE_COEF("Ch1 - Mix 1", 56),
549 SINGLE_COEF("Ch1 - Mix 2", 57),
550 SINGLE_COEF("Ch2 - Mix 1", 58),
551 SINGLE_COEF("Ch2 - Mix 2", 59),
552 SINGLE_COEF("Ch3 - Mix 1", 60),
553 SINGLE_COEF("Ch3 - Mix 2", 61),
592 * sta350_set_dai_sysclk - configure MCLK
608 struct snd_soc_component *component = codec_dai->component; in sta350_set_dai_sysclk()
611 dev_dbg(component->dev, "mclk=%u\n", freq); in sta350_set_dai_sysclk()
612 sta350->mclk = freq; in sta350_set_dai_sysclk()
618 * sta350_set_dai_fmt - configure the codec for the selected audio format
628 struct snd_soc_component *component = codec_dai->component; in sta350_set_dai_fmt()
636 return -EINVAL; in sta350_set_dai_fmt()
643 sta350->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; in sta350_set_dai_fmt()
646 return -EINVAL; in sta350_set_dai_fmt()
657 return -EINVAL; in sta350_set_dai_fmt()
660 return regmap_update_bits(sta350->regmap, STA350_CONFB, in sta350_set_dai_fmt()
665 * sta350_hw_params - program the STA350 with the given hardware parameters.
677 struct snd_soc_component *component = dai->component; in sta350_hw_params()
679 int i, mcs = -EINVAL, ir = -EINVAL; in sta350_hw_params()
684 if (!sta350->mclk) { in sta350_hw_params()
685 dev_err(component->dev, in sta350_hw_params()
686 "sta350->mclk is unset. Unable to determine ratio\n"); in sta350_hw_params()
687 return -EIO; in sta350_hw_params()
691 ratio = sta350->mclk / rate; in sta350_hw_params()
692 dev_dbg(component->dev, "rate: %u, ratio: %u\n", rate, ratio); in sta350_hw_params()
702 dev_err(component->dev, "Unsupported samplerate: %u\n", rate); in sta350_hw_params()
703 return -EINVAL; in sta350_hw_params()
714 dev_err(component->dev, "Unresolvable ratio: %u\n", ratio); in sta350_hw_params()
715 return -EINVAL; in sta350_hw_params()
724 dev_dbg(component->dev, "24bit\n"); in sta350_hw_params()
727 dev_dbg(component->dev, "24bit or 32bit\n"); in sta350_hw_params()
728 switch (sta350->format) { in sta350_hw_params()
742 dev_dbg(component->dev, "20bit\n"); in sta350_hw_params()
743 switch (sta350->format) { in sta350_hw_params()
757 dev_dbg(component->dev, "18bit\n"); in sta350_hw_params()
758 switch (sta350->format) { in sta350_hw_params()
772 dev_dbg(component->dev, "16bit\n"); in sta350_hw_params()
773 switch (sta350->format) { in sta350_hw_params()
787 return -EINVAL; in sta350_hw_params()
790 ret = regmap_update_bits(sta350->regmap, STA350_CONFA, in sta350_hw_params()
796 ret = regmap_update_bits(sta350->regmap, STA350_CONFB, in sta350_hw_params()
807 if (sta350->gpiod_power_down) in sta350_startup_sequence()
808 gpiod_set_value(sta350->gpiod_power_down, 1); in sta350_startup_sequence()
810 if (sta350->gpiod_nreset) { in sta350_startup_sequence()
811 gpiod_set_value(sta350->gpiod_nreset, 0); in sta350_startup_sequence()
813 gpiod_set_value(sta350->gpiod_nreset, 1); in sta350_startup_sequence()
821 * sta350_set_bias_level - DAPM callback
835 dev_dbg(component->dev, "level = %d\n", level); in sta350_set_bias_level()
842 regmap_update_bits(sta350->regmap, STA350_CONFF, in sta350_set_bias_level()
850 ARRAY_SIZE(sta350->supplies), in sta350_set_bias_level()
851 sta350->supplies); in sta350_set_bias_level()
853 dev_err(component->dev, in sta350_set_bias_level()
854 "Failed to enable supplies: %d\n", in sta350_set_bias_level()
863 regmap_update_bits(sta350->regmap, STA350_CONFF, in sta350_set_bias_level()
871 regmap_update_bits(sta350->regmap, STA350_CONFF, in sta350_set_bias_level()
875 if (sta350->gpiod_power_down) in sta350_set_bias_level()
876 gpiod_set_value(sta350->gpiod_power_down, 0); in sta350_set_bias_level()
878 if (sta350->gpiod_nreset) in sta350_set_bias_level()
879 gpiod_set_value(sta350->gpiod_nreset, 0); in sta350_set_bias_level()
881 regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), in sta350_set_bias_level()
882 sta350->supplies); in sta350_set_bias_level()
895 .name = "sta350-hifi",
909 struct sta350_platform_data *pdata = sta350->pdata; in sta350_probe()
912 ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies), in sta350_probe()
913 sta350->supplies); in sta350_probe()
915 dev_err(component->dev, "Failed to enable supplies: %d\n", ret); in sta350_probe()
921 dev_err(component->dev, "Failed to startup device\n"); in sta350_probe()
926 if (!pdata->thermal_warning_recovery) in sta350_probe()
928 if (!pdata->thermal_warning_adjustment) in sta350_probe()
930 if (!pdata->fault_detect_recovery) in sta350_probe()
932 regmap_update_bits(sta350->regmap, STA350_CONFA, in sta350_probe()
938 regmap_update_bits(sta350->regmap, STA350_CONFC, in sta350_probe()
940 pdata->ffx_power_output_mode in sta350_probe()
942 regmap_update_bits(sta350->regmap, STA350_CONFC, in sta350_probe()
944 pdata->drop_compensation_ns in sta350_probe()
946 regmap_update_bits(sta350->regmap, in sta350_probe()
949 pdata->oc_warning_adjustment ? in sta350_probe()
953 regmap_update_bits(sta350->regmap, STA350_CONFE, in sta350_probe()
955 pdata->max_power_use_mpcc ? in sta350_probe()
957 regmap_update_bits(sta350->regmap, STA350_CONFE, in sta350_probe()
959 pdata->max_power_correction ? in sta350_probe()
961 regmap_update_bits(sta350->regmap, STA350_CONFE, in sta350_probe()
963 pdata->am_reduction_mode ? in sta350_probe()
965 regmap_update_bits(sta350->regmap, STA350_CONFE, in sta350_probe()
967 pdata->odd_pwm_speed_mode ? in sta350_probe()
969 regmap_update_bits(sta350->regmap, STA350_CONFE, in sta350_probe()
971 pdata->distortion_compensation ? in sta350_probe()
974 regmap_update_bits(sta350->regmap, STA350_CONFF, in sta350_probe()
976 pdata->invalid_input_detect_mute ? in sta350_probe()
978 regmap_update_bits(sta350->regmap, STA350_CONFF, in sta350_probe()
980 pdata->output_conf in sta350_probe()
984 regmap_update_bits(sta350->regmap, STA350_C1CFG, in sta350_probe()
986 pdata->ch1_output_mapping in sta350_probe()
988 regmap_update_bits(sta350->regmap, STA350_C2CFG, in sta350_probe()
990 pdata->ch2_output_mapping in sta350_probe()
992 regmap_update_bits(sta350->regmap, STA350_C3CFG, in sta350_probe()
994 pdata->ch3_output_mapping in sta350_probe()
998 regmap_update_bits(sta350->regmap, STA350_MISC1, in sta350_probe()
1000 pdata->activate_mute_output ? in sta350_probe()
1002 regmap_update_bits(sta350->regmap, STA350_MISC1, in sta350_probe()
1004 pdata->bridge_immediate_off ? in sta350_probe()
1006 regmap_update_bits(sta350->regmap, STA350_MISC1, in sta350_probe()
1008 pdata->noise_shape_dc_cut ? in sta350_probe()
1010 regmap_update_bits(sta350->regmap, STA350_MISC1, in sta350_probe()
1012 pdata->powerdown_master_vol ? in sta350_probe()
1015 regmap_update_bits(sta350->regmap, STA350_MISC2, in sta350_probe()
1017 pdata->powerdown_delay_divider in sta350_probe()
1022 sta350->coef_shadow[i] = 0x400000; in sta350_probe()
1024 sta350->coef_shadow[i] = 0x7fffff; in sta350_probe()
1025 sta350->coef_shadow[55] = 0x5a9df7; in sta350_probe()
1026 sta350->coef_shadow[56] = 0x7fffff; in sta350_probe()
1027 sta350->coef_shadow[59] = 0x7fffff; in sta350_probe()
1028 sta350->coef_shadow[60] = 0x400000; in sta350_probe()
1029 sta350->coef_shadow[61] = 0x400000; in sta350_probe()
1033 regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); in sta350_probe()
1042 regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); in sta350_remove()
1081 [STA350_FFX_PM_DROP_COMP] = "drop-compensation",
1082 [STA350_FFX_PM_TAPERED_COMP] = "tapered-compensation",
1083 [STA350_FFX_PM_FULL_POWER] = "full-power-mode",
1084 [STA350_FFX_PM_VARIABLE_DROP_COMP] = "variable-drop-compensation",
1089 struct device_node *np = dev->of_node; in sta350_probe_dt()
1097 return -ENOMEM; in sta350_probe_dt()
1099 of_property_read_u8(np, "st,output-conf", in sta350_probe_dt()
1100 &pdata->output_conf); in sta350_probe_dt()
1101 of_property_read_u8(np, "st,ch1-output-mapping", in sta350_probe_dt()
1102 &pdata->ch1_output_mapping); in sta350_probe_dt()
1103 of_property_read_u8(np, "st,ch2-output-mapping", in sta350_probe_dt()
1104 &pdata->ch2_output_mapping); in sta350_probe_dt()
1105 of_property_read_u8(np, "st,ch3-output-mapping", in sta350_probe_dt()
1106 &pdata->ch3_output_mapping); in sta350_probe_dt()
1108 pdata->thermal_warning_recovery = in sta350_probe_dt()
1109 of_property_read_bool(np, "st,thermal-warning-recovery"); in sta350_probe_dt()
1110 pdata->thermal_warning_adjustment = in sta350_probe_dt()
1111 of_property_read_bool(np, "st,thermal-warning-adjustment"); in sta350_probe_dt()
1112 pdata->fault_detect_recovery = in sta350_probe_dt()
1113 of_property_read_bool(np, "st,fault-detect-recovery"); in sta350_probe_dt()
1115 pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP; in sta350_probe_dt()
1116 if (!of_property_read_string(np, "st,ffx-power-output-mode", in sta350_probe_dt()
1118 int i, mode = -EINVAL; in sta350_probe_dt()
1128 pdata->ffx_power_output_mode = mode; in sta350_probe_dt()
1132 of_property_read_u16(np, "st,drop-compensation-ns", &tmp); in sta350_probe_dt()
1133 pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; in sta350_probe_dt()
1135 pdata->oc_warning_adjustment = in sta350_probe_dt()
1136 of_property_read_bool(np, "st,overcurrent-warning-adjustment"); in sta350_probe_dt()
1139 pdata->max_power_use_mpcc = in sta350_probe_dt()
1140 of_property_read_bool(np, "st,max-power-use-mpcc"); in sta350_probe_dt()
1141 pdata->max_power_correction = in sta350_probe_dt()
1142 of_property_read_bool(np, "st,max-power-correction"); in sta350_probe_dt()
1143 pdata->am_reduction_mode = in sta350_probe_dt()
1144 of_property_read_bool(np, "st,am-reduction-mode"); in sta350_probe_dt()
1145 pdata->odd_pwm_speed_mode = in sta350_probe_dt()
1146 of_property_read_bool(np, "st,odd-pwm-speed-mode"); in sta350_probe_dt()
1147 pdata->distortion_compensation = in sta350_probe_dt()
1148 of_property_read_bool(np, "st,distortion-compensation"); in sta350_probe_dt()
1151 pdata->invalid_input_detect_mute = in sta350_probe_dt()
1152 of_property_read_bool(np, "st,invalid-input-detect-mute"); in sta350_probe_dt()
1155 pdata->activate_mute_output = in sta350_probe_dt()
1156 of_property_read_bool(np, "st,activate-mute-output"); in sta350_probe_dt()
1157 pdata->bridge_immediate_off = in sta350_probe_dt()
1158 of_property_read_bool(np, "st,bridge-immediate-off"); in sta350_probe_dt()
1159 pdata->noise_shape_dc_cut = in sta350_probe_dt()
1160 of_property_read_bool(np, "st,noise-shape-dc-cut"); in sta350_probe_dt()
1161 pdata->powerdown_master_vol = in sta350_probe_dt()
1162 of_property_read_bool(np, "st,powerdown-master-volume"); in sta350_probe_dt()
1164 if (!of_property_read_u8(np, "st,powerdown-delay-divider", &tmp8)) { in sta350_probe_dt()
1166 pdata->powerdown_delay_divider = ilog2(tmp8); in sta350_probe_dt()
1172 sta350->pdata = pdata; in sta350_probe_dt()
1180 struct device *dev = &i2c->dev; in sta350_i2c_probe()
1186 return -ENOMEM; in sta350_i2c_probe()
1188 mutex_init(&sta350->coeff_lock); in sta350_i2c_probe()
1189 sta350->pdata = dev_get_platdata(dev); in sta350_i2c_probe()
1192 if (dev->of_node) { in sta350_i2c_probe()
1200 sta350->gpiod_nreset = devm_gpiod_get_optional(dev, "reset", in sta350_i2c_probe()
1202 if (IS_ERR(sta350->gpiod_nreset)) in sta350_i2c_probe()
1203 return PTR_ERR(sta350->gpiod_nreset); in sta350_i2c_probe()
1205 sta350->gpiod_power_down = devm_gpiod_get_optional(dev, "power-down", in sta350_i2c_probe()
1207 if (IS_ERR(sta350->gpiod_power_down)) in sta350_i2c_probe()
1208 return PTR_ERR(sta350->gpiod_power_down); in sta350_i2c_probe()
1211 for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++) in sta350_i2c_probe()
1212 sta350->supplies[i].supply = sta350_supply_names[i]; in sta350_i2c_probe()
1214 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sta350->supplies), in sta350_i2c_probe()
1215 sta350->supplies); in sta350_i2c_probe()
1217 dev_err(dev, "Failed to request supplies: %d\n", ret); in sta350_i2c_probe()
1221 sta350->regmap = devm_regmap_init_i2c(i2c, &sta350_regmap); in sta350_i2c_probe()
1222 if (IS_ERR(sta350->regmap)) { in sta350_i2c_probe()
1223 ret = PTR_ERR(sta350->regmap); in sta350_i2c_probe()