aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon/extcon-arizona.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2013-01-10 18:55:39 -0500
committerChanwoo Choi <cw00.choi@samsung.com>2013-01-15 01:42:17 -0500
commit92a49871b378b1e523a95da569cd38efdd06eee5 (patch)
tree3c23cf3eaa64350afec782787bf3f9b1e43c6791 /drivers/extcon/extcon-arizona.c
parentdab63eb25ced7539a51b8f4218f7b6b56d34df22 (diff)
extcon: arizona: Support use of GPIO5 as an input to jack detection
Some system designs provide an input on GPIO5 which in conjunction with the jack detection feature indicates the presence of an accessory. Support such systems, using the microphone clamp feature to minimise wakeups of the processor. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com> Signed-off-by: Myungjoo Ham <myungjoo.ham@samsung.com>
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);