aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/mc13xxx-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd/mc13xxx-core.c')
-rw-r--r--drivers/mfd/mc13xxx-core.c116
1 files changed, 55 insertions, 61 deletions
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 7e4d44bf92ab..e9619acc0237 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -26,20 +26,10 @@ struct mc13xxx {
26 26
27 irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; 27 irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
28 void *irqdata[MC13XXX_NUM_IRQ]; 28 void *irqdata[MC13XXX_NUM_IRQ];
29};
30
31struct mc13783 {
32 struct mc13xxx mc13xxx;
33 29
34 int adcflags; 30 int adcflags;
35}; 31};
36 32
37struct mc13xxx *mc13783_to_mc13xxx(struct mc13783 *mc13783)
38{
39 return &mc13783->mc13xxx;
40}
41EXPORT_SYMBOL(mc13783_to_mc13xxx);
42
43#define MC13XXX_IRQSTAT0 0 33#define MC13XXX_IRQSTAT0 0
44#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0) 34#define MC13XXX_IRQSTAT0_ADCDONEI (1 << 0)
45#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1) 35#define MC13XXX_IRQSTAT0_ADCBISDONEI (1 << 1)
@@ -136,14 +126,14 @@ EXPORT_SYMBOL(mc13783_to_mc13xxx);
136#define MC13XXX_REVISION_FAB (0x03 << 11) 126#define MC13XXX_REVISION_FAB (0x03 << 11)
137#define MC13XXX_REVISION_ICIDCODE (0x3f << 13) 127#define MC13XXX_REVISION_ICIDCODE (0x3f << 13)
138 128
139#define MC13783_ADC1 44 129#define MC13XXX_ADC1 44
140#define MC13783_ADC1_ADEN (1 << 0) 130#define MC13XXX_ADC1_ADEN (1 << 0)
141#define MC13783_ADC1_RAND (1 << 1) 131#define MC13XXX_ADC1_RAND (1 << 1)
142#define MC13783_ADC1_ADSEL (1 << 3) 132#define MC13XXX_ADC1_ADSEL (1 << 3)
143#define MC13783_ADC1_ASC (1 << 20) 133#define MC13XXX_ADC1_ASC (1 << 20)
144#define MC13783_ADC1_ADTRIGIGN (1 << 21) 134#define MC13XXX_ADC1_ADTRIGIGN (1 << 21)
145 135
146#define MC13783_ADC2 45 136#define MC13XXX_ADC2 45
147 137
148#define MC13XXX_NUMREGS 0x3f 138#define MC13XXX_NUMREGS 0x3f
149 139
@@ -487,7 +477,7 @@ enum mc13xxx_id {
487 MC13XXX_ID_INVALID, 477 MC13XXX_ID_INVALID,
488}; 478};
489 479
490const char *mc13xxx_chipname[] = { 480static const char *mc13xxx_chipname[] = {
491 [MC13XXX_ID_MC13783] = "mc13783", 481 [MC13XXX_ID_MC13783] = "mc13783",
492 [MC13XXX_ID_MC13892] = "mc13892", 482 [MC13XXX_ID_MC13892] = "mc13892",
493}; 483};
@@ -558,8 +548,6 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx)
558 return mc13xxx_chipname[devid->driver_data]; 548 return mc13xxx_chipname[devid->driver_data];
559} 549}
560 550
561#include <linux/mfd/mc13783.h>
562
563int mc13xxx_get_flags(struct mc13xxx *mc13xxx) 551int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
564{ 552{
565 struct mc13xxx_platform_data *pdata = 553 struct mc13xxx_platform_data *pdata =
@@ -569,15 +557,15 @@ int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
569} 557}
570EXPORT_SYMBOL(mc13xxx_get_flags); 558EXPORT_SYMBOL(mc13xxx_get_flags);
571 559
572#define MC13783_ADC1_CHAN0_SHIFT 5 560#define MC13XXX_ADC1_CHAN0_SHIFT 5
573#define MC13783_ADC1_CHAN1_SHIFT 8 561#define MC13XXX_ADC1_CHAN1_SHIFT 8
574 562
575struct mc13xxx_adcdone_data { 563struct mc13xxx_adcdone_data {
576 struct mc13xxx *mc13xxx; 564 struct mc13xxx *mc13xxx;
577 struct completion done; 565 struct completion done;
578}; 566};
579 567
580static irqreturn_t mc13783_handler_adcdone(int irq, void *data) 568static irqreturn_t mc13xxx_handler_adcdone(int irq, void *data)
581{ 569{
582 struct mc13xxx_adcdone_data *adcdone_data = data; 570 struct mc13xxx_adcdone_data *adcdone_data = data;
583 571
@@ -588,12 +576,11 @@ static irqreturn_t mc13783_handler_adcdone(int irq, void *data)
588 return IRQ_HANDLED; 576 return IRQ_HANDLED;
589} 577}
590 578
591#define MC13783_ADC_WORKING (1 << 0) 579#define MC13XXX_ADC_WORKING (1 << 0)
592 580
593int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode, 581int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
594 unsigned int channel, unsigned int *sample) 582 unsigned int channel, unsigned int *sample)
595{ 583{
596 struct mc13xxx *mc13xxx = &mc13783->mc13xxx;
597 u32 adc0, adc1, old_adc0; 584 u32 adc0, adc1, old_adc0;
598 int i, ret; 585 int i, ret;
599 struct mc13xxx_adcdone_data adcdone_data = { 586 struct mc13xxx_adcdone_data adcdone_data = {
@@ -605,51 +592,51 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
605 592
606 mc13xxx_lock(mc13xxx); 593 mc13xxx_lock(mc13xxx);
607 594
608 if (mc13783->adcflags & MC13783_ADC_WORKING) { 595 if (mc13xxx->adcflags & MC13XXX_ADC_WORKING) {
609 ret = -EBUSY; 596 ret = -EBUSY;
610 goto out; 597 goto out;
611 } 598 }
612 599
613 mc13783->adcflags |= MC13783_ADC_WORKING; 600 mc13xxx->adcflags |= MC13XXX_ADC_WORKING;
614 601
615 mc13xxx_reg_read(mc13xxx, MC13783_ADC0, &old_adc0); 602 mc13xxx_reg_read(mc13xxx, MC13XXX_ADC0, &old_adc0);
616 603
617 adc0 = MC13783_ADC0_ADINC1 | MC13783_ADC0_ADINC2; 604 adc0 = MC13XXX_ADC0_ADINC1 | MC13XXX_ADC0_ADINC2;
618 adc1 = MC13783_ADC1_ADEN | MC13783_ADC1_ADTRIGIGN | MC13783_ADC1_ASC; 605 adc1 = MC13XXX_ADC1_ADEN | MC13XXX_ADC1_ADTRIGIGN | MC13XXX_ADC1_ASC;
619 606
620 if (channel > 7) 607 if (channel > 7)
621 adc1 |= MC13783_ADC1_ADSEL; 608 adc1 |= MC13XXX_ADC1_ADSEL;
622 609
623 switch (mode) { 610 switch (mode) {
624 case MC13783_ADC_MODE_TS: 611 case MC13XXX_ADC_MODE_TS:
625 adc0 |= MC13783_ADC0_ADREFEN | MC13783_ADC0_TSMOD0 | 612 adc0 |= MC13XXX_ADC0_ADREFEN | MC13XXX_ADC0_TSMOD0 |
626 MC13783_ADC0_TSMOD1; 613 MC13XXX_ADC0_TSMOD1;
627 adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT; 614 adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
628 break; 615 break;
629 616
630 case MC13783_ADC_MODE_SINGLE_CHAN: 617 case MC13XXX_ADC_MODE_SINGLE_CHAN:
631 adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK; 618 adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK;
632 adc1 |= (channel & 0x7) << MC13783_ADC1_CHAN0_SHIFT; 619 adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT;
633 adc1 |= MC13783_ADC1_RAND; 620 adc1 |= MC13XXX_ADC1_RAND;
634 break; 621 break;
635 622
636 case MC13783_ADC_MODE_MULT_CHAN: 623 case MC13XXX_ADC_MODE_MULT_CHAN:
637 adc0 |= old_adc0 & MC13783_ADC0_TSMOD_MASK; 624 adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK;
638 adc1 |= 4 << MC13783_ADC1_CHAN1_SHIFT; 625 adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
639 break; 626 break;
640 627
641 default: 628 default:
642 mc13783_unlock(mc13783); 629 mc13xxx_unlock(mc13xxx);
643 return -EINVAL; 630 return -EINVAL;
644 } 631 }
645 632
646 dev_dbg(&mc13783->mc13xxx.spidev->dev, "%s: request irq\n", __func__); 633 dev_dbg(&mc13xxx->spidev->dev, "%s: request irq\n", __func__);
647 mc13xxx_irq_request(mc13xxx, MC13783_IRQ_ADCDONE, 634 mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE,
648 mc13783_handler_adcdone, __func__, &adcdone_data); 635 mc13xxx_handler_adcdone, __func__, &adcdone_data);
649 mc13xxx_irq_ack(mc13xxx, MC13783_IRQ_ADCDONE); 636 mc13xxx_irq_ack(mc13xxx, MC13XXX_IRQ_ADCDONE);
650 637
651 mc13xxx_reg_write(mc13xxx, MC13783_ADC0, adc0); 638 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0);
652 mc13xxx_reg_write(mc13xxx, MC13783_ADC1, adc1); 639 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1);
653 640
654 mc13xxx_unlock(mc13xxx); 641 mc13xxx_unlock(mc13xxx);
655 642
@@ -660,27 +647,27 @@ int mc13783_adc_do_conversion(struct mc13783 *mc13783, unsigned int mode,
660 647
661 mc13xxx_lock(mc13xxx); 648 mc13xxx_lock(mc13xxx);
662 649
663 mc13xxx_irq_free(mc13xxx, MC13783_IRQ_ADCDONE, &adcdone_data); 650 mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_ADCDONE, &adcdone_data);
664 651
665 if (ret > 0) 652 if (ret > 0)
666 for (i = 0; i < 4; ++i) { 653 for (i = 0; i < 4; ++i) {
667 ret = mc13xxx_reg_read(mc13xxx, 654 ret = mc13xxx_reg_read(mc13xxx,
668 MC13783_ADC2, &sample[i]); 655 MC13XXX_ADC2, &sample[i]);
669 if (ret) 656 if (ret)
670 break; 657 break;
671 } 658 }
672 659
673 if (mode == MC13783_ADC_MODE_TS) 660 if (mode == MC13XXX_ADC_MODE_TS)
674 /* restore TSMOD */ 661 /* restore TSMOD */
675 mc13xxx_reg_write(mc13xxx, MC13783_ADC0, old_adc0); 662 mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, old_adc0);
676 663
677 mc13783->adcflags &= ~MC13783_ADC_WORKING; 664 mc13xxx->adcflags &= ~MC13XXX_ADC_WORKING;
678out: 665out:
679 mc13xxx_unlock(mc13xxx); 666 mc13xxx_unlock(mc13xxx);
680 667
681 return ret; 668 return ret;
682} 669}
683EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion); 670EXPORT_SYMBOL_GPL(mc13xxx_adc_do_conversion);
684 671
685static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, 672static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
686 const char *format, void *pdata, size_t pdata_size) 673 const char *format, void *pdata, size_t pdata_size)
@@ -716,6 +703,11 @@ static int mc13xxx_probe(struct spi_device *spi)
716 enum mc13xxx_id id; 703 enum mc13xxx_id id;
717 int ret; 704 int ret;
718 705
706 if (!pdata) {
707 dev_err(&spi->dev, "invalid platform data\n");
708 return -EINVAL;
709 }
710
719 mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); 711 mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
720 if (!mc13xxx) 712 if (!mc13xxx)
721 return -ENOMEM; 713 return -ENOMEM;
@@ -763,10 +755,8 @@ err_revision:
763 if (pdata->flags & MC13XXX_USE_CODEC) 755 if (pdata->flags & MC13XXX_USE_CODEC)
764 mc13xxx_add_subdevice(mc13xxx, "%s-codec"); 756 mc13xxx_add_subdevice(mc13xxx, "%s-codec");
765 757
766 if (pdata->flags & MC13XXX_USE_REGULATOR) { 758 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
767 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", 759 &pdata->regulators, sizeof(pdata->regulators));
768 &pdata->regulators, sizeof(pdata->regulators));
769 }
770 760
771 if (pdata->flags & MC13XXX_USE_RTC) 761 if (pdata->flags & MC13XXX_USE_RTC)
772 mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); 762 mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
@@ -774,10 +764,14 @@ err_revision:
774 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) 764 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
775 mc13xxx_add_subdevice(mc13xxx, "%s-ts"); 765 mc13xxx_add_subdevice(mc13xxx, "%s-ts");
776 766
777 if (pdata->flags & MC13XXX_USE_LED) 767 if (pdata->leds)
778 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", 768 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
779 pdata->leds, sizeof(*pdata->leds)); 769 pdata->leds, sizeof(*pdata->leds));
780 770
771 if (pdata->buttons)
772 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton",
773 pdata->buttons, sizeof(*pdata->buttons));
774
781 return 0; 775 return 0;
782} 776}
783 777