extcon-max14577.c (0ca852b794dabb3a4dd5c38223cb49a07015540b) | extcon-max14577.c (4706a5253bcc502a5889feb98392ea7b15dd936e) |
---|---|
1/* | 1/* |
2 * extcon-max14577.c - MAX14577 extcon driver to support MAX14577 MUIC | 2 * extcon-max14577.c - MAX14577/77836 extcon driver to support MUIC |
3 * | 3 * |
4 * Copyright (C) 2013 Samsung Electrnoics | 4 * Copyright (C) 2013,2014 Samsung Electrnoics |
5 * Chanwoo Choi <cw00.choi@samsung.com> | 5 * Chanwoo Choi <cw00.choi@samsung.com> |
6 * Krzysztof Kozlowski <k.kozlowski@samsung.com> |
|
6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of --- 43 unchanged lines hidden (view full) --- 57 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" }, 58 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" }, 59 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" }, 60 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" }, 61 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" }, 62 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" }, 63}; 64 | 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of --- 43 unchanged lines hidden (view full) --- 58 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" }, 59 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" }, 60 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" }, 61 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" }, 62 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" }, 63 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" }, 64}; 65 |
66static struct max14577_muic_irq max77836_muic_irqs[] = { 67 { MAX14577_IRQ_INT1_ADC, "muic-ADC" }, 68 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" }, 69 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" }, 70 { MAX77836_IRQ_INT1_ADC1K, "muic-ADC1K" }, 71 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" }, 72 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" }, 73 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" }, 74 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" }, 75 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" }, 76 { MAX77836_IRQ_INT2_VIDRM, "muic-VIDRM" }, 77}; 78 |
|
65struct max14577_muic_info { 66 struct device *dev; 67 struct max14577 *max14577; 68 struct extcon_dev *edev; 69 int prev_cable_type; 70 int prev_chg_type; 71 u8 status[MAX14577_MUIC_STATUS_END]; 72 --- 451 unchanged lines hidden (view full) --- 524 if (ret < 0) 525 dev_err(info->dev, "failed to handle MUIC interrupt\n"); 526 527 mutex_unlock(&info->mutex); 528 529 return; 530} 531 | 79struct max14577_muic_info { 80 struct device *dev; 81 struct max14577 *max14577; 82 struct extcon_dev *edev; 83 int prev_cable_type; 84 int prev_chg_type; 85 u8 status[MAX14577_MUIC_STATUS_END]; 86 --- 451 unchanged lines hidden (view full) --- 538 if (ret < 0) 539 dev_err(info->dev, "failed to handle MUIC interrupt\n"); 540 541 mutex_unlock(&info->mutex); 542 543 return; 544} 545 |
546/* 547 * Sets irq_adc or irq_chg in max14577_muic_info and returns 1. 548 * Returns 0 if irq_type does not match registered IRQ for this device type. 549 */ 550static int max14577_parse_irq(struct max14577_muic_info *info, int irq_type) 551{ 552 switch (irq_type) { 553 case MAX14577_IRQ_INT1_ADC: 554 case MAX14577_IRQ_INT1_ADCLOW: 555 case MAX14577_IRQ_INT1_ADCERR: 556 /* Handle all of accessory except for 557 type of charger accessory */ 558 info->irq_adc = true; 559 return 1; 560 case MAX14577_IRQ_INT2_CHGTYP: 561 case MAX14577_IRQ_INT2_CHGDETRUN: 562 case MAX14577_IRQ_INT2_DCDTMR: 563 case MAX14577_IRQ_INT2_DBCHG: 564 case MAX14577_IRQ_INT2_VBVOLT: 565 /* Handle charger accessory */ 566 info->irq_chg = true; 567 return 1; 568 default: 569 return 0; 570 } 571} 572 573/* 574 * Sets irq_adc or irq_chg in max14577_muic_info and returns 1. 575 * Returns 0 if irq_type does not match registered IRQ for this device type. 576 */ 577static int max77836_parse_irq(struct max14577_muic_info *info, int irq_type) 578{ 579 /* First check common max14577 interrupts */ 580 if (max14577_parse_irq(info, irq_type)) 581 return 1; 582 583 switch (irq_type) { 584 case MAX77836_IRQ_INT1_ADC1K: 585 info->irq_adc = true; 586 return 1; 587 case MAX77836_IRQ_INT2_VIDRM: 588 /* Handle charger accessory */ 589 info->irq_chg = true; 590 return 1; 591 default: 592 return 0; 593 } 594} 595 |
|
532static irqreturn_t max14577_muic_irq_handler(int irq, void *data) 533{ 534 struct max14577_muic_info *info = data; 535 int i, irq_type = -1; | 596static irqreturn_t max14577_muic_irq_handler(int irq, void *data) 597{ 598 struct max14577_muic_info *info = data; 599 int i, irq_type = -1; |
600 bool irq_parsed; |
|
536 537 /* 538 * We may be called multiple times for different nested IRQ-s. 539 * Including changes in INT1_ADC and INT2_CGHTYP at once. 540 * However we only need to know whether it was ADC, charger 541 * or both interrupts so decode IRQ and turn on proper flags. 542 */ 543 for (i = 0; i < info->muic_irqs_num; i++) 544 if (irq == info->muic_irqs[i].virq) 545 irq_type = info->muic_irqs[i].irq; 546 | 601 602 /* 603 * We may be called multiple times for different nested IRQ-s. 604 * Including changes in INT1_ADC and INT2_CGHTYP at once. 605 * However we only need to know whether it was ADC, charger 606 * or both interrupts so decode IRQ and turn on proper flags. 607 */ 608 for (i = 0; i < info->muic_irqs_num; i++) 609 if (irq == info->muic_irqs[i].virq) 610 irq_type = info->muic_irqs[i].irq; 611 |
547 switch (irq_type) { 548 case MAX14577_IRQ_INT1_ADC: 549 case MAX14577_IRQ_INT1_ADCLOW: 550 case MAX14577_IRQ_INT1_ADCERR: 551 /* Handle all of accessory except for 552 type of charger accessory */ 553 info->irq_adc = true; | 612 switch (info->max14577->dev_type) { 613 case MAXIM_DEVICE_TYPE_MAX77836: 614 irq_parsed = max77836_parse_irq(info, irq_type); |
554 break; | 615 break; |
555 case MAX14577_IRQ_INT2_CHGTYP: 556 case MAX14577_IRQ_INT2_CHGDETRUN: 557 case MAX14577_IRQ_INT2_DCDTMR: 558 case MAX14577_IRQ_INT2_DBCHG: 559 case MAX14577_IRQ_INT2_VBVOLT: 560 /* Handle charger accessory */ 561 info->irq_chg = true; 562 break; | 616 case MAXIM_DEVICE_TYPE_MAX14577: |
563 default: | 617 default: |
618 irq_parsed = max14577_parse_irq(info, irq_type); 619 break; 620 } 621 622 if (!irq_parsed) { |
|
564 dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n", 565 irq_type); 566 return IRQ_HANDLED; 567 } 568 schedule_work(&info->irq_work); 569 570 return IRQ_HANDLED; 571} --- 69 unchanged lines hidden (view full) --- 641 info->max14577 = max14577; 642 643 platform_set_drvdata(pdev, info); 644 mutex_init(&info->mutex); 645 646 INIT_WORK(&info->irq_work, max14577_muic_irq_work); 647 648 switch (max14577->dev_type) { | 623 dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n", 624 irq_type); 625 return IRQ_HANDLED; 626 } 627 schedule_work(&info->irq_work); 628 629 return IRQ_HANDLED; 630} --- 69 unchanged lines hidden (view full) --- 700 info->max14577 = max14577; 701 702 platform_set_drvdata(pdev, info); 703 mutex_init(&info->mutex); 704 705 INIT_WORK(&info->irq_work, max14577_muic_irq_work); 706 707 switch (max14577->dev_type) { |
708 case MAXIM_DEVICE_TYPE_MAX77836: 709 info->muic_irqs = max77836_muic_irqs; 710 info->muic_irqs_num = ARRAY_SIZE(max77836_muic_irqs); 711 break; |
|
649 case MAXIM_DEVICE_TYPE_MAX14577: 650 default: 651 info->muic_irqs = max14577_muic_irqs; 652 info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs); 653 } 654 655 /* Support irq domain for max14577 MUIC device */ 656 for (i = 0; i < info->muic_irqs_num; i++) { --- 82 unchanged lines hidden (view full) --- 739 struct max14577_muic_info *info = platform_get_drvdata(pdev); 740 741 cancel_work_sync(&info->irq_work); 742 extcon_dev_unregister(info->edev); 743 744 return 0; 745} 746 | 712 case MAXIM_DEVICE_TYPE_MAX14577: 713 default: 714 info->muic_irqs = max14577_muic_irqs; 715 info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs); 716 } 717 718 /* Support irq domain for max14577 MUIC device */ 719 for (i = 0; i < info->muic_irqs_num; i++) { --- 82 unchanged lines hidden (view full) --- 802 struct max14577_muic_info *info = platform_get_drvdata(pdev); 803 804 cancel_work_sync(&info->irq_work); 805 extcon_dev_unregister(info->edev); 806 807 return 0; 808} 809 |
810static const struct platform_device_id max14577_muic_id[] = { 811 { "max14577-muic", MAXIM_DEVICE_TYPE_MAX14577, }, 812 { "max77836-muic", MAXIM_DEVICE_TYPE_MAX77836, }, 813 { } 814}; 815MODULE_DEVICE_TABLE(platform, max14577_muic_id); 816 |
|
747static struct platform_driver max14577_muic_driver = { 748 .driver = { 749 .name = "max14577-muic", 750 .owner = THIS_MODULE, 751 }, 752 .probe = max14577_muic_probe, 753 .remove = max14577_muic_remove, | 817static struct platform_driver max14577_muic_driver = { 818 .driver = { 819 .name = "max14577-muic", 820 .owner = THIS_MODULE, 821 }, 822 .probe = max14577_muic_probe, 823 .remove = max14577_muic_remove, |
824 .id_table = max14577_muic_id, |
|
754}; 755 756module_platform_driver(max14577_muic_driver); 757 | 825}; 826 827module_platform_driver(max14577_muic_driver); 828 |
758MODULE_DESCRIPTION("MAXIM 14577 Extcon driver"); 759MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>"); | 829MODULE_DESCRIPTION("Maxim 14577/77836 Extcon driver"); 830MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>, Krzysztof Kozlowski <k.kozlowski@samsung.com>"); |
760MODULE_LICENSE("GPL"); 761MODULE_ALIAS("platform:extcon-max14577"); | 831MODULE_LICENSE("GPL"); 832MODULE_ALIAS("platform:extcon-max14577"); |