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 14 #include <sound/jack.h> 15 #include <sound/soc.h> 16 #include <linux/gpio.h> 17 #include <linux/gpio/consumer.h> 18 #include <linux/interrupt.h> 19 #include <linux/workqueue.h> 20 #include <linux/delay.h> 21 #include <linux/export.h> 22 #include <linux/suspend.h> 23 #include <trace/events/asoc.h> 24 25 struct jack_gpio_tbl { 26 int count; 27 struct snd_soc_jack *jack; 28 struct snd_soc_jack_gpio *gpios; 29 }; 30 31 /** 32 * snd_soc_component_set_jack - configure component jack. 33 * @component: COMPONENTs 34 * @jack: structure to use for the jack 35 * @data: can be used if codec driver need extra data for configuring jack 36 * 37 * Configures and enables jack detection function. 38 */ 39 int snd_soc_component_set_jack(struct snd_soc_component *component, 40 struct snd_soc_jack *jack, void *data) 41 { 42 if (component->driver->set_jack) 43 return component->driver->set_jack(component, jack, data); 44 45 return -ENOTSUPP; 46 } 47 EXPORT_SYMBOL_GPL(snd_soc_component_set_jack); 48 49 /** 50 * snd_soc_card_jack_new - Create a new jack 51 * @card: ASoC card 52 * @id: an identifying string for this jack 53 * @type: a bitmask of enum snd_jack_type values that can be detected by 54 * this jack 55 * @jack: structure to use for the jack 56 * @pins: Array of jack pins to be added to the jack or NULL 57 * @num_pins: Number of elements in the @pins array 58 * 59 * Creates a new jack object. 60 * 61 * Returns zero if successful, or a negative error code on failure. 62 * On success jack will be initialised. 63 */ 64 int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type, 65 struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins, 66 unsigned int num_pins) 67 { 68 int ret; 69 70 mutex_init(&jack->mutex); 71 jack->card = card; 72 INIT_LIST_HEAD(&jack->pins); 73 INIT_LIST_HEAD(&jack->jack_zones); 74 BLOCKING_INIT_NOTIFIER_HEAD(&jack->notifier); 75 76 ret = snd_jack_new(card->snd_card, id, type, &jack->jack, false, false); 77 if (ret) 78 return ret; 79 80 if (num_pins) 81 return snd_soc_jack_add_pins(jack, num_pins, pins); 82 83 return 0; 84 } 85 EXPORT_SYMBOL_GPL(snd_soc_card_jack_new); 86 87 /** 88 * snd_soc_jack_report - Report the current status for a jack 89 * 90 * @jack: the jack 91 * @status: a bitmask of enum snd_jack_type values that are currently detected. 92 * @mask: a bitmask of enum snd_jack_type values that being reported. 93 * 94 * If configured using snd_soc_jack_add_pins() then the associated 95 * DAPM pins will be enabled or disabled as appropriate and DAPM 96 * synchronised. 97 * 98 * Note: This function uses mutexes and should be called from a 99 * context which can sleep (such as a workqueue). 100 */ 101 void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) 102 { 103 struct snd_soc_dapm_context *dapm; 104 struct snd_soc_jack_pin *pin; 105 unsigned int sync = 0; 106 int enable; 107 108 trace_snd_soc_jack_report(jack, mask, status); 109 110 if (!jack) 111 return; 112 113 dapm = &jack->card->dapm; 114 115 mutex_lock(&jack->mutex); 116 117 jack->status &= ~mask; 118 jack->status |= status & mask; 119 120 trace_snd_soc_jack_notify(jack, status); 121 122 list_for_each_entry(pin, &jack->pins, list) { 123 enable = pin->mask & jack->status; 124 125 if (pin->invert) 126 enable = !enable; 127 128 if (enable) 129 snd_soc_dapm_enable_pin(dapm, pin->pin); 130 else 131 snd_soc_dapm_disable_pin(dapm, pin->pin); 132 133 /* we need to sync for this case only */ 134 sync = 1; 135 } 136 137 /* Report before the DAPM sync to help users updating micbias status */ 138 blocking_notifier_call_chain(&jack->notifier, jack->status, jack); 139 140 if (sync) 141 snd_soc_dapm_sync(dapm); 142 143 snd_jack_report(jack->jack, jack->status); 144 145 mutex_unlock(&jack->mutex); 146 } 147 EXPORT_SYMBOL_GPL(snd_soc_jack_report); 148 149 /** 150 * snd_soc_jack_add_zones - Associate voltage zones with jack 151 * 152 * @jack: ASoC jack 153 * @count: Number of zones 154 * @zones: Array of zones 155 * 156 * After this function has been called the zones specified in the 157 * array will be associated with the jack. 158 */ 159 int snd_soc_jack_add_zones(struct snd_soc_jack *jack, int count, 160 struct snd_soc_jack_zone *zones) 161 { 162 int i; 163 164 for (i = 0; i < count; i++) { 165 INIT_LIST_HEAD(&zones[i].list); 166 list_add(&(zones[i].list), &jack->jack_zones); 167 } 168 return 0; 169 } 170 EXPORT_SYMBOL_GPL(snd_soc_jack_add_zones); 171 172 /** 173 * snd_soc_jack_get_type - Based on the mic bias value, this function returns 174 * the type of jack from the zones declared in the jack type 175 * 176 * @jack: ASoC jack 177 * @micbias_voltage: mic bias voltage at adc channel when jack is plugged in 178 * 179 * Based on the mic bias value passed, this function helps identify 180 * the type of jack from the already declared jack zones 181 */ 182 int snd_soc_jack_get_type(struct snd_soc_jack *jack, int micbias_voltage) 183 { 184 struct snd_soc_jack_zone *zone; 185 186 list_for_each_entry(zone, &jack->jack_zones, list) { 187 if (micbias_voltage >= zone->min_mv && 188 micbias_voltage < zone->max_mv) 189 return zone->jack_type; 190 } 191 return 0; 192 } 193 EXPORT_SYMBOL_GPL(snd_soc_jack_get_type); 194 195 /** 196 * snd_soc_jack_add_pins - Associate DAPM pins with an ASoC jack 197 * 198 * @jack: ASoC jack 199 * @count: Number of pins 200 * @pins: Array of pins 201 * 202 * After this function has been called the DAPM pins specified in the 203 * pins array will have their status updated to reflect the current 204 * state of the jack whenever the jack status is updated. 205 */ 206 int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, 207 struct snd_soc_jack_pin *pins) 208 { 209 int i; 210 211 for (i = 0; i < count; i++) { 212 if (!pins[i].pin) { 213 dev_err(jack->card->dev, "ASoC: No name for pin %d\n", 214 i); 215 return -EINVAL; 216 } 217 if (!pins[i].mask) { 218 dev_err(jack->card->dev, "ASoC: No mask for pin %d" 219 " (%s)\n", i, pins[i].pin); 220 return -EINVAL; 221 } 222 223 INIT_LIST_HEAD(&pins[i].list); 224 list_add(&(pins[i].list), &jack->pins); 225 snd_jack_add_new_kctl(jack->jack, pins[i].pin, pins[i].mask); 226 } 227 228 /* Update to reflect the last reported status; canned jack 229 * implementations are likely to set their state before the 230 * card has an opportunity to associate pins. 231 */ 232 snd_soc_jack_report(jack, 0, 0); 233 234 return 0; 235 } 236 EXPORT_SYMBOL_GPL(snd_soc_jack_add_pins); 237 238 /** 239 * snd_soc_jack_notifier_register - Register a notifier for jack status 240 * 241 * @jack: ASoC jack 242 * @nb: Notifier block to register 243 * 244 * Register for notification of the current status of the jack. Note 245 * that it is not possible to report additional jack events in the 246 * callback from the notifier, this is intended to support 247 * applications such as enabling electrical detection only when a 248 * mechanical detection event has occurred. 249 */ 250 void snd_soc_jack_notifier_register(struct snd_soc_jack *jack, 251 struct notifier_block *nb) 252 { 253 blocking_notifier_chain_register(&jack->notifier, nb); 254 } 255 EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_register); 256 257 /** 258 * snd_soc_jack_notifier_unregister - Unregister a notifier for jack status 259 * 260 * @jack: ASoC jack 261 * @nb: Notifier block to unregister 262 * 263 * Stop notifying for status changes. 264 */ 265 void snd_soc_jack_notifier_unregister(struct snd_soc_jack *jack, 266 struct notifier_block *nb) 267 { 268 blocking_notifier_chain_unregister(&jack->notifier, nb); 269 } 270 EXPORT_SYMBOL_GPL(snd_soc_jack_notifier_unregister); 271 272 #ifdef CONFIG_GPIOLIB 273 /* gpio detect */ 274 static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) 275 { 276 struct snd_soc_jack *jack = gpio->jack; 277 int enable; 278 int report; 279 280 enable = gpiod_get_value_cansleep(gpio->desc); 281 if (gpio->invert) 282 enable = !enable; 283 284 if (enable) 285 report = gpio->report; 286 else 287 report = 0; 288 289 if (gpio->jack_status_check) 290 report = gpio->jack_status_check(gpio->data); 291 292 snd_soc_jack_report(jack, report, gpio->report); 293 } 294 295 /* irq handler for gpio pin */ 296 static irqreturn_t gpio_handler(int irq, void *data) 297 { 298 struct snd_soc_jack_gpio *gpio = data; 299 struct device *dev = gpio->jack->card->dev; 300 301 trace_snd_soc_jack_irq(gpio->name); 302 303 if (device_may_wakeup(dev)) 304 pm_wakeup_event(dev, gpio->debounce_time + 50); 305 306 queue_delayed_work(system_power_efficient_wq, &gpio->work, 307 msecs_to_jiffies(gpio->debounce_time)); 308 309 return IRQ_HANDLED; 310 } 311 312 /* gpio work */ 313 static void gpio_work(struct work_struct *work) 314 { 315 struct snd_soc_jack_gpio *gpio; 316 317 gpio = container_of(work, struct snd_soc_jack_gpio, work.work); 318 snd_soc_jack_gpio_detect(gpio); 319 } 320 321 static int snd_soc_jack_pm_notifier(struct notifier_block *nb, 322 unsigned long action, void *data) 323 { 324 struct snd_soc_jack_gpio *gpio = 325 container_of(nb, struct snd_soc_jack_gpio, pm_notifier); 326 327 switch (action) { 328 case PM_POST_SUSPEND: 329 case PM_POST_HIBERNATION: 330 case PM_POST_RESTORE: 331 /* 332 * Use workqueue so we do not have to care about running 333 * concurrently with work triggered by the interrupt handler. 334 */ 335 queue_delayed_work(system_power_efficient_wq, &gpio->work, 0); 336 break; 337 } 338 339 return NOTIFY_DONE; 340 } 341 342 static void jack_free_gpios(struct snd_soc_jack *jack, int count, 343 struct snd_soc_jack_gpio *gpios) 344 { 345 int i; 346 347 for (i = 0; i < count; i++) { 348 gpiod_unexport(gpios[i].desc); 349 unregister_pm_notifier(&gpios[i].pm_notifier); 350 free_irq(gpiod_to_irq(gpios[i].desc), &gpios[i]); 351 cancel_delayed_work_sync(&gpios[i].work); 352 gpiod_put(gpios[i].desc); 353 gpios[i].jack = NULL; 354 } 355 } 356 357 static void jack_devres_free_gpios(struct device *dev, void *res) 358 { 359 struct jack_gpio_tbl *tbl = res; 360 361 jack_free_gpios(tbl->jack, tbl->count, tbl->gpios); 362 } 363 364 /** 365 * snd_soc_jack_add_gpios - Associate GPIO pins with an ASoC jack 366 * 367 * @jack: ASoC jack 368 * @count: number of pins 369 * @gpios: array of gpio pins 370 * 371 * This function will request gpio, set data direction and request irq 372 * for each gpio in the array. 373 */ 374 int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, 375 struct snd_soc_jack_gpio *gpios) 376 { 377 int i, ret; 378 struct jack_gpio_tbl *tbl; 379 380 tbl = devres_alloc(jack_devres_free_gpios, sizeof(*tbl), GFP_KERNEL); 381 if (!tbl) 382 return -ENOMEM; 383 tbl->jack = jack; 384 tbl->count = count; 385 tbl->gpios = gpios; 386 387 for (i = 0; i < count; i++) { 388 if (!gpios[i].name) { 389 dev_err(jack->card->dev, 390 "ASoC: No name for gpio at index %d\n", i); 391 ret = -EINVAL; 392 goto undo; 393 } 394 395 if (gpios[i].desc) { 396 /* Already have a GPIO descriptor. */ 397 goto got_gpio; 398 } else if (gpios[i].gpiod_dev) { 399 /* Get a GPIO descriptor */ 400 gpios[i].desc = gpiod_get_index(gpios[i].gpiod_dev, 401 gpios[i].name, 402 gpios[i].idx, GPIOD_IN); 403 if (IS_ERR(gpios[i].desc)) { 404 ret = PTR_ERR(gpios[i].desc); 405 dev_err(gpios[i].gpiod_dev, 406 "ASoC: Cannot get gpio at index %d: %d", 407 i, ret); 408 goto undo; 409 } 410 } else { 411 /* legacy GPIO number */ 412 if (!gpio_is_valid(gpios[i].gpio)) { 413 dev_err(jack->card->dev, 414 "ASoC: Invalid gpio %d\n", 415 gpios[i].gpio); 416 ret = -EINVAL; 417 goto undo; 418 } 419 420 ret = gpio_request_one(gpios[i].gpio, GPIOF_IN, 421 gpios[i].name); 422 if (ret) 423 goto undo; 424 425 gpios[i].desc = gpio_to_desc(gpios[i].gpio); 426 } 427 got_gpio: 428 INIT_DELAYED_WORK(&gpios[i].work, gpio_work); 429 gpios[i].jack = jack; 430 431 ret = request_any_context_irq(gpiod_to_irq(gpios[i].desc), 432 gpio_handler, 433 IRQF_TRIGGER_RISING | 434 IRQF_TRIGGER_FALLING, 435 gpios[i].name, 436 &gpios[i]); 437 if (ret < 0) 438 goto err; 439 440 if (gpios[i].wake) { 441 ret = irq_set_irq_wake(gpiod_to_irq(gpios[i].desc), 1); 442 if (ret != 0) 443 dev_err(jack->card->dev, 444 "ASoC: Failed to mark GPIO at index %d as wake source: %d\n", 445 i, ret); 446 } 447 448 /* 449 * Register PM notifier so we do not miss state transitions 450 * happening while system is asleep. 451 */ 452 gpios[i].pm_notifier.notifier_call = snd_soc_jack_pm_notifier; 453 register_pm_notifier(&gpios[i].pm_notifier); 454 455 /* Expose GPIO value over sysfs for diagnostic purposes */ 456 gpiod_export(gpios[i].desc, false); 457 458 /* Update initial jack status */ 459 schedule_delayed_work(&gpios[i].work, 460 msecs_to_jiffies(gpios[i].debounce_time)); 461 } 462 463 devres_add(jack->card->dev, tbl); 464 return 0; 465 466 err: 467 gpio_free(gpios[i].gpio); 468 undo: 469 jack_free_gpios(jack, i, gpios); 470 devres_free(tbl); 471 472 return ret; 473 } 474 EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpios); 475 476 /** 477 * snd_soc_jack_add_gpiods - Associate GPIO descriptor pins with an ASoC jack 478 * 479 * @gpiod_dev: GPIO consumer device 480 * @jack: ASoC jack 481 * @count: number of pins 482 * @gpios: array of gpio pins 483 * 484 * This function will request gpio, set data direction and request irq 485 * for each gpio in the array. 486 */ 487 int snd_soc_jack_add_gpiods(struct device *gpiod_dev, 488 struct snd_soc_jack *jack, 489 int count, struct snd_soc_jack_gpio *gpios) 490 { 491 int i; 492 493 for (i = 0; i < count; i++) 494 gpios[i].gpiod_dev = gpiod_dev; 495 496 return snd_soc_jack_add_gpios(jack, count, gpios); 497 } 498 EXPORT_SYMBOL_GPL(snd_soc_jack_add_gpiods); 499 500 /** 501 * snd_soc_jack_free_gpios - Release GPIO pins' resources of an ASoC jack 502 * 503 * @jack: ASoC jack 504 * @count: number of pins 505 * @gpios: array of gpio pins 506 * 507 * Release gpio and irq resources for gpio pins associated with an ASoC jack. 508 */ 509 void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, 510 struct snd_soc_jack_gpio *gpios) 511 { 512 jack_free_gpios(jack, count, gpios); 513 devres_destroy(jack->card->dev, jack_devres_free_gpios, NULL, NULL); 514 } 515 EXPORT_SYMBOL_GPL(snd_soc_jack_free_gpios); 516 #endif /* CONFIG_GPIOLIB */ 517