xref: /linux/sound/soc/codecs/aw87390.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // aw87390.c  --  AW87390 ALSA SoC Audio driver
4 //
5 // Copyright (c) 2023 awinic Technology CO., LTD
6 //
7 // Author: Weidong Wang <wangweidong.a@awinic.com>
8 //
9 
10 #include <linux/cleanup.h>
11 #include <linux/i2c.h>
12 #include <linux/firmware.h>
13 #include <linux/regmap.h>
14 #include <sound/soc.h>
15 #include "aw87390.h"
16 #include "aw88395/aw88395_data_type.h"
17 #include "aw88395/aw88395_device.h"
18 
19 static const struct regmap_config aw87390_remap_config = {
20 	.val_bits = 8,
21 	.reg_bits = 8,
22 	.max_register = AW87390_REG_MAX,
23 	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
24 	.val_format_endian = REGMAP_ENDIAN_BIG,
25 };
26 
27 static int aw87390_dev_reg_update(struct aw_device *aw_dev,
28 					unsigned char *data, unsigned int len)
29 {
30 	int i, ret;
31 
32 	if (!data) {
33 		dev_err(aw_dev->dev, "data is NULL\n");
34 		return -EINVAL;
35 	}
36 
37 	for (i = 0; i < len-1; i += 2) {
38 		if (data[i] == AW87390_DELAY_REG_ADDR) {
39 			usleep_range(data[i + 1] * AW87390_REG_DELAY_TIME,
40 					data[i + 1] * AW87390_REG_DELAY_TIME + 10);
41 			continue;
42 		}
43 		ret = regmap_write(aw_dev->regmap, data[i], data[i + 1]);
44 		if (ret)
45 			return ret;
46 	}
47 
48 	return 0;
49 }
50 
51 static int aw87390_dev_get_prof_name(struct aw_device *aw_dev, int index, char **prof_name)
52 {
53 	struct aw_prof_info *prof_info = &aw_dev->prof_info;
54 	struct aw_prof_desc *prof_desc;
55 
56 	if ((index >= aw_dev->prof_info.count) || (index < 0)) {
57 		dev_err(aw_dev->dev, "index[%d] overflow count[%d]\n",
58 			index, aw_dev->prof_info.count);
59 		return -EINVAL;
60 	}
61 
62 	prof_desc = &aw_dev->prof_info.prof_desc[index];
63 
64 	*prof_name = prof_info->prof_name_list[prof_desc->id];
65 
66 	return 0;
67 }
68 
69 static int aw87390_dev_get_prof_data(struct aw_device *aw_dev, int index,
70 			struct aw_prof_desc **prof_desc)
71 {
72 	if ((index >= aw_dev->prof_info.count) || (index < 0)) {
73 		dev_err(aw_dev->dev, "%s: index[%d] overflow count[%d]\n",
74 				__func__, index, aw_dev->prof_info.count);
75 		return -EINVAL;
76 	}
77 
78 	*prof_desc = &aw_dev->prof_info.prof_desc[index];
79 
80 	return 0;
81 }
82 
83 static int aw87390_dev_fw_update(struct aw_device *aw_dev)
84 {
85 	struct aw_prof_desc *prof_index_desc;
86 	struct aw_sec_data_desc *sec_desc;
87 	char *prof_name;
88 	int ret;
89 
90 	ret = aw87390_dev_get_prof_name(aw_dev, aw_dev->prof_index, &prof_name);
91 	if (ret) {
92 		dev_err(aw_dev->dev, "get prof name failed\n");
93 		return -EINVAL;
94 	}
95 
96 	dev_dbg(aw_dev->dev, "start update %s", prof_name);
97 
98 	ret = aw87390_dev_get_prof_data(aw_dev, aw_dev->prof_index, &prof_index_desc);
99 	if (ret) {
100 		dev_err(aw_dev->dev, "aw87390_dev_get_prof_data failed\n");
101 		return ret;
102 	}
103 
104 	/* update reg */
105 	sec_desc = prof_index_desc->sec_desc;
106 	ret = aw87390_dev_reg_update(aw_dev, sec_desc[AW88395_DATA_TYPE_REG].data,
107 					sec_desc[AW88395_DATA_TYPE_REG].len);
108 	if (ret) {
109 		dev_err(aw_dev->dev, "update reg failed\n");
110 		return ret;
111 	}
112 
113 	aw_dev->prof_cur = aw_dev->prof_index;
114 
115 	return 0;
116 }
117 
118 static int aw87390_power_off(struct aw_device *aw_dev)
119 {
120 	int ret;
121 
122 	if (aw_dev->status == AW87390_DEV_PW_OFF) {
123 		dev_dbg(aw_dev->dev, "already power off\n");
124 		return 0;
125 	}
126 
127 	ret = regmap_write(aw_dev->regmap, AW87390_SYSCTRL_REG, AW87390_POWER_DOWN_VALUE);
128 	if (ret)
129 		return ret;
130 	aw_dev->status = AW87390_DEV_PW_OFF;
131 
132 	return 0;
133 }
134 
135 static int aw87390_power_on(struct aw_device *aw_dev)
136 {
137 	int ret;
138 
139 	if (aw_dev->status == AW87390_DEV_PW_ON) {
140 		dev_dbg(aw_dev->dev, "already power on\n");
141 		return 0;
142 	}
143 
144 	if (!aw_dev->fw_status) {
145 		dev_err(aw_dev->dev, "fw not load\n");
146 		return -EINVAL;
147 	}
148 
149 	ret = regmap_write(aw_dev->regmap, AW87390_SYSCTRL_REG, AW87390_POWER_DOWN_VALUE);
150 	if (ret)
151 		return ret;
152 
153 	ret = aw87390_dev_fw_update(aw_dev);
154 	if (ret) {
155 		dev_err(aw_dev->dev, "%s load profile failed\n", __func__);
156 		return ret;
157 	}
158 	aw_dev->status = AW87390_DEV_PW_ON;
159 
160 	return 0;
161 }
162 
163 static int aw87390_dev_set_profile_index(struct aw_device *aw_dev, int index)
164 {
165 	if ((index >= aw_dev->prof_info.count) || (index < 0))
166 		return -EINVAL;
167 
168 	if (aw_dev->prof_index == index)
169 		return -EPERM;
170 
171 	aw_dev->prof_index = index;
172 
173 	return 0;
174 }
175 
176 static int aw87390_profile_info(struct snd_kcontrol *kcontrol,
177 			 struct snd_ctl_elem_info *uinfo)
178 {
179 	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
180 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(codec);
181 	char *prof_name;
182 	int count, ret;
183 
184 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
185 	uinfo->count = 1;
186 
187 	count = aw87390->aw_pa->prof_info.count;
188 	if (count <= 0) {
189 		uinfo->value.enumerated.items = 0;
190 		return 0;
191 	}
192 
193 	uinfo->value.enumerated.items = count;
194 
195 	if (uinfo->value.enumerated.item >= count)
196 		uinfo->value.enumerated.item = count - 1;
197 
198 	count = uinfo->value.enumerated.item;
199 
200 	ret = aw87390_dev_get_prof_name(aw87390->aw_pa, count, &prof_name);
201 	if (ret) {
202 		strscpy(uinfo->value.enumerated.name, "null");
203 		return 0;
204 	}
205 
206 	strscpy(uinfo->value.enumerated.name, prof_name);
207 
208 	return 0;
209 }
210 
211 static int aw87390_profile_get(struct snd_kcontrol *kcontrol,
212 			struct snd_ctl_elem_value *ucontrol)
213 {
214 	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
215 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(codec);
216 
217 	ucontrol->value.integer.value[0] = aw87390->aw_pa->prof_index;
218 
219 	return 0;
220 }
221 
222 static int aw87390_profile_set(struct snd_kcontrol *kcontrol,
223 		struct snd_ctl_elem_value *ucontrol)
224 {
225 	struct snd_soc_component *codec = snd_kcontrol_chip(kcontrol);
226 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(codec);
227 	int ret;
228 
229 	guard(mutex)(&aw87390->lock);
230 	ret = aw87390_dev_set_profile_index(aw87390->aw_pa, ucontrol->value.integer.value[0]);
231 	if (ret) {
232 		dev_dbg(codec->dev, "profile index does not change\n");
233 		return 0;
234 	}
235 
236 	if (aw87390->aw_pa->status == AW87390_DEV_PW_ON) {
237 		aw87390_power_off(aw87390->aw_pa);
238 		aw87390_power_on(aw87390->aw_pa);
239 	}
240 
241 	return 1;
242 }
243 
244 static const struct snd_kcontrol_new aw87390_controls[] = {
245 	AW87390_PROFILE_EXT("AW87390 Profile Set", aw87390_profile_info,
246 		aw87390_profile_get, aw87390_profile_set),
247 };
248 
249 static int aw87390_request_firmware_file(struct aw87390 *aw87390)
250 {
251 	const struct firmware *cont __free(firmware) = NULL;
252 	int ret;
253 
254 	aw87390->aw_pa->fw_status = AW87390_DEV_FW_FAILED;
255 
256 	ret = request_firmware(&cont, AW87390_ACF_FILE, aw87390->aw_pa->dev);
257 	if (ret)
258 		return dev_err_probe(aw87390->aw_pa->dev, ret,
259 					"load [%s] failed!\n", AW87390_ACF_FILE);
260 
261 	dev_dbg(aw87390->aw_pa->dev, "loaded %s - size: %zu\n",
262 			AW87390_ACF_FILE, cont ? cont->size : 0);
263 
264 	aw87390->aw_cfg = devm_kzalloc(aw87390->aw_pa->dev,
265 				struct_size(aw87390->aw_cfg, data, cont->size), GFP_KERNEL);
266 	if (!aw87390->aw_cfg)
267 		return -ENOMEM;
268 
269 	aw87390->aw_cfg->len = cont->size;
270 	memcpy(aw87390->aw_cfg->data, cont->data, cont->size);
271 
272 	ret = aw88395_dev_load_acf_check(aw87390->aw_pa, aw87390->aw_cfg);
273 	if (ret) {
274 		dev_err(aw87390->aw_pa->dev, "load [%s] failed!\n", AW87390_ACF_FILE);
275 		return ret;
276 	}
277 
278 	guard(mutex)(&aw87390->lock);
279 
280 	ret = aw88395_dev_cfg_load(aw87390->aw_pa, aw87390->aw_cfg);
281 	if (ret)
282 		dev_err(aw87390->aw_pa->dev, "aw_dev acf parse failed\n");
283 
284 	return ret;
285 }
286 
287 static int aw87390_drv_event(struct snd_soc_dapm_widget *w,
288 				struct snd_kcontrol *kcontrol, int event)
289 {
290 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
291 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(component);
292 	struct aw_device *aw_dev = aw87390->aw_pa;
293 	int ret;
294 
295 	switch (event) {
296 	case SND_SOC_DAPM_PRE_PMU:
297 		ret = aw87390_power_on(aw_dev);
298 		break;
299 	case SND_SOC_DAPM_POST_PMD:
300 		ret = aw87390_power_off(aw_dev);
301 		break;
302 	default:
303 		dev_err(aw_dev->dev, "%s: invalid event %d\n", __func__, event);
304 		ret = -EINVAL;
305 	}
306 
307 	return ret;
308 }
309 
310 static int aw87391_rgds_drv_event(struct snd_soc_dapm_widget *w,
311 				struct snd_kcontrol *kcontrol, int event)
312 {
313 	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
314 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(component);
315 	struct aw_device *aw_dev = aw87390->aw_pa;
316 
317 	switch (event) {
318 	case SND_SOC_DAPM_PRE_PMU:
319 		if (!IS_ERR(aw87390->vdd_reg)) {
320 			if (regulator_enable(aw87390->vdd_reg))
321 				dev_warn(aw_dev->dev, "Failed to enable vdd\n");
322 	}
323 		break;
324 	case SND_SOC_DAPM_POST_PMU:
325 		regmap_write(aw_dev->regmap, AW87391_SYSCTRL_REG,
326 			     AW87391_REG_VER_SEL_LOW | AW87391_REG_EN_ADAP |
327 			     AW87391_REG_EN_2X | AW87391_EN_SPK |
328 			     AW87391_EN_PA | AW87391_REG_EN_CP |
329 			     AW87391_EN_SW);
330 		break;
331 	case SND_SOC_DAPM_PRE_PMD:
332 		regmap_write(aw_dev->regmap, AW87390_SYSCTRL_REG,
333 			     AW87390_POWER_DOWN_VALUE);
334 		break;
335 	case SND_SOC_DAPM_POST_PMD:
336 		if (!IS_ERR(aw87390->vdd_reg)) {
337 			if (regulator_disable(aw87390->vdd_reg))
338 				dev_warn(aw_dev->dev, "Failed to disable vdd\n");
339 	}
340 		break;
341 	default:
342 		dev_err(aw_dev->dev, "%s: invalid event %d\n", __func__, event);
343 		return -EINVAL;
344 	}
345 
346 	return 0;
347 }
348 
349 static const struct snd_soc_dapm_widget aw87390_dapm_widgets[] = {
350 	SND_SOC_DAPM_INPUT("IN"),
351 	SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0, NULL, 0, aw87390_drv_event,
352 			       SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
353 	SND_SOC_DAPM_OUTPUT("OUT"),
354 };
355 
356 static const struct snd_soc_dapm_widget aw87391_rgds_dapm_widgets[] = {
357 	SND_SOC_DAPM_INPUT("IN"),
358 	SND_SOC_DAPM_PGA_E("SPK PA", SND_SOC_NOPM, 0, 0, NULL, 0, aw87391_rgds_drv_event,
359 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
360 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
361 	SND_SOC_DAPM_OUTPUT("OUT"),
362 };
363 
364 static const struct snd_soc_dapm_route aw87390_dapm_routes[] = {
365 	{ "SPK PA", NULL, "IN" },
366 	{ "OUT", NULL, "SPK PA" },
367 };
368 
369 static int aw87390_codec_probe(struct snd_soc_component *component)
370 {
371 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(component);
372 	int ret;
373 
374 	ret = aw87390_request_firmware_file(aw87390);
375 	if (ret)
376 		return dev_err_probe(aw87390->aw_pa->dev, ret,
377 				"aw87390_request_firmware_file failed\n");
378 
379 	return 0;
380 }
381 
382 /*
383  * Firmware typically is used to load the sequence of init commands,
384  * however for the Anbernic RG-DS we don't have a firmware file just
385  * a list of registers and values. Most of these values are undocumented
386  * in the AW87391 datasheet.
387  */
388 static void aw87391_rgds_codec_init(struct aw87390 *aw87390)
389 {
390 	struct aw_device *aw_dev = aw87390->aw_pa;
391 
392 	/* Undocumented command per datasheet. */
393 	regmap_write(aw_dev->regmap, 0x64, 0x3a);
394 
395 	/* Bits 7:4 are undocumented but provided by manufacturer. */
396 	regmap_write(aw_dev->regmap, AW87391_CP_REG,
397 		     (5 << 4) | AW87391_REG_CP_OVP_8_50V);
398 
399 	regmap_write(aw_dev->regmap, AW87391_AGCPO_REG,
400 		     AW87391_AK1_S_016 | AW87391_AGC2PO_MW(500));
401 
402 	regmap_write(aw_dev->regmap, AW87391_AGC2PA_REG,
403 		     AW87391_RK_S_20_48 | AW87391_AK2_S_41 | AW87391_AK2F_S_41);
404 
405 	/* Undocumented commands per datasheet. */
406 	regmap_write(aw_dev->regmap, 0x5d, 0x00);
407 	regmap_write(aw_dev->regmap, 0x5e, 0xb4);
408 	regmap_write(aw_dev->regmap, 0x5f, 0x30);
409 	regmap_write(aw_dev->regmap, 0x60, 0x39);
410 	regmap_write(aw_dev->regmap, 0x61, 0x10);
411 	regmap_write(aw_dev->regmap, 0x62, 0x03);
412 	regmap_write(aw_dev->regmap, 0x63, 0x7d);
413 	regmap_write(aw_dev->regmap, 0x65, 0xa0);
414 	regmap_write(aw_dev->regmap, 0x66, 0x21);
415 	regmap_write(aw_dev->regmap, 0x67, 0x41);
416 	regmap_write(aw_dev->regmap, 0x68, 0x3b);
417 	regmap_write(aw_dev->regmap, 0x6e, 0x00);
418 	regmap_write(aw_dev->regmap, 0x6f, 0x00);
419 	regmap_write(aw_dev->regmap, 0x70, 0x00);
420 	regmap_write(aw_dev->regmap, 0x71, 0x00);
421 	regmap_write(aw_dev->regmap, 0x72, 0x34);
422 	regmap_write(aw_dev->regmap, 0x73, 0x06);
423 	regmap_write(aw_dev->regmap, 0x74, 0x10);
424 	regmap_write(aw_dev->regmap, 0x75, 0x00);
425 	regmap_write(aw_dev->regmap, 0x7a, 0x00);
426 	regmap_write(aw_dev->regmap, 0x7b, 0x00);
427 	regmap_write(aw_dev->regmap, 0x7c, 0x00);
428 	regmap_write(aw_dev->regmap, 0x7d, 0x00);
429 
430 	regmap_write(aw_dev->regmap, AW87391_PAG_REG, AW87391_GAIN_12DB);
431 	regmap_write(aw_dev->regmap, AW87391_SYSCTRL_REG,
432 		     AW87391_EN_PA | AW87391_REG_EN_CP | AW87391_EN_SW);
433 	regmap_write(aw_dev->regmap, AW87391_SYSCTRL_REG,
434 		     AW87391_REG_VER_SEL_LOW | AW87391_REG_EN_ADAP |
435 		     AW87391_REG_EN_2X | AW87391_EN_SPK | AW87391_EN_PA |
436 		     AW87391_REG_EN_CP | AW87391_EN_SW);
437 	regmap_write(aw_dev->regmap, AW87391_PAG_REG, AW87391_GAIN_15DB);
438 }
439 
440 static int aw87391_rgds_codec_probe(struct snd_soc_component *component)
441 {
442 	struct aw87390 *aw87390 = snd_soc_component_get_drvdata(component);
443 
444 	aw87390->vdd_reg = devm_regulator_get_optional(aw87390->aw_pa->dev,
445 						       "vdd");
446 	if (IS_ERR(aw87390->vdd_reg) && PTR_ERR(aw87390->vdd_reg) != -ENODEV)
447 		return dev_err_probe(aw87390->aw_pa->dev,
448 				     PTR_ERR(aw87390->vdd_reg),
449 				     "Could not get vdd regulator\n");
450 
451 	aw87391_rgds_codec_init(aw87390);
452 
453 	return 0;
454 }
455 
456 static const struct snd_soc_component_driver soc_codec_dev_aw87390 = {
457 	.probe = aw87390_codec_probe,
458 	.dapm_widgets = aw87390_dapm_widgets,
459 	.num_dapm_widgets = ARRAY_SIZE(aw87390_dapm_widgets),
460 	.dapm_routes = aw87390_dapm_routes,
461 	.num_dapm_routes = ARRAY_SIZE(aw87390_dapm_routes),
462 	.controls = aw87390_controls,
463 	.num_controls = ARRAY_SIZE(aw87390_controls),
464 };
465 
466 static const struct snd_soc_component_driver soc_codec_dev_anbernic_rgds = {
467 	.probe = aw87391_rgds_codec_probe,
468 	.dapm_widgets = aw87391_rgds_dapm_widgets,
469 	.num_dapm_widgets = ARRAY_SIZE(aw87391_rgds_dapm_widgets),
470 	.dapm_routes = aw87390_dapm_routes,
471 	.num_dapm_routes = ARRAY_SIZE(aw87390_dapm_routes),
472 };
473 
474 static void aw87390_parse_channel_dt(struct aw87390 *aw87390)
475 {
476 	struct aw_device *aw_dev = aw87390->aw_pa;
477 	struct device_node *np = aw_dev->dev->of_node;
478 	u32 channel_value = AW87390_DEV_DEFAULT_CH;
479 
480 	of_property_read_u32(np, "awinic,audio-channel", &channel_value);
481 
482 	aw_dev->channel = channel_value;
483 }
484 
485 static int aw87390_init(struct aw87390 *aw87390, struct i2c_client *i2c, struct regmap *regmap)
486 {
487 	struct aw_device *aw_dev;
488 	unsigned int chip_id;
489 	int ret;
490 
491 	aw_dev = devm_kzalloc(&i2c->dev, sizeof(*aw_dev), GFP_KERNEL);
492 	if (!aw_dev)
493 		return -ENOMEM;
494 
495 	/* read chip id */
496 	ret = regmap_read(regmap, AW87390_ID_REG, &chip_id);
497 	if (ret) {
498 		dev_err(&i2c->dev, "%s read chipid error. ret = %d\n", __func__, ret);
499 		return ret;
500 	}
501 
502 	switch (chip_id) {
503 	case AW87390_CHIP_ID:
504 		aw_dev->chip_id = AW87390_CHIP_ID;
505 		break;
506 	case AW87391_CHIP_ID:
507 		aw_dev->chip_id = AW87391_CHIP_ID;
508 		break;
509 	default:
510 		dev_err(&i2c->dev, "unsupported device\n");
511 		return -ENXIO;
512 	}
513 
514 	dev_dbg(&i2c->dev, "chip id = 0x%x\n", chip_id);
515 
516 	aw87390->aw_pa = aw_dev;
517 	aw_dev->i2c = i2c;
518 	aw_dev->regmap = regmap;
519 	aw_dev->dev = &i2c->dev;
520 	aw_dev->acf = NULL;
521 	aw_dev->prof_info.prof_desc = NULL;
522 	aw_dev->prof_info.count = 0;
523 	aw_dev->prof_info.prof_type = AW88395_DEV_NONE_TYPE_ID;
524 	aw_dev->channel = AW87390_DEV_DEFAULT_CH;
525 	aw_dev->fw_status = AW87390_DEV_FW_FAILED;
526 	aw_dev->prof_index = AW87390_INIT_PROFILE;
527 	aw_dev->status = AW87390_DEV_PW_OFF;
528 
529 	aw87390_parse_channel_dt(aw87390);
530 
531 	return 0;
532 }
533 
534 static int aw87390_i2c_probe(struct i2c_client *i2c)
535 {
536 	struct aw87390 *aw87390;
537 	const struct snd_soc_component_driver *priv;
538 	int ret;
539 
540 	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
541 		return dev_err_probe(&i2c->dev, -ENXIO, "check_functionality failed\n");
542 
543 	aw87390 = devm_kzalloc(&i2c->dev, sizeof(*aw87390), GFP_KERNEL);
544 	if (!aw87390)
545 		return -ENOMEM;
546 
547 	mutex_init(&aw87390->lock);
548 
549 	i2c_set_clientdata(i2c, aw87390);
550 
551 	aw87390->regmap = devm_regmap_init_i2c(i2c, &aw87390_remap_config);
552 	if (IS_ERR(aw87390->regmap))
553 		return dev_err_probe(&i2c->dev, PTR_ERR(aw87390->regmap),
554 					"failed to init regmap\n");
555 
556 	/* aw pa init */
557 	ret = aw87390_init(aw87390, i2c, aw87390->regmap);
558 	if (ret)
559 		return ret;
560 
561 	ret = regmap_write(aw87390->regmap, AW87390_ID_REG, AW87390_SOFT_RESET_VALUE);
562 	if (ret)
563 		return ret;
564 
565 	switch (aw87390->aw_pa->chip_id) {
566 	case AW87390_CHIP_ID:
567 		ret = devm_snd_soc_register_component(&i2c->dev,
568 					&soc_codec_dev_aw87390, NULL, 0);
569 		break;
570 	case AW87391_CHIP_ID:
571 		priv = of_device_get_match_data(&i2c->dev);
572 		if (!priv)
573 			return dev_err_probe(&i2c->dev, -EINVAL,
574 					     "aw87391 not currently supported\n");
575 		ret = devm_snd_soc_register_component(&i2c->dev, priv, NULL, 0);
576 		break;
577 	default:
578 		return -ENXIO;
579 	}
580 
581 	if (ret)
582 		dev_err(&i2c->dev, "failed to register aw87390: %d\n", ret);
583 
584 	return ret;
585 }
586 
587 static const struct of_device_id aw87390_of_match[] = {
588 	{ .compatible = "awinic,aw87390" },
589 	{ .compatible = "anbernic,rgds-amp", .data = &soc_codec_dev_anbernic_rgds },
590 	{},
591 };
592 MODULE_DEVICE_TABLE(of, aw87390_of_match);
593 
594 static const struct i2c_device_id aw87390_i2c_id[] = {
595 	{ .name = AW87390_I2C_NAME },
596 	{ .name = AW87391_I2C_NAME },
597 	{ }
598 };
599 MODULE_DEVICE_TABLE(i2c, aw87390_i2c_id);
600 
601 static struct i2c_driver aw87390_i2c_driver = {
602 	.driver = {
603 		.name = AW87390_I2C_NAME,
604 		.of_match_table = of_match_ptr(aw87390_of_match),
605 	},
606 	.probe = aw87390_i2c_probe,
607 	.id_table = aw87390_i2c_id,
608 };
609 module_i2c_driver(aw87390_i2c_driver);
610 
611 MODULE_DESCRIPTION("ASoC AW87390 PA Driver");
612 MODULE_LICENSE("GPL v2");
613