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");