Lines Matching +full:pseudo +full:- +full:differential
1 // SPDX-License-Identifier: GPL-2.0-only
3 * cs42l56.c -- CS42L56 ALSA SoC audio driver
30 #include <sound/soc-dapm.h>
43 /* Analog Input 1A Reference 0=Single 1=Pseudo-Differential */
46 /* Analog Input 2A Reference 0=Single 1=Pseudo-Differential */
49 /* Analog Input 1B Reference 0=Single 1=Pseudo-Differential */
52 /* Analog Input 2B Reference 0=Single 1=Pseudo-Differential */
95 { 3, 0x7f }, /* r03 - Power Ctl 1 */
96 { 4, 0xff }, /* r04 - Power Ctl 2 */
97 { 5, 0x00 }, /* ro5 - Clocking Ctl 1 */
98 { 6, 0x0b }, /* r06 - Clocking Ctl 2 */
99 { 7, 0x00 }, /* r07 - Serial Format */
100 { 8, 0x05 }, /* r08 - Class H Ctl */
101 { 9, 0x0c }, /* r09 - Misc Ctl */
102 { 10, 0x80 }, /* r0a - INT Status */
103 { 11, 0x00 }, /* r0b - Playback Ctl */
104 { 12, 0x0c }, /* r0c - DSP Mute Ctl */
105 { 13, 0x00 }, /* r0d - ADCA Mixer Volume */
106 { 14, 0x00 }, /* r0e - ADCB Mixer Volume */
107 { 15, 0x00 }, /* r0f - PCMA Mixer Volume */
108 { 16, 0x00 }, /* r10 - PCMB Mixer Volume */
109 { 17, 0x00 }, /* r11 - Analog Input Advisory Volume */
110 { 18, 0x00 }, /* r12 - Digital Input Advisory Volume */
111 { 19, 0x00 }, /* r13 - Master A Volume */
112 { 20, 0x00 }, /* r14 - Master B Volume */
113 { 21, 0x00 }, /* r15 - Beep Freq / On Time */
114 { 22, 0x00 }, /* r16 - Beep Volume / Off Time */
115 { 23, 0x00 }, /* r17 - Beep Tone Ctl */
116 { 24, 0x88 }, /* r18 - Tone Ctl */
117 { 25, 0x00 }, /* r19 - Channel Mixer & Swap */
118 { 26, 0x00 }, /* r1a - AIN Ref Config / ADC Mux */
119 { 27, 0xa0 }, /* r1b - High-Pass Filter Ctl */
120 { 28, 0x00 }, /* r1c - Misc ADC Ctl */
121 { 29, 0x00 }, /* r1d - Gain & Bias Ctl */
122 { 30, 0x00 }, /* r1e - PGAA Mux & Volume */
123 { 31, 0x00 }, /* r1f - PGAB Mux & Volume */
124 { 32, 0x00 }, /* r20 - ADCA Attenuator */
125 { 33, 0x00 }, /* r21 - ADCB Attenuator */
126 { 34, 0x00 }, /* r22 - ALC Enable & Attack Rate */
127 { 35, 0xbf }, /* r23 - ALC Release Rate */
128 { 36, 0x00 }, /* r24 - ALC Threshold */
129 { 37, 0x00 }, /* r25 - Noise Gate Ctl */
130 { 38, 0x00 }, /* r26 - ALC, Limiter, SFT, ZeroCross */
131 { 39, 0x00 }, /* r27 - Analog Mute, LO & HP Mux */
132 { 40, 0x00 }, /* r28 - HP A Volume */
133 { 41, 0x00 }, /* r29 - HP B Volume */
134 { 42, 0x00 }, /* r2a - LINEOUT A Volume */
135 { 43, 0x00 }, /* r2b - LINEOUT B Volume */
136 { 44, 0x00 }, /* r2c - Limit Threshold Ctl */
137 { 45, 0x7f }, /* r2d - Limiter Ctl & Release Rate */
138 { 46, 0x00 }, /* r2e - Limiter Attack Rate */
161 static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0);
162 static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0);
163 static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0);
164 static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0);
165 static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0);
167 static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0);
170 0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0),
171 2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0)
174 0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0),
175 3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0)
178 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0),
179 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0)
743 return -EINVAL; in cs42l56_get_mclk_ratio()
749 struct snd_soc_component *component = codec_dai->component; in cs42l56_set_sysclk()
756 cs42l56->mclk_div2 = 0; in cs42l56_set_sysclk()
757 cs42l56->mclk_prediv = 0; in cs42l56_set_sysclk()
762 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2; in cs42l56_set_sysclk()
763 cs42l56->mclk_prediv = 0; in cs42l56_set_sysclk()
768 cs42l56->mclk_div2 = CS42L56_MCLK_DIV2; in cs42l56_set_sysclk()
769 cs42l56->mclk_prediv = CS42L56_MCLK_PREDIV; in cs42l56_set_sysclk()
772 return -EINVAL; in cs42l56_set_sysclk()
774 cs42l56->mclk = freq; in cs42l56_set_sysclk()
778 cs42l56->mclk_prediv); in cs42l56_set_sysclk()
781 cs42l56->mclk_div2); in cs42l56_set_sysclk()
788 struct snd_soc_component *component = codec_dai->component; in cs42l56_set_dai_fmt()
793 cs42l56->iface = CS42L56_MASTER_MODE; in cs42l56_set_dai_fmt()
796 cs42l56->iface = CS42L56_SLAVE_MODE; in cs42l56_set_dai_fmt()
799 return -EINVAL; in cs42l56_set_dai_fmt()
805 cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S; in cs42l56_set_dai_fmt()
808 cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J; in cs42l56_set_dai_fmt()
811 return -EINVAL; in cs42l56_set_dai_fmt()
817 cs42l56->iface_inv = 0; in cs42l56_set_dai_fmt()
820 cs42l56->iface_inv = CS42L56_SCLK_INV; in cs42l56_set_dai_fmt()
823 return -EINVAL; in cs42l56_set_dai_fmt()
827 CS42L56_MS_MODE_MASK, cs42l56->iface); in cs42l56_set_dai_fmt()
829 CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt); in cs42l56_set_dai_fmt()
831 CS42L56_SCLK_INV_MASK, cs42l56->iface_inv); in cs42l56_set_dai_fmt()
837 struct snd_soc_component *component = dai->component; in cs42l56_mute()
894 struct snd_soc_component *component = dai->component; in cs42l56_pcm_hw_params()
898 ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params)); in cs42l56_pcm_hw_params()
903 dev_err(component->dev, "unsupported mclk/sclk/lrclk ratio\n"); in cs42l56_pcm_hw_params()
904 return -EINVAL; in cs42l56_pcm_hw_params()
927 regcache_cache_only(cs42l56->regmap, false); in cs42l56_set_bias_level()
928 regcache_sync(cs42l56->regmap); in cs42l56_set_bias_level()
929 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), in cs42l56_set_bias_level()
930 cs42l56->supplies); in cs42l56_set_bias_level()
932 dev_err(cs42l56->dev, in cs42l56_set_bias_level()
946 regcache_cache_only(cs42l56->regmap, true); in cs42l56_set_bias_level()
947 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), in cs42l56_set_bias_level()
948 cs42l56->supplies); in cs42l56_set_bias_level()
998 struct snd_soc_component *component = cs42l56->component; in cs42l56_beep_work()
1004 if (cs42l56->beep_rate) { in cs42l56_beep_work()
1006 if (abs(cs42l56->beep_rate - beep_freq[i]) < in cs42l56_beep_work()
1007 abs(cs42l56->beep_rate - beep_freq[best])) in cs42l56_beep_work()
1011 dev_dbg(component->dev, "Set beep rate %dHz for requested %dHz\n", in cs42l56_beep_work()
1012 beep_freq[best], cs42l56->beep_rate); in cs42l56_beep_work()
1018 dev_dbg(component->dev, "Disabling beep\n"); in cs42l56_beep_work()
1028 /* For usability define a way of injecting beep events for the device -
1037 dev_dbg(component->dev, "Beep event %x %x\n", code, hz); in cs42l56_beep_event()
1047 return -1; in cs42l56_beep_event()
1051 cs42l56->beep_rate = hz; in cs42l56_beep_event()
1052 schedule_work(&cs42l56->beep_work); in cs42l56_beep_event()
1067 input_event(cs42l56->beep, EV_SND, SND_TONE, time); in beep_store()
1079 cs42l56->beep = devm_input_allocate_device(component->dev); in cs42l56_init_beep()
1080 if (!cs42l56->beep) { in cs42l56_init_beep()
1081 dev_err(component->dev, "Failed to allocate beep device\n"); in cs42l56_init_beep()
1085 INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work); in cs42l56_init_beep()
1086 cs42l56->beep_rate = 0; in cs42l56_init_beep()
1088 cs42l56->beep->name = "CS42L56 Beep Generator"; in cs42l56_init_beep()
1089 cs42l56->beep->phys = dev_name(component->dev); in cs42l56_init_beep()
1090 cs42l56->beep->id.bustype = BUS_I2C; in cs42l56_init_beep()
1092 cs42l56->beep->evbit[0] = BIT_MASK(EV_SND); in cs42l56_init_beep()
1093 cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); in cs42l56_init_beep()
1094 cs42l56->beep->event = cs42l56_beep_event; in cs42l56_init_beep()
1095 cs42l56->beep->dev.parent = component->dev; in cs42l56_init_beep()
1096 input_set_drvdata(cs42l56->beep, component); in cs42l56_init_beep()
1098 ret = input_register_device(cs42l56->beep); in cs42l56_init_beep()
1100 cs42l56->beep = NULL; in cs42l56_init_beep()
1101 dev_err(component->dev, "Failed to register beep device\n"); in cs42l56_init_beep()
1104 ret = device_create_file(component->dev, &dev_attr_beep); in cs42l56_init_beep()
1106 dev_err(component->dev, "Failed to create keyclick file: %d\n", in cs42l56_init_beep()
1115 device_remove_file(component->dev, &dev_attr_beep); in cs42l56_free_beep()
1116 cancel_work_sync(&cs42l56->beep_work); in cs42l56_free_beep()
1117 cs42l56->beep = NULL; in cs42l56_free_beep()
1166 struct device_node *np = i2c_client->dev.of_node; in cs42l56_handle_of_data()
1169 if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg")) in cs42l56_handle_of_data()
1170 pdata->ain1a_ref_cfg = true; in cs42l56_handle_of_data()
1172 if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg")) in cs42l56_handle_of_data()
1173 pdata->ain2a_ref_cfg = true; in cs42l56_handle_of_data()
1175 if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg")) in cs42l56_handle_of_data()
1176 pdata->ain1b_ref_cfg = true; in cs42l56_handle_of_data()
1178 if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg")) in cs42l56_handle_of_data()
1179 pdata->ain2b_ref_cfg = true; in cs42l56_handle_of_data()
1181 if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0) in cs42l56_handle_of_data()
1182 pdata->micbias_lvl = val32; in cs42l56_handle_of_data()
1184 if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0) in cs42l56_handle_of_data()
1185 pdata->chgfreq = val32; in cs42l56_handle_of_data()
1187 if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0) in cs42l56_handle_of_data()
1188 pdata->adaptive_pwr = val32; in cs42l56_handle_of_data()
1190 if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0) in cs42l56_handle_of_data()
1191 pdata->hpfa_freq = val32; in cs42l56_handle_of_data()
1193 if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0) in cs42l56_handle_of_data()
1194 pdata->hpfb_freq = val32; in cs42l56_handle_of_data()
1196 pdata->gpio_nreset = devm_gpiod_get_optional(&i2c_client->dev, "cirrus,gpio-nreset", in cs42l56_handle_of_data()
1199 if (IS_ERR(pdata->gpio_nreset)) in cs42l56_handle_of_data()
1200 return PTR_ERR(pdata->gpio_nreset); in cs42l56_handle_of_data()
1202 gpiod_set_consumer_name(pdata->gpio_nreset, "CS42L56 /RST"); in cs42l56_handle_of_data()
1215 cs42l56 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l56), GFP_KERNEL); in cs42l56_i2c_probe()
1217 return -ENOMEM; in cs42l56_i2c_probe()
1218 cs42l56->dev = &i2c_client->dev; in cs42l56_i2c_probe()
1220 cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap); in cs42l56_i2c_probe()
1221 if (IS_ERR(cs42l56->regmap)) { in cs42l56_i2c_probe()
1222 ret = PTR_ERR(cs42l56->regmap); in cs42l56_i2c_probe()
1223 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); in cs42l56_i2c_probe()
1227 if (i2c_client->dev.of_node) { in cs42l56_i2c_probe()
1228 ret = cs42l56_handle_of_data(i2c_client, &cs42l56->pdata); in cs42l56_i2c_probe()
1233 if (cs42l56->pdata.gpio_nreset) { in cs42l56_i2c_probe()
1234 gpiod_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1); in cs42l56_i2c_probe()
1235 gpiod_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0); in cs42l56_i2c_probe()
1240 for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++) in cs42l56_i2c_probe()
1241 cs42l56->supplies[i].supply = cs42l56_supply_names[i]; in cs42l56_i2c_probe()
1243 ret = devm_regulator_bulk_get(&i2c_client->dev, in cs42l56_i2c_probe()
1244 ARRAY_SIZE(cs42l56->supplies), in cs42l56_i2c_probe()
1245 cs42l56->supplies); in cs42l56_i2c_probe()
1247 dev_err(&i2c_client->dev, in cs42l56_i2c_probe()
1252 ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), in cs42l56_i2c_probe()
1253 cs42l56->supplies); in cs42l56_i2c_probe()
1255 dev_err(&i2c_client->dev, in cs42l56_i2c_probe()
1260 ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, ®); in cs42l56_i2c_probe()
1262 dev_err(&i2c_client->dev, "Failed to read chip ID: %d\n", ret); in cs42l56_i2c_probe()
1268 dev_err(&i2c_client->dev, in cs42l56_i2c_probe()
1271 ret = -EINVAL; in cs42l56_i2c_probe()
1277 dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 "); in cs42l56_i2c_probe()
1278 dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n", in cs42l56_i2c_probe()
1281 if (cs42l56->pdata.ain1a_ref_cfg) in cs42l56_i2c_probe()
1282 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, in cs42l56_i2c_probe()
1286 if (cs42l56->pdata.ain1b_ref_cfg) in cs42l56_i2c_probe()
1287 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, in cs42l56_i2c_probe()
1291 if (cs42l56->pdata.ain2a_ref_cfg) in cs42l56_i2c_probe()
1292 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, in cs42l56_i2c_probe()
1296 if (cs42l56->pdata.ain2b_ref_cfg) in cs42l56_i2c_probe()
1297 regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, in cs42l56_i2c_probe()
1301 if (cs42l56->pdata.micbias_lvl) in cs42l56_i2c_probe()
1302 regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL, in cs42l56_i2c_probe()
1304 cs42l56->pdata.micbias_lvl); in cs42l56_i2c_probe()
1306 if (cs42l56->pdata.chgfreq) in cs42l56_i2c_probe()
1307 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL, in cs42l56_i2c_probe()
1309 cs42l56->pdata.chgfreq); in cs42l56_i2c_probe()
1311 if (cs42l56->pdata.hpfb_freq) in cs42l56_i2c_probe()
1312 regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL, in cs42l56_i2c_probe()
1314 cs42l56->pdata.hpfb_freq); in cs42l56_i2c_probe()
1316 if (cs42l56->pdata.hpfa_freq) in cs42l56_i2c_probe()
1317 regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL, in cs42l56_i2c_probe()
1319 cs42l56->pdata.hpfa_freq); in cs42l56_i2c_probe()
1321 if (cs42l56->pdata.adaptive_pwr) in cs42l56_i2c_probe()
1322 regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL, in cs42l56_i2c_probe()
1324 cs42l56->pdata.adaptive_pwr); in cs42l56_i2c_probe()
1326 ret = devm_snd_soc_register_component(&i2c_client->dev, in cs42l56_i2c_probe()
1334 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), in cs42l56_i2c_probe()
1335 cs42l56->supplies); in cs42l56_i2c_probe()
1343 regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), in cs42l56_i2c_remove()
1344 cs42l56->supplies); in cs42l56_i2c_remove()