Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: wm5100: Convert to GPIO descriptors

This converts the WM5100 codec to use GPIO descriptors, a pretty
straight-forward conversion with the following peculiarities:

- The driver is instantiating a GPIO chip named wm5100, and the
headphone polarity detection GPIO is lifted from there. We add
this to the GPIO descriptor table as well, and we can then get
rid of also the base address for the GPIO chip from the
platform data and just use dynamic numbering.

- Fix up the only in-tree user which is the Cragganmore 6410
module.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20231208-descriptors-sound-wlf-v1-4-c4dab6f521ec@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Linus Walleij and committed by
Mark Brown
8563cfe3 0119b2a2

+52 -76
+13 -4
arch/arm/mach-s3c/mach-crag6410-module.c
··· 70 70 }, 71 71 }; 72 72 73 + static struct gpiod_lookup_table wm5100_gpiod_table = { 74 + .dev_id = "1-001a", /* Device 001a on I2C bus 1 */ 75 + .table = { 76 + GPIO_LOOKUP("GPION", 7, 77 + "wlf,ldo1ena", GPIO_ACTIVE_HIGH), 78 + GPIO_LOOKUP("wm5100", 3, 79 + "hp-pol", GPIO_ACTIVE_HIGH), 80 + { }, 81 + }, 82 + }; 83 + 73 84 static struct wm5100_pdata wm5100_pdata = { 74 - .ldo_ena = S3C64XX_GPN(7), 75 85 .irq_flags = IRQF_TRIGGER_HIGH, 76 - .gpio_base = CODEC_GPIO_BASE, 77 86 78 87 .in_mode = { 79 88 WM5100_IN_DIFF, ··· 91 82 WM5100_IN_SE, 92 83 }, 93 84 94 - .hp_pol = CODEC_GPIO_BASE + 3, 95 85 .jack_modes = { 96 86 { WM5100_MICDET_MICBIAS3, 0, 0 }, 97 87 { WM5100_MICDET_MICBIAS2, 1, 1 }, ··· 374 366 { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory", 375 367 .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) }, 376 368 { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman", 377 - .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs) }, 369 + .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs), 370 + .gpiod_table = &wm5100_gpiod_table }, 378 371 { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" }, 379 372 { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill", 380 373 .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs),
-4
include/sound/wm5100.h
··· 36 36 #define WM5100_GPIO_SET 0x10000 37 37 38 38 struct wm5100_pdata { 39 - int reset; /** GPIO controlling /RESET, if any */ 40 - int ldo_ena; /** GPIO controlling LODENA, if any */ 41 - int hp_pol; /** GPIO controlling headset polarity, if any */ 42 39 int irq_flags; 43 - int gpio_base; 44 40 45 41 struct wm5100_jack_mode jack_modes[2]; 46 42
+39 -68
sound/soc/codecs/wm5100.c
··· 15 15 #include <linux/pm.h> 16 16 #include <linux/gcd.h> 17 17 #include <linux/gpio/driver.h> 18 - #include <linux/gpio.h> 18 + #include <linux/gpio/consumer.h> 19 19 #include <linux/i2c.h> 20 20 #include <linux/pm_runtime.h> 21 21 #include <linux/regulator/consumer.h> ··· 55 55 struct snd_soc_component *component; 56 56 57 57 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; 58 + struct gpio_desc *reset; 59 + struct gpio_desc *ldo_ena; 60 + struct gpio_desc *hp_pol; 58 61 59 62 int rev; 60 63 ··· 208 205 209 206 static int wm5100_reset(struct wm5100_priv *wm5100) 210 207 { 211 - if (wm5100->pdata.reset) { 212 - gpio_set_value_cansleep(wm5100->pdata.reset, 0); 213 - gpio_set_value_cansleep(wm5100->pdata.reset, 1); 208 + if (wm5100->reset) { 209 + gpiod_set_value_cansleep(wm5100->reset, 1); 210 + gpiod_set_value_cansleep(wm5100->reset, 0); 214 211 215 212 return 0; 216 213 } else { ··· 1977 1974 if (WARN_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes))) 1978 1975 return; 1979 1976 1980 - gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol); 1977 + gpiod_set_value_cansleep(wm5100->hp_pol, mode->hp_pol); 1981 1978 regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1, 1982 1979 WM5100_ACCDET_BIAS_SRC_MASK | 1983 1980 WM5100_ACCDET_SRC, ··· 2302 2299 wm5100->gpio_chip = wm5100_template_chip; 2303 2300 wm5100->gpio_chip.ngpio = 6; 2304 2301 wm5100->gpio_chip.parent = &i2c->dev; 2305 - 2306 - if (wm5100->pdata.gpio_base) 2307 - wm5100->gpio_chip.base = wm5100->pdata.gpio_base; 2308 - else 2309 - wm5100->gpio_chip.base = -1; 2302 + wm5100->gpio_chip.base = -1; 2310 2303 2311 2304 ret = gpiochip_add_data(&wm5100->gpio_chip, wm5100); 2312 2305 if (ret != 0) ··· 2348 2349 snd_soc_dapm_new_controls(dapm, wm5100_dapm_widgets_noirq, 2349 2350 ARRAY_SIZE(wm5100_dapm_widgets_noirq)); 2350 2351 2351 - if (wm5100->pdata.hp_pol) { 2352 - ret = gpio_request_one(wm5100->pdata.hp_pol, 2353 - GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL"); 2354 - if (ret < 0) { 2355 - dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n", 2356 - wm5100->pdata.hp_pol, ret); 2357 - goto err_gpio; 2358 - } 2352 + wm5100->hp_pol = devm_gpiod_get_optional(&i2c->dev, "hp-pol", 2353 + GPIOD_OUT_HIGH); 2354 + if (IS_ERR(wm5100->hp_pol)) { 2355 + ret = PTR_ERR(wm5100->hp_pol); 2356 + dev_err(&i2c->dev, "Failed to request HP_POL GPIO: %d\n", 2357 + ret); 2358 + return ret; 2359 2359 } 2360 2360 2361 2361 return 0; 2362 - 2363 - err_gpio: 2364 - 2365 - return ret; 2366 - } 2367 - 2368 - static void wm5100_remove(struct snd_soc_component *component) 2369 - { 2370 - struct wm5100_priv *wm5100 = snd_soc_component_get_drvdata(component); 2371 - 2372 - if (wm5100->pdata.hp_pol) { 2373 - gpio_free(wm5100->pdata.hp_pol); 2374 - } 2375 2362 } 2376 2363 2377 2364 static const struct snd_soc_component_driver soc_component_dev_wm5100 = { 2378 2365 .probe = wm5100_probe, 2379 - .remove = wm5100_remove, 2380 2366 .set_sysclk = wm5100_set_sysclk, 2381 2367 .set_pll = wm5100_set_fll, 2382 2368 .seq_notifier = wm5100_seq_notifier, ··· 2444 2460 goto err; 2445 2461 } 2446 2462 2447 - if (wm5100->pdata.ldo_ena) { 2448 - ret = gpio_request_one(wm5100->pdata.ldo_ena, 2449 - GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA"); 2450 - if (ret < 0) { 2451 - dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", 2452 - wm5100->pdata.ldo_ena, ret); 2453 - goto err_enable; 2454 - } 2463 + wm5100->ldo_ena = devm_gpiod_get_optional(&i2c->dev, "wlf,ldo1ena", 2464 + GPIOD_OUT_HIGH); 2465 + if (IS_ERR(wm5100->ldo_ena)) { 2466 + ret = PTR_ERR(wm5100->ldo_ena); 2467 + dev_err(&i2c->dev, "Failed to request LDOENA GPIO: %d\n", ret); 2468 + goto err_enable; 2469 + } 2470 + if (wm5100->ldo_ena) { 2471 + gpiod_set_consumer_name(wm5100->ldo_ena, "WM5100 LDOENA"); 2455 2472 msleep(2); 2456 2473 } 2457 2474 2458 - if (wm5100->pdata.reset) { 2459 - ret = gpio_request_one(wm5100->pdata.reset, 2460 - GPIOF_OUT_INIT_HIGH, "WM5100 /RESET"); 2461 - if (ret < 0) { 2462 - dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", 2463 - wm5100->pdata.reset, ret); 2464 - goto err_ldo; 2465 - } 2475 + wm5100->reset = devm_gpiod_get_optional(&i2c->dev, "reset", 2476 + GPIOD_OUT_LOW); 2477 + if (IS_ERR(wm5100->reset)) { 2478 + ret = PTR_ERR(wm5100->reset); 2479 + dev_err(&i2c->dev, "Failed to request /RESET GPIO: %d\n", ret); 2480 + goto err_ldo; 2466 2481 } 2482 + gpiod_set_consumer_name(wm5100->reset, "WM5100 /RESET"); 2467 2483 2468 2484 ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg); 2469 2485 if (ret < 0) { ··· 2603 2619 if (i2c->irq) 2604 2620 free_irq(i2c->irq, wm5100); 2605 2621 wm5100_free_gpio(i2c); 2606 - if (wm5100->pdata.reset) { 2607 - gpio_set_value_cansleep(wm5100->pdata.reset, 0); 2608 - gpio_free(wm5100->pdata.reset); 2609 - } 2622 + gpiod_set_value_cansleep(wm5100->reset, 1); 2610 2623 err_ldo: 2611 - if (wm5100->pdata.ldo_ena) { 2612 - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2613 - gpio_free(wm5100->pdata.ldo_ena); 2614 - } 2624 + gpiod_set_value_cansleep(wm5100->ldo_ena, 0); 2615 2625 err_enable: 2616 2626 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), 2617 2627 wm5100->core_supplies); ··· 2621 2643 if (i2c->irq) 2622 2644 free_irq(i2c->irq, wm5100); 2623 2645 wm5100_free_gpio(i2c); 2624 - if (wm5100->pdata.reset) { 2625 - gpio_set_value_cansleep(wm5100->pdata.reset, 0); 2626 - gpio_free(wm5100->pdata.reset); 2627 - } 2628 - if (wm5100->pdata.ldo_ena) { 2629 - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2630 - gpio_free(wm5100->pdata.ldo_ena); 2631 - } 2646 + gpiod_set_value_cansleep(wm5100->reset, 1); 2647 + gpiod_set_value_cansleep(wm5100->ldo_ena, 0); 2632 2648 } 2633 2649 2634 2650 #ifdef CONFIG_PM ··· 2632 2660 2633 2661 regcache_cache_only(wm5100->regmap, true); 2634 2662 regcache_mark_dirty(wm5100->regmap); 2635 - if (wm5100->pdata.ldo_ena) 2636 - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); 2663 + gpiod_set_value_cansleep(wm5100->ldo_ena, 0); 2637 2664 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), 2638 2665 wm5100->core_supplies); 2639 2666 ··· 2652 2681 return ret; 2653 2682 } 2654 2683 2655 - if (wm5100->pdata.ldo_ena) { 2656 - gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1); 2684 + if (wm5100->ldo_ena) { 2685 + gpiod_set_value_cansleep(wm5100->ldo_ena, 1); 2657 2686 msleep(2); 2658 2687 } 2659 2688