diff options
author | Jarkko Nikula <jarkko.nikula@linux.intel.com> | 2014-05-26 07:34:37 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-05-26 10:26:00 -0400 |
commit | f025d3b9c64e1f7feb75a559d4a12f5f8c6a4a25 (patch) | |
tree | 819909f51afd408c50379e69c55d29337365d02c /sound/soc/soc-jack.c | |
parent | 50dfb69d1bb0062e2811547525c73e9a45a423e9 (diff) |
ASoC: jack: Add support for GPIO descriptor defined jack pins
Allow jack GPIO pins be defined also using GPIO descriptor-based interface
in addition to legacy GPIO numbers. This is done by adding two new fields to
struct snd_soc_jack_gpio: idx and gpiod_dev.
Legacy GPIO numbers are used only when GPIO consumer device gpiod_dev is
NULL and otherwise idx is the descriptor index within the GPIO consumer
device.
New function snd_soc_jack_add_gpiods() is added for typical cases where all
GPIO descriptor jack pins belong to same GPIO consumer device. For other
cases the caller must set the gpiod_dev in struct snd_soc_jack_gpio before
calling snd_soc_jack_add_gpios().
Signed-off-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/soc-jack.c')
-rw-r--r-- | sound/soc/soc-jack.c | 73 |
1 files changed, 57 insertions, 16 deletions
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7203842fea66..d0d98810af91 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -298,24 +298,41 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
298 | int i, ret; | 298 | int i, ret; |
299 | 299 | ||
300 | for (i = 0; i < count; i++) { | 300 | for (i = 0; i < count; i++) { |
301 | if (!gpio_is_valid(gpios[i].gpio)) { | ||
302 | dev_err(jack->codec->dev, "ASoC: Invalid gpio %d\n", | ||
303 | gpios[i].gpio); | ||
304 | ret = -EINVAL; | ||
305 | goto undo; | ||
306 | } | ||
307 | if (!gpios[i].name) { | 301 | if (!gpios[i].name) { |
308 | dev_err(jack->codec->dev, "ASoC: No name for gpio %d\n", | 302 | dev_err(jack->codec->dev, |
309 | gpios[i].gpio); | 303 | "ASoC: No name for gpio at index %d\n", i); |
310 | ret = -EINVAL; | 304 | ret = -EINVAL; |
311 | goto undo; | 305 | goto undo; |
312 | } | 306 | } |
313 | 307 | ||
314 | ret = gpio_request(gpios[i].gpio, gpios[i].name); | 308 | if (gpios[i].gpiod_dev) { |
315 | if (ret) | 309 | /* GPIO descriptor */ |
316 | goto undo; | 310 | gpios[i].desc = gpiod_get_index(gpios[i].gpiod_dev, |
317 | 311 | gpios[i].name, | |
318 | gpios[i].desc = gpio_to_desc(gpios[i].gpio); | 312 | gpios[i].idx); |
313 | if (IS_ERR(gpios[i].desc)) { | ||
314 | ret = PTR_ERR(gpios[i].desc); | ||
315 | dev_err(gpios[i].gpiod_dev, | ||
316 | "ASoC: Cannot get gpio at index %d: %d", | ||
317 | i, ret); | ||
318 | goto undo; | ||
319 | } | ||
320 | } else { | ||
321 | /* legacy GPIO number */ | ||
322 | if (!gpio_is_valid(gpios[i].gpio)) { | ||
323 | dev_err(jack->codec->dev, | ||
324 | "ASoC: Invalid gpio %d\n", | ||
325 | gpios[i].gpio); | ||
326 | ret = -EINVAL; | ||
327 | goto undo; | ||
328 | } | ||
329 | |||
330 | ret = gpio_request(gpios[i].gpio, gpios[i].name); | ||
331 | if (ret) | ||
332 | goto undo; | ||
333 | |||
334 | gpios[i].desc = gpio_to_desc(gpios[i].gpio); | ||
335 | } | ||
319 | 336 | ||
320 | ret = gpiod_direction_input(gpios[i].desc); | 337 | ret = gpiod_direction_input(gpios[i].desc); |
321 | if (ret) | 338 | if (ret) |
@@ -336,9 +353,9 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
336 | if (gpios[i].wake) { | 353 | if (gpios[i].wake) { |
337 | ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); | 354 | ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); |
338 | if (ret != 0) | 355 | if (ret != 0) |
339 | dev_err(jack->codec->dev, "ASoC: " | 356 | dev_err(jack->codec->dev, |
340 | "Failed to mark GPIO %d as wake source: %d\n", | 357 | "ASoC: Failed to mark GPIO at index %d as wake source: %d\n", |
341 | gpios[i].gpio, ret); | 358 | i, ret); |
342 | } | 359 | } |
343 | 360 | ||
344 | /* Expose GPIO value over sysfs for diagnostic purposes */ | 361 | /* Expose GPIO value over sysfs for diagnostic purposes */ |
@@ -361,6 +378,30 @@ undo: | |||
361 | EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios); | 378 | EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios); |
362 | 379 | ||
363 | /** | 380 | /** |
381 | * snd_soc_jack_add_gpiods - Associate GPIO descriptor pins with an ASoC jack | ||
382 | * | ||
383 | * @gpiod_dev: GPIO consumer device | ||
384 | * @jack: ASoC jack | ||
385 | * @count: number of pins | ||
386 | * @gpios: array of gpio pins | ||
387 | * | ||
388 | * This function will request gpio, set data direction and request irq | ||
389 | * for each gpio in the array. | ||
390 | */ | ||
391 | int snd_soc_jack_add_gpiods(struct device *gpiod_dev, | ||
392 | struct snd_soc_jack *jack, | ||
393 | int count, struct snd_soc_jack_gpio *gpios) | ||
394 | { | ||
395 | int i; | ||
396 | |||
397 | for (i = 0; i < count; i++) | ||
398 | gpios[i].gpiod_dev = gpiod_dev; | ||
399 | |||
400 | return snd_soc_jack_add_gpios(jack, count, gpios); | ||
401 | } | ||
402 | EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods); | ||
403 | |||
404 | /** | ||
364 | * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack | 405 | * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack |
365 | * | 406 | * |
366 | * @jack: ASoC jack | 407 | * @jack: ASoC jack |