xref: /linux/sound/soc/codecs/simple-amplifier.c (revision d2c9a99135da931377240942d44f3dea104cedb8)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Support for gpio amplifier
4  *   Copyright 2026 CS GROUP France
5  *   Author: Herve Codina <herve.codina@bootlin.com>
6  *
7  * Basic simple amplifier driver
8  *   Copyright (c) 2017 BayLibre, SAS.
9  *   Author: Jerome Brunet <jbrunet@baylibre.com>
10  */
11 
12 #include <linux/bitmap.h>
13 #include <linux/bits.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/math.h>
16 #include <linux/minmax.h>
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/slab.h>
21 #include <sound/soc.h>
22 #include <linux/sort.h>
23 #include <sound/tlv.h>
24 
25 struct simple_amp_single {
26 	struct gpio_desc *gpio;
27 	bool is_inverted;
28 	int kctrl_val;
29 	const char *control_name;
30 };
31 
32 struct simple_amp_point {
33 	u32 gpio_val;
34 	int gain_db;
35 };
36 
37 struct simple_amp_range {
38 	unsigned int nb_points;
39 	struct simple_amp_point min;
40 	struct simple_amp_point max;
41 };
42 
43 struct simple_amp_ranges {
44 	unsigned int nb_ranges;
45 	struct simple_amp_range *tab_ranges;
46 };
47 
48 struct simple_amp_labels {
49 	unsigned int nb_labels;
50 	const char **tab_labels;
51 };
52 
53 enum simple_amp_mode {
54 	SIMPLE_AMP_MODE_NONE,
55 	SIMPLE_AMP_MODE_RANGES,
56 	SIMPLE_AMP_MODE_LABELS,
57 };
58 
59 struct simple_amp_multi {
60 	struct gpio_descs *gpios;
61 	u32 kctrl_val;
62 	u32 kctrl_max;
63 	const char *control_name;
64 	unsigned int *tlv_array;
65 	enum simple_amp_mode mode;
66 	union {
67 		struct simple_amp_ranges ranges;
68 		struct simple_amp_labels labels;
69 	};
70 };
71 
72 struct simple_amp_data {
73 	unsigned int supports;
74 #define SIMPLE_AUDIO_SUPPORT_PGA		BIT(0)
75 #define SIMPLE_AUDIO_SUPPORT_POWER_SUPPLIES	BIT(1)
76 #define SIMPLE_AUDIO_SUPPORT_MUTE		BIT(2)
77 #define SIMPLE_AUDIO_SUPPORT_BYPASS		BIT(3)
78 
79 	const struct snd_soc_dapm_widget *dapm_widgets;
80 	unsigned int num_dapm_widgets;
81 	const struct snd_soc_dapm_route *dapm_routes;
82 	unsigned int num_dapm_routes;
83 };
84 
85 struct simple_amp {
86 	const struct simple_amp_data *data;
87 	struct gpio_desc *gpiod_enable;
88 	struct simple_amp_single mute;
89 	struct simple_amp_single bypass;
90 	struct simple_amp_multi gain;
91 };
92 
simple_amp_power_event(struct snd_soc_dapm_widget * w,struct snd_kcontrol * control,int event)93 static int simple_amp_power_event(struct snd_soc_dapm_widget *w,
94 				  struct snd_kcontrol *control, int event)
95 {
96 	struct snd_soc_component *c = snd_soc_dapm_to_component(w->dapm);
97 	struct simple_amp *simple_amp = snd_soc_component_get_drvdata(c);
98 	int val;
99 
100 	switch (event) {
101 	case SND_SOC_DAPM_POST_PMU:
102 		val = 1;
103 		break;
104 	case SND_SOC_DAPM_PRE_PMD:
105 		val = 0;
106 		break;
107 	default:
108 		WARN(1, "Unexpected event");
109 		return -EINVAL;
110 	}
111 
112 	gpiod_set_value_cansleep(simple_amp->gpiod_enable, val);
113 
114 	return 0;
115 }
116 
117 static const struct snd_soc_dapm_widget simple_amp_dapm_widgets[] = {
118 	SND_SOC_DAPM_INPUT("INL"),
119 	SND_SOC_DAPM_INPUT("INR"),
120 	SND_SOC_DAPM_OUT_DRV_E("DRV", SND_SOC_NOPM, 0, 0, NULL, 0, simple_amp_power_event,
121 			       (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)),
122 	SND_SOC_DAPM_OUTPUT("OUTL"),
123 	SND_SOC_DAPM_OUTPUT("OUTR"),
124 	SND_SOC_DAPM_REGULATOR_SUPPLY("VCC", 20, 0),
125 };
126 
127 static const struct snd_soc_dapm_route simple_amp_dapm_routes[] = {
128 	{ "DRV", NULL, "INL" },
129 	{ "DRV", NULL, "INR" },
130 	{ "OUTL", NULL, "VCC" },
131 	{ "OUTR", NULL, "VCC" },
132 	{ "OUTL", NULL, "DRV" },
133 	{ "OUTR", NULL, "DRV" },
134 };
135 
136 static const struct snd_soc_dapm_widget simple_amp_mono_pga_dapm_widgets[] = {
137 	SND_SOC_DAPM_INPUT("IN"),
138 	SND_SOC_DAPM_OUTPUT("OUT"),
139 	SND_SOC_DAPM_PGA_E("PGA", SND_SOC_NOPM, 0, 0, NULL, 0, simple_amp_power_event,
140 			   (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)),
141 	SND_SOC_DAPM_REGULATOR_SUPPLY("vdd", 0, 0),
142 };
143 
144 static const struct snd_soc_dapm_route simple_amp_mono_pga_dapm_routes[] = {
145 	{ "PGA", NULL, "IN" },
146 	{ "PGA", NULL, "vdd" },
147 	{ "OUT", NULL, "PGA" },
148 };
149 
150 static const struct snd_soc_dapm_widget simple_amp_stereo_pga_dapm_widgets[] = {
151 	SND_SOC_DAPM_INPUT("INL"),
152 	SND_SOC_DAPM_INPUT("INR"),
153 	SND_SOC_DAPM_OUTPUT("OUTL"),
154 	SND_SOC_DAPM_OUTPUT("OUTR"),
155 	SND_SOC_DAPM_PGA_E("PGA", SND_SOC_NOPM, 0, 0, NULL, 0, simple_amp_power_event,
156 			   (SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)),
157 	SND_SOC_DAPM_REGULATOR_SUPPLY("vdd", 0, 0),
158 };
159 
160 static const struct snd_soc_dapm_route simple_amp_stereo_pga_dapm_routes[] = {
161 	{ "PGA", NULL, "INL" },
162 	{ "PGA", NULL, "INR" },
163 	{ "PGA", NULL, "vdd" },
164 	{ "OUTL", NULL, "PGA" },
165 	{ "OUTR", NULL, "PGA" },
166 };
167 
simple_amp_single_kctrl_write_gpio(struct simple_amp_single * single,int kctrl_val)168 static int simple_amp_single_kctrl_write_gpio(struct simple_amp_single *single,
169 					      int kctrl_val)
170 {
171 	int gpio_val;
172 
173 	gpio_val = single->is_inverted ? !kctrl_val : kctrl_val;
174 
175 	return gpiod_set_value_cansleep(single->gpio, gpio_val);
176 }
177 
simple_amp_single_kctrl_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)178 static int simple_amp_single_kctrl_info(struct snd_kcontrol *kcontrol,
179 					struct snd_ctl_elem_info *uinfo)
180 {
181 	uinfo->count = 1;
182 	uinfo->value.integer.min = 0;
183 	uinfo->value.integer.max = 1;
184 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
185 	return 0;
186 }
187 
simple_amp_single_kctrl_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)188 static int simple_amp_single_kctrl_get(struct snd_kcontrol *kcontrol,
189 				       struct snd_ctl_elem_value *ucontrol)
190 {
191 	struct simple_amp_single *single = (struct simple_amp_single *)kcontrol->private_value;
192 
193 	ucontrol->value.integer.value[0] = single->kctrl_val;
194 
195 	return 0;
196 }
197 
simple_amp_single_kctrl_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)198 static int simple_amp_single_kctrl_put(struct snd_kcontrol *kcontrol,
199 				       struct snd_ctl_elem_value *ucontrol)
200 {
201 	struct simple_amp_single *single = (struct simple_amp_single *)kcontrol->private_value;
202 	int kctrl_val;
203 	int err;
204 
205 	kctrl_val = ucontrol->value.integer.value[0] ? 1 : 0;
206 
207 	if (kctrl_val == single->kctrl_val)
208 		return 0;
209 
210 	err = simple_amp_single_kctrl_write_gpio(single, kctrl_val);
211 	if (err)
212 		return err;
213 
214 	single->kctrl_val = kctrl_val;
215 
216 	return 1; /* The value changed */
217 }
218 
simple_amp_single_add_kcontrol(struct snd_soc_component * component,struct simple_amp_single * single)219 static int simple_amp_single_add_kcontrol(struct snd_soc_component *component,
220 					  struct simple_amp_single *single)
221 {
222 	struct snd_kcontrol_new control = {
223 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
224 		.name = single->control_name,
225 		.info = simple_amp_single_kctrl_info,
226 		.get = simple_amp_single_kctrl_get,
227 		.put = simple_amp_single_kctrl_put,
228 		.private_value = (unsigned long)single,
229 	};
230 	int ret;
231 
232 	/* Be consistent between single->kctrl_val value and the GPIO value */
233 	ret = simple_amp_single_kctrl_write_gpio(single, single->kctrl_val);
234 	if (ret)
235 		return ret;
236 
237 	return snd_soc_add_component_controls(component, &control, 1);
238 }
239 
simple_amp_multi_ranges_kctrl_to_gpio(u32 kctrl_val,struct simple_amp_ranges * ranges)240 static u32 simple_amp_multi_ranges_kctrl_to_gpio(u32 kctrl_val,
241 						 struct simple_amp_ranges *ranges)
242 {
243 	struct simple_amp_range *range;
244 	u32 index = kctrl_val;
245 	unsigned int i;
246 
247 	for (i = 0; i < ranges->nb_ranges; i++) {
248 		range = &ranges->tab_ranges[i];
249 
250 		if (index < range->nb_points)
251 			return (range->max.gpio_val >= range->min.gpio_val) ?
252 				range->min.gpio_val + index :
253 				range->min.gpio_val - index;
254 
255 		index -= range->nb_points;
256 	}
257 
258 	/*
259 	 * Given index out of possible ranges. This is shouldn't happen.
260 	 * Signal the issue and return the maximum value
261 	 */
262 	WARN(1, "kctrl_val %u out of ranges\n", kctrl_val);
263 	return ranges->tab_ranges[ranges->nb_ranges - 1].max.gpio_val;
264 }
265 
simple_amp_multi_kctrl_write_gpios(struct simple_amp_multi * multi,u32 kctrl_val)266 static int simple_amp_multi_kctrl_write_gpios(struct simple_amp_multi *multi,
267 					      u32 kctrl_val)
268 {
269 	DECLARE_BITMAP(bm, 32);
270 	u32 gpio_val;
271 
272 	if (kctrl_val > multi->kctrl_max)
273 		return -EINVAL;
274 
275 	if (multi->mode == SIMPLE_AMP_MODE_RANGES)
276 		gpio_val = simple_amp_multi_ranges_kctrl_to_gpio(kctrl_val,
277 								 &multi->ranges);
278 	else
279 		gpio_val = kctrl_val;
280 
281 	bitmap_from_arr32(bm, &gpio_val, multi->gpios->ndescs);
282 
283 	return gpiod_multi_set_value_cansleep(multi->gpios, bm);
284 }
285 
simple_amp_multi_kctrl_int_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)286 static int simple_amp_multi_kctrl_int_info(struct snd_kcontrol *kcontrol,
287 					   struct snd_ctl_elem_info *uinfo)
288 {
289 	struct simple_amp_multi *multi = (struct simple_amp_multi *)kcontrol->private_value;
290 
291 	uinfo->count = 1;
292 	uinfo->value.integer.min = 0;
293 	uinfo->value.integer.max = multi->kctrl_max;
294 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
295 	return 0;
296 }
297 
simple_amp_multi_kctrl_int_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)298 static int simple_amp_multi_kctrl_int_get(struct snd_kcontrol *kcontrol,
299 					  struct snd_ctl_elem_value *ucontrol)
300 {
301 	struct simple_amp_multi *multi = (struct simple_amp_multi *)kcontrol->private_value;
302 
303 	ucontrol->value.integer.value[0] = multi->kctrl_val;
304 	return 0;
305 }
306 
simple_amp_multi_kctrl_int_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)307 static int simple_amp_multi_kctrl_int_put(struct snd_kcontrol *kcontrol,
308 					  struct snd_ctl_elem_value *ucontrol)
309 {
310 	struct simple_amp_multi *multi = (struct simple_amp_multi *)kcontrol->private_value;
311 	u32 kctrl_val;
312 	int ret;
313 
314 	kctrl_val = ucontrol->value.integer.value[0];
315 
316 	if (kctrl_val == multi->kctrl_val)
317 		return 0;
318 
319 	ret = simple_amp_multi_kctrl_write_gpios(multi, kctrl_val);
320 	if (ret)
321 		return ret;
322 
323 	multi->kctrl_val = kctrl_val;
324 
325 	return 1; /* The value changed */
326 }
327 
simple_amp_multi_kctrl_enum_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)328 static int simple_amp_multi_kctrl_enum_info(struct snd_kcontrol *kcontrol,
329 					    struct snd_ctl_elem_info *uinfo)
330 {
331 	struct simple_amp_multi *multi = (struct simple_amp_multi *)kcontrol->private_value;
332 
333 	return snd_ctl_enum_info(uinfo, 1, multi->labels.nb_labels,
334 				 multi->labels.tab_labels);
335 }
336 
simple_amp_multi_kctrl_enum_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)337 static int simple_amp_multi_kctrl_enum_get(struct snd_kcontrol *kcontrol,
338 					   struct snd_ctl_elem_value *ucontrol)
339 {
340 	struct simple_amp_multi *multi = (struct simple_amp_multi *)kcontrol->private_value;
341 
342 	ucontrol->value.enumerated.item[0] = multi->kctrl_val;
343 	return 0;
344 }
345 
simple_amp_multi_kctrl_enum_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)346 static int simple_amp_multi_kctrl_enum_put(struct snd_kcontrol *kcontrol,
347 					   struct snd_ctl_elem_value *ucontrol)
348 {
349 	struct simple_amp_multi *multi = (struct simple_amp_multi *)kcontrol->private_value;
350 	u32 kctrl_val;
351 	int ret;
352 
353 	kctrl_val = ucontrol->value.enumerated.item[0];
354 
355 	if (kctrl_val == multi->kctrl_val)
356 		return 0;
357 
358 	ret = simple_amp_multi_kctrl_write_gpios(multi, kctrl_val);
359 	if (ret)
360 		return ret;
361 
362 	multi->kctrl_val = kctrl_val;
363 
364 	return 1; /* The value changed */
365 }
366 
simple_amp_alloc_tlv_ranges(const struct simple_amp_ranges * ranges)367 static unsigned int *simple_amp_alloc_tlv_ranges(const struct simple_amp_ranges *ranges)
368 {
369 	unsigned int index;
370 	unsigned int *tlv;
371 	unsigned int *t;
372 	unsigned int i;
373 
374 	tlv = kzalloc_objs(*tlv, 2 + ranges->nb_ranges * 6, GFP_KERNEL);
375 	if (!tlv)
376 		return NULL;
377 
378 	t = tlv;
379 
380 	/* Fill first TLV */
381 	*t++ = SNDRV_CTL_TLVT_DB_RANGE; /* Tag */
382 	*t++ = ranges->nb_ranges * 6 * sizeof(*tlv); /* Len */
383 	/* Ranges are sorted from lower to higher value */
384 	index = 0;
385 	for (i = 0; i < ranges->nb_ranges; i++) {
386 		/* Fill range item i */
387 		*t++ = index;  /* min */
388 		index += ranges->tab_ranges[i].nb_points;
389 		*t++ = index - 1;  /* max */
390 		*t++ = SNDRV_CTL_TLVT_DB_MINMAX; /* Tag */
391 		*t++ = 2 * sizeof(*tlv); /* Len */
392 		*t++ = ranges->tab_ranges[i].min.gain_db; /* min_dB */
393 		*t++ = ranges->tab_ranges[i].max.gain_db; /* max_dB */
394 	}
395 
396 	return tlv;
397 }
398 
simple_amp_multi_add_kcontrol(struct snd_soc_component * component,struct simple_amp_multi * multi)399 static int simple_amp_multi_add_kcontrol(struct snd_soc_component *component,
400 					 struct simple_amp_multi *multi)
401 {
402 	struct snd_kcontrol_new control = {
403 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
404 		.name = multi->control_name,
405 		.info = simple_amp_multi_kctrl_int_info,
406 		.get = simple_amp_multi_kctrl_int_get,
407 		.put = simple_amp_multi_kctrl_int_put,
408 		.private_value = (unsigned long)multi,
409 	};
410 	int ret;
411 
412 	switch (multi->mode) {
413 	case SIMPLE_AMP_MODE_RANGES:
414 		multi->tlv_array = simple_amp_alloc_tlv_ranges(&multi->ranges);
415 		if (!multi->tlv_array)
416 			return -ENOMEM;
417 
418 		control.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
419 				 SNDRV_CTL_ELEM_ACCESS_READWRITE;
420 		control.tlv.p = multi->tlv_array;
421 		break;
422 
423 	case SIMPLE_AMP_MODE_LABELS:
424 		/* Use enumerated values */
425 		control.info = simple_amp_multi_kctrl_enum_info;
426 		control.get = simple_amp_multi_kctrl_enum_get;
427 		control.put = simple_amp_multi_kctrl_enum_put;
428 		break;
429 
430 	case SIMPLE_AMP_MODE_NONE:
431 		/* Already set control configuration is enough */
432 		break;
433 
434 	default:
435 		return -EINVAL;
436 	}
437 
438 	/* Be consistent between multi->kctrl_val value and the GPIOs value */
439 	ret = simple_amp_multi_kctrl_write_gpios(multi, multi->kctrl_val);
440 	if (ret)
441 		goto err_free_tlv_array;
442 
443 	ret = snd_soc_add_component_controls(component, &control, 1);
444 	if (ret)
445 		goto err_free_tlv_array;
446 
447 	return 0;
448 
449 err_free_tlv_array:
450 	kfree(multi->tlv_array);
451 	return ret;
452 }
453 
simple_amp_add_basic_dapm(struct snd_soc_component * component)454 static int simple_amp_add_basic_dapm(struct snd_soc_component *component)
455 {
456 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
457 	struct simple_amp *simple_amp = snd_soc_component_get_drvdata(component);
458 	struct device *dev = component->dev;
459 	int ret;
460 
461 	/* Add basic dapm widgets and routes */
462 	ret = snd_soc_dapm_new_controls(dapm, simple_amp->data->dapm_widgets,
463 					simple_amp->data->num_dapm_widgets);
464 	if (ret) {
465 		dev_err(dev, "Failed to add basic dapm widgets (%d)\n", ret);
466 		return ret;
467 	}
468 
469 	ret = snd_soc_dapm_add_routes(dapm, simple_amp->data->dapm_routes,
470 				      simple_amp->data->num_dapm_routes);
471 	if (ret) {
472 		dev_err(dev, "Failed to add basic dapm routes (%d)\n", ret);
473 		return ret;
474 	}
475 
476 	return 0;
477 }
478 
479 struct simple_amp_supply {
480 	const char *prop_name;
481 	const struct snd_soc_dapm_widget dapm_widget;
482 	const struct snd_soc_dapm_route dapm_route;
483 };
484 
485 static const struct simple_amp_supply simple_amp_supplies[] = {
486 	{
487 		.prop_name = "vddio-supply",
488 		.dapm_widget = SND_SOC_DAPM_REGULATOR_SUPPLY("vddio", 0, 0),
489 		.dapm_route = { "PGA", NULL, "vddio" },
490 	}, {
491 		.prop_name = "vdda1-supply",
492 		.dapm_widget = SND_SOC_DAPM_REGULATOR_SUPPLY("vdda1", 0, 0),
493 		.dapm_route = { "PGA", NULL, "vdda1" },
494 	}, {
495 		.prop_name = "vdda2-supply",
496 		.dapm_widget = SND_SOC_DAPM_REGULATOR_SUPPLY("vdda2", 0, 0),
497 		.dapm_route = { "PGA", NULL, "vdda2" },
498 	},
499 	{ /* End of list */}
500 };
501 
simple_amp_add_power_supplies(struct snd_soc_component * component)502 static int simple_amp_add_power_supplies(struct snd_soc_component *component)
503 {
504 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
505 	struct simple_amp *simple_amp = snd_soc_component_get_drvdata(component);
506 	const struct simple_amp_supply *supply;
507 	struct device *dev = component->dev;
508 	int ret;
509 
510 	/*
511 	 * Those additional power supplies are attached to the PGA.
512 	 * If PGA is not supported, simply skipped them.
513 	 */
514 	if (!(simple_amp->data->supports & SIMPLE_AUDIO_SUPPORT_PGA)) {
515 		dev_err(dev, "Extra power supplied need PGA\n");
516 		return -EINVAL;
517 	}
518 
519 	supply = simple_amp_supplies;
520 	do {
521 		if (!of_property_present(dev->of_node, supply->prop_name))
522 			continue;
523 
524 		ret = snd_soc_dapm_new_controls(dapm, &supply->dapm_widget, 1);
525 		if (ret) {
526 			dev_err(dev, "Failed to add control for '%s' (%d)\n",
527 				supply->prop_name, ret);
528 			return ret;
529 		}
530 		ret = snd_soc_dapm_add_routes(dapm, &supply->dapm_route, 1);
531 		if (ret) {
532 			dev_err(dev, "Failed to add route for '%s' (%d)\n",
533 				supply->prop_name, ret);
534 			return ret;
535 		}
536 	} while ((++supply)->prop_name);
537 
538 	return 0;
539 }
540 
simple_amp_component_probe(struct snd_soc_component * component)541 static int simple_amp_component_probe(struct snd_soc_component *component)
542 {
543 	struct simple_amp *simple_amp = snd_soc_component_get_drvdata(component);
544 	int ret;
545 
546 	/* Add basic dapm widgets and routes */
547 	ret = simple_amp_add_basic_dapm(component);
548 	if (ret)
549 		return ret;
550 
551 	/* Add additional power supplies */
552 	if (simple_amp->data->supports & SIMPLE_AUDIO_SUPPORT_POWER_SUPPLIES) {
553 		ret = simple_amp_add_power_supplies(component);
554 		if (ret)
555 			return ret;
556 	}
557 
558 	if (simple_amp->mute.gpio) {
559 		/*
560 		 * The name of the GPIO used is mute. According to this name, 1
561 		 * means muted and 0 means un-muted.
562 		 *
563 		 * An inversion is expected by ALSA. Indeed from ALSA point of
564 		 * view, 1 means 'on' (un-muted) and 0 means 'off' (muted).
565 		 */
566 		simple_amp->mute.is_inverted = true;
567 		simple_amp->mute.kctrl_val = 1; /* Un-muted */
568 		ret = simple_amp_single_add_kcontrol(component, &simple_amp->mute);
569 		if (ret)
570 			return ret;
571 	}
572 
573 	if (simple_amp->bypass.gpio) {
574 		ret = simple_amp_single_add_kcontrol(component, &simple_amp->bypass);
575 		if (ret)
576 			return ret;
577 	}
578 
579 	if (simple_amp->gain.gpios) {
580 		ret = simple_amp_multi_add_kcontrol(component, &simple_amp->gain);
581 		if (ret)
582 			return ret;
583 	}
584 
585 	return 0;
586 }
587 
simple_amp_component_remove(struct snd_soc_component * component)588 static void simple_amp_component_remove(struct snd_soc_component *component)
589 {
590 	struct simple_amp *simple_amp = snd_soc_component_get_drvdata(component);
591 
592 	kfree(simple_amp->gain.tlv_array);
593 	simple_amp->gain.tlv_array = NULL;
594 }
595 
596 static const struct snd_soc_component_driver simple_amp_component_driver = {
597 	.probe = simple_amp_component_probe,
598 	.remove = simple_amp_component_remove,
599 };
600 
simple_amp_parse_single_gpio(struct device * dev,struct simple_amp_single * single,const char * gpio_property)601 static int simple_amp_parse_single_gpio(struct device *dev,
602 					struct simple_amp_single *single,
603 					const char *gpio_property)
604 {
605 	/* Start with the inactive value */
606 	single->is_inverted = false;
607 	single->kctrl_val = 0;
608 	single->gpio = devm_gpiod_get_optional(dev, gpio_property, GPIOD_OUT_LOW);
609 	if (IS_ERR(single->gpio))
610 		return dev_err_probe(dev, PTR_ERR(single->gpio),
611 				     "Failed to get '%s' gpio\n",
612 				     gpio_property);
613 	return 0;
614 }
615 
simple_amp_cmp_ranges(const void * a,const void * b)616 static int simple_amp_cmp_ranges(const void *a, const void *b)
617 {
618 	const struct simple_amp_range *a_range = a;
619 	const struct simple_amp_range *b_range = b;
620 
621 	/* Ranges a and b don't overlap. This has been already checked */
622 
623 	return a_range->min.gain_db - b_range->max.gain_db;
624 }
625 
simple_amp_check_new_range(const struct simple_amp_range * new_range,const struct simple_amp_range * tab_ranges,unsigned int nb_ranges)626 static int simple_amp_check_new_range(const struct simple_amp_range *new_range,
627 				      const struct simple_amp_range *tab_ranges,
628 				      unsigned int nb_ranges)
629 {
630 	unsigned int i;
631 
632 	for (i = 0; i < nb_ranges; i++) {
633 		/* Check for range overlaps */
634 		if (new_range->min.gain_db >= tab_ranges[i].min.gain_db &&
635 		    new_range->min.gain_db <= tab_ranges[i].max.gain_db)
636 			return -EINVAL;
637 
638 		if (new_range->max.gain_db >= tab_ranges[i].min.gain_db &&
639 		    new_range->max.gain_db <= tab_ranges[i].max.gain_db)
640 			return -EINVAL;
641 
642 		if (new_range->min.gain_db <= tab_ranges[i].min.gain_db &&
643 		    new_range->max.gain_db >= tab_ranges[i].max.gain_db)
644 			return -EINVAL;
645 	}
646 	return 0;
647 }
648 
simple_amp_parse_ranges(struct device * dev,struct simple_amp_multi * multi,const char * ranges_property)649 static int simple_amp_parse_ranges(struct device *dev,
650 				   struct simple_amp_multi *multi,
651 				   const char *ranges_property)
652 {
653 	struct simple_amp_ranges *ranges = &multi->ranges;
654 	struct simple_amp_range *range;
655 	struct device_node *np = dev->of_node;
656 	struct simple_amp_point first_point;
657 	unsigned int max_gpio_val;
658 	unsigned int i;
659 	int ret;
660 	u32 u;
661 	s32 s;
662 
663 	max_gpio_val = (1 << multi->gpios->ndescs) - 1;
664 
665 	ret = of_property_count_u32_elems(np, ranges_property);
666 	if (ret < 0)
667 		return ret;
668 
669 	/* The ranges array cannot be empty */
670 	if (ret == 0)
671 		return -EINVAL;
672 	/*
673 	 * One range item is composed of 2 points and each point is composed of
674 	 * 2 values.
675 	 */
676 	if (ret % 4)
677 		return -EINVAL;
678 
679 	ranges->nb_ranges = ret / 4;
680 
681 	/* The worst case is one range per possible gpio value */
682 	if (ranges->nb_ranges > max_gpio_val + 1)
683 		return -EINVAL;
684 
685 	ranges->tab_ranges = devm_kcalloc(dev, ranges->nb_ranges,
686 					  sizeof(*ranges->tab_ranges),
687 					  GFP_KERNEL);
688 	if (!ranges->tab_ranges)
689 		return -ENOMEM;
690 
691 	multi->kctrl_max = 0;
692 	for (i = 0; i < ranges->nb_ranges; i++) {
693 		range = &ranges->tab_ranges[i];
694 
695 		/* First gpios value */
696 		ret = of_property_read_u32_index(np, ranges_property, i * 4, &u);
697 		if (ret)
698 			return ret;
699 		if (u > max_gpio_val)
700 			return -EINVAL;
701 
702 		range->min.gpio_val = u;
703 
704 		/* First Gain value */
705 		ret = of_property_read_s32_index(np, ranges_property, i * 4 + 1, &s);
706 		if (ret)
707 			return ret;
708 
709 		range->min.gain_db = s;
710 
711 		/* Second gpios value */
712 		ret = of_property_read_u32_index(np, ranges_property, i * 4 + 2, &u);
713 		if (ret)
714 			return ret;
715 		if (u > max_gpio_val)
716 			return -EINVAL;
717 
718 		range->max.gpio_val = u;
719 
720 		/* Second Gain value */
721 		ret = of_property_read_s32_index(np, ranges_property, i * 4 + 3, &s);
722 		if (ret)
723 			return ret;
724 
725 		range->max.gain_db = s;
726 
727 		/* Save the first point for later usage */
728 		if (i == 0)
729 			first_point = range->min;
730 
731 		/* Fix min and max if needed */
732 		if (range->min.gain_db > range->max.gain_db)
733 			swap(range->min, range->max);
734 
735 		ret = simple_amp_check_new_range(range, ranges->tab_ranges, i);
736 		if (ret)
737 			return ret;
738 
739 		range->nb_points = abs_diff(range->min.gpio_val,
740 					    range->max.gpio_val) + 1;
741 
742 		multi->kctrl_max += range->nb_points;
743 	}
744 
745 	multi->kctrl_max -= 1;
746 
747 	/* Sort the tab_range array by gain_db value */
748 	sort(ranges->tab_ranges, ranges->nb_ranges, sizeof(*ranges->tab_ranges),
749 	     simple_amp_cmp_ranges, NULL);
750 
751 	/*
752 	 * multi->kctrl_val is the index in tab_ranges.
753 	 *
754 	 * Choose to have the initial amplification value set to the first point
755 	 * available in the first range available in the tab_ranges array before
756 	 * sorting.
757 	 *
758 	 * This first point has been identified before sorting. Search for it in
759 	 * the sorted array in order to set the multi->kctrl_val initial value.
760 	 */
761 	multi->kctrl_val = 0;
762 	for (i = 0; i < ranges->nb_ranges; i++) {
763 		range = &ranges->tab_ranges[i];
764 
765 		if (range->min.gpio_val == first_point.gpio_val &&
766 		    range->min.gain_db == first_point.gain_db)
767 			break;
768 
769 		multi->kctrl_val += range->nb_points;
770 
771 		if (range->max.gpio_val == first_point.gpio_val &&
772 		    range->max.gain_db == first_point.gain_db) {
773 			multi->kctrl_val--;
774 			break;
775 		}
776 	}
777 
778 	return 0;
779 }
780 
simple_amp_parse_labels(struct device * dev,struct simple_amp_multi * multi,const char * labels_property)781 static int simple_amp_parse_labels(struct device *dev,
782 				   struct simple_amp_multi *multi,
783 				   const char *labels_property)
784 {
785 	struct simple_amp_labels *labels = &multi->labels;
786 	struct device_node *np = dev->of_node;
787 	int ret;
788 
789 	ret = of_property_count_strings(np, labels_property);
790 	if (ret < 0)
791 		return ret;
792 
793 	/* The labels array cannot be empty */
794 	if (ret == 0)
795 		return -EINVAL;
796 
797 	labels->nb_labels = ret;
798 	if (labels->nb_labels > (1 << multi->gpios->ndescs))
799 		return -EINVAL;
800 
801 	labels->tab_labels = devm_kcalloc(dev, labels->nb_labels,
802 					  sizeof(*labels->tab_labels),
803 					  GFP_KERNEL);
804 	if (!labels->tab_labels)
805 		return -ENOMEM;
806 
807 	multi->kctrl_max = labels->nb_labels - 1;
808 	multi->kctrl_val = 0;
809 
810 	return of_property_read_string_array(np, labels_property, labels->tab_labels,
811 					     labels->nb_labels);
812 }
813 
simple_amp_parse_multi_gpio(struct device * dev,struct simple_amp_multi * multi,const char * gpios_property,const char * ranges_property,const char * labels_property)814 static int simple_amp_parse_multi_gpio(struct device *dev,
815 				       struct simple_amp_multi *multi,
816 				       const char *gpios_property,
817 				       const char *ranges_property,
818 				       const char *labels_property)
819 {
820 	struct device_node *np = dev->of_node;
821 	int ret;
822 
823 	/* Start with the value 0 (GPIO inactive). Can be changed later */
824 	multi->kctrl_val = 0;
825 	multi->gpios = devm_gpiod_get_array_optional(dev, gpios_property, GPIOD_OUT_LOW);
826 	if (IS_ERR(multi->gpios))
827 		return dev_err_probe(dev, PTR_ERR(multi->gpios),
828 				     "Failed to get '%s' gpios\n",
829 				     gpios_property);
830 	if (!multi->gpios)
831 		return 0;
832 
833 	if (multi->gpios->ndescs > 16)
834 		return dev_err_probe(dev, -EINVAL,
835 				     "Number of '%s' gpios limited to 16\n",
836 				     gpios_property);
837 
838 	/* Set default value for the kctrl_max. Can be changed later */
839 	multi->kctrl_max = (1 << multi->gpios->ndescs) - 1;
840 
841 	multi->mode = SIMPLE_AMP_MODE_NONE;
842 	if (of_property_present(np, ranges_property)) {
843 		ret = simple_amp_parse_ranges(dev, multi, ranges_property);
844 		if (ret < 0)
845 			return dev_err_probe(dev, ret, "Failed to parse '%s'\n",
846 					     ranges_property);
847 		multi->mode = SIMPLE_AMP_MODE_RANGES;
848 	} else if (of_property_present(np, labels_property)) {
849 		ret = simple_amp_parse_labels(dev, multi, labels_property);
850 		if (ret < 0)
851 			return dev_err_probe(dev, ret, "Failed to parse '%s'\n",
852 					     labels_property);
853 
854 		multi->mode = SIMPLE_AMP_MODE_LABELS;
855 	}
856 
857 	return 0;
858 }
859 
simple_amp_probe(struct platform_device * pdev)860 static int simple_amp_probe(struct platform_device *pdev)
861 {
862 	struct device *dev = &pdev->dev;
863 	struct simple_amp *simple_amp;
864 	int ret;
865 
866 	simple_amp = devm_kzalloc(dev, sizeof(*simple_amp), GFP_KERNEL);
867 	if (!simple_amp)
868 		return -ENOMEM;
869 	platform_set_drvdata(pdev, simple_amp);
870 
871 	simple_amp->data = of_device_get_match_data(dev);
872 	if (!simple_amp->data)
873 		return -EINVAL;
874 
875 	simple_amp->gpiod_enable = devm_gpiod_get_optional(dev, "enable",
876 							   GPIOD_OUT_LOW);
877 	if (IS_ERR(simple_amp->gpiod_enable))
878 		return dev_err_probe(dev, PTR_ERR(simple_amp->gpiod_enable),
879 				     "Failed to get 'enable' gpio");
880 
881 	if (simple_amp->data->supports & SIMPLE_AUDIO_SUPPORT_MUTE) {
882 		ret = simple_amp_parse_single_gpio(dev, &simple_amp->mute, "mute");
883 		if (ret)
884 			return ret;
885 	}
886 
887 	if (simple_amp->data->supports & SIMPLE_AUDIO_SUPPORT_BYPASS) {
888 		ret = simple_amp_parse_single_gpio(dev, &simple_amp->bypass, "bypass");
889 		if (ret)
890 			return ret;
891 	}
892 
893 	if (simple_amp->data->supports & SIMPLE_AUDIO_SUPPORT_PGA) {
894 		ret = simple_amp_parse_multi_gpio(dev, &simple_amp->gain, "gain",
895 						  "gain-ranges", "gain-labels");
896 		if (ret)
897 			return ret;
898 	}
899 
900 	/* Set controls name */
901 	simple_amp->gain.control_name = "Volume";
902 	simple_amp->mute.control_name = "Switch";
903 	simple_amp->bypass.control_name = "Bypass Switch";
904 
905 	if (simple_amp->gain.mode == SIMPLE_AMP_MODE_LABELS) {
906 		/*
907 		 * The gain widget control will use enumerated values.
908 		 *
909 		 * Having just "Voltage" and "Switch" widget names with
910 		 * enumerated values and boolean value can confuse ALSA in terms
911 		 * of possible values (strings).
912 		 *
913 		 * Make things clear and avoid the just "Switch" name in that
914 		 * case.
915 		 */
916 		simple_amp->mute.control_name = "Out Switch";
917 	}
918 
919 	return devm_snd_soc_register_component(dev,
920 					       &simple_amp_component_driver,
921 					       NULL, 0);
922 }
923 
924 static const struct simple_amp_data simple_audio_amplifier_data = {
925 	.dapm_widgets		= simple_amp_dapm_widgets,
926 	.num_dapm_widgets	= ARRAY_SIZE(simple_amp_dapm_widgets),
927 	.dapm_routes		= simple_amp_dapm_routes,
928 	.num_dapm_routes	= ARRAY_SIZE(simple_amp_dapm_routes),
929 };
930 
931 static const struct simple_amp_data simple_audio_mono_pga_data = {
932 	.supports		= SIMPLE_AUDIO_SUPPORT_PGA |
933 				  SIMPLE_AUDIO_SUPPORT_POWER_SUPPLIES |
934 				  SIMPLE_AUDIO_SUPPORT_MUTE |
935 				  SIMPLE_AUDIO_SUPPORT_BYPASS,
936 	.dapm_widgets		= simple_amp_mono_pga_dapm_widgets,
937 	.num_dapm_widgets	= ARRAY_SIZE(simple_amp_mono_pga_dapm_widgets),
938 	.dapm_routes		= simple_amp_mono_pga_dapm_routes,
939 	.num_dapm_routes	= ARRAY_SIZE(simple_amp_mono_pga_dapm_routes),
940 };
941 
942 static const struct simple_amp_data simple_audio_stereo_pga_data = {
943 	.supports		= SIMPLE_AUDIO_SUPPORT_PGA |
944 				  SIMPLE_AUDIO_SUPPORT_POWER_SUPPLIES |
945 				  SIMPLE_AUDIO_SUPPORT_MUTE |
946 				  SIMPLE_AUDIO_SUPPORT_BYPASS,
947 	.dapm_widgets		= simple_amp_stereo_pga_dapm_widgets,
948 	.num_dapm_widgets	= ARRAY_SIZE(simple_amp_stereo_pga_dapm_widgets),
949 	.dapm_routes		= simple_amp_stereo_pga_dapm_routes,
950 	.num_dapm_routes	= ARRAY_SIZE(simple_amp_stereo_pga_dapm_routes),
951 };
952 
953 static const struct of_device_id simple_amp_ids[] = {
954 	{ .compatible = "dioo,dio2125",		  .data = &simple_audio_amplifier_data},
955 	{ .compatible = "simple-audio-amplifier", .data = &simple_audio_amplifier_data},
956 	{ .compatible = "gpio-audio-amp-mono",	  .data = &simple_audio_mono_pga_data},
957 	{ .compatible = "gpio-audio-amp-stereo",  .data = &simple_audio_stereo_pga_data},
958 	{ }
959 };
960 MODULE_DEVICE_TABLE(of, simple_amp_ids);
961 
962 static struct platform_driver simple_amp_driver = {
963 	.driver = {
964 		.name = "simple-amplifier",
965 		.of_match_table = simple_amp_ids,
966 	},
967 	.probe = simple_amp_probe,
968 };
969 
970 module_platform_driver(simple_amp_driver);
971 
972 MODULE_DESCRIPTION("ASoC Simple Audio Amplifier driver");
973 MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
974 MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>");
975 MODULE_LICENSE("GPL");
976