~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/mfd/88pm860x-core.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
#define INT_STATUS_NUM                  3
23
23
 
24
 
static struct resource bk_resources[] __initdata = {
 
24
static struct resource bk_resources[] __devinitdata = {
25
25
        {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,},
26
26
        {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,},
27
27
        {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,},
28
28
};
29
29
 
30
 
static struct resource led_resources[] __initdata = {
 
30
static struct resource led_resources[] __devinitdata = {
31
31
        {PM8606_LED1_RED,   PM8606_LED1_RED,   "led0-red",   IORESOURCE_IO,},
32
32
        {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,},
33
33
        {PM8606_LED1_BLUE,  PM8606_LED1_BLUE,  "led0-blue",  IORESOURCE_IO,},
36
36
        {PM8606_LED2_BLUE,  PM8606_LED2_BLUE,  "led1-blue",  IORESOURCE_IO,},
37
37
};
38
38
 
39
 
static struct resource regulator_resources[] __initdata = {
 
39
static struct resource regulator_resources[] __devinitdata = {
40
40
        {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
41
41
        {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
42
42
        {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
57
57
        {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
58
58
};
59
59
 
60
 
static struct resource touch_resources[] __initdata = {
 
60
static struct resource touch_resources[] __devinitdata = {
61
61
        {PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
62
62
};
63
63
 
64
 
static struct resource onkey_resources[] __initdata = {
 
64
static struct resource onkey_resources[] __devinitdata = {
65
65
        {PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
66
66
};
67
67
 
68
 
static struct resource codec_resources[] __initdata = {
 
68
static struct resource codec_resources[] __devinitdata = {
69
69
        /* Headset microphone insertion or removal */
70
70
        {PM8607_IRQ_MICIN,   PM8607_IRQ_MICIN,   "micin",   IORESOURCE_IRQ,},
71
71
        /* Hook-switch press or release */
76
76
        {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
77
77
};
78
78
 
79
 
static struct resource battery_resources[] __initdata = {
 
79
static struct resource battery_resources[] __devinitdata = {
80
80
        {PM8607_IRQ_CC,  PM8607_IRQ_CC,  "columb counter", IORESOURCE_IRQ,},
81
81
        {PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery",        IORESOURCE_IRQ,},
82
82
};
83
83
 
84
 
static struct resource charger_resources[] __initdata = {
 
84
static struct resource charger_resources[] __devinitdata = {
85
85
        {PM8607_IRQ_CHG,  PM8607_IRQ_CHG,  "charger detect",  IORESOURCE_IRQ,},
86
86
        {PM8607_IRQ_CHG_DONE,  PM8607_IRQ_CHG_DONE,  "charging done",       IORESOURCE_IRQ,},
87
87
        {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout",    IORESOURCE_IRQ,},
90
90
        {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage",    IORESOURCE_IRQ,},
91
91
};
92
92
 
93
 
static struct mfd_cell bk_devs[] __initdata = {
 
93
static struct resource rtc_resources[] __devinitdata = {
 
94
        {PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
 
95
};
 
96
 
 
97
static struct mfd_cell bk_devs[] = {
94
98
        {"88pm860x-backlight", 0,},
95
99
        {"88pm860x-backlight", 1,},
96
100
        {"88pm860x-backlight", 2,},
97
101
};
98
102
 
99
 
static struct mfd_cell led_devs[] __initdata = {
 
103
static struct mfd_cell led_devs[] = {
100
104
        {"88pm860x-led", 0,},
101
105
        {"88pm860x-led", 1,},
102
106
        {"88pm860x-led", 2,},
105
109
        {"88pm860x-led", 5,},
106
110
};
107
111
 
108
 
static struct mfd_cell regulator_devs[] __initdata = {
 
112
static struct mfd_cell regulator_devs[] = {
109
113
        {"88pm860x-regulator", 0,},
110
114
        {"88pm860x-regulator", 1,},
111
115
        {"88pm860x-regulator", 2,},
126
130
        {"88pm860x-regulator", 17,},
127
131
};
128
132
 
129
 
static struct mfd_cell touch_devs[] __initdata = {
 
133
static struct mfd_cell touch_devs[] = {
130
134
        {"88pm860x-touch", -1,},
131
135
};
132
136
 
133
 
static struct mfd_cell onkey_devs[] __initdata = {
 
137
static struct mfd_cell onkey_devs[] = {
134
138
        {"88pm860x-onkey", -1,},
135
139
};
136
140
 
137
 
static struct mfd_cell codec_devs[] __initdata = {
 
141
static struct mfd_cell codec_devs[] = {
138
142
        {"88pm860x-codec", -1,},
139
143
};
140
144
 
143
147
        {"88pm860x-charger", -1,},
144
148
};
145
149
 
146
 
static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)];
147
 
static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)];
148
 
static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)];
149
 
static struct pm860x_touch_pdata touch_pdata;
150
 
static struct pm860x_power_pdata power_pdata;
 
150
static struct mfd_cell rtc_devs[] = {
 
151
        {"88pm860x-rtc", -1,},
 
152
};
 
153
 
151
154
 
152
155
struct pm860x_irq_data {
153
156
        int     reg;
416
419
                                : chip->companion;
417
420
        unsigned char status_buf[INT_STATUS_NUM];
418
421
        unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
419
 
        struct irq_desc *desc;
420
422
        int i, data, mask, ret = -EINVAL;
421
423
        int __irq;
422
424
 
468
470
        if (!chip->core_irq)
469
471
                goto out;
470
472
 
471
 
        desc = irq_to_desc(chip->core_irq);
472
 
 
473
473
        /* register IRQ by genirq */
474
474
        for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
475
475
                __irq = i + chip->irq_base;
476
 
                set_irq_chip_data(__irq, chip);
477
 
                set_irq_chip_and_handler(__irq, &pm860x_irq_chip,
 
476
                irq_set_chip_data(__irq, chip);
 
477
                irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
478
478
                                         handle_edge_irq);
479
 
                set_irq_nested_thread(__irq, 1);
 
479
                irq_set_nested_thread(__irq, 1);
480
480
#ifdef CONFIG_ARM
481
481
                set_irq_flags(__irq, IRQF_VALID);
482
482
#else
483
 
                set_irq_noprobe(__irq);
 
483
                irq_set_noprobe(__irq);
484
484
#endif
485
485
        }
486
486
 
504
504
}
505
505
 
506
506
static void __devinit device_bk_init(struct pm860x_chip *chip,
507
 
                                     struct i2c_client *i2c,
508
507
                                     struct pm860x_platform_data *pdata)
509
508
{
510
509
        int ret;
517
516
                pdata->num_backlights = ARRAY_SIZE(bk_devs);
518
517
 
519
518
        for (i = 0; i < pdata->num_backlights; i++) {
520
 
                memcpy(&bk_pdata[i], &pdata->backlight[i],
521
 
                        sizeof(struct pm860x_backlight_pdata));
522
 
                bk_devs[i].mfd_data = &bk_pdata[i];
 
519
                bk_devs[i].platform_data = &pdata->backlight[i];
 
520
                bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
523
521
 
524
522
                for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
525
523
                        id = bk_resources[j].start;
526
 
                        if (bk_pdata[i].flags != id)
 
524
                        if (pdata->backlight[i].flags != id)
527
525
                                continue;
528
526
 
529
527
                        bk_devs[i].num_resources = 1;
541
539
}
542
540
 
543
541
static void __devinit device_led_init(struct pm860x_chip *chip,
544
 
                                      struct i2c_client *i2c,
545
542
                                      struct pm860x_platform_data *pdata)
546
543
{
547
544
        int ret;
554
551
                pdata->num_leds = ARRAY_SIZE(led_devs);
555
552
 
556
553
        for (i = 0; i < pdata->num_leds; i++) {
557
 
                memcpy(&led_pdata[i], &pdata->led[i],
558
 
                        sizeof(struct pm860x_led_pdata));
559
 
                led_devs[i].mfd_data = &led_pdata[i];
 
554
                led_devs[i].platform_data = &pdata->led[i];
 
555
                led_devs[i].pdata_size = sizeof(struct pm860x_led_pdata);
560
556
 
561
557
                for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
562
558
                        id = led_resources[j].start;
563
 
                        if (led_pdata[i].flags != id)
 
559
                        if (pdata->led[i].flags != id)
564
560
                                continue;
565
561
 
566
562
                        led_devs[i].num_resources = 1;
578
574
}
579
575
 
580
576
static void __devinit device_regulator_init(struct pm860x_chip *chip,
581
 
                                            struct i2c_client *i2c,
582
577
                                            struct pm860x_platform_data *pdata)
583
578
{
584
579
        struct regulator_init_data *initdata;
585
580
        int ret;
586
 
        int i, j;
 
581
        int i, seq;
587
582
 
588
583
        if ((pdata == NULL) || (pdata->regulator == NULL))
589
584
                return;
591
586
        if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
592
587
                pdata->num_regulators = ARRAY_SIZE(regulator_devs);
593
588
 
594
 
        for (i = 0, j = -1; i < pdata->num_regulators; i++) {
 
589
        for (i = 0, seq = -1; i < pdata->num_regulators; i++) {
595
590
                initdata = &pdata->regulator[i];
596
 
                if (strstr(initdata->constraints.name, "BUCK")) {
597
 
                        sscanf(initdata->constraints.name, "BUCK%d", &j);
598
 
                        /* BUCK1 ~ BUCK3 */
599
 
                        if ((j < 1) || (j > 3)) {
600
 
                                dev_err(chip->dev, "Failed to add constraint "
601
 
                                        "(%s)\n", initdata->constraints.name);
602
 
                                goto out;
603
 
                        }
604
 
                        j = (j - 1) + PM8607_ID_BUCK1;
605
 
                }
606
 
                if (strstr(initdata->constraints.name, "LDO")) {
607
 
                        sscanf(initdata->constraints.name, "LDO%d", &j);
608
 
                        /* LDO1 ~ LDO15 */
609
 
                        if ((j < 1) || (j > 15)) {
610
 
                                dev_err(chip->dev, "Failed to add constraint "
611
 
                                        "(%s)\n", initdata->constraints.name);
612
 
                                goto out;
613
 
                        }
614
 
                        j = (j - 1) + PM8607_ID_LDO1;
615
 
                }
616
 
                if (j == -1) {
617
 
                        dev_err(chip->dev, "Failed to add constraint (%s)\n",
618
 
                                initdata->constraints.name);
 
591
                seq = *(unsigned int *)initdata->driver_data;
 
592
                if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) {
 
593
                        dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n",
 
594
                                seq, initdata->constraints.name);
619
595
                        goto out;
620
596
                }
621
 
                memcpy(&regulator_pdata[i], &pdata->regulator[i],
622
 
                        sizeof(struct regulator_init_data));
623
 
                regulator_devs[i].mfd_data = &regulator_pdata[i];
 
597
                regulator_devs[i].platform_data = &pdata->regulator[i];
 
598
                regulator_devs[i].pdata_size = sizeof(struct regulator_init_data);
624
599
                regulator_devs[i].num_resources = 1;
625
 
                regulator_devs[i].resources = &regulator_resources[j];
 
600
                regulator_devs[i].resources = &regulator_resources[seq];
626
601
 
627
602
                ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
628
 
                                      &regulator_resources[j], 0);
 
603
                                      &regulator_resources[seq], 0);
629
604
                if (ret < 0) {
630
605
                        dev_err(chip->dev, "Failed to add regulator subdev\n");
631
606
                        goto out;
635
610
        return;
636
611
}
637
612
 
 
613
static void __devinit device_rtc_init(struct pm860x_chip *chip,
 
614
                                      struct pm860x_platform_data *pdata)
 
615
{
 
616
        int ret;
 
617
 
 
618
        if ((pdata == NULL))
 
619
                return;
 
620
 
 
621
        rtc_devs[0].platform_data = pdata->rtc;
 
622
        rtc_devs[0].pdata_size = sizeof(struct pm860x_rtc_pdata);
 
623
        rtc_devs[0].num_resources = ARRAY_SIZE(rtc_resources);
 
624
        rtc_devs[0].resources = &rtc_resources[0];
 
625
        ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
 
626
                              ARRAY_SIZE(rtc_devs), &rtc_resources[0],
 
627
                              chip->irq_base);
 
628
        if (ret < 0)
 
629
                dev_err(chip->dev, "Failed to add rtc subdev\n");
 
630
}
 
631
 
638
632
static void __devinit device_touch_init(struct pm860x_chip *chip,
639
 
                                        struct i2c_client *i2c,
640
633
                                        struct pm860x_platform_data *pdata)
641
634
{
642
635
        int ret;
643
636
 
644
 
        if ((pdata == NULL) || (pdata->touch == NULL))
 
637
        if (pdata == NULL)
645
638
                return;
646
639
 
647
 
        memcpy(&touch_pdata, pdata->touch, sizeof(struct pm860x_touch_pdata));
648
 
        touch_devs[0].mfd_data = &touch_pdata;
 
640
        touch_devs[0].platform_data = pdata->touch;
 
641
        touch_devs[0].pdata_size = sizeof(struct pm860x_touch_pdata);
649
642
        touch_devs[0].num_resources = ARRAY_SIZE(touch_resources);
650
643
        touch_devs[0].resources = &touch_resources[0];
651
644
        ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
656
649
}
657
650
 
658
651
static void __devinit device_power_init(struct pm860x_chip *chip,
659
 
                                        struct i2c_client *i2c,
660
652
                                        struct pm860x_platform_data *pdata)
661
653
{
662
654
        int ret;
663
655
 
664
 
        if ((pdata == NULL) || (pdata->power == NULL))
 
656
        if (pdata == NULL)
665
657
                return;
666
658
 
667
 
        memcpy(&power_pdata, pdata->power, sizeof(struct pm860x_power_pdata));
668
 
        power_devs[0].mfd_data = &power_pdata;
 
659
        power_devs[0].platform_data = pdata->power;
 
660
        power_devs[0].pdata_size = sizeof(struct pm860x_power_pdata);
669
661
        power_devs[0].num_resources = ARRAY_SIZE(battery_resources);
670
662
        power_devs[0].resources = &battery_resources[0],
671
663
        ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1,
673
665
        if (ret < 0)
674
666
                dev_err(chip->dev, "Failed to add battery subdev\n");
675
667
 
676
 
        power_devs[1].mfd_data = &power_pdata;
 
668
        power_devs[1].platform_data = pdata->power;
 
669
        power_devs[1].pdata_size = sizeof(struct pm860x_power_pdata);
677
670
        power_devs[1].num_resources = ARRAY_SIZE(charger_resources);
678
671
        power_devs[1].resources = &charger_resources[0],
679
672
        ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1,
683
676
}
684
677
 
685
678
static void __devinit device_onkey_init(struct pm860x_chip *chip,
686
 
                                        struct i2c_client *i2c,
687
679
                                        struct pm860x_platform_data *pdata)
688
680
{
689
681
        int ret;
698
690
}
699
691
 
700
692
static void __devinit device_codec_init(struct pm860x_chip *chip,
701
 
                                        struct i2c_client *i2c,
702
693
                                        struct pm860x_platform_data *pdata)
703
694
{
704
695
        int ret;
766
757
        if (ret < 0)
767
758
                goto out;
768
759
 
769
 
        device_regulator_init(chip, i2c, pdata);
770
 
        device_onkey_init(chip, i2c, pdata);
771
 
        device_touch_init(chip, i2c, pdata);
772
 
        device_power_init(chip, i2c, pdata);
773
 
        device_codec_init(chip, i2c, pdata);
 
760
        device_regulator_init(chip, pdata);
 
761
        device_rtc_init(chip, pdata);
 
762
        device_onkey_init(chip, pdata);
 
763
        device_touch_init(chip, pdata);
 
764
        device_power_init(chip, pdata);
 
765
        device_codec_init(chip, pdata);
774
766
out:
775
767
        return;
776
768
}
782
774
 
783
775
        switch (chip->id) {
784
776
        case CHIP_PM8606:
785
 
                device_bk_init(chip, chip->client, pdata);
786
 
                device_led_init(chip, chip->client, pdata);
 
777
                device_bk_init(chip, pdata);
 
778
                device_led_init(chip, pdata);
787
779
                break;
788
780
        case CHIP_PM8607:
789
781
                device_8607_init(chip, chip->client, pdata);
793
785
        if (chip->companion) {
794
786
                switch (chip->id) {
795
787
                case CHIP_PM8607:
796
 
                        device_bk_init(chip, chip->companion, pdata);
797
 
                        device_led_init(chip, chip->companion, pdata);
 
788
                        device_bk_init(chip, pdata);
 
789
                        device_led_init(chip, pdata);
798
790
                        break;
799
791
                case CHIP_PM8606:
800
792
                        device_8607_init(chip, chip->companion, pdata);