aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-jack.c
diff options
context:
space:
mode:
authorJarkko Nikula <jarkko.nikula@linux.intel.com>2014-05-26 07:34:37 -0400
committerMark Brown <broonie@linaro.org>2014-05-26 10:26:00 -0400
commitf025d3b9c64e1f7feb75a559d4a12f5f8c6a4a25 (patch)
tree819909f51afd408c50379e69c55d29337365d02c /sound/soc/soc-jack.c
parent50dfb69d1bb0062e2811547525c73e9a45a423e9 (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.c73
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:
361EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios); 378EXPORT_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 */
391int 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}
402EXPORT_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