diff options
Diffstat (limited to 'sound/soc/soc-jack.c')
| -rw-r--r-- | sound/soc/soc-jack.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 28346fb2e70c..1d455ab79490 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
| @@ -73,14 +73,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
| 73 | oldstatus = jack->status; | 73 | oldstatus = jack->status; |
| 74 | 74 | ||
| 75 | jack->status &= ~mask; | 75 | jack->status &= ~mask; |
| 76 | jack->status |= status; | 76 | jack->status |= status & mask; |
| 77 | 77 | ||
| 78 | /* The DAPM sync is expensive enough to be worth skipping */ | 78 | /* The DAPM sync is expensive enough to be worth skipping. |
| 79 | if (jack->status == oldstatus) | 79 | * However, empty mask means pin synchronization is desired. */ |
| 80 | if (mask && (jack->status == oldstatus)) | ||
| 80 | goto out; | 81 | goto out; |
| 81 | 82 | ||
| 82 | list_for_each_entry(pin, &jack->pins, list) { | 83 | list_for_each_entry(pin, &jack->pins, list) { |
| 83 | enable = pin->mask & status; | 84 | enable = pin->mask & jack->status; |
| 84 | 85 | ||
| 85 | if (pin->invert) | 86 | if (pin->invert) |
| 86 | enable = !enable; | 87 | enable = !enable; |
| @@ -220,6 +221,9 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
| 220 | if (ret) | 221 | if (ret) |
| 221 | goto err; | 222 | goto err; |
| 222 | 223 | ||
| 224 | INIT_WORK(&gpios[i].work, gpio_work); | ||
| 225 | gpios[i].jack = jack; | ||
| 226 | |||
| 223 | ret = request_irq(gpio_to_irq(gpios[i].gpio), | 227 | ret = request_irq(gpio_to_irq(gpios[i].gpio), |
| 224 | gpio_handler, | 228 | gpio_handler, |
| 225 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 229 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| @@ -228,8 +232,13 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, | |||
| 228 | if (ret) | 232 | if (ret) |
| 229 | goto err; | 233 | goto err; |
| 230 | 234 | ||
| 231 | INIT_WORK(&gpios[i].work, gpio_work); | 235 | #ifdef CONFIG_GPIO_SYSFS |
| 232 | gpios[i].jack = jack; | 236 | /* Expose GPIO value over sysfs for diagnostic purposes */ |
| 237 | gpio_export(gpios[i].gpio, false); | ||
| 238 | #endif | ||
| 239 | |||
| 240 | /* Update initial jack status */ | ||
| 241 | snd_soc_jack_gpio_detect(&gpios[i]); | ||
| 233 | } | 242 | } |
| 234 | 243 | ||
| 235 | return 0; | 244 | return 0; |
| @@ -258,6 +267,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, | |||
| 258 | int i; | 267 | int i; |
| 259 | 268 | ||
| 260 | for (i = 0; i < count; i++) { | 269 | for (i = 0; i < count; i++) { |
| 270 | #ifdef CONFIG_GPIO_SYSFS | ||
| 271 | gpio_unexport(gpios[i].gpio); | ||
| 272 | #endif | ||
| 261 | free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]); | 273 | free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]); |
| 262 | gpio_free(gpios[i].gpio); | 274 | gpio_free(gpios[i].gpio); |
| 263 | gpios[i].jack = NULL; | 275 | gpios[i].jack = NULL; |
