aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon/extcon-arizona.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon/extcon-arizona.c')
-rw-r--r--drivers/extcon/extcon-arizona.c76
1 files changed, 58 insertions, 18 deletions
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 3ef3bee7d1e6..b5190a811601 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -290,13 +290,21 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
290{ 290{
291 struct arizona_extcon_info *info = data; 291 struct arizona_extcon_info *info = data;
292 struct arizona *arizona = info->arizona; 292 struct arizona *arizona = info->arizona;
293 unsigned int val; 293 unsigned int val, present, mask;
294 int ret, i; 294 int ret, i;
295 295
296 pm_runtime_get_sync(info->dev); 296 pm_runtime_get_sync(info->dev);
297 297
298 mutex_lock(&info->lock); 298 mutex_lock(&info->lock);
299 299
300 if (arizona->pdata.jd_gpio5) {
301 mask = ARIZONA_MICD_CLAMP_STS;
302 present = 0;
303 } else {
304 mask = ARIZONA_JD1_STS;
305 present = ARIZONA_JD1_STS;
306 }
307
300 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val); 308 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
301 if (ret != 0) { 309 if (ret != 0) {
302 dev_err(arizona->dev, "Failed to read jackdet status: %d\n", 310 dev_err(arizona->dev, "Failed to read jackdet status: %d\n",
@@ -306,7 +314,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
306 return IRQ_NONE; 314 return IRQ_NONE;
307 } 315 }
308 316
309 if (val & ARIZONA_JD1_STS) { 317 if ((val & mask) == present) {
310 dev_dbg(arizona->dev, "Detected jack\n"); 318 dev_dbg(arizona->dev, "Detected jack\n");
311 ret = extcon_set_cable_state_(&info->edev, 319 ret = extcon_set_cable_state_(&info->edev,
312 ARIZONA_CABLE_MECHANICAL, true); 320 ARIZONA_CABLE_MECHANICAL, true);
@@ -321,6 +329,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
321 329
322 arizona_stop_mic(info); 330 arizona_stop_mic(info);
323 331
332
324 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++) 333 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
325 input_report_key(info->input, 334 input_report_key(info->input,
326 arizona_lvl_to_key[i].report, 0); 335 arizona_lvl_to_key[i].report, 0);
@@ -345,6 +354,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
345 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 354 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
346 struct arizona_pdata *pdata; 355 struct arizona_pdata *pdata;
347 struct arizona_extcon_info *info; 356 struct arizona_extcon_info *info;
357 int jack_irq_fall, jack_irq_rise;
348 int ret, mode, i; 358 int ret, mode, i;
349 359
350 pdata = dev_get_platdata(arizona->dev); 360 pdata = dev_get_platdata(arizona->dev);
@@ -426,12 +436,24 @@ static int arizona_extcon_probe(struct platform_device *pdev)
426 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT); 436 << ARIZONA_MICD_BIAS_STARTTIME_SHIFT);
427 437
428 /* 438 /*
429 * If we have a clamp use it. 439 * If we have a clamp use it, activating in conjunction with
440 * GPIO5 if that is connected for jack detect operation.
430 */ 441 */
431 if (info->micd_clamp) { 442 if (info->micd_clamp) {
432 regmap_update_bits(arizona->regmap, 443 if (arizona->pdata.jd_gpio5) {
433 ARIZONA_MICD_CLAMP_CONTROL, 444 /* Put the GPIO into input mode */
434 ARIZONA_MICD_CLAMP_MODE_MASK, 4); 445 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
446 0xc101);
447
448 regmap_update_bits(arizona->regmap,
449 ARIZONA_MICD_CLAMP_CONTROL,
450 ARIZONA_MICD_CLAMP_MODE_MASK, 0x9);
451 } else {
452 regmap_update_bits(arizona->regmap,
453 ARIZONA_MICD_CLAMP_CONTROL,
454 ARIZONA_MICD_CLAMP_MODE_MASK, 0x4);
455 }
456
435 regmap_update_bits(arizona->regmap, 457 regmap_update_bits(arizona->regmap,
436 ARIZONA_JACK_DETECT_DEBOUNCE, 458 ARIZONA_JACK_DETECT_DEBOUNCE,
437 ARIZONA_MICD_CLAMP_DB, 459 ARIZONA_MICD_CLAMP_DB,
@@ -458,7 +480,15 @@ static int arizona_extcon_probe(struct platform_device *pdev)
458 pm_runtime_idle(&pdev->dev); 480 pm_runtime_idle(&pdev->dev);
459 pm_runtime_get_sync(&pdev->dev); 481 pm_runtime_get_sync(&pdev->dev);
460 482
461 ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_RISE, 483 if (arizona->pdata.jd_gpio5) {
484 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
485 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
486 } else {
487 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
488 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
489 }
490
491 ret = arizona_request_irq(arizona, jack_irq_rise,
462 "JACKDET rise", arizona_jackdet, info); 492 "JACKDET rise", arizona_jackdet, info);
463 if (ret != 0) { 493 if (ret != 0) {
464 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n", 494 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
@@ -466,21 +496,21 @@ static int arizona_extcon_probe(struct platform_device *pdev)
466 goto err_input; 496 goto err_input;
467 } 497 }
468 498
469 ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1); 499 ret = arizona_set_irq_wake(arizona, jack_irq_rise, 1);
470 if (ret != 0) { 500 if (ret != 0) {
471 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n", 501 dev_err(&pdev->dev, "Failed to set JD rise IRQ wake: %d\n",
472 ret); 502 ret);
473 goto err_rise; 503 goto err_rise;
474 } 504 }
475 505
476 ret = arizona_request_irq(arizona, ARIZONA_IRQ_JD_FALL, 506 ret = arizona_request_irq(arizona, jack_irq_fall,
477 "JACKDET fall", arizona_jackdet, info); 507 "JACKDET fall", arizona_jackdet, info);
478 if (ret != 0) { 508 if (ret != 0) {
479 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret); 509 dev_err(&pdev->dev, "Failed to get JD fall IRQ: %d\n", ret);
480 goto err_rise_wake; 510 goto err_rise_wake;
481 } 511 }
482 512
483 ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 1); 513 ret = arizona_set_irq_wake(arizona, jack_irq_fall, 1);
484 if (ret != 0) { 514 if (ret != 0) {
485 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n", 515 dev_err(&pdev->dev, "Failed to set JD fall IRQ wake: %d\n",
486 ret); 516 ret);
@@ -522,13 +552,13 @@ static int arizona_extcon_probe(struct platform_device *pdev)
522err_micdet: 552err_micdet:
523 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info); 553 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
524err_fall_wake: 554err_fall_wake:
525 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); 555 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
526err_fall: 556err_fall:
527 arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); 557 arizona_free_irq(arizona, jack_irq_fall, info);
528err_rise_wake: 558err_rise_wake:
529 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); 559 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
530err_rise: 560err_rise:
531 arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); 561 arizona_free_irq(arizona, jack_irq_rise, info);
532err_input: 562err_input:
533err_register: 563err_register:
534 pm_runtime_disable(&pdev->dev); 564 pm_runtime_disable(&pdev->dev);
@@ -541,6 +571,7 @@ static int arizona_extcon_remove(struct platform_device *pdev)
541{ 571{
542 struct arizona_extcon_info *info = platform_get_drvdata(pdev); 572 struct arizona_extcon_info *info = platform_get_drvdata(pdev);
543 struct arizona *arizona = info->arizona; 573 struct arizona *arizona = info->arizona;
574 int jack_irq_rise, jack_irq_fall;
544 575
545 pm_runtime_disable(&pdev->dev); 576 pm_runtime_disable(&pdev->dev);
546 577
@@ -548,11 +579,20 @@ static int arizona_extcon_remove(struct platform_device *pdev)
548 ARIZONA_MICD_CLAMP_CONTROL, 579 ARIZONA_MICD_CLAMP_CONTROL,
549 ARIZONA_MICD_CLAMP_MODE_MASK, 0); 580 ARIZONA_MICD_CLAMP_MODE_MASK, 0);
550 581
551 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); 582 if (arizona->pdata.jd_gpio5) {
552 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); 583 jack_irq_rise = ARIZONA_IRQ_MICD_CLAMP_RISE;
584 jack_irq_fall = ARIZONA_IRQ_MICD_CLAMP_FALL;
585 } else {
586 jack_irq_rise = ARIZONA_IRQ_JD_RISE;
587 jack_irq_fall = ARIZONA_IRQ_JD_FALL;
588 }
589
590 arizona_set_irq_wake(arizona, jack_irq_rise, 0);
591 arizona_set_irq_wake(arizona, jack_irq_fall, 0);
592 arizona_free_irq(arizona, ARIZONA_IRQ_HPDET, info);
553 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info); 593 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
554 arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); 594 arizona_free_irq(arizona, jack_irq_rise, info);
555 arizona_free_irq(arizona, ARIZONA_IRQ_JD_FALL, info); 595 arizona_free_irq(arizona, jack_irq_fall, info);
556 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, 596 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
557 ARIZONA_JD1_ENA, 0); 597 ARIZONA_JD1_ENA, 0);
558 arizona_clk32k_disable(arizona); 598 arizona_clk32k_disable(arizona);