soc-jack.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. * soc-jack.c -- ALSA SoC jack handling
  3. *
  4. * Copyright 2008 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. */
  13. #include <sound/jack.h>
  14. #include <sound/soc.h>
  15. #include <sound/soc-dapm.h>
  16. /**
  17. * snd_soc_jack_new - Create a new jack
  18. * @card: ASoC card
  19. * @id: an identifying string for this jack
  20. * @type: a bitmask of enum snd_jack_type values that can be detected by
  21. * this jack
  22. * @jack: structure to use for the jack
  23. *
  24. * Creates a new jack object.
  25. *
  26. * Returns zero if successful, or a negative error code on failure.
  27. * On success jack will be initialised.
  28. */
  29. int snd_soc_jack_new(struct snd_soc_card *card, const char *id, int type,
  30. struct snd_soc_jack *jack)
  31. {
  32. jack->card = card;
  33. INIT_LIST_HEAD(&jack->pins);
  34. return snd_jack_new(card->codec->card, id, type, &jack->jack);
  35. }
  36. EXPORT_SYMBOL_GPL(snd_soc_jack_new);
  37. /**
  38. * snd_soc_jack_report - Report the current status for a jack
  39. *
  40. * @jack: the jack
  41. * @status: a bitmask of enum snd_jack_type values that are currently detected.
  42. * @mask: a bitmask of enum snd_jack_type values that being reported.
  43. *
  44. * If configured using snd_soc_jack_add_pins() then the associated
  45. * DAPM pins will be enabled or disabled as appropriate and DAPM
  46. * synchronised.
  47. *
  48. * Note: This function uses mutexes and should be called from a
  49. * context which can sleep (such as a workqueue).
  50. */
  51. void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
  52. {
  53. struct snd_soc_codec *codec = jack->card->codec;
  54. struct snd_soc_jack_pin *pin;
  55. int enable;
  56. int oldstatus;
  57. if (!jack) {
  58. WARN_ON_ONCE(!jack);
  59. return;
  60. }
  61. mutex_lock(&codec->mutex);
  62. oldstatus = jack->status;
  63. jack->status &= ~mask;
  64. jack->status |= status;
  65. /* The DAPM sync is expensive enough to be worth skipping */
  66. if (jack->status == oldstatus)
  67. goto out;
  68. list_for_each_entry(pin, &jack->pins, list) {
  69. enable = pin->mask & status;
  70. if (pin->invert)
  71. enable = !enable;
  72. if (enable)
  73. snd_soc_dapm_enable_pin(codec, pin->pin);
  74. else
  75. snd_soc_dapm_disable_pin(codec, pin->pin);
  76. }
  77. snd_soc_dapm_sync(codec);
  78. snd_jack_report(jack->jack, status);
  79. out:
  80. mutex_unlock(&codec->mutex);
  81. }
  82. EXPORT_SYMBOL_GPL(snd_soc_jack_report);
  83. /**
  84. * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack
  85. *
  86. * @jack: ASoC jack
  87. * @count: Number of pins
  88. * @pins: Array of pins
  89. *
  90. * After this function has been called the DAPM pins specified in the
  91. * pins array will have their status updated to reflect the current
  92. * state of the jack whenever the jack status is updated.
  93. */
  94. int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
  95. struct snd_soc_jack_pin *pins)
  96. {
  97. int i;
  98. for (i = 0; i < count; i++) {
  99. if (!pins[i].pin) {
  100. printk(KERN_ERR "No name for pin %d\n", i);
  101. return -EINVAL;
  102. }
  103. if (!pins[i].mask) {
  104. printk(KERN_ERR "No mask for pin %d (%s)\n", i,
  105. pins[i].pin);
  106. return -EINVAL;
  107. }
  108. INIT_LIST_HEAD(&pins[i].list);
  109. list_add(&(pins[i].list), &jack->pins);
  110. }
  111. /* Update to reflect the last reported status; canned jack
  112. * implementations are likely to set their state before the
  113. * card has an opportunity to associate pins.
  114. */
  115. snd_soc_jack_report(jack, 0, 0);
  116. return 0;
  117. }
  118. EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins);