xref: /openbmc/linux/sound/soc/codecs/rt9120.c (revision fbb6b31a)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <linux/bits.h>
4 #include <linux/bitfield.h>
5 #include <linux/delay.h>
6 #include <linux/gpio/consumer.h>
7 #include <linux/i2c.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/regmap.h>
11 #include <linux/regulator/consumer.h>
12 #include <sound/pcm.h>
13 #include <sound/pcm_params.h>
14 #include <sound/soc.h>
15 #include <sound/tlv.h>
16 
17 #define RT9120_REG_DEVID	0x00
18 #define RT9120_REG_I2SFMT	0x02
19 #define RT9120_REG_I2SWL	0x03
20 #define RT9120_REG_SDIOSEL	0x04
21 #define RT9120_REG_SYSCTL	0x05
22 #define RT9120_REG_SPKGAIN	0x07
23 #define RT9120_REG_VOLRAMP	0x0A
24 #define RT9120_REG_ERRRPT	0x10
25 #define RT9120_REG_MSVOL	0x20
26 #define RT9120_REG_SWRESET	0x40
27 #define RT9120_REG_INTERCFG	0x63
28 #define RT9120_REG_INTERNAL0	0x65
29 #define RT9120_REG_INTERNAL1	0x69
30 #define RT9120_REG_UVPOPT	0x6C
31 #define RT9120_REG_DIGCFG	0xF8
32 
33 #define RT9120_VID_MASK		GENMASK(15, 8)
34 #define RT9120_SWRST_MASK	BIT(7)
35 #define RT9120_MUTE_MASK	GENMASK(5, 4)
36 #define RT9120_I2SFMT_MASK	GENMASK(4, 2)
37 #define RT9120_I2SFMT_SHIFT	2
38 #define RT9120_CFG_FMT_I2S	0
39 #define RT9120_CFG_FMT_LEFTJ	1
40 #define RT9120_CFG_FMT_RIGHTJ	2
41 #define RT9120_CFG_FMT_DSPA	3
42 #define RT9120_CFG_FMT_DSPB	7
43 #define RT9120_AUDBIT_MASK	GENMASK(1, 0)
44 #define RT9120_CFG_AUDBIT_16	0
45 #define RT9120_CFG_AUDBIT_20	1
46 #define RT9120_CFG_AUDBIT_24	2
47 #define RT9120_AUDWL_MASK	GENMASK(5, 0)
48 #define RT9120_CFG_WORDLEN_16	16
49 #define RT9120_CFG_WORDLEN_24	24
50 #define RT9120_CFG_WORDLEN_32	32
51 #define RT9120_DVDD_UVSEL_MASK	GENMASK(5, 4)
52 #define RT9120_AUTOSYNC_MASK	BIT(6)
53 
54 #define RT9120_VENDOR_ID	0x42
55 #define RT9120S_VENDOR_ID	0x43
56 #define RT9120_RESET_WAITMS	20
57 #define RT9120_CHIPON_WAITMS	20
58 #define RT9120_AMPON_WAITMS	50
59 #define RT9120_AMPOFF_WAITMS	100
60 #define RT9120_LVAPP_THRESUV	2000000
61 
62 /* 8000 to 192000 supported , only 176400 not support */
63 #define RT9120_RATES_MASK	(SNDRV_PCM_RATE_8000_192000 &\
64 				 ~SNDRV_PCM_RATE_176400)
65 #define RT9120_FMTS_MASK	(SNDRV_PCM_FMTBIT_S16_LE |\
66 				 SNDRV_PCM_FMTBIT_S24_LE |\
67 				 SNDRV_PCM_FMTBIT_S32_LE)
68 
69 enum {
70 	CHIP_IDX_RT9120 = 0,
71 	CHIP_IDX_RT9120S,
72 	CHIP_IDX_MAX
73 };
74 
75 struct rt9120_data {
76 	struct device *dev;
77 	struct regmap *regmap;
78 	int chip_idx;
79 };
80 
81 /* 11bit [min,max,step] = [-103.9375dB, 24dB, 0.0625dB] */
82 static const DECLARE_TLV_DB_SCALE(digital_tlv, -1039375, 625, 1);
83 
84 /* {6, 8, 10, 12, 13, 14, 15, 16}dB */
85 static const DECLARE_TLV_DB_RANGE(classd_tlv,
86 	0, 3, TLV_DB_SCALE_ITEM(600, 200, 0),
87 	4, 7, TLV_DB_SCALE_ITEM(1300, 100, 0)
88 );
89 
90 static const char * const sdo_select_text[] = {
91 	"None", "INTF", "Final", "RMS Detect"
92 };
93 
94 static const struct soc_enum sdo_select_enum =
95 	SOC_ENUM_SINGLE(RT9120_REG_SDIOSEL, 4, ARRAY_SIZE(sdo_select_text),
96 			sdo_select_text);
97 
98 static const struct snd_kcontrol_new rt9120_snd_controls[] = {
99 	SOC_SINGLE_TLV("MS Volume", RT9120_REG_MSVOL, 0, 2047, 1, digital_tlv),
100 	SOC_SINGLE_TLV("SPK Gain Volume", RT9120_REG_SPKGAIN, 0, 7, 0, classd_tlv),
101 	SOC_SINGLE("PBTL Switch", RT9120_REG_SYSCTL, 3, 1, 0),
102 	SOC_ENUM("SDO Select", sdo_select_enum),
103 };
104 
105 static int internal_power_event(struct snd_soc_dapm_widget *w,
106 				struct snd_kcontrol *kcontrol, int event)
107 {
108 	struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
109 
110 	switch (event) {
111 	case SND_SOC_DAPM_PRE_PMU:
112 		snd_soc_component_write(comp, RT9120_REG_ERRRPT, 0);
113 		break;
114 	case SND_SOC_DAPM_POST_PMU:
115 		msleep(RT9120_AMPON_WAITMS);
116 		break;
117 	case SND_SOC_DAPM_POST_PMD:
118 		msleep(RT9120_AMPOFF_WAITMS);
119 		break;
120 	default:
121 		break;
122 	}
123 
124 	return 0;
125 }
126 
127 static const struct snd_soc_dapm_widget rt9120_dapm_widgets[] = {
128 	SND_SOC_DAPM_MIXER("DMIX", SND_SOC_NOPM, 0, 0, NULL, 0),
129 	SND_SOC_DAPM_DAC("LDAC", NULL, SND_SOC_NOPM, 0, 0),
130 	SND_SOC_DAPM_DAC("RDAC", NULL, SND_SOC_NOPM, 0, 0),
131 	SND_SOC_DAPM_SUPPLY("PWND", RT9120_REG_SYSCTL, 6, 1,
132 			    internal_power_event, SND_SOC_DAPM_PRE_PMU |
133 			    SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
134 	SND_SOC_DAPM_PGA("SPKL PA", SND_SOC_NOPM, 0, 0, NULL, 0),
135 	SND_SOC_DAPM_PGA("SPKR PA", SND_SOC_NOPM, 0, 0, NULL, 0),
136 	SND_SOC_DAPM_OUTPUT("SPKL"),
137 	SND_SOC_DAPM_OUTPUT("SPKR"),
138 };
139 
140 static const struct snd_soc_dapm_route rt9120_dapm_routes[] = {
141 	{ "DMIX", NULL, "AIF Playback" },
142 	/* SPKL */
143 	{ "LDAC", NULL, "PWND" },
144 	{ "LDAC", NULL, "DMIX" },
145 	{ "SPKL PA", NULL, "LDAC" },
146 	{ "SPKL", NULL, "SPKL PA" },
147 	/* SPKR */
148 	{ "RDAC", NULL, "PWND" },
149 	{ "RDAC", NULL, "DMIX" },
150 	{ "SPKR PA", NULL, "RDAC" },
151 	{ "SPKR", NULL, "SPKR PA" },
152 	/* Cap */
153 	{ "AIF Capture", NULL, "LDAC" },
154 	{ "AIF Capture", NULL, "RDAC" },
155 };
156 
157 static int rt9120_codec_probe(struct snd_soc_component *comp)
158 {
159 	struct rt9120_data *data = snd_soc_component_get_drvdata(comp);
160 
161 	snd_soc_component_init_regmap(comp, data->regmap);
162 
163 	/* Internal setting */
164 	if (data->chip_idx == CHIP_IDX_RT9120S) {
165 		snd_soc_component_write(comp, RT9120_REG_INTERCFG, 0xde);
166 		snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x66);
167 	} else
168 		snd_soc_component_write(comp, RT9120_REG_INTERNAL0, 0x04);
169 
170 	return 0;
171 }
172 
173 static const struct snd_soc_component_driver rt9120_component_driver = {
174 	.probe = rt9120_codec_probe,
175 	.controls = rt9120_snd_controls,
176 	.num_controls = ARRAY_SIZE(rt9120_snd_controls),
177 	.dapm_widgets = rt9120_dapm_widgets,
178 	.num_dapm_widgets = ARRAY_SIZE(rt9120_dapm_widgets),
179 	.dapm_routes = rt9120_dapm_routes,
180 	.num_dapm_routes = ARRAY_SIZE(rt9120_dapm_routes),
181 };
182 
183 static int rt9120_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
184 {
185 	struct snd_soc_component *comp = dai->component;
186 	unsigned int format;
187 
188 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
189 	case SND_SOC_DAIFMT_I2S:
190 		format = RT9120_CFG_FMT_I2S;
191 		break;
192 	case SND_SOC_DAIFMT_LEFT_J:
193 		format = RT9120_CFG_FMT_LEFTJ;
194 		break;
195 	case SND_SOC_DAIFMT_RIGHT_J:
196 		format = RT9120_CFG_FMT_RIGHTJ;
197 		break;
198 	case SND_SOC_DAIFMT_DSP_A:
199 		format = RT9120_CFG_FMT_DSPA;
200 		break;
201 	case SND_SOC_DAIFMT_DSP_B:
202 		format = RT9120_CFG_FMT_DSPB;
203 		break;
204 	default:
205 		dev_err(dai->dev, "Unknown dai format\n");
206 		return -EINVAL;
207 	}
208 
209 	snd_soc_component_update_bits(comp, RT9120_REG_I2SFMT,
210 				      RT9120_I2SFMT_MASK,
211 				      format << RT9120_I2SFMT_SHIFT);
212 	return 0;
213 }
214 
215 static int rt9120_hw_params(struct snd_pcm_substream *substream,
216 			    struct snd_pcm_hw_params *param,
217 			    struct snd_soc_dai *dai)
218 {
219 	struct snd_soc_component *comp = dai->component;
220 	unsigned int param_width, param_slot_width, auto_sync;
221 	int width, fs;
222 
223 	switch (width = params_width(param)) {
224 	case 16:
225 		param_width = RT9120_CFG_AUDBIT_16;
226 		break;
227 	case 20:
228 		param_width = RT9120_CFG_AUDBIT_20;
229 		break;
230 	case 24:
231 	case 32:
232 		param_width = RT9120_CFG_AUDBIT_24;
233 		break;
234 	default:
235 		dev_err(dai->dev, "Unsupported data width [%d]\n", width);
236 		return -EINVAL;
237 	}
238 
239 	snd_soc_component_update_bits(comp, RT9120_REG_I2SFMT,
240 				      RT9120_AUDBIT_MASK, param_width);
241 
242 	switch (width = params_physical_width(param)) {
243 	case 16:
244 		param_slot_width = RT9120_CFG_WORDLEN_16;
245 		break;
246 	case 24:
247 		param_slot_width = RT9120_CFG_WORDLEN_24;
248 		break;
249 	case 32:
250 		param_slot_width = RT9120_CFG_WORDLEN_32;
251 		break;
252 	default:
253 		dev_err(dai->dev, "Unsupported slot width [%d]\n", width);
254 		return -EINVAL;
255 	}
256 
257 	snd_soc_component_update_bits(comp, RT9120_REG_I2SWL,
258 				      RT9120_AUDWL_MASK, param_slot_width);
259 
260 	fs = width * params_channels(param);
261 	/* If fs is divided by 48, disable auto sync */
262 	if (fs % 48 == 0)
263 		auto_sync = 0;
264 	else
265 		auto_sync = RT9120_AUTOSYNC_MASK;
266 
267 	snd_soc_component_update_bits(comp, RT9120_REG_DIGCFG,
268 				      RT9120_AUTOSYNC_MASK, auto_sync);
269 	return 0;
270 }
271 
272 static const struct snd_soc_dai_ops rt9120_dai_ops = {
273 	.set_fmt = rt9120_set_fmt,
274 	.hw_params = rt9120_hw_params,
275 };
276 
277 static struct snd_soc_dai_driver rt9120_dai = {
278 	.name = "rt9120_aif",
279 	.playback = {
280 		.stream_name = "AIF Playback",
281 		.rates = RT9120_RATES_MASK,
282 		.formats = RT9120_FMTS_MASK,
283 		.rate_max = 192000,
284 		.rate_min = 8000,
285 		.channels_min = 1,
286 		.channels_max = 2,
287 	},
288 	.capture = {
289 		.stream_name = "AIF Capture",
290 		.rates = RT9120_RATES_MASK,
291 		.formats = RT9120_FMTS_MASK,
292 		.rate_max = 192000,
293 		.rate_min = 8000,
294 		.channels_min = 1,
295 		.channels_max = 2,
296 	},
297 	.ops = &rt9120_dai_ops,
298 	.symmetric_rate = 1,
299 	.symmetric_sample_bits = 1,
300 };
301 
302 static const struct regmap_range rt9120_rd_yes_ranges[] = {
303 	regmap_reg_range(0x00, 0x0C),
304 	regmap_reg_range(0x10, 0x15),
305 	regmap_reg_range(0x20, 0x27),
306 	regmap_reg_range(0x30, 0x38),
307 	regmap_reg_range(0x3A, 0x40),
308 	regmap_reg_range(0x63, 0x63),
309 	regmap_reg_range(0x65, 0x65),
310 	regmap_reg_range(0x69, 0x69),
311 	regmap_reg_range(0x6C, 0x6C),
312 	regmap_reg_range(0xF8, 0xF8)
313 };
314 
315 static const struct regmap_access_table rt9120_rd_table = {
316 	.yes_ranges = rt9120_rd_yes_ranges,
317 	.n_yes_ranges = ARRAY_SIZE(rt9120_rd_yes_ranges),
318 };
319 
320 static const struct regmap_range rt9120_wr_yes_ranges[] = {
321 	regmap_reg_range(0x00, 0x00),
322 	regmap_reg_range(0x02, 0x0A),
323 	regmap_reg_range(0x10, 0x15),
324 	regmap_reg_range(0x20, 0x27),
325 	regmap_reg_range(0x30, 0x38),
326 	regmap_reg_range(0x3A, 0x3D),
327 	regmap_reg_range(0x40, 0x40),
328 	regmap_reg_range(0x63, 0x63),
329 	regmap_reg_range(0x65, 0x65),
330 	regmap_reg_range(0x69, 0x69),
331 	regmap_reg_range(0x6C, 0x6C),
332 	regmap_reg_range(0xF8, 0xF8)
333 };
334 
335 static const struct regmap_access_table rt9120_wr_table = {
336 	.yes_ranges = rt9120_wr_yes_ranges,
337 	.n_yes_ranges = ARRAY_SIZE(rt9120_wr_yes_ranges),
338 };
339 
340 static int rt9120_get_reg_size(unsigned int reg)
341 {
342 	switch (reg) {
343 	case 0x00:
344 	case 0x20 ... 0x27:
345 		return 2;
346 	case 0x30 ... 0x3D:
347 		return 3;
348 	case 0x3E ... 0x3F:
349 		return 4;
350 	default:
351 		return 1;
352 	}
353 }
354 
355 static int rt9120_reg_read(void *context, unsigned int reg, unsigned int *val)
356 {
357 	struct rt9120_data *data = context;
358 	struct i2c_client *i2c = to_i2c_client(data->dev);
359 	int size = rt9120_get_reg_size(reg);
360 	u8 raw[4] = {0};
361 	int ret;
362 
363 	ret = i2c_smbus_read_i2c_block_data(i2c, reg, size, raw);
364 	if (ret < 0)
365 		return ret;
366 	else if (ret != size)
367 		return -EIO;
368 
369 	switch (size) {
370 	case 4:
371 		*val = be32_to_cpup((__be32 *)raw);
372 		break;
373 	case 3:
374 		*val = raw[0] << 16 | raw[1] << 8 | raw[0];
375 		break;
376 	case 2:
377 		*val = be16_to_cpup((__be16 *)raw);
378 		break;
379 	default:
380 		*val = raw[0];
381 	}
382 
383 	return 0;
384 }
385 
386 static int rt9120_reg_write(void *context, unsigned int reg, unsigned int val)
387 {
388 	struct rt9120_data *data = context;
389 	struct i2c_client *i2c = to_i2c_client(data->dev);
390 	int size = rt9120_get_reg_size(reg);
391 	__be32 be32_val;
392 	u8 *rawp = (u8 *)&be32_val;
393 	int offs = 4 - size;
394 
395 	be32_val = cpu_to_be32(val);
396 	return i2c_smbus_write_i2c_block_data(i2c, reg, size, rawp + offs);
397 }
398 
399 static const struct regmap_config rt9120_regmap_config = {
400 	.reg_bits = 8,
401 	.val_bits = 32,
402 	.max_register = RT9120_REG_DIGCFG,
403 
404 	.reg_read = rt9120_reg_read,
405 	.reg_write = rt9120_reg_write,
406 
407 	.wr_table = &rt9120_wr_table,
408 	.rd_table = &rt9120_rd_table,
409 };
410 
411 static int rt9120_check_vendor_info(struct rt9120_data *data)
412 {
413 	unsigned int devid;
414 	int ret;
415 
416 	ret = regmap_read(data->regmap, RT9120_REG_DEVID, &devid);
417 	if (ret)
418 		return ret;
419 
420 	devid = FIELD_GET(RT9120_VID_MASK, devid);
421 	switch (devid) {
422 	case RT9120_VENDOR_ID:
423 		data->chip_idx = CHIP_IDX_RT9120;
424 		break;
425 	case RT9120S_VENDOR_ID:
426 		data->chip_idx = CHIP_IDX_RT9120S;
427 		break;
428 	default:
429 		dev_err(data->dev, "DEVID not correct [0x%0x]\n", devid);
430 		return -ENODEV;
431 	}
432 
433 	return 0;
434 }
435 
436 static int rt9120_do_register_reset(struct rt9120_data *data)
437 {
438 	int ret;
439 
440 	ret = regmap_write(data->regmap, RT9120_REG_SWRESET,
441 			   RT9120_SWRST_MASK);
442 	if (ret)
443 		return ret;
444 
445 	msleep(RT9120_RESET_WAITMS);
446 	return 0;
447 }
448 
449 static int rt9120_probe(struct i2c_client *i2c)
450 {
451 	struct rt9120_data *data;
452 	struct gpio_desc *pwdnn_gpio;
453 	struct regulator *dvdd_supply;
454 	int dvdd_supply_volt, ret;
455 
456 	data = devm_kzalloc(&i2c->dev, sizeof(*data), GFP_KERNEL);
457 	if (!data)
458 		return -ENOMEM;
459 
460 	data->dev = &i2c->dev;
461 	i2c_set_clientdata(i2c, data);
462 
463 	pwdnn_gpio = devm_gpiod_get_optional(&i2c->dev, "pwdnn",
464 					     GPIOD_OUT_HIGH);
465 	if (IS_ERR(pwdnn_gpio)) {
466 		dev_err(&i2c->dev, "Failed to initialize 'pwdnn' gpio\n");
467 		return PTR_ERR(pwdnn_gpio);
468 	} else if (pwdnn_gpio) {
469 		dev_dbg(&i2c->dev, "'pwdnn' from low to high, wait chip on\n");
470 		msleep(RT9120_CHIPON_WAITMS);
471 	}
472 
473 	data->regmap = devm_regmap_init(&i2c->dev, NULL, data,
474 					&rt9120_regmap_config);
475 	if (IS_ERR(data->regmap)) {
476 		ret = PTR_ERR(data->regmap);
477 		dev_err(&i2c->dev, "Failed to init regmap [%d]\n", ret);
478 		return ret;
479 	}
480 
481 	ret = rt9120_check_vendor_info(data);
482 	if (ret) {
483 		dev_err(&i2c->dev, "Failed to check vendor info\n");
484 		return ret;
485 	}
486 
487 	ret = rt9120_do_register_reset(data);
488 	if (ret) {
489 		dev_err(&i2c->dev, "Failed to do register reset\n");
490 		return ret;
491 	}
492 
493 	dvdd_supply = devm_regulator_get(&i2c->dev, "dvdd");
494 	if (IS_ERR(dvdd_supply)) {
495 		dev_err(&i2c->dev, "No dvdd regulator found\n");
496 		return PTR_ERR(dvdd_supply);
497 	}
498 
499 	dvdd_supply_volt = regulator_get_voltage(dvdd_supply);
500 	if (dvdd_supply_volt <= RT9120_LVAPP_THRESUV) {
501 		dev_dbg(&i2c->dev, "dvdd low voltage design\n");
502 		ret = regmap_update_bits(data->regmap, RT9120_REG_UVPOPT,
503 					 RT9120_DVDD_UVSEL_MASK, 0);
504 		if (ret) {
505 			dev_err(&i2c->dev, "Failed to config dvdd uvsel\n");
506 			return ret;
507 		}
508 	}
509 
510 	return devm_snd_soc_register_component(&i2c->dev,
511 					       &rt9120_component_driver,
512 					       &rt9120_dai, 1);
513 }
514 
515 static const struct of_device_id __maybe_unused rt9120_device_table[] = {
516 	{ .compatible = "richtek,rt9120", },
517 	{ }
518 };
519 MODULE_DEVICE_TABLE(of, rt9120_device_table);
520 
521 static struct i2c_driver rt9120_driver = {
522 	.driver = {
523 		.name = "rt9120",
524 		.of_match_table = rt9120_device_table,
525 	},
526 	.probe_new = rt9120_probe,
527 };
528 module_i2c_driver(rt9120_driver);
529 
530 MODULE_AUTHOR("ChiYuan Huang <cy_huang@richtek.com>");
531 MODULE_DESCRIPTION("RT9120 Audio Amplifier Driver");
532 MODULE_LICENSE("GPL");
533