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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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); 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 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 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 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 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 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 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 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 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 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 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 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 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