aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:59:01 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-24 10:59:01 -0400
commita6a1d6485e77f28c11cdf943a3ed2a3fd83ac727 (patch)
treed9b1948c2c07509f9fab16cd1444de15457c08f4 /drivers/mfd
parent1b506cfb6ae63f352643d6e208c85c1351547036 (diff)
parent316b6cc081b112546842d44ded21512bd8454a85 (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (90 commits) mfd: Push byte swaps out of wm8994 bulk read path mfd: Rename ab8500 gpadc header mfd: Constify WM8994 write path mfd: Push byte swap out of WM8994 bulk I/O mfd: Avoid copying data in WM8994 I2C write mfd: Remove copy from WM831x I2C write function mfd: Staticise WM8994 PM ops regulator: Add a subdriver for TI TPS6105x regulator portions v2 mfd: Add a core driver for TI TPS61050/TPS61052 chips v2 gpio: Add Tunnel Creek support to sch_gpio mfd: Add Tunnel Creek support to lpc_sch pci_ids: Add Intel Tunnel Creek LPC Bridge device ID. regulator: MAX8997/8966 support mfd: Add WM8994 bulk register write operation mfd: Append additional read write on 88pm860x mfd: Adopt mfd_data in 88pm860x input driver mfd: Adopt mfd_data in 88pm860x regulator mfd: Adopt mfd_data in 88pm860x led mfd: Adopt mfd_data in 88pm860x backlight mfd: Fix MAX8997 Kconfig entry typos ...
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/88pm860x-core.c567
-rw-r--r--drivers/mfd/88pm860x-i2c.c103
-rw-r--r--drivers/mfd/Kconfig40
-rw-r--r--drivers/mfd/Makefile6
-rw-r--r--drivers/mfd/ab3100-core.c10
-rw-r--r--drivers/mfd/ab3550-core.c12
-rw-r--r--drivers/mfd/ab8500-core.c56
-rw-r--r--drivers/mfd/ab8500-debugfs.c6
-rw-r--r--drivers/mfd/ab8500-gpadc.c614
-rw-r--r--drivers/mfd/ab8500-sysctrl.c80
-rw-r--r--drivers/mfd/adp5520.c15
-rw-r--r--drivers/mfd/asic3.c10
-rw-r--r--drivers/mfd/cs5535-mfd.c37
-rw-r--r--drivers/mfd/davinci_voicecodec.c4
-rw-r--r--drivers/mfd/htc-pasic3.c7
-rw-r--r--drivers/mfd/janz-cmodio.c3
-rw-r--r--drivers/mfd/jz4740-adc.c4
-rw-r--r--drivers/mfd/lpc_sch.c7
-rw-r--r--drivers/mfd/max8997.c427
-rw-r--r--drivers/mfd/max8998.c4
-rw-r--r--drivers/mfd/mc13xxx-core.c21
-rw-r--r--drivers/mfd/mfd-core.c135
-rw-r--r--drivers/mfd/pcf50633-core.c24
-rw-r--r--drivers/mfd/rdc321x-southbridge.c4
-rw-r--r--drivers/mfd/sh_mobile_sdhi.c4
-rw-r--r--drivers/mfd/t7l66xb.c13
-rw-r--r--drivers/mfd/tc6387xb.c7
-rw-r--r--drivers/mfd/tc6393xb.c25
-rw-r--r--drivers/mfd/timberdale.c81
-rw-r--r--drivers/mfd/tps6105x.c246
-rw-r--r--drivers/mfd/tps6586x.c26
-rw-r--r--drivers/mfd/twl-core.c8
-rw-r--r--drivers/mfd/twl4030-codec.c6
-rw-r--r--drivers/mfd/twl4030-madc.c802
-rw-r--r--drivers/mfd/ucb1x00-ts.c5
-rw-r--r--drivers/mfd/vx855.c1
-rw-r--r--drivers/mfd/wl1273-core.c8
-rw-r--r--drivers/mfd/wm831x-i2c.c18
-rw-r--r--drivers/mfd/wm831x-irq.c44
-rw-r--r--drivers/mfd/wm831x-spi.c24
-rw-r--r--drivers/mfd/wm8400-core.c2
-rw-r--r--drivers/mfd/wm8994-core.c77
-rw-r--r--drivers/mfd/wm8994-irq.c14
43 files changed, 3077 insertions, 530 deletions
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index 793300c554b4..9c511c1604a5 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -17,230 +17,138 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h> 18#include <linux/mfd/core.h>
19#include <linux/mfd/88pm860x.h> 19#include <linux/mfd/88pm860x.h>
20#include <linux/regulator/machine.h>
20 21
21#define INT_STATUS_NUM 3 22#define INT_STATUS_NUM 3
22 23
23char pm860x_backlight_name[][MFD_NAME_SIZE] = { 24static struct resource bk_resources[] __initdata = {
24 "backlight-0", 25 {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,},
25 "backlight-1", 26 {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,},
26 "backlight-2", 27 {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,},
27}; 28};
28EXPORT_SYMBOL(pm860x_backlight_name);
29
30char pm860x_led_name[][MFD_NAME_SIZE] = {
31 "led0-red",
32 "led0-green",
33 "led0-blue",
34 "led1-red",
35 "led1-green",
36 "led1-blue",
37};
38EXPORT_SYMBOL(pm860x_led_name);
39
40#define PM8606_BACKLIGHT_RESOURCE(_i, _x) \
41{ \
42 .name = pm860x_backlight_name[_i], \
43 .start = PM8606_##_x, \
44 .end = PM8606_##_x, \
45 .flags = IORESOURCE_IO, \
46}
47 29
48static struct resource backlight_resources[] = { 30static struct resource led_resources[] __initdata = {
49 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A), 31 {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO,},
50 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A), 32 {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,},
51 PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A), 33 {PM8606_LED1_BLUE, PM8606_LED1_BLUE, "led0-blue", IORESOURCE_IO,},
34 {PM8606_LED2_RED, PM8606_LED2_RED, "led1-red", IORESOURCE_IO,},
35 {PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO,},
36 {PM8606_LED2_BLUE, PM8606_LED2_BLUE, "led1-blue", IORESOURCE_IO,},
52}; 37};
53 38
54#define PM8606_BACKLIGHT_DEVS(_i) \ 39static struct resource regulator_resources[] __initdata = {
55{ \ 40 {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
56 .name = "88pm860x-backlight", \ 41 {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
57 .num_resources = 1, \ 42 {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
58 .resources = &backlight_resources[_i], \ 43 {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,},
59 .id = _i, \ 44 {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,},
60} 45 {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,},
61 46 {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,},
62static struct mfd_cell backlight_devs[] = { 47 {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,},
63 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1), 48 {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,},
64 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2), 49 {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,},
65 PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3), 50 {PM8607_ID_LDO8, PM8607_ID_LDO8, "ldo-08", IORESOURCE_IO,},
51 {PM8607_ID_LDO9, PM8607_ID_LDO9, "ldo-09", IORESOURCE_IO,},
52 {PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,},
53 {PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,},
54 {PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,},
55 {PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,},
56 {PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,},
57 {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
66}; 58};
67 59
68#define PM8606_LED_RESOURCE(_i, _x) \ 60static struct resource touch_resources[] __initdata = {
69{ \ 61 {PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
70 .name = pm860x_led_name[_i], \
71 .start = PM8606_##_x, \
72 .end = PM8606_##_x, \
73 .flags = IORESOURCE_IO, \
74}
75
76static struct resource led_resources[] = {
77 PM8606_LED_RESOURCE(PM8606_LED1_RED, RGB1B),
78 PM8606_LED_RESOURCE(PM8606_LED1_GREEN, RGB1C),
79 PM8606_LED_RESOURCE(PM8606_LED1_BLUE, RGB1D),
80 PM8606_LED_RESOURCE(PM8606_LED2_RED, RGB2B),
81 PM8606_LED_RESOURCE(PM8606_LED2_GREEN, RGB2C),
82 PM8606_LED_RESOURCE(PM8606_LED2_BLUE, RGB2D),
83}; 62};
84 63
85#define PM8606_LED_DEVS(_i) \ 64static struct resource onkey_resources[] __initdata = {
86{ \ 65 {PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
87 .name = "88pm860x-led", \
88 .num_resources = 1, \
89 .resources = &led_resources[_i], \
90 .id = _i, \
91}
92
93static struct mfd_cell led_devs[] = {
94 PM8606_LED_DEVS(PM8606_LED1_RED),
95 PM8606_LED_DEVS(PM8606_LED1_GREEN),
96 PM8606_LED_DEVS(PM8606_LED1_BLUE),
97 PM8606_LED_DEVS(PM8606_LED2_RED),
98 PM8606_LED_DEVS(PM8606_LED2_GREEN),
99 PM8606_LED_DEVS(PM8606_LED2_BLUE),
100}; 66};
101 67
102static struct resource touch_resources[] = { 68static struct resource codec_resources[] __initdata = {
103 { 69 /* Headset microphone insertion or removal */
104 .start = PM8607_IRQ_PEN, 70 {PM8607_IRQ_MICIN, PM8607_IRQ_MICIN, "micin", IORESOURCE_IRQ,},
105 .end = PM8607_IRQ_PEN, 71 /* Hook-switch press or release */
106 .flags = IORESOURCE_IRQ, 72 {PM8607_IRQ_HOOK, PM8607_IRQ_HOOK, "hook", IORESOURCE_IRQ,},
107 }, 73 /* Headset insertion or removal */
74 {PM8607_IRQ_HEADSET, PM8607_IRQ_HEADSET, "headset", IORESOURCE_IRQ,},
75 /* Audio short */
76 {PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
108}; 77};
109 78
110static struct mfd_cell touch_devs[] = { 79static struct resource battery_resources[] __initdata = {
111 { 80 {PM8607_IRQ_CC, PM8607_IRQ_CC, "columb counter", IORESOURCE_IRQ,},
112 .name = "88pm860x-touch", 81 {PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery", IORESOURCE_IRQ,},
113 .num_resources = 1,
114 .resources = &touch_resources[0],
115 },
116}; 82};
117 83
118#define PM8607_REG_RESOURCE(_start, _end) \ 84static struct resource charger_resources[] __initdata = {
119{ \ 85 {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,},
120 .start = PM8607_##_start, \ 86 {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,},
121 .end = PM8607_##_end, \ 87 {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout", IORESOURCE_IRQ,},
122 .flags = IORESOURCE_IO, \ 88 {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,},
123} 89 {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,},
124 90 {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,},
125static struct resource power_supply_resources[] = {
126 {
127 .name = "88pm860x-power",
128 .start = PM8607_IRQ_CHG,
129 .end = PM8607_IRQ_CHG,
130 .flags = IORESOURCE_IRQ,
131 },
132}; 91};
133 92
134static struct mfd_cell power_devs[] = { 93static struct mfd_cell bk_devs[] __initdata = {
135 { 94 {"88pm860x-backlight", 0,},
136 .name = "88pm860x-power", 95 {"88pm860x-backlight", 1,},
137 .num_resources = 1, 96 {"88pm860x-backlight", 2,},
138 .resources = &power_supply_resources[0],
139 .id = -1,
140 },
141}; 97};
142 98
143static struct resource onkey_resources[] = { 99static struct mfd_cell led_devs[] __initdata = {
144 { 100 {"88pm860x-led", 0,},
145 .name = "88pm860x-onkey", 101 {"88pm860x-led", 1,},
146 .start = PM8607_IRQ_ONKEY, 102 {"88pm860x-led", 2,},
147 .end = PM8607_IRQ_ONKEY, 103 {"88pm860x-led", 3,},
148 .flags = IORESOURCE_IRQ, 104 {"88pm860x-led", 4,},
149 }, 105 {"88pm860x-led", 5,},
150}; 106};
151 107
152static struct mfd_cell onkey_devs[] = { 108static struct mfd_cell regulator_devs[] __initdata = {
153 { 109 {"88pm860x-regulator", 0,},
154 .name = "88pm860x-onkey", 110 {"88pm860x-regulator", 1,},
155 .num_resources = 1, 111 {"88pm860x-regulator", 2,},
156 .resources = &onkey_resources[0], 112 {"88pm860x-regulator", 3,},
157 .id = -1, 113 {"88pm860x-regulator", 4,},
158 }, 114 {"88pm860x-regulator", 5,},
115 {"88pm860x-regulator", 6,},
116 {"88pm860x-regulator", 7,},
117 {"88pm860x-regulator", 8,},
118 {"88pm860x-regulator", 9,},
119 {"88pm860x-regulator", 10,},
120 {"88pm860x-regulator", 11,},
121 {"88pm860x-regulator", 12,},
122 {"88pm860x-regulator", 13,},
123 {"88pm860x-regulator", 14,},
124 {"88pm860x-regulator", 15,},
125 {"88pm860x-regulator", 16,},
126 {"88pm860x-regulator", 17,},
159}; 127};
160 128
161static struct resource codec_resources[] = { 129static struct mfd_cell touch_devs[] __initdata = {
162 { 130 {"88pm860x-touch", -1,},
163 /* Headset microphone insertion or removal */
164 .name = "micin",
165 .start = PM8607_IRQ_MICIN,
166 .end = PM8607_IRQ_MICIN,
167 .flags = IORESOURCE_IRQ,
168 }, {
169 /* Hook-switch press or release */
170 .name = "hook",
171 .start = PM8607_IRQ_HOOK,
172 .end = PM8607_IRQ_HOOK,
173 .flags = IORESOURCE_IRQ,
174 }, {
175 /* Headset insertion or removal */
176 .name = "headset",
177 .start = PM8607_IRQ_HEADSET,
178 .end = PM8607_IRQ_HEADSET,
179 .flags = IORESOURCE_IRQ,
180 }, {
181 /* Audio short */
182 .name = "audio-short",
183 .start = PM8607_IRQ_AUDIO_SHORT,
184 .end = PM8607_IRQ_AUDIO_SHORT,
185 .flags = IORESOURCE_IRQ,
186 },
187}; 131};
188 132
189static struct mfd_cell codec_devs[] = { 133static struct mfd_cell onkey_devs[] __initdata = {
190 { 134 {"88pm860x-onkey", -1,},
191 .name = "88pm860x-codec",
192 .num_resources = ARRAY_SIZE(codec_resources),
193 .resources = &codec_resources[0],
194 .id = -1,
195 },
196}; 135};
197 136
198static struct resource regulator_resources[] = { 137static struct mfd_cell codec_devs[] __initdata = {
199 PM8607_REG_RESOURCE(BUCK1, BUCK1), 138 {"88pm860x-codec", -1,},
200 PM8607_REG_RESOURCE(BUCK2, BUCK2),
201 PM8607_REG_RESOURCE(BUCK3, BUCK3),
202 PM8607_REG_RESOURCE(LDO1, LDO1),
203 PM8607_REG_RESOURCE(LDO2, LDO2),
204 PM8607_REG_RESOURCE(LDO3, LDO3),
205 PM8607_REG_RESOURCE(LDO4, LDO4),
206 PM8607_REG_RESOURCE(LDO5, LDO5),
207 PM8607_REG_RESOURCE(LDO6, LDO6),
208 PM8607_REG_RESOURCE(LDO7, LDO7),
209 PM8607_REG_RESOURCE(LDO8, LDO8),
210 PM8607_REG_RESOURCE(LDO9, LDO9),
211 PM8607_REG_RESOURCE(LDO10, LDO10),
212 PM8607_REG_RESOURCE(LDO12, LDO12),
213 PM8607_REG_RESOURCE(VIBRATOR_SET, VIBRATOR_SET),
214 PM8607_REG_RESOURCE(LDO14, LDO14),
215}; 139};
216 140
217#define PM8607_REG_DEVS(_id) \ 141static struct mfd_cell power_devs[] = {
218{ \ 142 {"88pm860x-battery", -1,},
219 .name = "88pm860x-regulator", \ 143 {"88pm860x-charger", -1,},
220 .num_resources = 1, \
221 .resources = &regulator_resources[PM8607_ID_##_id], \
222 .id = PM8607_ID_##_id, \
223}
224
225static struct mfd_cell regulator_devs[] = {
226 PM8607_REG_DEVS(BUCK1),
227 PM8607_REG_DEVS(BUCK2),
228 PM8607_REG_DEVS(BUCK3),
229 PM8607_REG_DEVS(LDO1),
230 PM8607_REG_DEVS(LDO2),
231 PM8607_REG_DEVS(LDO3),
232 PM8607_REG_DEVS(LDO4),
233 PM8607_REG_DEVS(LDO5),
234 PM8607_REG_DEVS(LDO6),
235 PM8607_REG_DEVS(LDO7),
236 PM8607_REG_DEVS(LDO8),
237 PM8607_REG_DEVS(LDO9),
238 PM8607_REG_DEVS(LDO10),
239 PM8607_REG_DEVS(LDO12),
240 PM8607_REG_DEVS(LDO13),
241 PM8607_REG_DEVS(LDO14),
242}; 144};
243 145
146static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)];
147static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)];
148static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)];
149static struct pm860x_touch_pdata touch_pdata;
150static struct pm860x_power_pdata power_pdata;
151
244struct pm860x_irq_data { 152struct pm860x_irq_data {
245 int reg; 153 int reg;
246 int mask_reg; 154 int mask_reg;
@@ -595,37 +503,212 @@ static void device_irq_exit(struct pm860x_chip *chip)
595 free_irq(chip->core_irq, chip); 503 free_irq(chip->core_irq, chip);
596} 504}
597 505
598static void __devinit device_8606_init(struct pm860x_chip *chip, 506static void __devinit device_bk_init(struct pm860x_chip *chip,
599 struct i2c_client *i2c, 507 struct i2c_client *i2c,
600 struct pm860x_platform_data *pdata) 508 struct pm860x_platform_data *pdata)
601{ 509{
602 int ret; 510 int ret;
511 int i, j, id;
512
513 if ((pdata == NULL) || (pdata->backlight == NULL))
514 return;
515
516 if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
517 pdata->num_backlights = ARRAY_SIZE(bk_devs);
518
519 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];
523
524 for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
525 id = bk_resources[j].start;
526 if (bk_pdata[i].flags != id)
527 continue;
528
529 bk_devs[i].num_resources = 1;
530 bk_devs[i].resources = &bk_resources[j];
531 ret = mfd_add_devices(chip->dev, 0,
532 &bk_devs[i], 1,
533 &bk_resources[j], 0);
534 if (ret < 0) {
535 dev_err(chip->dev, "Failed to add "
536 "backlight subdev\n");
537 return;
538 }
539 }
540 }
541}
603 542
604 if (pdata && pdata->backlight) { 543static void __devinit device_led_init(struct pm860x_chip *chip,
605 ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], 544 struct i2c_client *i2c,
606 ARRAY_SIZE(backlight_devs), 545 struct pm860x_platform_data *pdata)
607 &backlight_resources[0], 0); 546{
608 if (ret < 0) { 547 int ret;
609 dev_err(chip->dev, "Failed to add backlight " 548 int i, j, id;
610 "subdev\n"); 549
611 goto out_dev; 550 if ((pdata == NULL) || (pdata->led == NULL))
551 return;
552
553 if (pdata->num_leds > ARRAY_SIZE(led_devs))
554 pdata->num_leds = ARRAY_SIZE(led_devs);
555
556 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];
560
561 for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
562 id = led_resources[j].start;
563 if (led_pdata[i].flags != id)
564 continue;
565
566 led_devs[i].num_resources = 1;
567 led_devs[i].resources = &led_resources[j],
568 ret = mfd_add_devices(chip->dev, 0,
569 &led_devs[i], 1,
570 &led_resources[j], 0);
571 if (ret < 0) {
572 dev_err(chip->dev, "Failed to add "
573 "led subdev\n");
574 return;
575 }
612 } 576 }
613 } 577 }
578}
614 579
615 if (pdata && pdata->led) { 580static void __devinit device_regulator_init(struct pm860x_chip *chip,
616 ret = mfd_add_devices(chip->dev, 0, &led_devs[0], 581 struct i2c_client *i2c,
617 ARRAY_SIZE(led_devs), 582 struct pm860x_platform_data *pdata)
618 &led_resources[0], 0); 583{
584 struct regulator_init_data *initdata;
585 int ret;
586 int i, j;
587
588 if ((pdata == NULL) || (pdata->regulator == NULL))
589 return;
590
591 if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
592 pdata->num_regulators = ARRAY_SIZE(regulator_devs);
593
594 for (i = 0, j = -1; i < pdata->num_regulators; i++) {
595 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);
619 goto out;
620 }
621 memcpy(&regulator_pdata[i], &pdata->regulator[i],
622 sizeof(struct regulator_init_data));
623 regulator_devs[i].mfd_data = &regulator_pdata[i];
624 regulator_devs[i].num_resources = 1;
625 regulator_devs[i].resources = &regulator_resources[j];
626
627 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
628 &regulator_resources[j], 0);
619 if (ret < 0) { 629 if (ret < 0) {
620 dev_err(chip->dev, "Failed to add led " 630 dev_err(chip->dev, "Failed to add regulator subdev\n");
621 "subdev\n"); 631 goto out;
622 goto out_dev;
623 } 632 }
624 } 633 }
634out:
625 return; 635 return;
626out_dev: 636}
627 mfd_remove_devices(chip->dev); 637
628 device_irq_exit(chip); 638static void __devinit device_touch_init(struct pm860x_chip *chip,
639 struct i2c_client *i2c,
640 struct pm860x_platform_data *pdata)
641{
642 int ret;
643
644 if ((pdata == NULL) || (pdata->touch == NULL))
645 return;
646
647 memcpy(&touch_pdata, pdata->touch, sizeof(struct pm860x_touch_pdata));
648 touch_devs[0].mfd_data = &touch_pdata;
649 touch_devs[0].num_resources = ARRAY_SIZE(touch_resources);
650 touch_devs[0].resources = &touch_resources[0];
651 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
652 ARRAY_SIZE(touch_devs), &touch_resources[0],
653 chip->irq_base);
654 if (ret < 0)
655 dev_err(chip->dev, "Failed to add touch subdev\n");
656}
657
658static void __devinit device_power_init(struct pm860x_chip *chip,
659 struct i2c_client *i2c,
660 struct pm860x_platform_data *pdata)
661{
662 int ret;
663
664 if ((pdata == NULL) || (pdata->power == NULL))
665 return;
666
667 memcpy(&power_pdata, pdata->power, sizeof(struct pm860x_power_pdata));
668 power_devs[0].mfd_data = &power_pdata;
669 power_devs[0].num_resources = ARRAY_SIZE(battery_resources);
670 power_devs[0].resources = &battery_resources[0],
671 ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1,
672 &battery_resources[0], chip->irq_base);
673 if (ret < 0)
674 dev_err(chip->dev, "Failed to add battery subdev\n");
675
676 power_devs[1].mfd_data = &power_pdata;
677 power_devs[1].num_resources = ARRAY_SIZE(charger_resources);
678 power_devs[1].resources = &charger_resources[0],
679 ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1,
680 &charger_resources[0], chip->irq_base);
681 if (ret < 0)
682 dev_err(chip->dev, "Failed to add charger subdev\n");
683}
684
685static void __devinit device_onkey_init(struct pm860x_chip *chip,
686 struct i2c_client *i2c,
687 struct pm860x_platform_data *pdata)
688{
689 int ret;
690
691 onkey_devs[0].num_resources = ARRAY_SIZE(onkey_resources);
692 onkey_devs[0].resources = &onkey_resources[0],
693 ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
694 ARRAY_SIZE(onkey_devs), &onkey_resources[0],
695 chip->irq_base);
696 if (ret < 0)
697 dev_err(chip->dev, "Failed to add onkey subdev\n");
698}
699
700static void __devinit device_codec_init(struct pm860x_chip *chip,
701 struct i2c_client *i2c,
702 struct pm860x_platform_data *pdata)
703{
704 int ret;
705
706 codec_devs[0].num_resources = ARRAY_SIZE(codec_resources);
707 codec_devs[0].resources = &codec_resources[0],
708 ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
709 ARRAY_SIZE(codec_devs), &codec_resources[0], 0);
710 if (ret < 0)
711 dev_err(chip->dev, "Failed to add codec subdev\n");
629} 712}
630 713
631static void __devinit device_8607_init(struct pm860x_chip *chip, 714static void __devinit device_8607_init(struct pm860x_chip *chip,
@@ -683,55 +766,11 @@ static void __devinit device_8607_init(struct pm860x_chip *chip,
683 if (ret < 0) 766 if (ret < 0)
684 goto out; 767 goto out;
685 768
686 ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0], 769 device_regulator_init(chip, i2c, pdata);
687 ARRAY_SIZE(regulator_devs), 770 device_onkey_init(chip, i2c, pdata);
688 &regulator_resources[0], 0); 771 device_touch_init(chip, i2c, pdata);
689 if (ret < 0) { 772 device_power_init(chip, i2c, pdata);
690 dev_err(chip->dev, "Failed to add regulator subdev\n"); 773 device_codec_init(chip, i2c, pdata);
691 goto out_dev;
692 }
693
694 if (pdata && pdata->touch) {
695 ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
696 ARRAY_SIZE(touch_devs),
697 &touch_resources[0], 0);
698 if (ret < 0) {
699 dev_err(chip->dev, "Failed to add touch "
700 "subdev\n");
701 goto out_dev;
702 }
703 }
704
705 if (pdata && pdata->power) {
706 ret = mfd_add_devices(chip->dev, 0, &power_devs[0],
707 ARRAY_SIZE(power_devs),
708 &power_supply_resources[0], 0);
709 if (ret < 0) {
710 dev_err(chip->dev, "Failed to add power supply "
711 "subdev\n");
712 goto out_dev;
713 }
714 }
715
716 ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0],
717 ARRAY_SIZE(onkey_devs),
718 &onkey_resources[0], 0);
719 if (ret < 0) {
720 dev_err(chip->dev, "Failed to add onkey subdev\n");
721 goto out_dev;
722 }
723
724 ret = mfd_add_devices(chip->dev, 0, &codec_devs[0],
725 ARRAY_SIZE(codec_devs),
726 &codec_resources[0], 0);
727 if (ret < 0) {
728 dev_err(chip->dev, "Failed to add codec subdev\n");
729 goto out_dev;
730 }
731 return;
732out_dev:
733 mfd_remove_devices(chip->dev);
734 device_irq_exit(chip);
735out: 774out:
736 return; 775 return;
737} 776}
@@ -743,7 +782,8 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
743 782
744 switch (chip->id) { 783 switch (chip->id) {
745 case CHIP_PM8606: 784 case CHIP_PM8606:
746 device_8606_init(chip, chip->client, pdata); 785 device_bk_init(chip, chip->client, pdata);
786 device_led_init(chip, chip->client, pdata);
747 break; 787 break;
748 case CHIP_PM8607: 788 case CHIP_PM8607:
749 device_8607_init(chip, chip->client, pdata); 789 device_8607_init(chip, chip->client, pdata);
@@ -753,7 +793,8 @@ int __devinit pm860x_device_init(struct pm860x_chip *chip,
753 if (chip->companion) { 793 if (chip->companion) {
754 switch (chip->id) { 794 switch (chip->id) {
755 case CHIP_PM8607: 795 case CHIP_PM8607:
756 device_8606_init(chip, chip->companion, pdata); 796 device_bk_init(chip, chip->companion, pdata);
797 device_led_init(chip, chip->companion, pdata);
757 break; 798 break;
758 case CHIP_PM8606: 799 case CHIP_PM8606:
759 device_8607_init(chip, chip->companion, pdata); 800 device_8607_init(chip, chip->companion, pdata);
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index bc02e6b21608..e017dc88622a 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -126,6 +126,109 @@ out:
126} 126}
127EXPORT_SYMBOL(pm860x_set_bits); 127EXPORT_SYMBOL(pm860x_set_bits);
128 128
129int pm860x_page_reg_read(struct i2c_client *i2c, int reg)
130{
131 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
132 unsigned char zero = 0;
133 unsigned char data;
134 int ret;
135
136 mutex_lock(&chip->io_lock);
137 pm860x_write_device(i2c, 0xFA, 0, &zero);
138 pm860x_write_device(i2c, 0xFB, 0, &zero);
139 pm860x_write_device(i2c, 0xFF, 0, &zero);
140 ret = pm860x_read_device(i2c, reg, 1, &data);
141 if (ret >= 0)
142 ret = (int)data;
143 pm860x_write_device(i2c, 0xFE, 0, &zero);
144 pm860x_write_device(i2c, 0xFC, 0, &zero);
145 mutex_unlock(&chip->io_lock);
146 return ret;
147}
148EXPORT_SYMBOL(pm860x_page_reg_read);
149
150int pm860x_page_reg_write(struct i2c_client *i2c, int reg,
151 unsigned char data)
152{
153 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
154 unsigned char zero;
155 int ret;
156
157 mutex_lock(&chip->io_lock);
158 pm860x_write_device(i2c, 0xFA, 0, &zero);
159 pm860x_write_device(i2c, 0xFB, 0, &zero);
160 pm860x_write_device(i2c, 0xFF, 0, &zero);
161 ret = pm860x_write_device(i2c, reg, 1, &data);
162 pm860x_write_device(i2c, 0xFE, 0, &zero);
163 pm860x_write_device(i2c, 0xFC, 0, &zero);
164 mutex_unlock(&chip->io_lock);
165 return ret;
166}
167EXPORT_SYMBOL(pm860x_page_reg_write);
168
169int pm860x_page_bulk_read(struct i2c_client *i2c, int reg,
170 int count, unsigned char *buf)
171{
172 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
173 unsigned char zero = 0;
174 int ret;
175
176 mutex_lock(&chip->io_lock);
177 pm860x_write_device(i2c, 0xFA, 0, &zero);
178 pm860x_write_device(i2c, 0xFB, 0, &zero);
179 pm860x_write_device(i2c, 0xFF, 0, &zero);
180 ret = pm860x_read_device(i2c, reg, count, buf);
181 pm860x_write_device(i2c, 0xFE, 0, &zero);
182 pm860x_write_device(i2c, 0xFC, 0, &zero);
183 mutex_unlock(&chip->io_lock);
184 return ret;
185}
186EXPORT_SYMBOL(pm860x_page_bulk_read);
187
188int pm860x_page_bulk_write(struct i2c_client *i2c, int reg,
189 int count, unsigned char *buf)
190{
191 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
192 unsigned char zero = 0;
193 int ret;
194
195 mutex_lock(&chip->io_lock);
196 pm860x_write_device(i2c, 0xFA, 0, &zero);
197 pm860x_write_device(i2c, 0xFB, 0, &zero);
198 pm860x_write_device(i2c, 0xFF, 0, &zero);
199 ret = pm860x_write_device(i2c, reg, count, buf);
200 pm860x_write_device(i2c, 0xFE, 0, &zero);
201 pm860x_write_device(i2c, 0xFC, 0, &zero);
202 mutex_unlock(&chip->io_lock);
203 return ret;
204}
205EXPORT_SYMBOL(pm860x_page_bulk_write);
206
207int pm860x_page_set_bits(struct i2c_client *i2c, int reg,
208 unsigned char mask, unsigned char data)
209{
210 struct pm860x_chip *chip = i2c_get_clientdata(i2c);
211 unsigned char zero;
212 unsigned char value;
213 int ret;
214
215 mutex_lock(&chip->io_lock);
216 pm860x_write_device(i2c, 0xFA, 0, &zero);
217 pm860x_write_device(i2c, 0xFB, 0, &zero);
218 pm860x_write_device(i2c, 0xFF, 0, &zero);
219 ret = pm860x_read_device(i2c, reg, 1, &value);
220 if (ret < 0)
221 goto out;
222 value &= ~mask;
223 value |= data;
224 ret = pm860x_write_device(i2c, reg, 1, &value);
225out:
226 pm860x_write_device(i2c, 0xFE, 0, &zero);
227 pm860x_write_device(i2c, 0xFC, 0, &zero);
228 mutex_unlock(&chip->io_lock);
229 return ret;
230}
231EXPORT_SYMBOL(pm860x_page_set_bits);
129 232
130static const struct i2c_device_id pm860x_id_table[] = { 233static const struct i2c_device_id pm860x_id_table[] = {
131 { "88PM860x", 0 }, 234 { "88PM860x", 0 },
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fdca643249e1..8d7d098f7a03 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -129,6 +129,17 @@ config UCB1400_CORE
129 To compile this driver as a module, choose M here: the 129 To compile this driver as a module, choose M here: the
130 module will be called ucb1400_core. 130 module will be called ucb1400_core.
131 131
132config TPS6105X
133 tristate "TPS61050/61052 Boost Converters"
134 depends on I2C
135 select REGULATOR
136 select REGULATOR_FIXED_VOLTAGE
137 help
138 This option enables a driver for the TP61050/TPS61052
139 high-power "white LED driver". This boost converter is
140 sometimes used for other things than white LEDs, and
141 also contains a GPIO pin.
142
132config TPS65010 143config TPS65010
133 tristate "TPS6501x Power Management chips" 144 tristate "TPS6501x Power Management chips"
134 depends on I2C && GPIOLIB 145 depends on I2C && GPIOLIB
@@ -178,6 +189,16 @@ config TWL4030_CORE
178 high speed USB OTG transceiver, an audio codec (on most 189 high speed USB OTG transceiver, an audio codec (on most
179 versions) and many other features. 190 versions) and many other features.
180 191
192config TWL4030_MADC
193 tristate "Texas Instruments TWL4030 MADC"
194 depends on TWL4030_CORE
195 help
196 This driver provides support for triton TWL4030-MADC. The
197 driver supports both RT and SW conversion methods.
198
199 This driver can be built as a module. If so it will be
200 named twl4030-madc
201
181config TWL4030_POWER 202config TWL4030_POWER
182 bool "Support power resources on TWL4030 family chips" 203 bool "Support power resources on TWL4030 family chips"
183 depends on TWL4030_CORE && ARM 204 depends on TWL4030_CORE && ARM
@@ -304,6 +325,18 @@ config MFD_MAX8925
304 accessing the device, additional drivers must be enabled in order 325 accessing the device, additional drivers must be enabled in order
305 to use the functionality of the device. 326 to use the functionality of the device.
306 327
328config MFD_MAX8997
329 bool "Maxim Semiconductor MAX8997/8966 PMIC Support"
330 depends on I2C=y && GENERIC_HARDIRQS
331 select MFD_CORE
332 help
333 Say yes here to support for Maxim Semiconductor MAX8998/8966.
334 This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic,
335 MUIC controls on chip.
336 This driver provides common support for accessing the device;
337 additional drivers must be enabled in order to use the functionality
338 of the device.
339
307config MFD_MAX8998 340config MFD_MAX8998
308 bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support" 341 bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support"
309 depends on I2C=y && GENERIC_HARDIRQS 342 depends on I2C=y && GENERIC_HARDIRQS
@@ -534,6 +567,13 @@ config AB8500_DEBUG
534 Select this option if you want debug information using the debug 567 Select this option if you want debug information using the debug
535 filesystem, debugfs. 568 filesystem, debugfs.
536 569
570config AB8500_GPADC
571 bool "AB8500 GPADC driver"
572 depends on AB8500_CORE && REGULATOR_AB8500
573 default y
574 help
575 AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage
576
537config AB3550_CORE 577config AB3550_CORE
538 bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions" 578 bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions"
539 select MFD_CORE 579 select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index f0e25cad762e..47f5709f3828 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -33,11 +33,13 @@ obj-$(CONFIG_MFD_WM8350) += wm8350.o
33obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o 33obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
34obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o 34obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o
35 35
36obj-$(CONFIG_TPS6105X) += tps6105x.o
36obj-$(CONFIG_TPS65010) += tps65010.o 37obj-$(CONFIG_TPS65010) += tps65010.o
37obj-$(CONFIG_TPS6507X) += tps6507x.o 38obj-$(CONFIG_TPS6507X) += tps6507x.o
38obj-$(CONFIG_MENELAUS) += menelaus.o 39obj-$(CONFIG_MENELAUS) += menelaus.o
39 40
40obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o 41obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o
42obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
41obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o 43obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o
42obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o 44obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o
43obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o 45obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
@@ -61,6 +63,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
61obj-$(CONFIG_PMIC_DA903X) += da903x.o 63obj-$(CONFIG_PMIC_DA903X) += da903x.o
62max8925-objs := max8925-core.o max8925-i2c.o 64max8925-objs := max8925-core.o max8925-i2c.o
63obj-$(CONFIG_MFD_MAX8925) += max8925.o 65obj-$(CONFIG_MFD_MAX8925) += max8925.o
66obj-$(CONFIG_MFD_MAX8997) += max8997.o
64obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o 67obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o
65 68
66pcf50633-objs := pcf50633-core.o pcf50633-irq.o 69pcf50633-objs := pcf50633-core.o pcf50633-irq.o
@@ -71,9 +74,10 @@ obj-$(CONFIG_ABX500_CORE) += abx500-core.o
71obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 74obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
72obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 75obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
73obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 76obj-$(CONFIG_AB3550_CORE) += ab3550-core.o
74obj-$(CONFIG_AB8500_CORE) += ab8500-core.o 77obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
75obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o 78obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o
76obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 79obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
80obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
77obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 81obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
78obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 82obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
79obj-$(CONFIG_LPC_SCH) += lpc_sch.o 83obj-$(CONFIG_LPC_SCH) += lpc_sch.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 4193af5f2743..a751927047ac 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -613,7 +613,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100)
613 ab3100_get_priv.ab3100 = ab3100; 613 ab3100_get_priv.ab3100 = ab3100;
614 ab3100_get_priv.mode = false; 614 ab3100_get_priv.mode = false;
615 ab3100_get_reg_file = debugfs_create_file("get_reg", 615 ab3100_get_reg_file = debugfs_create_file("get_reg",
616 S_IWUGO, ab3100_dir, &ab3100_get_priv, 616 S_IWUSR, ab3100_dir, &ab3100_get_priv,
617 &ab3100_get_set_reg_fops); 617 &ab3100_get_set_reg_fops);
618 if (!ab3100_get_reg_file) { 618 if (!ab3100_get_reg_file) {
619 err = -ENOMEM; 619 err = -ENOMEM;
@@ -623,7 +623,7 @@ static void ab3100_setup_debugfs(struct ab3100 *ab3100)
623 ab3100_set_priv.ab3100 = ab3100; 623 ab3100_set_priv.ab3100 = ab3100;
624 ab3100_set_priv.mode = true; 624 ab3100_set_priv.mode = true;
625 ab3100_set_reg_file = debugfs_create_file("set_reg", 625 ab3100_set_reg_file = debugfs_create_file("set_reg",
626 S_IWUGO, ab3100_dir, &ab3100_set_priv, 626 S_IWUSR, ab3100_dir, &ab3100_set_priv,
627 &ab3100_get_set_reg_fops); 627 &ab3100_get_set_reg_fops);
628 if (!ab3100_set_reg_file) { 628 if (!ab3100_set_reg_file) {
629 err = -ENOMEM; 629 err = -ENOMEM;
@@ -949,10 +949,8 @@ static int __devinit ab3100_probe(struct i2c_client *client,
949 goto exit_no_ops; 949 goto exit_no_ops;
950 950
951 /* Set up and register the platform devices. */ 951 /* Set up and register the platform devices. */
952 for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) { 952 for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++)
953 ab3100_devs[i].platform_data = ab3100_plf_data; 953 ab3100_devs[i].mfd_data = ab3100_plf_data;
954 ab3100_devs[i].data_size = sizeof(struct ab3100_platform_data);
955 }
956 954
957 err = mfd_add_devices(&client->dev, 0, ab3100_devs, 955 err = mfd_add_devices(&client->dev, 0, ab3100_devs,
958 ARRAY_SIZE(ab3100_devs), NULL, 0); 956 ARRAY_SIZE(ab3100_devs), NULL, 0);
diff --git a/drivers/mfd/ab3550-core.c b/drivers/mfd/ab3550-core.c
index 5fbca346b998..c12d04285226 100644
--- a/drivers/mfd/ab3550-core.c
+++ b/drivers/mfd/ab3550-core.c
@@ -1053,17 +1053,17 @@ static inline void ab3550_setup_debugfs(struct ab3550 *ab)
1053 goto exit_destroy_dir; 1053 goto exit_destroy_dir;
1054 1054
1055 ab3550_bank_file = debugfs_create_file("register-bank", 1055 ab3550_bank_file = debugfs_create_file("register-bank",
1056 (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_bank_fops); 1056 (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_bank_fops);
1057 if (!ab3550_bank_file) 1057 if (!ab3550_bank_file)
1058 goto exit_destroy_reg; 1058 goto exit_destroy_reg;
1059 1059
1060 ab3550_address_file = debugfs_create_file("register-address", 1060 ab3550_address_file = debugfs_create_file("register-address",
1061 (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_address_fops); 1061 (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_address_fops);
1062 if (!ab3550_address_file) 1062 if (!ab3550_address_file)
1063 goto exit_destroy_bank; 1063 goto exit_destroy_bank;
1064 1064
1065 ab3550_val_file = debugfs_create_file("register-value", 1065 ab3550_val_file = debugfs_create_file("register-value",
1066 (S_IRUGO | S_IWUGO), ab3550_dir, ab, &ab3550_val_fops); 1066 (S_IRUGO | S_IWUSR), ab3550_dir, ab, &ab3550_val_fops);
1067 if (!ab3550_val_file) 1067 if (!ab3550_val_file)
1068 goto exit_destroy_address; 1068 goto exit_destroy_address;
1069 1069
@@ -1320,10 +1320,8 @@ static int __init ab3550_probe(struct i2c_client *client,
1320 goto exit_no_ops; 1320 goto exit_no_ops;
1321 1321
1322 /* Set up and register the platform devices. */ 1322 /* Set up and register the platform devices. */
1323 for (i = 0; i < AB3550_NUM_DEVICES; i++) { 1323 for (i = 0; i < AB3550_NUM_DEVICES; i++)
1324 ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i]; 1324 ab3550_devs[i].mfd_data = ab3550_plf_data->dev_data[i];
1325 ab3550_devs[i].data_size = ab3550_plf_data->dev_data_sz[i];
1326 }
1327 1325
1328 err = mfd_add_devices(&client->dev, 0, ab3550_devs, 1326 err = mfd_add_devices(&client->dev, 0, ab3550_devs,
1329 ARRAY_SIZE(ab3550_devs), NULL, 1327 ARRAY_SIZE(ab3550_devs), NULL,
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index b6887014d687..6e185b272d00 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -4,7 +4,7 @@
4 * License Terms: GNU General Public License v2 4 * License Terms: GNU General Public License v2
5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
6 * Author: Rabin Vincent <rabin.vincent@stericsson.com> 6 * Author: Rabin Vincent <rabin.vincent@stericsson.com>
7 * Changes: Mattias Wallin <mattias.wallin@stericsson.com> 7 * Author: Mattias Wallin <mattias.wallin@stericsson.com>
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
@@ -90,6 +90,7 @@
90#define AB8500_IT_MASK24_REG 0x57 90#define AB8500_IT_MASK24_REG 0x57
91 91
92#define AB8500_REV_REG 0x80 92#define AB8500_REV_REG 0x80
93#define AB8500_SWITCH_OFF_STATUS 0x00
93 94
94/* 95/*
95 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt 96 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt
@@ -652,10 +653,38 @@ static ssize_t show_chip_id(struct device *dev,
652 return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); 653 return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL);
653} 654}
654 655
656/*
657 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
658 * 0x01 Swoff bit programming
659 * 0x02 Thermal protection activation
660 * 0x04 Vbat lower then BattOk falling threshold
661 * 0x08 Watchdog expired
662 * 0x10 Non presence of 32kHz clock
663 * 0x20 Battery level lower than power on reset threshold
664 * 0x40 Power on key 1 pressed longer than 10 seconds
665 * 0x80 DB8500 thermal shutdown
666 */
667static ssize_t show_switch_off_status(struct device *dev,
668 struct device_attribute *attr, char *buf)
669{
670 int ret;
671 u8 value;
672 struct ab8500 *ab8500;
673
674 ab8500 = dev_get_drvdata(dev);
675 ret = get_register_interruptible(ab8500, AB8500_RTC,
676 AB8500_SWITCH_OFF_STATUS, &value);
677 if (ret < 0)
678 return ret;
679 return sprintf(buf, "%#x\n", value);
680}
681
655static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); 682static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL);
683static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL);
656 684
657static struct attribute *ab8500_sysfs_entries[] = { 685static struct attribute *ab8500_sysfs_entries[] = {
658 &dev_attr_chip_id.attr, 686 &dev_attr_chip_id.attr,
687 &dev_attr_switch_off_status.attr,
659 NULL, 688 NULL,
660}; 689};
661 690
@@ -686,9 +715,10 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
686 * 0x10 - Cut 1.0 715 * 0x10 - Cut 1.0
687 * 0x11 - Cut 1.1 716 * 0x11 - Cut 1.1
688 * 0x20 - Cut 2.0 717 * 0x20 - Cut 2.0
718 * 0x30 - Cut 3.0
689 */ 719 */
690 if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { 720 if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20 ||
691 ab8500->revision = value; 721 value == 0x30) {
692 dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); 722 dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
693 } else { 723 } else {
694 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value); 724 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
@@ -696,6 +726,24 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
696 } 726 }
697 ab8500->chip_id = value; 727 ab8500->chip_id = value;
698 728
729 /*
730 * ab8500 has switched off due to (SWITCH_OFF_STATUS):
731 * 0x01 Swoff bit programming
732 * 0x02 Thermal protection activation
733 * 0x04 Vbat lower then BattOk falling threshold
734 * 0x08 Watchdog expired
735 * 0x10 Non presence of 32kHz clock
736 * 0x20 Battery level lower than power on reset threshold
737 * 0x40 Power on key 1 pressed longer than 10 seconds
738 * 0x80 DB8500 thermal shutdown
739 */
740
741 ret = get_register_interruptible(ab8500, AB8500_RTC,
742 AB8500_SWITCH_OFF_STATUS, &value);
743 if (ret < 0)
744 return ret;
745 dev_info(ab8500->dev, "switch off status: %#x", value);
746
699 if (plat && plat->init) 747 if (plat && plat->init)
700 plat->init(ab8500); 748 plat->init(ab8500);
701 749
@@ -764,6 +812,6 @@ int __devexit ab8500_exit(struct ab8500 *ab8500)
764 return 0; 812 return 0;
765} 813}
766 814
767MODULE_AUTHOR("Srinidhi Kasagar, Rabin Vincent"); 815MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent");
768MODULE_DESCRIPTION("AB8500 MFD core"); 816MODULE_DESCRIPTION("AB8500 MFD core");
769MODULE_LICENSE("GPL v2"); 817MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index 3c1541ae7223..64748e42ac03 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -585,18 +585,18 @@ static int __devinit ab8500_debug_probe(struct platform_device *plf)
585 goto exit_destroy_dir; 585 goto exit_destroy_dir;
586 586
587 ab8500_bank_file = debugfs_create_file("register-bank", 587 ab8500_bank_file = debugfs_create_file("register-bank",
588 (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_bank_fops); 588 (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_bank_fops);
589 if (!ab8500_bank_file) 589 if (!ab8500_bank_file)
590 goto exit_destroy_reg; 590 goto exit_destroy_reg;
591 591
592 ab8500_address_file = debugfs_create_file("register-address", 592 ab8500_address_file = debugfs_create_file("register-address",
593 (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, 593 (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev,
594 &ab8500_address_fops); 594 &ab8500_address_fops);
595 if (!ab8500_address_file) 595 if (!ab8500_address_file)
596 goto exit_destroy_bank; 596 goto exit_destroy_bank;
597 597
598 ab8500_val_file = debugfs_create_file("register-value", 598 ab8500_val_file = debugfs_create_file("register-value",
599 (S_IRUGO | S_IWUGO), ab8500_dir, &plf->dev, &ab8500_val_fops); 599 (S_IRUGO | S_IWUSR), ab8500_dir, &plf->dev, &ab8500_val_fops);
600 if (!ab8500_val_file) 600 if (!ab8500_val_file)
601 goto exit_destroy_address; 601 goto exit_destroy_address;
602 602
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
new file mode 100644
index 000000000000..bc93b2e8230c
--- /dev/null
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -0,0 +1,614 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * License Terms: GNU General Public License v2
5 * Author: Arun R Murthy <arun.murthy@stericsson.com>
6 * Author: Daniel Willerud <daniel.willerud@stericsson.com>
7 * Author: Johan Palsson <johan.palsson@stericsson.com>
8 */
9#include <linux/init.h>
10#include <linux/module.h>
11#include <linux/device.h>
12#include <linux/interrupt.h>
13#include <linux/spinlock.h>
14#include <linux/delay.h>
15#include <linux/platform_device.h>
16#include <linux/completion.h>
17#include <linux/regulator/consumer.h>
18#include <linux/err.h>
19#include <linux/slab.h>
20#include <linux/list.h>
21#include <linux/mfd/ab8500.h>
22#include <linux/mfd/abx500.h>
23#include <linux/mfd/ab8500/gpadc.h>
24
25/*
26 * GPADC register offsets
27 * Bank : 0x0A
28 */
29#define AB8500_GPADC_CTRL1_REG 0x00
30#define AB8500_GPADC_CTRL2_REG 0x01
31#define AB8500_GPADC_CTRL3_REG 0x02
32#define AB8500_GPADC_AUTO_TIMER_REG 0x03
33#define AB8500_GPADC_STAT_REG 0x04
34#define AB8500_GPADC_MANDATAL_REG 0x05
35#define AB8500_GPADC_MANDATAH_REG 0x06
36#define AB8500_GPADC_AUTODATAL_REG 0x07
37#define AB8500_GPADC_AUTODATAH_REG 0x08
38#define AB8500_GPADC_MUX_CTRL_REG 0x09
39
40/*
41 * OTP register offsets
42 * Bank : 0x15
43 */
44#define AB8500_GPADC_CAL_1 0x0F
45#define AB8500_GPADC_CAL_2 0x10
46#define AB8500_GPADC_CAL_3 0x11
47#define AB8500_GPADC_CAL_4 0x12
48#define AB8500_GPADC_CAL_5 0x13
49#define AB8500_GPADC_CAL_6 0x14
50#define AB8500_GPADC_CAL_7 0x15
51
52/* gpadc constants */
53#define EN_VINTCORE12 0x04
54#define EN_VTVOUT 0x02
55#define EN_GPADC 0x01
56#define DIS_GPADC 0x00
57#define SW_AVG_16 0x60
58#define ADC_SW_CONV 0x04
59#define EN_ICHAR 0x80
60#define EN_BUF 0x40
61#define DIS_ZERO 0x00
62#define GPADC_BUSY 0x01
63
64/* GPADC constants from AB8500 spec, UM0836 */
65#define ADC_RESOLUTION 1024
66#define ADC_CH_BTEMP_MIN 0
67#define ADC_CH_BTEMP_MAX 1350
68#define ADC_CH_DIETEMP_MIN 0
69#define ADC_CH_DIETEMP_MAX 1350
70#define ADC_CH_CHG_V_MIN 0
71#define ADC_CH_CHG_V_MAX 20030
72#define ADC_CH_ACCDET2_MIN 0
73#define ADC_CH_ACCDET2_MAX 2500
74#define ADC_CH_VBAT_MIN 2300
75#define ADC_CH_VBAT_MAX 4800
76#define ADC_CH_CHG_I_MIN 0
77#define ADC_CH_CHG_I_MAX 1500
78#define ADC_CH_BKBAT_MIN 0
79#define ADC_CH_BKBAT_MAX 3200
80
81/* This is used to not lose precision when dividing to get gain and offset */
82#define CALIB_SCALE 1000
83
84enum cal_channels {
85 ADC_INPUT_VMAIN = 0,
86 ADC_INPUT_BTEMP,
87 ADC_INPUT_VBAT,
88 NBR_CAL_INPUTS,
89};
90
91/**
92 * struct adc_cal_data - Table for storing gain and offset for the calibrated
93 * ADC channels
94 * @gain: Gain of the ADC channel
95 * @offset: Offset of the ADC channel
96 */
97struct adc_cal_data {
98 u64 gain;
99 u64 offset;
100};
101
102/**
103 * struct ab8500_gpadc - AB8500 GPADC device information
104 * @dev: pointer to the struct device
105 * @node: a list of AB8500 GPADCs, hence prepared for
106 reentrance
107 * @ab8500_gpadc_complete: pointer to the struct completion, to indicate
108 * the completion of gpadc conversion
109 * @ab8500_gpadc_lock: structure of type mutex
110 * @regu: pointer to the struct regulator
111 * @irq: interrupt number that is used by gpadc
112 * @cal_data array of ADC calibration data structs
113 */
114struct ab8500_gpadc {
115 struct device *dev;
116 struct list_head node;
117 struct completion ab8500_gpadc_complete;
118 struct mutex ab8500_gpadc_lock;
119 struct regulator *regu;
120 int irq;
121 struct adc_cal_data cal_data[NBR_CAL_INPUTS];
122};
123
124static LIST_HEAD(ab8500_gpadc_list);
125
126/**
127 * ab8500_gpadc_get() - returns a reference to the primary AB8500 GPADC
128 * (i.e. the first GPADC in the instance list)
129 */
130struct ab8500_gpadc *ab8500_gpadc_get(char *name)
131{
132 struct ab8500_gpadc *gpadc;
133
134 list_for_each_entry(gpadc, &ab8500_gpadc_list, node) {
135 if (!strcmp(name, dev_name(gpadc->dev)))
136 return gpadc;
137 }
138
139 return ERR_PTR(-ENOENT);
140}
141EXPORT_SYMBOL(ab8500_gpadc_get);
142
143static int ab8500_gpadc_ad_to_voltage(struct ab8500_gpadc *gpadc, u8 input,
144 int ad_value)
145{
146 int res;
147
148 switch (input) {
149 case MAIN_CHARGER_V:
150 /* For some reason we don't have calibrated data */
151 if (!gpadc->cal_data[ADC_INPUT_VMAIN].gain) {
152 res = ADC_CH_CHG_V_MIN + (ADC_CH_CHG_V_MAX -
153 ADC_CH_CHG_V_MIN) * ad_value /
154 ADC_RESOLUTION;
155 break;
156 }
157 /* Here we can use the calibrated data */
158 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VMAIN].gain +
159 gpadc->cal_data[ADC_INPUT_VMAIN].offset) / CALIB_SCALE;
160 break;
161
162 case BAT_CTRL:
163 case BTEMP_BALL:
164 case ACC_DETECT1:
165 case ADC_AUX1:
166 case ADC_AUX2:
167 /* For some reason we don't have calibrated data */
168 if (!gpadc->cal_data[ADC_INPUT_BTEMP].gain) {
169 res = ADC_CH_BTEMP_MIN + (ADC_CH_BTEMP_MAX -
170 ADC_CH_BTEMP_MIN) * ad_value /
171 ADC_RESOLUTION;
172 break;
173 }
174 /* Here we can use the calibrated data */
175 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_BTEMP].gain +
176 gpadc->cal_data[ADC_INPUT_BTEMP].offset) / CALIB_SCALE;
177 break;
178
179 case MAIN_BAT_V:
180 /* For some reason we don't have calibrated data */
181 if (!gpadc->cal_data[ADC_INPUT_VBAT].gain) {
182 res = ADC_CH_VBAT_MIN + (ADC_CH_VBAT_MAX -
183 ADC_CH_VBAT_MIN) * ad_value /
184 ADC_RESOLUTION;
185 break;
186 }
187 /* Here we can use the calibrated data */
188 res = (int) (ad_value * gpadc->cal_data[ADC_INPUT_VBAT].gain +
189 gpadc->cal_data[ADC_INPUT_VBAT].offset) / CALIB_SCALE;
190 break;
191
192 case DIE_TEMP:
193 res = ADC_CH_DIETEMP_MIN +
194 (ADC_CH_DIETEMP_MAX - ADC_CH_DIETEMP_MIN) * ad_value /
195 ADC_RESOLUTION;
196 break;
197
198 case ACC_DETECT2:
199 res = ADC_CH_ACCDET2_MIN +
200 (ADC_CH_ACCDET2_MAX - ADC_CH_ACCDET2_MIN) * ad_value /
201 ADC_RESOLUTION;
202 break;
203
204 case VBUS_V:
205 res = ADC_CH_CHG_V_MIN +
206 (ADC_CH_CHG_V_MAX - ADC_CH_CHG_V_MIN) * ad_value /
207 ADC_RESOLUTION;
208 break;
209
210 case MAIN_CHARGER_C:
211 case USB_CHARGER_C:
212 res = ADC_CH_CHG_I_MIN +
213 (ADC_CH_CHG_I_MAX - ADC_CH_CHG_I_MIN) * ad_value /
214 ADC_RESOLUTION;
215 break;
216
217 case BK_BAT_V:
218 res = ADC_CH_BKBAT_MIN +
219 (ADC_CH_BKBAT_MAX - ADC_CH_BKBAT_MIN) * ad_value /
220 ADC_RESOLUTION;
221 break;
222
223 default:
224 dev_err(gpadc->dev,
225 "unknown channel, not possible to convert\n");
226 res = -EINVAL;
227 break;
228
229 }
230 return res;
231}
232
233/**
234 * ab8500_gpadc_convert() - gpadc conversion
235 * @input: analog input to be converted to digital data
236 *
237 * This function converts the selected analog i/p to digital
238 * data.
239 */
240int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input)
241{
242 int ret;
243 u16 data = 0;
244 int looplimit = 0;
245 u8 val, low_data, high_data;
246
247 if (!gpadc)
248 return -ENODEV;
249
250 mutex_lock(&gpadc->ab8500_gpadc_lock);
251 /* Enable VTVout LDO this is required for GPADC */
252 regulator_enable(gpadc->regu);
253
254 /* Check if ADC is not busy, lock and proceed */
255 do {
256 ret = abx500_get_register_interruptible(gpadc->dev,
257 AB8500_GPADC, AB8500_GPADC_STAT_REG, &val);
258 if (ret < 0)
259 goto out;
260 if (!(val & GPADC_BUSY))
261 break;
262 msleep(10);
263 } while (++looplimit < 10);
264 if (looplimit >= 10 && (val & GPADC_BUSY)) {
265 dev_err(gpadc->dev, "gpadc_conversion: GPADC busy");
266 ret = -EINVAL;
267 goto out;
268 }
269
270 /* Enable GPADC */
271 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
272 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_GPADC, EN_GPADC);
273 if (ret < 0) {
274 dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
275 goto out;
276 }
277 /* Select the input source and set average samples to 16 */
278 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
279 AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
280 if (ret < 0) {
281 dev_err(gpadc->dev,
282 "gpadc_conversion: set avg samples failed\n");
283 goto out;
284 }
285 /*
286 * Enable ADC, buffering, select rising edge and enable ADC path
287 * charging current sense if it needed
288 */
289 switch (input) {
290 case MAIN_CHARGER_C:
291 case USB_CHARGER_C:
292 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
293 AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
294 EN_BUF | EN_ICHAR,
295 EN_BUF | EN_ICHAR);
296 break;
297 default:
298 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
299 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
300 break;
301 }
302 if (ret < 0) {
303 dev_err(gpadc->dev,
304 "gpadc_conversion: select falling edge failed\n");
305 goto out;
306 }
307 ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
308 AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV);
309 if (ret < 0) {
310 dev_err(gpadc->dev,
311 "gpadc_conversion: start s/w conversion failed\n");
312 goto out;
313 }
314 /* wait for completion of conversion */
315 if (!wait_for_completion_timeout(&gpadc->ab8500_gpadc_complete, 2*HZ)) {
316 dev_err(gpadc->dev,
317 "timeout: didnt recieve GPADC conversion interrupt\n");
318 ret = -EINVAL;
319 goto out;
320 }
321
322 /* Read the converted RAW data */
323 ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC,
324 AB8500_GPADC_MANDATAL_REG, &low_data);
325 if (ret < 0) {
326 dev_err(gpadc->dev, "gpadc_conversion: read low data failed\n");
327 goto out;
328 }
329
330 ret = abx500_get_register_interruptible(gpadc->dev, AB8500_GPADC,
331 AB8500_GPADC_MANDATAH_REG, &high_data);
332 if (ret < 0) {
333 dev_err(gpadc->dev,
334 "gpadc_conversion: read high data failed\n");
335 goto out;
336 }
337
338 data = (high_data << 8) | low_data;
339 /* Disable GPADC */
340 ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
341 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
342 if (ret < 0) {
343 dev_err(gpadc->dev, "gpadc_conversion: disable gpadc failed\n");
344 goto out;
345 }
346 /* Disable VTVout LDO this is required for GPADC */
347 regulator_disable(gpadc->regu);
348 mutex_unlock(&gpadc->ab8500_gpadc_lock);
349 ret = ab8500_gpadc_ad_to_voltage(gpadc, input, data);
350 return ret;
351
352out:
353 /*
354 * It has shown to be needed to turn off the GPADC if an error occurs,
355 * otherwise we might have problem when waiting for the busy bit in the
356 * GPADC status register to go low. In V1.1 there wait_for_completion
357 * seems to timeout when waiting for an interrupt.. Not seen in V2.0
358 */
359 (void) abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
360 AB8500_GPADC_CTRL1_REG, DIS_GPADC);
361 regulator_disable(gpadc->regu);
362 mutex_unlock(&gpadc->ab8500_gpadc_lock);
363 dev_err(gpadc->dev,
364 "gpadc_conversion: Failed to AD convert channel %d\n", input);
365 return ret;
366}
367EXPORT_SYMBOL(ab8500_gpadc_convert);
368
369/**
370 * ab8500_bm_gpswadcconvend_handler() - isr for s/w gpadc conversion completion
371 * @irq: irq number
372 * @data: pointer to the data passed during request irq
373 *
374 * This is a interrupt service routine for s/w gpadc conversion completion.
375 * Notifies the gpadc completion is completed and the converted raw value
376 * can be read from the registers.
377 * Returns IRQ status(IRQ_HANDLED)
378 */
379static irqreturn_t ab8500_bm_gpswadcconvend_handler(int irq, void *_gpadc)
380{
381 struct ab8500_gpadc *gpadc = _gpadc;
382
383 complete(&gpadc->ab8500_gpadc_complete);
384
385 return IRQ_HANDLED;
386}
387
388static int otp_cal_regs[] = {
389 AB8500_GPADC_CAL_1,
390 AB8500_GPADC_CAL_2,
391 AB8500_GPADC_CAL_3,
392 AB8500_GPADC_CAL_4,
393 AB8500_GPADC_CAL_5,
394 AB8500_GPADC_CAL_6,
395 AB8500_GPADC_CAL_7,
396};
397
398static void ab8500_gpadc_read_calibration_data(struct ab8500_gpadc *gpadc)
399{
400 int i;
401 int ret[ARRAY_SIZE(otp_cal_regs)];
402 u8 gpadc_cal[ARRAY_SIZE(otp_cal_regs)];
403
404 int vmain_high, vmain_low;
405 int btemp_high, btemp_low;
406 int vbat_high, vbat_low;
407
408 /* First we read all OTP registers and store the error code */
409 for (i = 0; i < ARRAY_SIZE(otp_cal_regs); i++) {
410 ret[i] = abx500_get_register_interruptible(gpadc->dev,
411 AB8500_OTP_EMUL, otp_cal_regs[i], &gpadc_cal[i]);
412 if (ret[i] < 0)
413 dev_err(gpadc->dev, "%s: read otp reg 0x%02x failed\n",
414 __func__, otp_cal_regs[i]);
415 }
416
417 /*
418 * The ADC calibration data is stored in OTP registers.
419 * The layout of the calibration data is outlined below and a more
420 * detailed description can be found in UM0836
421 *
422 * vm_h/l = vmain_high/low
423 * bt_h/l = btemp_high/low
424 * vb_h/l = vbat_high/low
425 *
426 * Data bits:
427 * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
428 * |.......|.......|.......|.......|.......|.......|.......|.......
429 * | | vm_h9 | vm_h8
430 * |.......|.......|.......|.......|.......|.......|.......|.......
431 * | | vm_h7 | vm_h6 | vm_h5 | vm_h4 | vm_h3 | vm_h2
432 * |.......|.......|.......|.......|.......|.......|.......|.......
433 * | vm_h1 | vm_h0 | vm_l4 | vm_l3 | vm_l2 | vm_l1 | vm_l0 | bt_h9
434 * |.......|.......|.......|.......|.......|.......|.......|.......
435 * | bt_h8 | bt_h7 | bt_h6 | bt_h5 | bt_h4 | bt_h3 | bt_h2 | bt_h1
436 * |.......|.......|.......|.......|.......|.......|.......|.......
437 * | bt_h0 | bt_l4 | bt_l3 | bt_l2 | bt_l1 | bt_l0 | vb_h9 | vb_h8
438 * |.......|.......|.......|.......|.......|.......|.......|.......
439 * | vb_h7 | vb_h6 | vb_h5 | vb_h4 | vb_h3 | vb_h2 | vb_h1 | vb_h0
440 * |.......|.......|.......|.......|.......|.......|.......|.......
441 * | vb_l5 | vb_l4 | vb_l3 | vb_l2 | vb_l1 | vb_l0 |
442 * |.......|.......|.......|.......|.......|.......|.......|.......
443 *
444 *
445 * Ideal output ADC codes corresponding to injected input voltages
446 * during manufacturing is:
447 *
448 * vmain_high: Vin = 19500mV / ADC ideal code = 997
449 * vmain_low: Vin = 315mV / ADC ideal code = 16
450 * btemp_high: Vin = 1300mV / ADC ideal code = 985
451 * btemp_low: Vin = 21mV / ADC ideal code = 16
452 * vbat_high: Vin = 4700mV / ADC ideal code = 982
453 * vbat_low: Vin = 2380mV / ADC ideal code = 33
454 */
455
456 /* Calculate gain and offset for VMAIN if all reads succeeded */
457 if (!(ret[0] < 0 || ret[1] < 0 || ret[2] < 0)) {
458 vmain_high = (((gpadc_cal[0] & 0x03) << 8) |
459 ((gpadc_cal[1] & 0x3F) << 2) |
460 ((gpadc_cal[2] & 0xC0) >> 6));
461
462 vmain_low = ((gpadc_cal[2] & 0x3E) >> 1);
463
464 gpadc->cal_data[ADC_INPUT_VMAIN].gain = CALIB_SCALE *
465 (19500 - 315) / (vmain_high - vmain_low);
466
467 gpadc->cal_data[ADC_INPUT_VMAIN].offset = CALIB_SCALE * 19500 -
468 (CALIB_SCALE * (19500 - 315) /
469 (vmain_high - vmain_low)) * vmain_high;
470 } else {
471 gpadc->cal_data[ADC_INPUT_VMAIN].gain = 0;
472 }
473
474 /* Calculate gain and offset for BTEMP if all reads succeeded */
475 if (!(ret[2] < 0 || ret[3] < 0 || ret[4] < 0)) {
476 btemp_high = (((gpadc_cal[2] & 0x01) << 9) |
477 (gpadc_cal[3] << 1) |
478 ((gpadc_cal[4] & 0x80) >> 7));
479
480 btemp_low = ((gpadc_cal[4] & 0x7C) >> 2);
481
482 gpadc->cal_data[ADC_INPUT_BTEMP].gain =
483 CALIB_SCALE * (1300 - 21) / (btemp_high - btemp_low);
484
485 gpadc->cal_data[ADC_INPUT_BTEMP].offset = CALIB_SCALE * 1300 -
486 (CALIB_SCALE * (1300 - 21) /
487 (btemp_high - btemp_low)) * btemp_high;
488 } else {
489 gpadc->cal_data[ADC_INPUT_BTEMP].gain = 0;
490 }
491
492 /* Calculate gain and offset for VBAT if all reads succeeded */
493 if (!(ret[4] < 0 || ret[5] < 0 || ret[6] < 0)) {
494 vbat_high = (((gpadc_cal[4] & 0x03) << 8) | gpadc_cal[5]);
495 vbat_low = ((gpadc_cal[6] & 0xFC) >> 2);
496
497 gpadc->cal_data[ADC_INPUT_VBAT].gain = CALIB_SCALE *
498 (4700 - 2380) / (vbat_high - vbat_low);
499
500 gpadc->cal_data[ADC_INPUT_VBAT].offset = CALIB_SCALE * 4700 -
501 (CALIB_SCALE * (4700 - 2380) /
502 (vbat_high - vbat_low)) * vbat_high;
503 } else {
504 gpadc->cal_data[ADC_INPUT_VBAT].gain = 0;
505 }
506
507 dev_dbg(gpadc->dev, "VMAIN gain %llu offset %llu\n",
508 gpadc->cal_data[ADC_INPUT_VMAIN].gain,
509 gpadc->cal_data[ADC_INPUT_VMAIN].offset);
510
511 dev_dbg(gpadc->dev, "BTEMP gain %llu offset %llu\n",
512 gpadc->cal_data[ADC_INPUT_BTEMP].gain,
513 gpadc->cal_data[ADC_INPUT_BTEMP].offset);
514
515 dev_dbg(gpadc->dev, "VBAT gain %llu offset %llu\n",
516 gpadc->cal_data[ADC_INPUT_VBAT].gain,
517 gpadc->cal_data[ADC_INPUT_VBAT].offset);
518}
519
520static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
521{
522 int ret = 0;
523 struct ab8500_gpadc *gpadc;
524
525 gpadc = kzalloc(sizeof(struct ab8500_gpadc), GFP_KERNEL);
526 if (!gpadc) {
527 dev_err(&pdev->dev, "Error: No memory\n");
528 return -ENOMEM;
529 }
530
531 gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END");
532 if (gpadc->irq < 0) {
533 dev_err(gpadc->dev, "failed to get platform irq-%d\n",
534 gpadc->irq);
535 ret = gpadc->irq;
536 goto fail;
537 }
538
539 gpadc->dev = &pdev->dev;
540 mutex_init(&gpadc->ab8500_gpadc_lock);
541
542 /* Initialize completion used to notify completion of conversion */
543 init_completion(&gpadc->ab8500_gpadc_complete);
544
545 /* Register interrupt - SwAdcComplete */
546 ret = request_threaded_irq(gpadc->irq, NULL,
547 ab8500_bm_gpswadcconvend_handler,
548 IRQF_NO_SUSPEND | IRQF_SHARED, "ab8500-gpadc", gpadc);
549 if (ret < 0) {
550 dev_err(gpadc->dev, "Failed to register interrupt, irq: %d\n",
551 gpadc->irq);
552 goto fail;
553 }
554
555 /* VTVout LDO used to power up ab8500-GPADC */
556 gpadc->regu = regulator_get(&pdev->dev, "vddadc");
557 if (IS_ERR(gpadc->regu)) {
558 ret = PTR_ERR(gpadc->regu);
559 dev_err(gpadc->dev, "failed to get vtvout LDO\n");
560 goto fail_irq;
561 }
562 ab8500_gpadc_read_calibration_data(gpadc);
563 list_add_tail(&gpadc->node, &ab8500_gpadc_list);
564 dev_dbg(gpadc->dev, "probe success\n");
565 return 0;
566fail_irq:
567 free_irq(gpadc->irq, gpadc);
568fail:
569 kfree(gpadc);
570 gpadc = NULL;
571 return ret;
572}
573
574static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
575{
576 struct ab8500_gpadc *gpadc = platform_get_drvdata(pdev);
577
578 /* remove this gpadc entry from the list */
579 list_del(&gpadc->node);
580 /* remove interrupt - completion of Sw ADC conversion */
581 free_irq(gpadc->irq, gpadc);
582 /* disable VTVout LDO that is being used by GPADC */
583 regulator_put(gpadc->regu);
584 kfree(gpadc);
585 gpadc = NULL;
586 return 0;
587}
588
589static struct platform_driver ab8500_gpadc_driver = {
590 .probe = ab8500_gpadc_probe,
591 .remove = __devexit_p(ab8500_gpadc_remove),
592 .driver = {
593 .name = "ab8500-gpadc",
594 .owner = THIS_MODULE,
595 },
596};
597
598static int __init ab8500_gpadc_init(void)
599{
600 return platform_driver_register(&ab8500_gpadc_driver);
601}
602
603static void __exit ab8500_gpadc_exit(void)
604{
605 platform_driver_unregister(&ab8500_gpadc_driver);
606}
607
608subsys_initcall_sync(ab8500_gpadc_init);
609module_exit(ab8500_gpadc_exit);
610
611MODULE_LICENSE("GPL v2");
612MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson");
613MODULE_ALIAS("platform:ab8500_gpadc");
614MODULE_DESCRIPTION("AB8500 GPADC driver");
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
new file mode 100644
index 000000000000..392185965b39
--- /dev/null
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2010
3 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com> for ST Ericsson.
4 * License terms: GNU General Public License (GPL) version 2
5 */
6
7#include <linux/err.h>
8#include <linux/platform_device.h>
9#include <linux/mfd/ab8500.h>
10#include <linux/mfd/abx500.h>
11#include <linux/mfd/ab8500/sysctrl.h>
12
13static struct device *sysctrl_dev;
14
15static inline bool valid_bank(u8 bank)
16{
17 return ((bank == AB8500_SYS_CTRL1_BLOCK) ||
18 (bank == AB8500_SYS_CTRL2_BLOCK));
19}
20
21int ab8500_sysctrl_read(u16 reg, u8 *value)
22{
23 u8 bank;
24
25 if (sysctrl_dev == NULL)
26 return -EAGAIN;
27
28 bank = (reg >> 8);
29 if (!valid_bank(bank))
30 return -EINVAL;
31
32 return abx500_get_register_interruptible(sysctrl_dev, bank,
33 (u8)(reg & 0xFF), value);
34}
35
36int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
37{
38 u8 bank;
39
40 if (sysctrl_dev == NULL)
41 return -EAGAIN;
42
43 bank = (reg >> 8);
44 if (!valid_bank(bank))
45 return -EINVAL;
46
47 return abx500_mask_and_set_register_interruptible(sysctrl_dev, bank,
48 (u8)(reg & 0xFF), mask, value);
49}
50
51static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev)
52{
53 sysctrl_dev = &pdev->dev;
54 return 0;
55}
56
57static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev)
58{
59 sysctrl_dev = NULL;
60 return 0;
61}
62
63static struct platform_driver ab8500_sysctrl_driver = {
64 .driver = {
65 .name = "ab8500-sysctrl",
66 .owner = THIS_MODULE,
67 },
68 .probe = ab8500_sysctrl_probe,
69 .remove = __devexit_p(ab8500_sysctrl_remove),
70};
71
72static int __init ab8500_sysctrl_init(void)
73{
74 return platform_driver_register(&ab8500_sysctrl_driver);
75}
76subsys_initcall(ab8500_sysctrl_init);
77
78MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com");
79MODULE_DESCRIPTION("AB8500 system control driver");
80MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c
index 3122139b4300..f1d88483112c 100644
--- a/drivers/mfd/adp5520.c
+++ b/drivers/mfd/adp5520.c
@@ -321,27 +321,27 @@ static int __devexit adp5520_remove(struct i2c_client *client)
321} 321}
322 322
323#ifdef CONFIG_PM 323#ifdef CONFIG_PM
324static int adp5520_suspend(struct i2c_client *client, 324static int adp5520_suspend(struct device *dev)
325 pm_message_t state)
326{ 325{
326 struct i2c_client *client = to_i2c_client(dev);
327 struct adp5520_chip *chip = dev_get_drvdata(&client->dev); 327 struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
328 328
329 adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); 329 adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
330 return 0; 330 return 0;
331} 331}
332 332
333static int adp5520_resume(struct i2c_client *client) 333static int adp5520_resume(struct device *dev)
334{ 334{
335 struct i2c_client *client = to_i2c_client(dev);
335 struct adp5520_chip *chip = dev_get_drvdata(&client->dev); 336 struct adp5520_chip *chip = dev_get_drvdata(&client->dev);
336 337
337 adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); 338 adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY);
338 return 0; 339 return 0;
339} 340}
340#else
341#define adp5520_suspend NULL
342#define adp5520_resume NULL
343#endif 341#endif
344 342
343static SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume);
344
345static const struct i2c_device_id adp5520_id[] = { 345static const struct i2c_device_id adp5520_id[] = {
346 { "pmic-adp5520", ID_ADP5520 }, 346 { "pmic-adp5520", ID_ADP5520 },
347 { "pmic-adp5501", ID_ADP5501 }, 347 { "pmic-adp5501", ID_ADP5501 },
@@ -353,11 +353,10 @@ static struct i2c_driver adp5520_driver = {
353 .driver = { 353 .driver = {
354 .name = "adp5520", 354 .name = "adp5520",
355 .owner = THIS_MODULE, 355 .owner = THIS_MODULE,
356 .pm = &adp5520_pm,
356 }, 357 },
357 .probe = adp5520_probe, 358 .probe = adp5520_probe,
358 .remove = __devexit_p(adp5520_remove), 359 .remove = __devexit_p(adp5520_remove),
359 .suspend = adp5520_suspend,
360 .resume = adp5520_resume,
361 .id_table = adp5520_id, 360 .id_table = adp5520_id,
362}; 361};
363 362
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c
index c45e6305b26f..0241f08fc00d 100644
--- a/drivers/mfd/asic3.c
+++ b/drivers/mfd/asic3.c
@@ -682,7 +682,7 @@ static struct mfd_cell asic3_cell_ds1wm = {
682 .name = "ds1wm", 682 .name = "ds1wm",
683 .enable = ds1wm_enable, 683 .enable = ds1wm_enable,
684 .disable = ds1wm_disable, 684 .disable = ds1wm_disable,
685 .driver_data = &ds1wm_pdata, 685 .mfd_data = &ds1wm_pdata,
686 .num_resources = ARRAY_SIZE(ds1wm_resources), 686 .num_resources = ARRAY_SIZE(ds1wm_resources),
687 .resources = ds1wm_resources, 687 .resources = ds1wm_resources,
688}; 688};
@@ -783,7 +783,7 @@ static struct mfd_cell asic3_cell_mmc = {
783 .name = "tmio-mmc", 783 .name = "tmio-mmc",
784 .enable = asic3_mmc_enable, 784 .enable = asic3_mmc_enable,
785 .disable = asic3_mmc_disable, 785 .disable = asic3_mmc_disable,
786 .driver_data = &asic3_mmc_data, 786 .mfd_data = &asic3_mmc_data,
787 .num_resources = ARRAY_SIZE(asic3_mmc_resources), 787 .num_resources = ARRAY_SIZE(asic3_mmc_resources),
788 .resources = asic3_mmc_resources, 788 .resources = asic3_mmc_resources,
789}; 789};
@@ -810,9 +810,6 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
810 ds1wm_resources[0].start >>= asic->bus_shift; 810 ds1wm_resources[0].start >>= asic->bus_shift;
811 ds1wm_resources[0].end >>= asic->bus_shift; 811 ds1wm_resources[0].end >>= asic->bus_shift;
812 812
813 asic3_cell_ds1wm.platform_data = &asic3_cell_ds1wm;
814 asic3_cell_ds1wm.data_size = sizeof(asic3_cell_ds1wm);
815
816 /* MMC */ 813 /* MMC */
817 asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + 814 asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
818 mem_sdio->start, 0x400 >> asic->bus_shift); 815 mem_sdio->start, 0x400 >> asic->bus_shift);
@@ -824,9 +821,6 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
824 asic3_mmc_resources[0].start >>= asic->bus_shift; 821 asic3_mmc_resources[0].start >>= asic->bus_shift;
825 asic3_mmc_resources[0].end >>= asic->bus_shift; 822 asic3_mmc_resources[0].end >>= asic->bus_shift;
826 823
827 asic3_cell_mmc.platform_data = &asic3_cell_mmc;
828 asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc);
829
830 ret = mfd_add_devices(&pdev->dev, pdev->id, 824 ret = mfd_add_devices(&pdev->dev, pdev->id,
831 &asic3_cell_ds1wm, 1, mem, asic->irq_base); 825 &asic3_cell_ds1wm, 1, mem, asic->irq_base);
832 if (ret < 0) 826 if (ret < 0)
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index 59ca6f151e78..886a06871065 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -39,6 +39,37 @@ enum cs5535_mfd_bars {
39 NR_BARS, 39 NR_BARS,
40}; 40};
41 41
42static int cs5535_mfd_res_enable(struct platform_device *pdev)
43{
44 struct resource *res;
45
46 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
47 if (!res) {
48 dev_err(&pdev->dev, "can't fetch device resource info\n");
49 return -EIO;
50 }
51
52 if (!request_region(res->start, resource_size(res), DRV_NAME)) {
53 dev_err(&pdev->dev, "can't request region\n");
54 return -EIO;
55 }
56
57 return 0;
58}
59
60static int cs5535_mfd_res_disable(struct platform_device *pdev)
61{
62 struct resource *res;
63 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
64 if (!res) {
65 dev_err(&pdev->dev, "can't fetch device resource info\n");
66 return -EIO;
67 }
68
69 release_region(res->start, resource_size(res));
70 return 0;
71}
72
42static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; 73static __devinitdata struct resource cs5535_mfd_resources[NR_BARS];
43 74
44static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { 75static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
@@ -65,12 +96,18 @@ static __devinitdata struct mfd_cell cs5535_mfd_cells[] = {
65 .name = "cs5535-pms", 96 .name = "cs5535-pms",
66 .num_resources = 1, 97 .num_resources = 1,
67 .resources = &cs5535_mfd_resources[PMS_BAR], 98 .resources = &cs5535_mfd_resources[PMS_BAR],
99
100 .enable = cs5535_mfd_res_enable,
101 .disable = cs5535_mfd_res_disable,
68 }, 102 },
69 { 103 {
70 .id = ACPI_BAR, 104 .id = ACPI_BAR,
71 .name = "cs5535-acpi", 105 .name = "cs5535-acpi",
72 .num_resources = 1, 106 .num_resources = 1,
73 .resources = &cs5535_mfd_resources[ACPI_BAR], 107 .resources = &cs5535_mfd_resources[ACPI_BAR],
108
109 .enable = cs5535_mfd_res_enable,
110 .disable = cs5535_mfd_res_disable,
74 }, 111 },
75}; 112};
76 113
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c
index fdd8a1b8bc67..414783b04849 100644
--- a/drivers/mfd/davinci_voicecodec.c
+++ b/drivers/mfd/davinci_voicecodec.c
@@ -119,12 +119,12 @@ static int __init davinci_vc_probe(struct platform_device *pdev)
119 /* Voice codec interface client */ 119 /* Voice codec interface client */
120 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; 120 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];
121 cell->name = "davinci-vcif"; 121 cell->name = "davinci-vcif";
122 cell->driver_data = davinci_vc; 122 cell->mfd_data = davinci_vc;
123 123
124 /* Voice codec CQ93VC client */ 124 /* Voice codec CQ93VC client */
125 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; 125 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];
126 cell->name = "cq93vc-codec"; 126 cell->name = "cq93vc-codec";
127 cell->driver_data = davinci_vc; 127 cell->mfd_data = davinci_vc;
128 128
129 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, 129 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
130 DAVINCI_VC_CELLS, NULL, 0); 130 DAVINCI_VC_CELLS, NULL, 0);
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 7bc752272dc1..fb9770b39a32 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -117,7 +117,7 @@ static struct mfd_cell ds1wm_cell __initdata = {
117 .name = "ds1wm", 117 .name = "ds1wm",
118 .enable = ds1wm_enable, 118 .enable = ds1wm_enable,
119 .disable = ds1wm_disable, 119 .disable = ds1wm_disable,
120 .driver_data = &ds1wm_pdata, 120 .mfd_data = &ds1wm_pdata,
121 .num_resources = 2, 121 .num_resources = 2,
122 .resources = ds1wm_resources, 122 .resources = ds1wm_resources,
123}; 123};
@@ -165,8 +165,6 @@ static int __init pasic3_probe(struct platform_device *pdev)
165 ds1wm_pdata.clock_rate = pdata->clock_rate; 165 ds1wm_pdata.clock_rate = pdata->clock_rate;
166 /* the first 5 PASIC3 registers control the DS1WM */ 166 /* the first 5 PASIC3 registers control the DS1WM */
167 ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; 167 ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
168 ds1wm_cell.platform_data = &ds1wm_cell;
169 ds1wm_cell.data_size = sizeof(ds1wm_cell);
170 ret = mfd_add_devices(&pdev->dev, pdev->id, 168 ret = mfd_add_devices(&pdev->dev, pdev->id,
171 &ds1wm_cell, 1, r, irq); 169 &ds1wm_cell, 1, r, irq);
172 if (ret < 0) 170 if (ret < 0)
@@ -174,9 +172,6 @@ static int __init pasic3_probe(struct platform_device *pdev)
174 } 172 }
175 173
176 if (pdata && pdata->led_pdata) { 174 if (pdata && pdata->led_pdata) {
177 led_cell.driver_data = pdata->led_pdata;
178 led_cell.platform_data = &led_cell;
179 led_cell.data_size = sizeof(ds1wm_cell);
180 ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); 175 ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
181 if (ret < 0) 176 if (ret < 0)
182 dev_warn(dev, "failed to register LED device\n"); 177 dev_warn(dev, "failed to register LED device\n");
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 36a166bcdb08..fc4191137e90 100644
--- a/drivers/mfd/janz-cmodio.c
+++ b/drivers/mfd/janz-cmodio.c
@@ -86,8 +86,7 @@ static int __devinit cmodio_setup_subdevice(struct cmodio_device *priv,
86 86
87 /* Add platform data */ 87 /* Add platform data */
88 pdata->modno = modno; 88 pdata->modno = modno;
89 cell->platform_data = pdata; 89 cell->mfd_data = pdata;
90 cell->data_size = sizeof(*pdata);
91 90
92 /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */ 91 /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */
93 res->flags = IORESOURCE_MEM; 92 res->flags = IORESOURCE_MEM;
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index 0cc59795f600..aa518b9beaf5 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -232,8 +232,6 @@ const struct mfd_cell jz4740_adc_cells[] = {
232 .name = "jz4740-hwmon", 232 .name = "jz4740-hwmon",
233 .num_resources = ARRAY_SIZE(jz4740_hwmon_resources), 233 .num_resources = ARRAY_SIZE(jz4740_hwmon_resources),
234 .resources = jz4740_hwmon_resources, 234 .resources = jz4740_hwmon_resources,
235 .platform_data = (void *)&jz4740_adc_cells[0],
236 .data_size = sizeof(struct mfd_cell),
237 235
238 .enable = jz4740_adc_cell_enable, 236 .enable = jz4740_adc_cell_enable,
239 .disable = jz4740_adc_cell_disable, 237 .disable = jz4740_adc_cell_disable,
@@ -243,8 +241,6 @@ const struct mfd_cell jz4740_adc_cells[] = {
243 .name = "jz4740-battery", 241 .name = "jz4740-battery",
244 .num_resources = ARRAY_SIZE(jz4740_battery_resources), 242 .num_resources = ARRAY_SIZE(jz4740_battery_resources),
245 .resources = jz4740_battery_resources, 243 .resources = jz4740_battery_resources,
246 .platform_data = (void *)&jz4740_adc_cells[1],
247 .data_size = sizeof(struct mfd_cell),
248 244
249 .enable = jz4740_adc_cell_enable, 245 .enable = jz4740_adc_cell_enable,
250 .disable = jz4740_adc_cell_disable, 246 .disable = jz4740_adc_cell_disable,
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index 51b2f6065a0b..ea3f52c07ef7 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -61,6 +61,7 @@ static struct mfd_cell lpc_sch_cells[] = {
61 61
62static struct pci_device_id lpc_sch_ids[] = { 62static struct pci_device_id lpc_sch_ids[] = {
63 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, 63 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
64 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) },
64 { 0, } 65 { 0, }
65}; 66};
66MODULE_DEVICE_TABLE(pci, lpc_sch_ids); 67MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
@@ -70,6 +71,7 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
70{ 71{
71 unsigned int base_addr_cfg; 72 unsigned int base_addr_cfg;
72 unsigned short base_addr; 73 unsigned short base_addr;
74 int i;
73 75
74 pci_read_config_dword(dev, SMBASE, &base_addr_cfg); 76 pci_read_config_dword(dev, SMBASE, &base_addr_cfg);
75 if (!(base_addr_cfg & (1 << 31))) { 77 if (!(base_addr_cfg & (1 << 31))) {
@@ -99,7 +101,10 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
99 gpio_sch_resource.start = base_addr; 101 gpio_sch_resource.start = base_addr;
100 gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; 102 gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
101 103
102 return mfd_add_devices(&dev->dev, -1, 104 for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++)
105 lpc_sch_cells[i].id = id->device;
106
107 return mfd_add_devices(&dev->dev, 0,
103 lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); 108 lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0);
104} 109}
105 110
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
new file mode 100644
index 000000000000..5d1fca0277ef
--- /dev/null
+++ b/drivers/mfd/max8997.c
@@ -0,0 +1,427 @@
1/*
2 * max8997.c - mfd core driver for the Maxim 8966 and 8997
3 *
4 * Copyright (C) 2011 Samsung Electronics
5 * MyungJoo Ham <myungjoo.ham@smasung.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
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * This driver is based on max8998.c
22 */
23
24#include <linux/slab.h>
25#include <linux/i2c.h>
26#include <linux/pm_runtime.h>
27#include <linux/mutex.h>
28#include <linux/mfd/core.h>
29#include <linux/mfd/max8997.h>
30#include <linux/mfd/max8997-private.h>
31
32#define I2C_ADDR_PMIC (0xCC >> 1)
33#define I2C_ADDR_MUIC (0x4A >> 1)
34#define I2C_ADDR_BATTERY (0x6C >> 1)
35#define I2C_ADDR_RTC (0x0C >> 1)
36#define I2C_ADDR_HAPTIC (0x90 >> 1)
37
38static struct mfd_cell max8997_devs[] = {
39 { .name = "max8997-pmic", },
40 { .name = "max8997-rtc", },
41 { .name = "max8997-battery", },
42 { .name = "max8997-haptic", },
43 { .name = "max8997-muic", },
44 { .name = "max8997-flash", },
45};
46
47int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
48{
49 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
50 int ret;
51
52 mutex_lock(&max8997->iolock);
53 ret = i2c_smbus_read_byte_data(i2c, reg);
54 mutex_unlock(&max8997->iolock);
55 if (ret < 0)
56 return ret;
57
58 ret &= 0xff;
59 *dest = ret;
60 return 0;
61}
62EXPORT_SYMBOL_GPL(max8997_read_reg);
63
64int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, u8 *buf)
65{
66 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
67 int ret;
68
69 mutex_lock(&max8997->iolock);
70 ret = i2c_smbus_read_i2c_block_data(i2c, reg, count, buf);
71 mutex_unlock(&max8997->iolock);
72 if (ret < 0)
73 return ret;
74
75 return 0;
76}
77EXPORT_SYMBOL_GPL(max8997_bulk_read);
78
79int max8997_write_reg(struct i2c_client *i2c, u8 reg, u8 value)
80{
81 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
82 int ret;
83
84 mutex_lock(&max8997->iolock);
85 ret = i2c_smbus_write_byte_data(i2c, reg, value);
86 mutex_unlock(&max8997->iolock);
87 return ret;
88}
89EXPORT_SYMBOL_GPL(max8997_write_reg);
90
91int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count, u8 *buf)
92{
93 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
94 int ret;
95
96 mutex_lock(&max8997->iolock);
97 ret = i2c_smbus_write_i2c_block_data(i2c, reg, count, buf);
98 mutex_unlock(&max8997->iolock);
99 if (ret < 0)
100 return ret;
101
102 return 0;
103}
104EXPORT_SYMBOL_GPL(max8997_bulk_write);
105
106int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask)
107{
108 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
109 int ret;
110
111 mutex_lock(&max8997->iolock);
112 ret = i2c_smbus_read_byte_data(i2c, reg);
113 if (ret >= 0) {
114 u8 old_val = ret & 0xff;
115 u8 new_val = (val & mask) | (old_val & (~mask));
116 ret = i2c_smbus_write_byte_data(i2c, reg, new_val);
117 }
118 mutex_unlock(&max8997->iolock);
119 return ret;
120}
121EXPORT_SYMBOL_GPL(max8997_update_reg);
122
123static int max8997_i2c_probe(struct i2c_client *i2c,
124 const struct i2c_device_id *id)
125{
126 struct max8997_dev *max8997;
127 struct max8997_platform_data *pdata = i2c->dev.platform_data;
128 int ret = 0;
129
130 max8997 = kzalloc(sizeof(struct max8997_dev), GFP_KERNEL);
131 if (max8997 == NULL)
132 return -ENOMEM;
133
134 i2c_set_clientdata(i2c, max8997);
135 max8997->dev = &i2c->dev;
136 max8997->i2c = i2c;
137 max8997->type = id->driver_data;
138
139 if (!pdata)
140 goto err;
141
142 max8997->wakeup = pdata->wakeup;
143
144 mutex_init(&max8997->iolock);
145
146 max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC);
147 i2c_set_clientdata(max8997->rtc, max8997);
148 max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
149 i2c_set_clientdata(max8997->haptic, max8997);
150 max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
151 i2c_set_clientdata(max8997->muic, max8997);
152
153 pm_runtime_set_active(max8997->dev);
154
155 mfd_add_devices(max8997->dev, -1, max8997_devs,
156 ARRAY_SIZE(max8997_devs),
157 NULL, 0);
158
159 /*
160 * TODO: enable others (flash, muic, rtc, battery, ...) and
161 * check the return value
162 */
163
164 if (ret < 0)
165 goto err_mfd;
166
167 return ret;
168
169err_mfd:
170 mfd_remove_devices(max8997->dev);
171 i2c_unregister_device(max8997->muic);
172 i2c_unregister_device(max8997->haptic);
173 i2c_unregister_device(max8997->rtc);
174err:
175 kfree(max8997);
176 return ret;
177}
178
179static int max8997_i2c_remove(struct i2c_client *i2c)
180{
181 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
182
183 mfd_remove_devices(max8997->dev);
184 i2c_unregister_device(max8997->muic);
185 i2c_unregister_device(max8997->haptic);
186 i2c_unregister_device(max8997->rtc);
187 kfree(max8997);
188
189 return 0;
190}
191
192static const struct i2c_device_id max8997_i2c_id[] = {
193 { "max8997", TYPE_MAX8997 },
194 { "max8966", TYPE_MAX8966 },
195 { }
196};
197MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
198
199u8 max8997_dumpaddr_pmic[] = {
200 MAX8997_REG_INT1MSK,
201 MAX8997_REG_INT2MSK,
202 MAX8997_REG_INT3MSK,
203 MAX8997_REG_INT4MSK,
204 MAX8997_REG_MAINCON1,
205 MAX8997_REG_MAINCON2,
206 MAX8997_REG_BUCKRAMP,
207 MAX8997_REG_BUCK1CTRL,
208 MAX8997_REG_BUCK1DVS1,
209 MAX8997_REG_BUCK1DVS2,
210 MAX8997_REG_BUCK1DVS3,
211 MAX8997_REG_BUCK1DVS4,
212 MAX8997_REG_BUCK1DVS5,
213 MAX8997_REG_BUCK1DVS6,
214 MAX8997_REG_BUCK1DVS7,
215 MAX8997_REG_BUCK1DVS8,
216 MAX8997_REG_BUCK2CTRL,
217 MAX8997_REG_BUCK2DVS1,
218 MAX8997_REG_BUCK2DVS2,
219 MAX8997_REG_BUCK2DVS3,
220 MAX8997_REG_BUCK2DVS4,
221 MAX8997_REG_BUCK2DVS5,
222 MAX8997_REG_BUCK2DVS6,
223 MAX8997_REG_BUCK2DVS7,
224 MAX8997_REG_BUCK2DVS8,
225 MAX8997_REG_BUCK3CTRL,
226 MAX8997_REG_BUCK3DVS,
227 MAX8997_REG_BUCK4CTRL,
228 MAX8997_REG_BUCK4DVS,
229 MAX8997_REG_BUCK5CTRL,
230 MAX8997_REG_BUCK5DVS1,
231 MAX8997_REG_BUCK5DVS2,
232 MAX8997_REG_BUCK5DVS3,
233 MAX8997_REG_BUCK5DVS4,
234 MAX8997_REG_BUCK5DVS5,
235 MAX8997_REG_BUCK5DVS6,
236 MAX8997_REG_BUCK5DVS7,
237 MAX8997_REG_BUCK5DVS8,
238 MAX8997_REG_BUCK6CTRL,
239 MAX8997_REG_BUCK6BPSKIPCTRL,
240 MAX8997_REG_BUCK7CTRL,
241 MAX8997_REG_BUCK7DVS,
242 MAX8997_REG_LDO1CTRL,
243 MAX8997_REG_LDO2CTRL,
244 MAX8997_REG_LDO3CTRL,
245 MAX8997_REG_LDO4CTRL,
246 MAX8997_REG_LDO5CTRL,
247 MAX8997_REG_LDO6CTRL,
248 MAX8997_REG_LDO7CTRL,
249 MAX8997_REG_LDO8CTRL,
250 MAX8997_REG_LDO9CTRL,
251 MAX8997_REG_LDO10CTRL,
252 MAX8997_REG_LDO11CTRL,
253 MAX8997_REG_LDO12CTRL,
254 MAX8997_REG_LDO13CTRL,
255 MAX8997_REG_LDO14CTRL,
256 MAX8997_REG_LDO15CTRL,
257 MAX8997_REG_LDO16CTRL,
258 MAX8997_REG_LDO17CTRL,
259 MAX8997_REG_LDO18CTRL,
260 MAX8997_REG_LDO21CTRL,
261 MAX8997_REG_MBCCTRL1,
262 MAX8997_REG_MBCCTRL2,
263 MAX8997_REG_MBCCTRL3,
264 MAX8997_REG_MBCCTRL4,
265 MAX8997_REG_MBCCTRL5,
266 MAX8997_REG_MBCCTRL6,
267 MAX8997_REG_OTPCGHCVS,
268 MAX8997_REG_SAFEOUTCTRL,
269 MAX8997_REG_LBCNFG1,
270 MAX8997_REG_LBCNFG2,
271 MAX8997_REG_BBCCTRL,
272
273 MAX8997_REG_FLASH1_CUR,
274 MAX8997_REG_FLASH2_CUR,
275 MAX8997_REG_MOVIE_CUR,
276 MAX8997_REG_GSMB_CUR,
277 MAX8997_REG_BOOST_CNTL,
278 MAX8997_REG_LEN_CNTL,
279 MAX8997_REG_FLASH_CNTL,
280 MAX8997_REG_WDT_CNTL,
281 MAX8997_REG_MAXFLASH1,
282 MAX8997_REG_MAXFLASH2,
283 MAX8997_REG_FLASHSTATUSMASK,
284
285 MAX8997_REG_GPIOCNTL1,
286 MAX8997_REG_GPIOCNTL2,
287 MAX8997_REG_GPIOCNTL3,
288 MAX8997_REG_GPIOCNTL4,
289 MAX8997_REG_GPIOCNTL5,
290 MAX8997_REG_GPIOCNTL6,
291 MAX8997_REG_GPIOCNTL7,
292 MAX8997_REG_GPIOCNTL8,
293 MAX8997_REG_GPIOCNTL9,
294 MAX8997_REG_GPIOCNTL10,
295 MAX8997_REG_GPIOCNTL11,
296 MAX8997_REG_GPIOCNTL12,
297
298 MAX8997_REG_LDO1CONFIG,
299 MAX8997_REG_LDO2CONFIG,
300 MAX8997_REG_LDO3CONFIG,
301 MAX8997_REG_LDO4CONFIG,
302 MAX8997_REG_LDO5CONFIG,
303 MAX8997_REG_LDO6CONFIG,
304 MAX8997_REG_LDO7CONFIG,
305 MAX8997_REG_LDO8CONFIG,
306 MAX8997_REG_LDO9CONFIG,
307 MAX8997_REG_LDO10CONFIG,
308 MAX8997_REG_LDO11CONFIG,
309 MAX8997_REG_LDO12CONFIG,
310 MAX8997_REG_LDO13CONFIG,
311 MAX8997_REG_LDO14CONFIG,
312 MAX8997_REG_LDO15CONFIG,
313 MAX8997_REG_LDO16CONFIG,
314 MAX8997_REG_LDO17CONFIG,
315 MAX8997_REG_LDO18CONFIG,
316 MAX8997_REG_LDO21CONFIG,
317
318 MAX8997_REG_DVSOKTIMER1,
319 MAX8997_REG_DVSOKTIMER2,
320 MAX8997_REG_DVSOKTIMER4,
321 MAX8997_REG_DVSOKTIMER5,
322};
323
324u8 max8997_dumpaddr_muic[] = {
325 MAX8997_MUIC_REG_INTMASK1,
326 MAX8997_MUIC_REG_INTMASK2,
327 MAX8997_MUIC_REG_INTMASK3,
328 MAX8997_MUIC_REG_CDETCTRL,
329 MAX8997_MUIC_REG_CONTROL1,
330 MAX8997_MUIC_REG_CONTROL2,
331 MAX8997_MUIC_REG_CONTROL3,
332};
333
334u8 max8997_dumpaddr_haptic[] = {
335 MAX8997_HAPTIC_REG_CONF1,
336 MAX8997_HAPTIC_REG_CONF2,
337 MAX8997_HAPTIC_REG_DRVCONF,
338 MAX8997_HAPTIC_REG_CYCLECONF1,
339 MAX8997_HAPTIC_REG_CYCLECONF2,
340 MAX8997_HAPTIC_REG_SIGCONF1,
341 MAX8997_HAPTIC_REG_SIGCONF2,
342 MAX8997_HAPTIC_REG_SIGCONF3,
343 MAX8997_HAPTIC_REG_SIGCONF4,
344 MAX8997_HAPTIC_REG_SIGDC1,
345 MAX8997_HAPTIC_REG_SIGDC2,
346 MAX8997_HAPTIC_REG_SIGPWMDC1,
347 MAX8997_HAPTIC_REG_SIGPWMDC2,
348 MAX8997_HAPTIC_REG_SIGPWMDC3,
349 MAX8997_HAPTIC_REG_SIGPWMDC4,
350};
351
352static int max8997_freeze(struct device *dev)
353{
354 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
355 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
356 int i;
357
358 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_pmic); i++)
359 max8997_read_reg(i2c, max8997_dumpaddr_pmic[i],
360 &max8997->reg_dump[i]);
361
362 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_muic); i++)
363 max8997_read_reg(i2c, max8997_dumpaddr_muic[i],
364 &max8997->reg_dump[i + MAX8997_REG_PMIC_END]);
365
366 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_haptic); i++)
367 max8997_read_reg(i2c, max8997_dumpaddr_haptic[i],
368 &max8997->reg_dump[i + MAX8997_REG_PMIC_END +
369 MAX8997_MUIC_REG_END]);
370
371 return 0;
372}
373
374static int max8997_restore(struct device *dev)
375{
376 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
377 struct max8997_dev *max8997 = i2c_get_clientdata(i2c);
378 int i;
379
380 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_pmic); i++)
381 max8997_write_reg(i2c, max8997_dumpaddr_pmic[i],
382 max8997->reg_dump[i]);
383
384 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_muic); i++)
385 max8997_write_reg(i2c, max8997_dumpaddr_muic[i],
386 max8997->reg_dump[i + MAX8997_REG_PMIC_END]);
387
388 for (i = 0; i < ARRAY_SIZE(max8997_dumpaddr_haptic); i++)
389 max8997_write_reg(i2c, max8997_dumpaddr_haptic[i],
390 max8997->reg_dump[i + MAX8997_REG_PMIC_END +
391 MAX8997_MUIC_REG_END]);
392
393 return 0;
394}
395
396const struct dev_pm_ops max8997_pm = {
397 .freeze = max8997_freeze,
398 .restore = max8997_restore,
399};
400
401static struct i2c_driver max8997_i2c_driver = {
402 .driver = {
403 .name = "max8997",
404 .owner = THIS_MODULE,
405 .pm = &max8997_pm,
406 },
407 .probe = max8997_i2c_probe,
408 .remove = max8997_i2c_remove,
409 .id_table = max8997_i2c_id,
410};
411
412static int __init max8997_i2c_init(void)
413{
414 return i2c_add_driver(&max8997_i2c_driver);
415}
416/* init early so consumer devices can complete system boot */
417subsys_initcall(max8997_i2c_init);
418
419static void __exit max8997_i2c_exit(void)
420{
421 i2c_del_driver(&max8997_i2c_driver);
422}
423module_exit(max8997_i2c_exit);
424
425MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver");
426MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
427MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index bbfe86732602..c00214257da2 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -233,7 +233,7 @@ struct max8998_reg_dump {
233 u8 val; 233 u8 val;
234}; 234};
235#define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } 235#define SAVE_ITEM(x) { .addr = (x), .val = 0x0, }
236struct max8998_reg_dump max8998_dump[] = { 236static struct max8998_reg_dump max8998_dump[] = {
237 SAVE_ITEM(MAX8998_REG_IRQM1), 237 SAVE_ITEM(MAX8998_REG_IRQM1),
238 SAVE_ITEM(MAX8998_REG_IRQM2), 238 SAVE_ITEM(MAX8998_REG_IRQM2),
239 SAVE_ITEM(MAX8998_REG_IRQM3), 239 SAVE_ITEM(MAX8998_REG_IRQM3),
@@ -298,7 +298,7 @@ static int max8998_restore(struct device *dev)
298 return 0; 298 return 0;
299} 299}
300 300
301const struct dev_pm_ops max8998_pm = { 301static const struct dev_pm_ops max8998_pm = {
302 .suspend = max8998_suspend, 302 .suspend = max8998_suspend,
303 .resume = max8998_resume, 303 .resume = max8998_resume,
304 .freeze = max8998_freeze, 304 .freeze = max8998_freeze,
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index b9fcaf0004da..668634e89e81 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -683,14 +683,13 @@ out:
683EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion); 683EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
684 684
685static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, 685static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
686 const char *format, void *pdata, size_t pdata_size) 686 const char *format, void *pdata)
687{ 687{
688 char buf[30]; 688 char buf[30];
689 const char *name = mc13xxx_get_chipname(mc13xxx); 689 const char *name = mc13xxx_get_chipname(mc13xxx);
690 690
691 struct mfd_cell cell = { 691 struct mfd_cell cell = {
692 .platform_data = pdata, 692 .mfd_data = pdata,
693 .data_size = pdata_size,
694 }; 693 };
695 694
696 /* there is no asnprintf in the kernel :-( */ 695 /* there is no asnprintf in the kernel :-( */
@@ -706,7 +705,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
706 705
707static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) 706static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
708{ 707{
709 return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); 708 return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL);
710} 709}
711 710
712static int mc13xxx_probe(struct spi_device *spi) 711static int mc13xxx_probe(struct spi_device *spi)
@@ -764,13 +763,8 @@ err_revision:
764 mc13xxx_add_subdevice(mc13xxx, "%s-codec"); 763 mc13xxx_add_subdevice(mc13xxx, "%s-codec");
765 764
766 if (pdata->flags & MC13XXX_USE_REGULATOR) { 765 if (pdata->flags & MC13XXX_USE_REGULATOR) {
767 struct mc13xxx_regulator_platform_data regulator_pdata = {
768 .num_regulators = pdata->num_regulators,
769 .regulators = pdata->regulators,
770 };
771
772 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", 766 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
773 &regulator_pdata, sizeof(regulator_pdata)); 767 &pdata->regulators);
774 } 768 }
775 769
776 if (pdata->flags & MC13XXX_USE_RTC) 770 if (pdata->flags & MC13XXX_USE_RTC)
@@ -779,10 +773,8 @@ err_revision:
779 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) 773 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
780 mc13xxx_add_subdevice(mc13xxx, "%s-ts"); 774 mc13xxx_add_subdevice(mc13xxx, "%s-ts");
781 775
782 if (pdata->flags & MC13XXX_USE_LED) { 776 if (pdata->flags & MC13XXX_USE_LED)
783 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", 777 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", pdata->leds);
784 pdata->leds, sizeof(*pdata->leds));
785 }
786 778
787 return 0; 779 return 0;
788} 780}
@@ -811,6 +803,7 @@ static const struct spi_device_id mc13xxx_device_id[] = {
811 /* sentinel */ 803 /* sentinel */
812 } 804 }
813}; 805};
806MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
814 807
815static struct spi_driver mc13xxx_driver = { 808static struct spi_driver mc13xxx_driver = {
816 .id_table = mc13xxx_device_id, 809 .id_table = mc13xxx_device_id,
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
index d83ad0f141af..79eda0264fb2 100644
--- a/drivers/mfd/mfd-core.c
+++ b/drivers/mfd/mfd-core.c
@@ -18,6 +18,43 @@
18#include <linux/pm_runtime.h> 18#include <linux/pm_runtime.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20 20
21int mfd_cell_enable(struct platform_device *pdev)
22{
23 const struct mfd_cell *cell = mfd_get_cell(pdev);
24 int err = 0;
25
26 /* only call enable hook if the cell wasn't previously enabled */
27 if (atomic_inc_return(cell->usage_count) == 1)
28 err = cell->enable(pdev);
29
30 /* if the enable hook failed, decrement counter to allow retries */
31 if (err)
32 atomic_dec(cell->usage_count);
33
34 return err;
35}
36EXPORT_SYMBOL(mfd_cell_enable);
37
38int mfd_cell_disable(struct platform_device *pdev)
39{
40 const struct mfd_cell *cell = mfd_get_cell(pdev);
41 int err = 0;
42
43 /* only disable if no other clients are using it */
44 if (atomic_dec_return(cell->usage_count) == 0)
45 err = cell->disable(pdev);
46
47 /* if the disable hook failed, increment to allow retries */
48 if (err)
49 atomic_inc(cell->usage_count);
50
51 /* sanity check; did someone call disable too many times? */
52 WARN_ON(atomic_read(cell->usage_count) < 0);
53
54 return err;
55}
56EXPORT_SYMBOL(mfd_cell_disable);
57
21static int mfd_add_device(struct device *parent, int id, 58static int mfd_add_device(struct device *parent, int id,
22 const struct mfd_cell *cell, 59 const struct mfd_cell *cell,
23 struct resource *mem_base, 60 struct resource *mem_base,
@@ -37,14 +74,10 @@ static int mfd_add_device(struct device *parent, int id,
37 goto fail_device; 74 goto fail_device;
38 75
39 pdev->dev.parent = parent; 76 pdev->dev.parent = parent;
40 platform_set_drvdata(pdev, cell->driver_data);
41 77
42 if (cell->data_size) { 78 ret = platform_device_add_data(pdev, cell, sizeof(*cell));
43 ret = platform_device_add_data(pdev, 79 if (ret)
44 cell->platform_data, cell->data_size); 80 goto fail_res;
45 if (ret)
46 goto fail_res;
47 }
48 81
49 for (r = 0; r < cell->num_resources; r++) { 82 for (r = 0; r < cell->num_resources; r++) {
50 res[r].name = cell->resources[r].name; 83 res[r].name = cell->resources[r].name;
@@ -100,14 +133,22 @@ fail_alloc:
100} 133}
101 134
102int mfd_add_devices(struct device *parent, int id, 135int mfd_add_devices(struct device *parent, int id,
103 const struct mfd_cell *cells, int n_devs, 136 struct mfd_cell *cells, int n_devs,
104 struct resource *mem_base, 137 struct resource *mem_base,
105 int irq_base) 138 int irq_base)
106{ 139{
107 int i; 140 int i;
108 int ret = 0; 141 int ret = 0;
142 atomic_t *cnts;
143
144 /* initialize reference counting for all cells */
145 cnts = kcalloc(sizeof(*cnts), n_devs, GFP_KERNEL);
146 if (!cnts)
147 return -ENOMEM;
109 148
110 for (i = 0; i < n_devs; i++) { 149 for (i = 0; i < n_devs; i++) {
150 atomic_set(&cnts[i], 0);
151 cells[i].usage_count = &cnts[i];
111 ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); 152 ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base);
112 if (ret) 153 if (ret)
113 break; 154 break;
@@ -120,17 +161,89 @@ int mfd_add_devices(struct device *parent, int id,
120} 161}
121EXPORT_SYMBOL(mfd_add_devices); 162EXPORT_SYMBOL(mfd_add_devices);
122 163
123static int mfd_remove_devices_fn(struct device *dev, void *unused) 164static int mfd_remove_devices_fn(struct device *dev, void *c)
124{ 165{
125 platform_device_unregister(to_platform_device(dev)); 166 struct platform_device *pdev = to_platform_device(dev);
167 const struct mfd_cell *cell = mfd_get_cell(pdev);
168 atomic_t **usage_count = c;
169
170 /* find the base address of usage_count pointers (for freeing) */
171 if (!*usage_count || (cell->usage_count < *usage_count))
172 *usage_count = cell->usage_count;
173
174 platform_device_unregister(pdev);
126 return 0; 175 return 0;
127} 176}
128 177
129void mfd_remove_devices(struct device *parent) 178void mfd_remove_devices(struct device *parent)
130{ 179{
131 device_for_each_child(parent, NULL, mfd_remove_devices_fn); 180 atomic_t *cnts = NULL;
181
182 device_for_each_child(parent, &cnts, mfd_remove_devices_fn);
183 kfree(cnts);
132} 184}
133EXPORT_SYMBOL(mfd_remove_devices); 185EXPORT_SYMBOL(mfd_remove_devices);
134 186
187static int add_shared_platform_device(const char *cell, const char *name)
188{
189 struct mfd_cell cell_entry;
190 struct device *dev;
191 struct platform_device *pdev;
192 int err;
193
194 /* check if we've already registered a device (don't fail if we have) */
195 if (bus_find_device_by_name(&platform_bus_type, NULL, name))
196 return 0;
197
198 /* fetch the parent cell's device (should already be registered!) */
199 dev = bus_find_device_by_name(&platform_bus_type, NULL, cell);
200 if (!dev) {
201 printk(KERN_ERR "failed to find device for cell %s\n", cell);
202 return -ENODEV;
203 }
204 pdev = to_platform_device(dev);
205 memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry));
206
207 WARN_ON(!cell_entry.enable);
208
209 cell_entry.name = name;
210 err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0);
211 if (err)
212 dev_err(dev, "MFD add devices failed: %d\n", err);
213 return err;
214}
215
216int mfd_shared_platform_driver_register(struct platform_driver *drv,
217 const char *cellname)
218{
219 int err;
220
221 err = add_shared_platform_device(cellname, drv->driver.name);
222 if (err)
223 printk(KERN_ERR "failed to add platform device %s\n",
224 drv->driver.name);
225
226 err = platform_driver_register(drv);
227 if (err)
228 printk(KERN_ERR "failed to add platform driver %s\n",
229 drv->driver.name);
230
231 return err;
232}
233EXPORT_SYMBOL(mfd_shared_platform_driver_register);
234
235void mfd_shared_platform_driver_unregister(struct platform_driver *drv)
236{
237 struct device *dev;
238
239 dev = bus_find_device_by_name(&platform_bus_type, NULL,
240 drv->driver.name);
241 if (dev)
242 platform_device_unregister(to_platform_device(dev));
243
244 platform_driver_unregister(drv);
245}
246EXPORT_SYMBOL(mfd_shared_platform_driver_unregister);
247
135MODULE_LICENSE("GPL"); 248MODULE_LICENSE("GPL");
136MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov"); 249MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 501ce13b693e..c1306ed43e3c 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -21,6 +21,7 @@
21#include <linux/workqueue.h> 21#include <linux/workqueue.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/pm.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
25 26
26#include <linux/mfd/pcf50633/core.h> 27#include <linux/mfd/pcf50633/core.h>
@@ -230,27 +231,26 @@ pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
230 } 231 }
231} 232}
232 233
233#ifdef CONFIG_PM 234#ifdef CONFIG_PM_SLEEP
234static int pcf50633_suspend(struct i2c_client *client, pm_message_t state) 235static int pcf50633_suspend(struct device *dev)
235{ 236{
236 struct pcf50633 *pcf; 237 struct i2c_client *client = to_i2c_client(dev);
237 pcf = i2c_get_clientdata(client); 238 struct pcf50633 *pcf = i2c_get_clientdata(client);
238 239
239 return pcf50633_irq_suspend(pcf); 240 return pcf50633_irq_suspend(pcf);
240} 241}
241 242
242static int pcf50633_resume(struct i2c_client *client) 243static int pcf50633_resume(struct device *dev)
243{ 244{
244 struct pcf50633 *pcf; 245 struct i2c_client *client = to_i2c_client(dev);
245 pcf = i2c_get_clientdata(client); 246 struct pcf50633 *pcf = i2c_get_clientdata(client);
246 247
247 return pcf50633_irq_resume(pcf); 248 return pcf50633_irq_resume(pcf);
248} 249}
249#else
250#define pcf50633_suspend NULL
251#define pcf50633_resume NULL
252#endif 250#endif
253 251
252static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume);
253
254static int __devinit pcf50633_probe(struct i2c_client *client, 254static int __devinit pcf50633_probe(struct i2c_client *client,
255 const struct i2c_device_id *ids) 255 const struct i2c_device_id *ids)
256{ 256{
@@ -360,16 +360,16 @@ static struct i2c_device_id pcf50633_id_table[] = {
360 {"pcf50633", 0x73}, 360 {"pcf50633", 0x73},
361 {/* end of list */} 361 {/* end of list */}
362}; 362};
363MODULE_DEVICE_TABLE(i2c, pcf50633_id_table);
363 364
364static struct i2c_driver pcf50633_driver = { 365static struct i2c_driver pcf50633_driver = {
365 .driver = { 366 .driver = {
366 .name = "pcf50633", 367 .name = "pcf50633",
368 .pm = &pcf50633_pm,
367 }, 369 },
368 .id_table = pcf50633_id_table, 370 .id_table = pcf50633_id_table,
369 .probe = pcf50633_probe, 371 .probe = pcf50633_probe,
370 .remove = __devexit_p(pcf50633_remove), 372 .remove = __devexit_p(pcf50633_remove),
371 .suspend = pcf50633_suspend,
372 .resume = pcf50633_resume,
373}; 373};
374 374
375static int __init pcf50633_init(void) 375static int __init pcf50633_init(void)
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c
index 50922975bda3..193c940225b5 100644
--- a/drivers/mfd/rdc321x-southbridge.c
+++ b/drivers/mfd/rdc321x-southbridge.c
@@ -61,12 +61,12 @@ static struct mfd_cell rdc321x_sb_cells[] = {
61 .name = "rdc321x-wdt", 61 .name = "rdc321x-wdt",
62 .resources = rdc321x_wdt_resource, 62 .resources = rdc321x_wdt_resource,
63 .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), 63 .num_resources = ARRAY_SIZE(rdc321x_wdt_resource),
64 .driver_data = &rdc321x_wdt_pdata, 64 .mfd_data = &rdc321x_wdt_pdata,
65 }, { 65 }, {
66 .name = "rdc321x-gpio", 66 .name = "rdc321x-gpio",
67 .resources = rdc321x_gpio_resources, 67 .resources = rdc321x_gpio_resources,
68 .num_resources = ARRAY_SIZE(rdc321x_gpio_resources), 68 .num_resources = ARRAY_SIZE(rdc321x_gpio_resources),
69 .driver_data = &rdc321x_gpio_pdata, 69 .mfd_data = &rdc321x_gpio_pdata,
70 }, 70 },
71}; 71};
72 72
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mfd/sh_mobile_sdhi.c
index 0a7df44a93c0..53a63024bf11 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mfd/sh_mobile_sdhi.c
@@ -146,9 +146,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
146 } 146 }
147 147
148 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); 148 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
149 priv->cell_mmc.driver_data = mmc_data; 149 priv->cell_mmc.mfd_data = mmc_data;
150 priv->cell_mmc.platform_data = &priv->cell_mmc;
151 priv->cell_mmc.data_size = sizeof(priv->cell_mmc);
152 150
153 platform_set_drvdata(pdev, priv); 151 platform_set_drvdata(pdev, priv);
154 152
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 9caeb4ac6ea6..af57fc706a4c 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -170,7 +170,7 @@ static struct mfd_cell t7l66xb_cells[] = {
170 .name = "tmio-mmc", 170 .name = "tmio-mmc",
171 .enable = t7l66xb_mmc_enable, 171 .enable = t7l66xb_mmc_enable,
172 .disable = t7l66xb_mmc_disable, 172 .disable = t7l66xb_mmc_disable,
173 .driver_data = &t7166xb_mmc_data, 173 .mfd_data = &t7166xb_mmc_data,
174 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), 174 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources),
175 .resources = t7l66xb_mmc_resources, 175 .resources = t7l66xb_mmc_resources,
176 }, 176 },
@@ -383,16 +383,7 @@ static int t7l66xb_probe(struct platform_device *dev)
383 383
384 t7l66xb_attach_irq(dev); 384 t7l66xb_attach_irq(dev);
385 385
386 t7l66xb_cells[T7L66XB_CELL_NAND].driver_data = pdata->nand_data; 386 t7l66xb_cells[T7L66XB_CELL_NAND].mfd_data = pdata->nand_data;
387 t7l66xb_cells[T7L66XB_CELL_NAND].platform_data =
388 &t7l66xb_cells[T7L66XB_CELL_NAND];
389 t7l66xb_cells[T7L66XB_CELL_NAND].data_size =
390 sizeof(t7l66xb_cells[T7L66XB_CELL_NAND]);
391
392 t7l66xb_cells[T7L66XB_CELL_MMC].platform_data =
393 &t7l66xb_cells[T7L66XB_CELL_MMC];
394 t7l66xb_cells[T7L66XB_CELL_MMC].data_size =
395 sizeof(t7l66xb_cells[T7L66XB_CELL_MMC]);
396 387
397 ret = mfd_add_devices(&dev->dev, dev->id, 388 ret = mfd_add_devices(&dev->dev, dev->id,
398 t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), 389 t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells),
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 6315f63f017d..b006f7cee952 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -131,7 +131,7 @@ static struct mfd_cell tc6387xb_cells[] = {
131 .name = "tmio-mmc", 131 .name = "tmio-mmc",
132 .enable = tc6387xb_mmc_enable, 132 .enable = tc6387xb_mmc_enable,
133 .disable = tc6387xb_mmc_disable, 133 .disable = tc6387xb_mmc_disable,
134 .driver_data = &tc6387xb_mmc_data, 134 .mfd_data = &tc6387xb_mmc_data,
135 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), 135 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
136 .resources = tc6387xb_mmc_resources, 136 .resources = tc6387xb_mmc_resources,
137 }, 137 },
@@ -190,11 +190,6 @@ static int __devinit tc6387xb_probe(struct platform_device *dev)
190 190
191 printk(KERN_INFO "Toshiba tc6387xb initialised\n"); 191 printk(KERN_INFO "Toshiba tc6387xb initialised\n");
192 192
193 tc6387xb_cells[TC6387XB_CELL_MMC].platform_data =
194 &tc6387xb_cells[TC6387XB_CELL_MMC];
195 tc6387xb_cells[TC6387XB_CELL_MMC].data_size =
196 sizeof(tc6387xb_cells[TC6387XB_CELL_MMC]);
197
198 ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, 193 ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells,
199 ARRAY_SIZE(tc6387xb_cells), iomem, irq); 194 ARRAY_SIZE(tc6387xb_cells), iomem, irq);
200 195
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index 9a238633a54d..3d62ded86a8f 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -393,7 +393,7 @@ static struct mfd_cell __devinitdata tc6393xb_cells[] = {
393 .name = "tmio-mmc", 393 .name = "tmio-mmc",
394 .enable = tc6393xb_mmc_enable, 394 .enable = tc6393xb_mmc_enable,
395 .resume = tc6393xb_mmc_resume, 395 .resume = tc6393xb_mmc_resume,
396 .driver_data = &tc6393xb_mmc_data, 396 .mfd_data = &tc6393xb_mmc_data,
397 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), 397 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
398 .resources = tc6393xb_mmc_resources, 398 .resources = tc6393xb_mmc_resources,
399 }, 399 },
@@ -693,27 +693,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev)
693 goto err_setup; 693 goto err_setup;
694 } 694 }
695 695
696 tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; 696 tc6393xb_cells[TC6393XB_CELL_NAND].mfd_data = tcpd->nand_data;
697 tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = 697 tc6393xb_cells[TC6393XB_CELL_FB].mfd_data = tcpd->fb_data;
698 &tc6393xb_cells[TC6393XB_CELL_NAND];
699 tc6393xb_cells[TC6393XB_CELL_NAND].data_size =
700 sizeof(tc6393xb_cells[TC6393XB_CELL_NAND]);
701
702 tc6393xb_cells[TC6393XB_CELL_MMC].platform_data =
703 &tc6393xb_cells[TC6393XB_CELL_MMC];
704 tc6393xb_cells[TC6393XB_CELL_MMC].data_size =
705 sizeof(tc6393xb_cells[TC6393XB_CELL_MMC]);
706
707 tc6393xb_cells[TC6393XB_CELL_OHCI].platform_data =
708 &tc6393xb_cells[TC6393XB_CELL_OHCI];
709 tc6393xb_cells[TC6393XB_CELL_OHCI].data_size =
710 sizeof(tc6393xb_cells[TC6393XB_CELL_OHCI]);
711
712 tc6393xb_cells[TC6393XB_CELL_FB].driver_data = tcpd->fb_data;
713 tc6393xb_cells[TC6393XB_CELL_FB].platform_data =
714 &tc6393xb_cells[TC6393XB_CELL_FB];
715 tc6393xb_cells[TC6393XB_CELL_FB].data_size =
716 sizeof(tc6393xb_cells[TC6393XB_CELL_FB]);
717 698
718 ret = mfd_add_devices(&dev->dev, dev->id, 699 ret = mfd_add_devices(&dev->dev, dev->id,
719 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), 700 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 6ad8a7f8d390..94c6c8afad12 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -384,8 +384,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
384 .name = "timb-dma", 384 .name = "timb-dma",
385 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 385 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
386 .resources = timberdale_dma_resources, 386 .resources = timberdale_dma_resources,
387 .platform_data = &timb_dma_platform_data, 387 .mfd_data = &timb_dma_platform_data,
388 .data_size = sizeof(timb_dma_platform_data),
389 }, 388 },
390 { 389 {
391 .name = "timb-uart", 390 .name = "timb-uart",
@@ -396,43 +395,37 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg0[] = {
396 .name = "xiic-i2c", 395 .name = "xiic-i2c",
397 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 396 .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
398 .resources = timberdale_xiic_resources, 397 .resources = timberdale_xiic_resources,
399 .platform_data = &timberdale_xiic_platform_data, 398 .mfd_data = &timberdale_xiic_platform_data,
400 .data_size = sizeof(timberdale_xiic_platform_data),
401 }, 399 },
402 { 400 {
403 .name = "timb-gpio", 401 .name = "timb-gpio",
404 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 402 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
405 .resources = timberdale_gpio_resources, 403 .resources = timberdale_gpio_resources,
406 .platform_data = &timberdale_gpio_platform_data, 404 .mfd_data = &timberdale_gpio_platform_data,
407 .data_size = sizeof(timberdale_gpio_platform_data),
408 }, 405 },
409 { 406 {
410 .name = "timb-video", 407 .name = "timb-video",
411 .num_resources = ARRAY_SIZE(timberdale_video_resources), 408 .num_resources = ARRAY_SIZE(timberdale_video_resources),
412 .resources = timberdale_video_resources, 409 .resources = timberdale_video_resources,
413 .platform_data = &timberdale_video_platform_data, 410 .mfd_data = &timberdale_video_platform_data,
414 .data_size = sizeof(timberdale_video_platform_data),
415 }, 411 },
416 { 412 {
417 .name = "timb-radio", 413 .name = "timb-radio",
418 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 414 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
419 .resources = timberdale_radio_resources, 415 .resources = timberdale_radio_resources,
420 .platform_data = &timberdale_radio_platform_data, 416 .mfd_data = &timberdale_radio_platform_data,
421 .data_size = sizeof(timberdale_radio_platform_data),
422 }, 417 },
423 { 418 {
424 .name = "xilinx_spi", 419 .name = "xilinx_spi",
425 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 420 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
426 .resources = timberdale_spi_resources, 421 .resources = timberdale_spi_resources,
427 .platform_data = &timberdale_xspi_platform_data, 422 .mfd_data = &timberdale_xspi_platform_data,
428 .data_size = sizeof(timberdale_xspi_platform_data),
429 }, 423 },
430 { 424 {
431 .name = "ks8842", 425 .name = "ks8842",
432 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 426 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
433 .resources = timberdale_eth_resources, 427 .resources = timberdale_eth_resources,
434 .platform_data = &timberdale_ks8842_platform_data, 428 .mfd_data = &timberdale_ks8842_platform_data,
435 .data_size = sizeof(timberdale_ks8842_platform_data)
436 }, 429 },
437}; 430};
438 431
@@ -441,8 +434,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
441 .name = "timb-dma", 434 .name = "timb-dma",
442 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 435 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
443 .resources = timberdale_dma_resources, 436 .resources = timberdale_dma_resources,
444 .platform_data = &timb_dma_platform_data, 437 .mfd_data = &timb_dma_platform_data,
445 .data_size = sizeof(timb_dma_platform_data),
446 }, 438 },
447 { 439 {
448 .name = "timb-uart", 440 .name = "timb-uart",
@@ -458,15 +450,13 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
458 .name = "xiic-i2c", 450 .name = "xiic-i2c",
459 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 451 .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
460 .resources = timberdale_xiic_resources, 452 .resources = timberdale_xiic_resources,
461 .platform_data = &timberdale_xiic_platform_data, 453 .mfd_data = &timberdale_xiic_platform_data,
462 .data_size = sizeof(timberdale_xiic_platform_data),
463 }, 454 },
464 { 455 {
465 .name = "timb-gpio", 456 .name = "timb-gpio",
466 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 457 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
467 .resources = timberdale_gpio_resources, 458 .resources = timberdale_gpio_resources,
468 .platform_data = &timberdale_gpio_platform_data, 459 .mfd_data = &timberdale_gpio_platform_data,
469 .data_size = sizeof(timberdale_gpio_platform_data),
470 }, 460 },
471 { 461 {
472 .name = "timb-mlogicore", 462 .name = "timb-mlogicore",
@@ -477,29 +467,25 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg1[] = {
477 .name = "timb-video", 467 .name = "timb-video",
478 .num_resources = ARRAY_SIZE(timberdale_video_resources), 468 .num_resources = ARRAY_SIZE(timberdale_video_resources),
479 .resources = timberdale_video_resources, 469 .resources = timberdale_video_resources,
480 .platform_data = &timberdale_video_platform_data, 470 .mfd_data = &timberdale_video_platform_data,
481 .data_size = sizeof(timberdale_video_platform_data),
482 }, 471 },
483 { 472 {
484 .name = "timb-radio", 473 .name = "timb-radio",
485 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 474 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
486 .resources = timberdale_radio_resources, 475 .resources = timberdale_radio_resources,
487 .platform_data = &timberdale_radio_platform_data, 476 .mfd_data = &timberdale_radio_platform_data,
488 .data_size = sizeof(timberdale_radio_platform_data),
489 }, 477 },
490 { 478 {
491 .name = "xilinx_spi", 479 .name = "xilinx_spi",
492 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 480 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
493 .resources = timberdale_spi_resources, 481 .resources = timberdale_spi_resources,
494 .platform_data = &timberdale_xspi_platform_data, 482 .mfd_data = &timberdale_xspi_platform_data,
495 .data_size = sizeof(timberdale_xspi_platform_data),
496 }, 483 },
497 { 484 {
498 .name = "ks8842", 485 .name = "ks8842",
499 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 486 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
500 .resources = timberdale_eth_resources, 487 .resources = timberdale_eth_resources,
501 .platform_data = &timberdale_ks8842_platform_data, 488 .mfd_data = &timberdale_ks8842_platform_data,
502 .data_size = sizeof(timberdale_ks8842_platform_data)
503 }, 489 },
504}; 490};
505 491
@@ -508,8 +494,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
508 .name = "timb-dma", 494 .name = "timb-dma",
509 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 495 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
510 .resources = timberdale_dma_resources, 496 .resources = timberdale_dma_resources,
511 .platform_data = &timb_dma_platform_data, 497 .mfd_data = &timb_dma_platform_data,
512 .data_size = sizeof(timb_dma_platform_data),
513 }, 498 },
514 { 499 {
515 .name = "timb-uart", 500 .name = "timb-uart",
@@ -520,36 +505,31 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg2[] = {
520 .name = "xiic-i2c", 505 .name = "xiic-i2c",
521 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 506 .num_resources = ARRAY_SIZE(timberdale_xiic_resources),
522 .resources = timberdale_xiic_resources, 507 .resources = timberdale_xiic_resources,
523 .platform_data = &timberdale_xiic_platform_data, 508 .mfd_data = &timberdale_xiic_platform_data,
524 .data_size = sizeof(timberdale_xiic_platform_data),
525 }, 509 },
526 { 510 {
527 .name = "timb-gpio", 511 .name = "timb-gpio",
528 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 512 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
529 .resources = timberdale_gpio_resources, 513 .resources = timberdale_gpio_resources,
530 .platform_data = &timberdale_gpio_platform_data, 514 .mfd_data = &timberdale_gpio_platform_data,
531 .data_size = sizeof(timberdale_gpio_platform_data),
532 }, 515 },
533 { 516 {
534 .name = "timb-video", 517 .name = "timb-video",
535 .num_resources = ARRAY_SIZE(timberdale_video_resources), 518 .num_resources = ARRAY_SIZE(timberdale_video_resources),
536 .resources = timberdale_video_resources, 519 .resources = timberdale_video_resources,
537 .platform_data = &timberdale_video_platform_data, 520 .mfd_data = &timberdale_video_platform_data,
538 .data_size = sizeof(timberdale_video_platform_data),
539 }, 521 },
540 { 522 {
541 .name = "timb-radio", 523 .name = "timb-radio",
542 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 524 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
543 .resources = timberdale_radio_resources, 525 .resources = timberdale_radio_resources,
544 .platform_data = &timberdale_radio_platform_data, 526 .mfd_data = &timberdale_radio_platform_data,
545 .data_size = sizeof(timberdale_radio_platform_data),
546 }, 527 },
547 { 528 {
548 .name = "xilinx_spi", 529 .name = "xilinx_spi",
549 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 530 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
550 .resources = timberdale_spi_resources, 531 .resources = timberdale_spi_resources,
551 .platform_data = &timberdale_xspi_platform_data, 532 .mfd_data = &timberdale_xspi_platform_data,
552 .data_size = sizeof(timberdale_xspi_platform_data),
553 }, 533 },
554}; 534};
555 535
@@ -558,8 +538,7 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
558 .name = "timb-dma", 538 .name = "timb-dma",
559 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 539 .num_resources = ARRAY_SIZE(timberdale_dma_resources),
560 .resources = timberdale_dma_resources, 540 .resources = timberdale_dma_resources,
561 .platform_data = &timb_dma_platform_data, 541 .mfd_data = &timb_dma_platform_data,
562 .data_size = sizeof(timb_dma_platform_data),
563 }, 542 },
564 { 543 {
565 .name = "timb-uart", 544 .name = "timb-uart",
@@ -570,43 +549,37 @@ static __devinitdata struct mfd_cell timberdale_cells_bar0_cfg3[] = {
570 .name = "ocores-i2c", 549 .name = "ocores-i2c",
571 .num_resources = ARRAY_SIZE(timberdale_ocores_resources), 550 .num_resources = ARRAY_SIZE(timberdale_ocores_resources),
572 .resources = timberdale_ocores_resources, 551 .resources = timberdale_ocores_resources,
573 .platform_data = &timberdale_ocores_platform_data, 552 .mfd_data = &timberdale_ocores_platform_data,
574 .data_size = sizeof(timberdale_ocores_platform_data),
575 }, 553 },
576 { 554 {
577 .name = "timb-gpio", 555 .name = "timb-gpio",
578 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 556 .num_resources = ARRAY_SIZE(timberdale_gpio_resources),
579 .resources = timberdale_gpio_resources, 557 .resources = timberdale_gpio_resources,
580 .platform_data = &timberdale_gpio_platform_data, 558 .mfd_data = &timberdale_gpio_platform_data,
581 .data_size = sizeof(timberdale_gpio_platform_data),
582 }, 559 },
583 { 560 {
584 .name = "timb-video", 561 .name = "timb-video",
585 .num_resources = ARRAY_SIZE(timberdale_video_resources), 562 .num_resources = ARRAY_SIZE(timberdale_video_resources),
586 .resources = timberdale_video_resources, 563 .resources = timberdale_video_resources,
587 .platform_data = &timberdale_video_platform_data, 564 .mfd_data = &timberdale_video_platform_data,
588 .data_size = sizeof(timberdale_video_platform_data),
589 }, 565 },
590 { 566 {
591 .name = "timb-radio", 567 .name = "timb-radio",
592 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 568 .num_resources = ARRAY_SIZE(timberdale_radio_resources),
593 .resources = timberdale_radio_resources, 569 .resources = timberdale_radio_resources,
594 .platform_data = &timberdale_radio_platform_data, 570 .mfd_data = &timberdale_radio_platform_data,
595 .data_size = sizeof(timberdale_radio_platform_data),
596 }, 571 },
597 { 572 {
598 .name = "xilinx_spi", 573 .name = "xilinx_spi",
599 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 574 .num_resources = ARRAY_SIZE(timberdale_spi_resources),
600 .resources = timberdale_spi_resources, 575 .resources = timberdale_spi_resources,
601 .platform_data = &timberdale_xspi_platform_data, 576 .mfd_data = &timberdale_xspi_platform_data,
602 .data_size = sizeof(timberdale_xspi_platform_data),
603 }, 577 },
604 { 578 {
605 .name = "ks8842", 579 .name = "ks8842",
606 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 580 .num_resources = ARRAY_SIZE(timberdale_eth_resources),
607 .resources = timberdale_eth_resources, 581 .resources = timberdale_eth_resources,
608 .platform_data = &timberdale_ks8842_platform_data, 582 .mfd_data = &timberdale_ks8842_platform_data,
609 .data_size = sizeof(timberdale_ks8842_platform_data)
610 }, 583 },
611}; 584};
612 585
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
new file mode 100644
index 000000000000..46d8205646b6
--- /dev/null
+++ b/drivers/mfd/tps6105x.c
@@ -0,0 +1,246 @@
1/*
2 * Core driver for TPS61050/61052 boost converters, used for while LED
3 * driving, audio power amplification, white LED flash, and generic
4 * boost conversion. Additionally it provides a 1-bit GPIO pin (out or in)
5 * and a flash synchronization pin to synchronize flash events when used as
6 * flashgun.
7 *
8 * Copyright (C) 2011 ST-Ericsson SA
9 * Written on behalf of Linaro for ST-Ericsson
10 *
11 * Author: Linus Walleij <linus.walleij@linaro.org>
12 *
13 * License terms: GNU General Public License (GPL) version 2
14 */
15
16#include <linux/module.h>
17#include <linux/init.h>
18#include <linux/i2c.h>
19#include <linux/mutex.h>
20#include <linux/gpio.h>
21#include <linux/spinlock.h>
22#include <linux/slab.h>
23#include <linux/err.h>
24#include <linux/regulator/driver.h>
25#include <linux/mfd/core.h>
26#include <linux/mfd/tps6105x.h>
27
28int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value)
29{
30 int ret;
31
32 ret = mutex_lock_interruptible(&tps6105x->lock);
33 if (ret)
34 return ret;
35 ret = i2c_smbus_write_byte_data(tps6105x->client, reg, value);
36 mutex_unlock(&tps6105x->lock);
37 if (ret < 0)
38 return ret;
39
40 return 0;
41}
42EXPORT_SYMBOL(tps6105x_set);
43
44int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf)
45{
46 int ret;
47
48 ret = mutex_lock_interruptible(&tps6105x->lock);
49 if (ret)
50 return ret;
51 ret = i2c_smbus_read_byte_data(tps6105x->client, reg);
52 mutex_unlock(&tps6105x->lock);
53 if (ret < 0)
54 return ret;
55
56 *buf = ret;
57 return 0;
58}
59EXPORT_SYMBOL(tps6105x_get);
60
61/*
62 * Masks off the bits in the mask and sets the bits in the bitvalues
63 * parameter in one atomic operation
64 */
65int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg,
66 u8 bitmask, u8 bitvalues)
67{
68 int ret;
69 u8 regval;
70
71 ret = mutex_lock_interruptible(&tps6105x->lock);
72 if (ret)
73 return ret;
74 ret = i2c_smbus_read_byte_data(tps6105x->client, reg);
75 if (ret < 0)
76 goto fail;
77 regval = ret;
78 regval = (~bitmask & regval) | (bitmask & bitvalues);
79 ret = i2c_smbus_write_byte_data(tps6105x->client, reg, regval);
80fail:
81 mutex_unlock(&tps6105x->lock);
82 if (ret < 0)
83 return ret;
84
85 return 0;
86}
87EXPORT_SYMBOL(tps6105x_mask_and_set);
88
89static int __devinit tps6105x_startup(struct tps6105x *tps6105x)
90{
91 int ret;
92 u8 regval;
93
94 ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
95 if (ret)
96 return ret;
97 switch (regval >> TPS6105X_REG0_MODE_SHIFT) {
98 case TPS6105X_REG0_MODE_SHUTDOWN:
99 dev_info(&tps6105x->client->dev,
100 "TPS6105x found in SHUTDOWN mode\n");
101 break;
102 case TPS6105X_REG0_MODE_TORCH:
103 dev_info(&tps6105x->client->dev,
104 "TPS6105x found in TORCH mode\n");
105 break;
106 case TPS6105X_REG0_MODE_TORCH_FLASH:
107 dev_info(&tps6105x->client->dev,
108 "TPS6105x found in FLASH mode\n");
109 break;
110 case TPS6105X_REG0_MODE_VOLTAGE:
111 dev_info(&tps6105x->client->dev,
112 "TPS6105x found in VOLTAGE mode\n");
113 break;
114 default:
115 break;
116 }
117
118 return ret;
119}
120
121/*
122 * MFD cells - we have one cell which is selected operation
123 * mode, and we always have a GPIO cell.
124 */
125static struct mfd_cell tps6105x_cells[] = {
126 {
127 /* name will be runtime assigned */
128 .id = -1,
129 },
130 {
131 .name = "tps6105x-gpio",
132 .id = -1,
133 },
134};
135
136static int __devinit tps6105x_probe(struct i2c_client *client,
137 const struct i2c_device_id *id)
138{
139 struct tps6105x *tps6105x;
140 struct tps6105x_platform_data *pdata;
141 int ret;
142 int i;
143
144 tps6105x = kmalloc(sizeof(*tps6105x), GFP_KERNEL);
145 if (!tps6105x)
146 return -ENOMEM;
147
148 i2c_set_clientdata(client, tps6105x);
149 tps6105x->client = client;
150 pdata = client->dev.platform_data;
151 tps6105x->pdata = pdata;
152 mutex_init(&tps6105x->lock);
153
154 ret = tps6105x_startup(tps6105x);
155 if (ret) {
156 dev_err(&client->dev, "chip initialization failed\n");
157 goto fail;
158 }
159
160 /* Remove warning texts when you implement new cell drivers */
161 switch (pdata->mode) {
162 case TPS6105X_MODE_SHUTDOWN:
163 dev_info(&client->dev,
164 "present, not used for anything, only GPIO\n");
165 break;
166 case TPS6105X_MODE_TORCH:
167 tps6105x_cells[0].name = "tps6105x-leds";
168 dev_warn(&client->dev,
169 "torch mode is unsupported\n");
170 break;
171 case TPS6105X_MODE_TORCH_FLASH:
172 tps6105x_cells[0].name = "tps6105x-flash";
173 dev_warn(&client->dev,
174 "flash mode is unsupported\n");
175 break;
176 case TPS6105X_MODE_VOLTAGE:
177 tps6105x_cells[0].name ="tps6105x-regulator";
178 break;
179 default:
180 break;
181 }
182
183 /* Set up and register the platform devices. */
184 for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) {
185 /* One state holder for all drivers, this is simple */
186 tps6105x_cells[i].mfd_data = tps6105x;
187 }
188
189 ret = mfd_add_devices(&client->dev, 0, tps6105x_cells,
190 ARRAY_SIZE(tps6105x_cells), NULL, 0);
191 if (ret)
192 goto fail;
193
194 return 0;
195
196fail:
197 kfree(tps6105x);
198 return ret;
199}
200
201static int __devexit tps6105x_remove(struct i2c_client *client)
202{
203 struct tps6105x *tps6105x = i2c_get_clientdata(client);
204
205 mfd_remove_devices(&client->dev);
206
207 /* Put chip in shutdown mode */
208 tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
209 TPS6105X_REG0_MODE_MASK,
210 TPS6105X_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
211
212 kfree(tps6105x);
213 return 0;
214}
215
216static const struct i2c_device_id tps6105x_id[] = {
217 { "tps61050", 0 },
218 { "tps61052", 0 },
219 { }
220};
221MODULE_DEVICE_TABLE(i2c, tps6105x_id);
222
223static struct i2c_driver tps6105x_driver = {
224 .driver = {
225 .name = "tps6105x",
226 },
227 .probe = tps6105x_probe,
228 .remove = __devexit_p(tps6105x_remove),
229 .id_table = tps6105x_id,
230};
231
232static int __init tps6105x_init(void)
233{
234 return i2c_add_driver(&tps6105x_driver);
235}
236subsys_initcall(tps6105x_init);
237
238static void __exit tps6105x_exit(void)
239{
240 i2c_del_driver(&tps6105x_driver);
241}
242module_exit(tps6105x_exit);
243
244MODULE_AUTHOR("Linus Walleij");
245MODULE_DESCRIPTION("TPS6105x White LED Boost Converter Driver");
246MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index e9018d1394ee..0aa9186aec19 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -288,12 +288,10 @@ static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset,
288 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask); 288 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask);
289} 289}
290 290
291static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base) 291static int tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base)
292{ 292{
293 int ret;
294
295 if (!gpio_base) 293 if (!gpio_base)
296 return; 294 return 0;
297 295
298 tps6586x->gpio.owner = THIS_MODULE; 296 tps6586x->gpio.owner = THIS_MODULE;
299 tps6586x->gpio.label = tps6586x->client->name; 297 tps6586x->gpio.label = tps6586x->client->name;
@@ -307,9 +305,7 @@ static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base)
307 tps6586x->gpio.set = tps6586x_gpio_set; 305 tps6586x->gpio.set = tps6586x_gpio_set;
308 tps6586x->gpio.get = tps6586x_gpio_get; 306 tps6586x->gpio.get = tps6586x_gpio_get;
309 307
310 ret = gpiochip_add(&tps6586x->gpio); 308 return gpiochip_add(&tps6586x->gpio);
311 if (ret)
312 dev_warn(tps6586x->dev, "GPIO registration failed: %d\n", ret);
313} 309}
314 310
315static int __remove_subdev(struct device *dev, void *unused) 311static int __remove_subdev(struct device *dev, void *unused)
@@ -517,17 +513,28 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
517 } 513 }
518 } 514 }
519 515
516 ret = tps6586x_gpio_init(tps6586x, pdata->gpio_base);
517 if (ret) {
518 dev_err(&client->dev, "GPIO registration failed: %d\n", ret);
519 goto err_gpio_init;
520 }
521
520 ret = tps6586x_add_subdevs(tps6586x, pdata); 522 ret = tps6586x_add_subdevs(tps6586x, pdata);
521 if (ret) { 523 if (ret) {
522 dev_err(&client->dev, "add devices failed: %d\n", ret); 524 dev_err(&client->dev, "add devices failed: %d\n", ret);
523 goto err_add_devs; 525 goto err_add_devs;
524 } 526 }
525 527
526 tps6586x_gpio_init(tps6586x, pdata->gpio_base);
527
528 return 0; 528 return 0;
529 529
530err_add_devs: 530err_add_devs:
531 if (pdata->gpio_base) {
532 ret = gpiochip_remove(&tps6586x->gpio);
533 if (ret)
534 dev_err(&client->dev, "Can't remove gpio chip: %d\n",
535 ret);
536 }
537err_gpio_init:
531 if (client->irq) 538 if (client->irq)
532 free_irq(client->irq, tps6586x); 539 free_irq(client->irq, tps6586x);
533err_irq_init: 540err_irq_init:
@@ -587,4 +594,3 @@ module_exit(tps6586x_exit);
587MODULE_DESCRIPTION("TPS6586X core driver"); 594MODULE_DESCRIPTION("TPS6586X core driver");
588MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 595MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
589MODULE_LICENSE("GPL"); 596MODULE_LICENSE("GPL");
590
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index a35fa7dcbf53..960b5bed7f52 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -721,13 +721,13 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
721 721
722 } 722 }
723 723
724 if (twl_has_watchdog()) { 724 if (twl_has_watchdog() && twl_class_is_4030()) {
725 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); 725 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
726 if (IS_ERR(child)) 726 if (IS_ERR(child))
727 return PTR_ERR(child); 727 return PTR_ERR(child);
728 } 728 }
729 729
730 if (twl_has_pwrbutton()) { 730 if (twl_has_pwrbutton() && twl_class_is_4030()) {
731 child = add_child(1, "twl4030_pwrbutton", 731 child = add_child(1, "twl4030_pwrbutton",
732 NULL, 0, true, pdata->irq_base + 8 + 0, 0); 732 NULL, 0, true, pdata->irq_base + 8 + 0, 0);
733 if (IS_ERR(child)) 733 if (IS_ERR(child))
@@ -864,6 +864,10 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
864 child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3); 864 child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3);
865 if (IS_ERR(child)) 865 if (IS_ERR(child))
866 return PTR_ERR(child); 866 return PTR_ERR(child);
867
868 child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg);
869 if (IS_ERR(child))
870 return PTR_ERR(child);
867 } 871 }
868 872
869 if (twl_has_bci() && pdata->bci && 873 if (twl_has_bci() && pdata->bci &&
diff --git a/drivers/mfd/twl4030-codec.c b/drivers/mfd/twl4030-codec.c
index 9a4b196d6deb..c02fded316c9 100644
--- a/drivers/mfd/twl4030-codec.c
+++ b/drivers/mfd/twl4030-codec.c
@@ -208,15 +208,13 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
208 if (pdata->audio) { 208 if (pdata->audio) {
209 cell = &codec->cells[childs]; 209 cell = &codec->cells[childs];
210 cell->name = "twl4030-codec"; 210 cell->name = "twl4030-codec";
211 cell->platform_data = pdata->audio; 211 cell->mfd_data = pdata->audio;
212 cell->data_size = sizeof(*pdata->audio);
213 childs++; 212 childs++;
214 } 213 }
215 if (pdata->vibra) { 214 if (pdata->vibra) {
216 cell = &codec->cells[childs]; 215 cell = &codec->cells[childs];
217 cell->name = "twl4030-vibra"; 216 cell->name = "twl4030-vibra";
218 cell->platform_data = pdata->vibra; 217 cell->mfd_data = pdata->vibra;
219 cell->data_size = sizeof(*pdata->vibra);
220 childs++; 218 childs++;
221 } 219 }
222 220
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
new file mode 100644
index 000000000000..3941ddcf15fe
--- /dev/null
+++ b/drivers/mfd/twl4030-madc.c
@@ -0,0 +1,802 @@
1/*
2 *
3 * TWL4030 MADC module driver-This driver monitors the real time
4 * conversion of analog signals like battery temperature,
5 * battery type, battery level etc.
6 *
7 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
8 * J Keerthy <j-keerthy@ti.com>
9 *
10 * Based on twl4030-madc.c
11 * Copyright (C) 2008 Nokia Corporation
12 * Mikko Ylinen <mikko.k.ylinen@nokia.com>
13 *
14 * Amit Kucheria <amit.kucheria@canonical.com>
15 *
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * version 2 as published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
28 * 02110-1301 USA
29 *
30 */
31
32#include <linux/init.h>
33#include <linux/device.h>
34#include <linux/interrupt.h>
35#include <linux/kernel.h>
36#include <linux/delay.h>
37#include <linux/platform_device.h>
38#include <linux/slab.h>
39#include <linux/i2c/twl.h>
40#include <linux/i2c/twl4030-madc.h>
41#include <linux/module.h>
42#include <linux/stddef.h>
43#include <linux/mutex.h>
44#include <linux/bitops.h>
45#include <linux/jiffies.h>
46#include <linux/types.h>
47#include <linux/gfp.h>
48#include <linux/err.h>
49
50/*
51 * struct twl4030_madc_data - a container for madc info
52 * @dev - pointer to device structure for madc
53 * @lock - mutex protecting this data structure
54 * @requests - Array of request struct corresponding to SW1, SW2 and RT
55 * @imr - Interrupt mask register of MADC
56 * @isr - Interrupt status register of MADC
57 */
58struct twl4030_madc_data {
59 struct device *dev;
60 struct mutex lock; /* mutex protecting this data structure */
61 struct twl4030_madc_request requests[TWL4030_MADC_NUM_METHODS];
62 int imr;
63 int isr;
64};
65
66static struct twl4030_madc_data *twl4030_madc;
67
68struct twl4030_prescale_divider_ratios {
69 s16 numerator;
70 s16 denominator;
71};
72
73static const struct twl4030_prescale_divider_ratios
74twl4030_divider_ratios[16] = {
75 {1, 1}, /* CHANNEL 0 No Prescaler */
76 {1, 1}, /* CHANNEL 1 No Prescaler */
77 {6, 10}, /* CHANNEL 2 */
78 {6, 10}, /* CHANNEL 3 */
79 {6, 10}, /* CHANNEL 4 */
80 {6, 10}, /* CHANNEL 5 */
81 {6, 10}, /* CHANNEL 6 */
82 {6, 10}, /* CHANNEL 7 */
83 {3, 14}, /* CHANNEL 8 */
84 {1, 3}, /* CHANNEL 9 */
85 {1, 1}, /* CHANNEL 10 No Prescaler */
86 {15, 100}, /* CHANNEL 11 */
87 {1, 4}, /* CHANNEL 12 */
88 {1, 1}, /* CHANNEL 13 Reserved channels */
89 {1, 1}, /* CHANNEL 14 Reseved channels */
90 {5, 11}, /* CHANNEL 15 */
91};
92
93
94/*
95 * Conversion table from -3 to 55 degree Celcius
96 */
97static int therm_tbl[] = {
9830800, 29500, 28300, 27100,
9926000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900,
10017200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100,
10111600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310,
1028020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830,
1035640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170,
1044040, 3910, 3790, 3670, 3550
105};
106
107/*
108 * Structure containing the registers
109 * of different conversion methods supported by MADC.
110 * Hardware or RT real time conversion request initiated by external host
111 * processor for RT Signal conversions.
112 * External host processors can also request for non RT conversions
113 * SW1 and SW2 software conversions also called asynchronous or GPC request.
114 */
115static
116const struct twl4030_madc_conversion_method twl4030_conversion_methods[] = {
117 [TWL4030_MADC_RT] = {
118 .sel = TWL4030_MADC_RTSELECT_LSB,
119 .avg = TWL4030_MADC_RTAVERAGE_LSB,
120 .rbase = TWL4030_MADC_RTCH0_LSB,
121 },
122 [TWL4030_MADC_SW1] = {
123 .sel = TWL4030_MADC_SW1SELECT_LSB,
124 .avg = TWL4030_MADC_SW1AVERAGE_LSB,
125 .rbase = TWL4030_MADC_GPCH0_LSB,
126 .ctrl = TWL4030_MADC_CTRL_SW1,
127 },
128 [TWL4030_MADC_SW2] = {
129 .sel = TWL4030_MADC_SW2SELECT_LSB,
130 .avg = TWL4030_MADC_SW2AVERAGE_LSB,
131 .rbase = TWL4030_MADC_GPCH0_LSB,
132 .ctrl = TWL4030_MADC_CTRL_SW2,
133 },
134};
135
136/*
137 * Function to read a particular channel value.
138 * @madc - pointer to struct twl4030_madc_data
139 * @reg - lsb of ADC Channel
140 * If the i2c read fails it returns an error else returns 0.
141 */
142static int twl4030_madc_channel_raw_read(struct twl4030_madc_data *madc, u8 reg)
143{
144 u8 msb, lsb;
145 int ret;
146 /*
147 * For each ADC channel, we have MSB and LSB register pair. MSB address
148 * is always LSB address+1. reg parameter is the address of LSB register
149 */
150 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &msb, reg + 1);
151 if (ret) {
152 dev_err(madc->dev, "unable to read MSB register 0x%X\n",
153 reg + 1);
154 return ret;
155 }
156 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &lsb, reg);
157 if (ret) {
158 dev_err(madc->dev, "unable to read LSB register 0x%X\n", reg);
159 return ret;
160 }
161
162 return (int)(((msb << 8) | lsb) >> 6);
163}
164
165/*
166 * Return battery temperature
167 * Or < 0 on failure.
168 */
169static int twl4030battery_temperature(int raw_volt)
170{
171 u8 val;
172 int temp, curr, volt, res, ret;
173
174 volt = (raw_volt * TEMP_STEP_SIZE) / TEMP_PSR_R;
175 /* Getting and calculating the supply current in micro ampers */
176 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
177 REG_BCICTL2);
178 if (ret < 0)
179 return ret;
180 curr = ((val & TWL4030_BCI_ITHEN) + 1) * 10;
181 /* Getting and calculating the thermistor resistance in ohms */
182 res = volt * 1000 / curr;
183 /* calculating temperature */
184 for (temp = 58; temp >= 0; temp--) {
185 int actual = therm_tbl[temp];
186
187 if ((actual - res) >= 0)
188 break;
189 }
190
191 return temp + 1;
192}
193
194static int twl4030battery_current(int raw_volt)
195{
196 int ret;
197 u8 val;
198
199 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &val,
200 TWL4030_BCI_BCICTL1);
201 if (ret)
202 return ret;
203 if (val & TWL4030_BCI_CGAIN) /* slope of 0.44 mV/mA */
204 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R1;
205 else /* slope of 0.88 mV/mA */
206 return (raw_volt * CURR_STEP_SIZE) / CURR_PSR_R2;
207}
208/*
209 * Function to read channel values
210 * @madc - pointer to twl4030_madc_data struct
211 * @reg_base - Base address of the first channel
212 * @Channels - 16 bit bitmap. If the bit is set, channel value is read
213 * @buf - The channel values are stored here. if read fails error
214 * value is stored
215 * Returns the number of successfully read channels.
216 */
217static int twl4030_madc_read_channels(struct twl4030_madc_data *madc,
218 u8 reg_base, unsigned
219 long channels, int *buf)
220{
221 int count = 0, count_req = 0, i;
222 u8 reg;
223
224 for_each_set_bit(i, &channels, TWL4030_MADC_MAX_CHANNELS) {
225 reg = reg_base + 2 * i;
226 buf[i] = twl4030_madc_channel_raw_read(madc, reg);
227 if (buf[i] < 0) {
228 dev_err(madc->dev,
229 "Unable to read register 0x%X\n", reg);
230 count_req++;
231 continue;
232 }
233 switch (i) {
234 case 10:
235 buf[i] = twl4030battery_current(buf[i]);
236 if (buf[i] < 0) {
237 dev_err(madc->dev, "err reading current\n");
238 count_req++;
239 } else {
240 count++;
241 buf[i] = buf[i] - 750;
242 }
243 break;
244 case 1:
245 buf[i] = twl4030battery_temperature(buf[i]);
246 if (buf[i] < 0) {
247 dev_err(madc->dev, "err reading temperature\n");
248 count_req++;
249 } else {
250 buf[i] -= 3;
251 count++;
252 }
253 break;
254 default:
255 count++;
256 /* Analog Input (V) = conv_result * step_size / R
257 * conv_result = decimal value of 10-bit conversion
258 * result
259 * step size = 1.5 / (2 ^ 10 -1)
260 * R = Prescaler ratio for input channels.
261 * Result given in mV hence multiplied by 1000.
262 */
263 buf[i] = (buf[i] * 3 * 1000 *
264 twl4030_divider_ratios[i].denominator)
265 / (2 * 1023 *
266 twl4030_divider_ratios[i].numerator);
267 }
268 }
269 if (count_req)
270 dev_err(madc->dev, "%d channel conversion failed\n", count_req);
271
272 return count;
273}
274
275/*
276 * Enables irq.
277 * @madc - pointer to twl4030_madc_data struct
278 * @id - irq number to be enabled
279 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
280 * corresponding to RT, SW1, SW2 conversion requests.
281 * If the i2c read fails it returns an error else returns 0.
282 */
283static int twl4030_madc_enable_irq(struct twl4030_madc_data *madc, u8 id)
284{
285 u8 val;
286 int ret;
287
288 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
289 if (ret) {
290 dev_err(madc->dev, "unable to read imr register 0x%X\n",
291 madc->imr);
292 return ret;
293 }
294 val &= ~(1 << id);
295 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
296 if (ret) {
297 dev_err(madc->dev,
298 "unable to write imr register 0x%X\n", madc->imr);
299 return ret;
300
301 }
302
303 return 0;
304}
305
306/*
307 * Disables irq.
308 * @madc - pointer to twl4030_madc_data struct
309 * @id - irq number to be disabled
310 * can take one of TWL4030_MADC_RT, TWL4030_MADC_SW1, TWL4030_MADC_SW2
311 * corresponding to RT, SW1, SW2 conversion requests.
312 * Returns error if i2c read/write fails.
313 */
314static int twl4030_madc_disable_irq(struct twl4030_madc_data *madc, u8 id)
315{
316 u8 val;
317 int ret;
318
319 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &val, madc->imr);
320 if (ret) {
321 dev_err(madc->dev, "unable to read imr register 0x%X\n",
322 madc->imr);
323 return ret;
324 }
325 val |= (1 << id);
326 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, val, madc->imr);
327 if (ret) {
328 dev_err(madc->dev,
329 "unable to write imr register 0x%X\n", madc->imr);
330 return ret;
331 }
332
333 return 0;
334}
335
336static irqreturn_t twl4030_madc_threaded_irq_handler(int irq, void *_madc)
337{
338 struct twl4030_madc_data *madc = _madc;
339 const struct twl4030_madc_conversion_method *method;
340 u8 isr_val, imr_val;
341 int i, len, ret;
342 struct twl4030_madc_request *r;
343
344 mutex_lock(&madc->lock);
345 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &isr_val, madc->isr);
346 if (ret) {
347 dev_err(madc->dev, "unable to read isr register 0x%X\n",
348 madc->isr);
349 goto err_i2c;
350 }
351 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &imr_val, madc->imr);
352 if (ret) {
353 dev_err(madc->dev, "unable to read imr register 0x%X\n",
354 madc->imr);
355 goto err_i2c;
356 }
357 isr_val &= ~imr_val;
358 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
359 if (!(isr_val & (1 << i)))
360 continue;
361 ret = twl4030_madc_disable_irq(madc, i);
362 if (ret < 0)
363 dev_dbg(madc->dev, "Disable interrupt failed%d\n", i);
364 madc->requests[i].result_pending = 1;
365 }
366 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
367 r = &madc->requests[i];
368 /* No pending results for this method, move to next one */
369 if (!r->result_pending)
370 continue;
371 method = &twl4030_conversion_methods[r->method];
372 /* Read results */
373 len = twl4030_madc_read_channels(madc, method->rbase,
374 r->channels, r->rbuf);
375 /* Return results to caller */
376 if (r->func_cb != NULL) {
377 r->func_cb(len, r->channels, r->rbuf);
378 r->func_cb = NULL;
379 }
380 /* Free request */
381 r->result_pending = 0;
382 r->active = 0;
383 }
384 mutex_unlock(&madc->lock);
385
386 return IRQ_HANDLED;
387
388err_i2c:
389 /*
390 * In case of error check whichever request is active
391 * and service the same.
392 */
393 for (i = 0; i < TWL4030_MADC_NUM_METHODS; i++) {
394 r = &madc->requests[i];
395 if (r->active == 0)
396 continue;
397 method = &twl4030_conversion_methods[r->method];
398 /* Read results */
399 len = twl4030_madc_read_channels(madc, method->rbase,
400 r->channels, r->rbuf);
401 /* Return results to caller */
402 if (r->func_cb != NULL) {
403 r->func_cb(len, r->channels, r->rbuf);
404 r->func_cb = NULL;
405 }
406 /* Free request */
407 r->result_pending = 0;
408 r->active = 0;
409 }
410 mutex_unlock(&madc->lock);
411
412 return IRQ_HANDLED;
413}
414
415static int twl4030_madc_set_irq(struct twl4030_madc_data *madc,
416 struct twl4030_madc_request *req)
417{
418 struct twl4030_madc_request *p;
419 int ret;
420
421 p = &madc->requests[req->method];
422 memcpy(p, req, sizeof(*req));
423 ret = twl4030_madc_enable_irq(madc, req->method);
424 if (ret < 0) {
425 dev_err(madc->dev, "enable irq failed!!\n");
426 return ret;
427 }
428
429 return 0;
430}
431
432/*
433 * Function which enables the madc conversion
434 * by writing to the control register.
435 * @madc - pointer to twl4030_madc_data struct
436 * @conv_method - can be TWL4030_MADC_RT, TWL4030_MADC_SW2, TWL4030_MADC_SW1
437 * corresponding to RT SW1 or SW2 conversion methods.
438 * Returns 0 if succeeds else a negative error value
439 */
440static int twl4030_madc_start_conversion(struct twl4030_madc_data *madc,
441 int conv_method)
442{
443 const struct twl4030_madc_conversion_method *method;
444 int ret = 0;
445 method = &twl4030_conversion_methods[conv_method];
446 switch (conv_method) {
447 case TWL4030_MADC_SW1:
448 case TWL4030_MADC_SW2:
449 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
450 TWL4030_MADC_SW_START, method->ctrl);
451 if (ret) {
452 dev_err(madc->dev,
453 "unable to write ctrl register 0x%X\n",
454 method->ctrl);
455 return ret;
456 }
457 break;
458 default:
459 break;
460 }
461
462 return 0;
463}
464
465/*
466 * Function that waits for conversion to be ready
467 * @madc - pointer to twl4030_madc_data struct
468 * @timeout_ms - timeout value in milliseconds
469 * @status_reg - ctrl register
470 * returns 0 if succeeds else a negative error value
471 */
472static int twl4030_madc_wait_conversion_ready(struct twl4030_madc_data *madc,
473 unsigned int timeout_ms,
474 u8 status_reg)
475{
476 unsigned long timeout;
477 int ret;
478
479 timeout = jiffies + msecs_to_jiffies(timeout_ms);
480 do {
481 u8 reg;
482
483 ret = twl_i2c_read_u8(TWL4030_MODULE_MADC, &reg, status_reg);
484 if (ret) {
485 dev_err(madc->dev,
486 "unable to read status register 0x%X\n",
487 status_reg);
488 return ret;
489 }
490 if (!(reg & TWL4030_MADC_BUSY) && (reg & TWL4030_MADC_EOC_SW))
491 return 0;
492 usleep_range(500, 2000);
493 } while (!time_after(jiffies, timeout));
494 dev_err(madc->dev, "conversion timeout!\n");
495
496 return -EAGAIN;
497}
498
499/*
500 * An exported function which can be called from other kernel drivers.
501 * @req twl4030_madc_request structure
502 * req->rbuf will be filled with read values of channels based on the
503 * channel index. If a particular channel reading fails there will
504 * be a negative error value in the corresponding array element.
505 * returns 0 if succeeds else error value
506 */
507int twl4030_madc_conversion(struct twl4030_madc_request *req)
508{
509 const struct twl4030_madc_conversion_method *method;
510 u8 ch_msb, ch_lsb;
511 int ret;
512
513 if (!req)
514 return -EINVAL;
515 mutex_lock(&twl4030_madc->lock);
516 if (req->method < TWL4030_MADC_RT || req->method > TWL4030_MADC_SW2) {
517 ret = -EINVAL;
518 goto out;
519 }
520 /* Do we have a conversion request ongoing */
521 if (twl4030_madc->requests[req->method].active) {
522 ret = -EBUSY;
523 goto out;
524 }
525 ch_msb = (req->channels >> 8) & 0xff;
526 ch_lsb = req->channels & 0xff;
527 method = &twl4030_conversion_methods[req->method];
528 /* Select channels to be converted */
529 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_msb, method->sel + 1);
530 if (ret) {
531 dev_err(twl4030_madc->dev,
532 "unable to write sel register 0x%X\n", method->sel + 1);
533 return ret;
534 }
535 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, ch_lsb, method->sel);
536 if (ret) {
537 dev_err(twl4030_madc->dev,
538 "unable to write sel register 0x%X\n", method->sel + 1);
539 return ret;
540 }
541 /* Select averaging for all channels if do_avg is set */
542 if (req->do_avg) {
543 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
544 ch_msb, method->avg + 1);
545 if (ret) {
546 dev_err(twl4030_madc->dev,
547 "unable to write avg register 0x%X\n",
548 method->avg + 1);
549 return ret;
550 }
551 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC,
552 ch_lsb, method->avg);
553 if (ret) {
554 dev_err(twl4030_madc->dev,
555 "unable to write sel reg 0x%X\n",
556 method->sel + 1);
557 return ret;
558 }
559 }
560 if (req->type == TWL4030_MADC_IRQ_ONESHOT && req->func_cb != NULL) {
561 ret = twl4030_madc_set_irq(twl4030_madc, req);
562 if (ret < 0)
563 goto out;
564 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
565 if (ret < 0)
566 goto out;
567 twl4030_madc->requests[req->method].active = 1;
568 ret = 0;
569 goto out;
570 }
571 /* With RT method we should not be here anymore */
572 if (req->method == TWL4030_MADC_RT) {
573 ret = -EINVAL;
574 goto out;
575 }
576 ret = twl4030_madc_start_conversion(twl4030_madc, req->method);
577 if (ret < 0)
578 goto out;
579 twl4030_madc->requests[req->method].active = 1;
580 /* Wait until conversion is ready (ctrl register returns EOC) */
581 ret = twl4030_madc_wait_conversion_ready(twl4030_madc, 5, method->ctrl);
582 if (ret) {
583 twl4030_madc->requests[req->method].active = 0;
584 goto out;
585 }
586 ret = twl4030_madc_read_channels(twl4030_madc, method->rbase,
587 req->channels, req->rbuf);
588 twl4030_madc->requests[req->method].active = 0;
589
590out:
591 mutex_unlock(&twl4030_madc->lock);
592
593 return ret;
594}
595EXPORT_SYMBOL_GPL(twl4030_madc_conversion);
596
597/*
598 * Return channel value
599 * Or < 0 on failure.
600 */
601int twl4030_get_madc_conversion(int channel_no)
602{
603 struct twl4030_madc_request req;
604 int temp = 0;
605 int ret;
606
607 req.channels = (1 << channel_no);
608 req.method = TWL4030_MADC_SW2;
609 req.active = 0;
610 req.func_cb = NULL;
611 ret = twl4030_madc_conversion(&req);
612 if (ret < 0)
613 return ret;
614 if (req.rbuf[channel_no] > 0)
615 temp = req.rbuf[channel_no];
616
617 return temp;
618}
619EXPORT_SYMBOL_GPL(twl4030_get_madc_conversion);
620
621/*
622 * Function to enable or disable bias current for
623 * main battery type reading or temperature sensing
624 * @madc - pointer to twl4030_madc_data struct
625 * @chan - can be one of the two values
626 * TWL4030_BCI_ITHEN - Enables bias current for main battery type reading
627 * TWL4030_BCI_TYPEN - Enables bias current for main battery temperature
628 * sensing
629 * @on - enable or disable chan.
630 */
631static int twl4030_madc_set_current_generator(struct twl4030_madc_data *madc,
632 int chan, int on)
633{
634 int ret;
635 u8 regval;
636
637 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
638 &regval, TWL4030_BCI_BCICTL1);
639 if (ret) {
640 dev_err(madc->dev, "unable to read BCICTL1 reg 0x%X",
641 TWL4030_BCI_BCICTL1);
642 return ret;
643 }
644 if (on)
645 regval |= chan ? TWL4030_BCI_ITHEN : TWL4030_BCI_TYPEN;
646 else
647 regval &= chan ? ~TWL4030_BCI_ITHEN : ~TWL4030_BCI_TYPEN;
648 ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
649 regval, TWL4030_BCI_BCICTL1);
650 if (ret) {
651 dev_err(madc->dev, "unable to write BCICTL1 reg 0x%X\n",
652 TWL4030_BCI_BCICTL1);
653 return ret;
654 }
655
656 return 0;
657}
658
659/*
660 * Function that sets MADC software power on bit to enable MADC
661 * @madc - pointer to twl4030_madc_data struct
662 * @on - Enable or disable MADC software powen on bit.
663 * returns error if i2c read/write fails else 0
664 */
665static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
666{
667 u8 regval;
668 int ret;
669
670 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
671 &regval, TWL4030_MADC_CTRL1);
672 if (ret) {
673 dev_err(madc->dev, "unable to read madc ctrl1 reg 0x%X\n",
674 TWL4030_MADC_CTRL1);
675 return ret;
676 }
677 if (on)
678 regval |= TWL4030_MADC_MADCON;
679 else
680 regval &= ~TWL4030_MADC_MADCON;
681 ret = twl_i2c_write_u8(TWL4030_MODULE_MADC, regval, TWL4030_MADC_CTRL1);
682 if (ret) {
683 dev_err(madc->dev, "unable to write madc ctrl1 reg 0x%X\n",
684 TWL4030_MADC_CTRL1);
685 return ret;
686 }
687
688 return 0;
689}
690
691/*
692 * Initialize MADC and request for threaded irq
693 */
694static int __devinit twl4030_madc_probe(struct platform_device *pdev)
695{
696 struct twl4030_madc_data *madc;
697 struct twl4030_madc_platform_data *pdata = pdev->dev.platform_data;
698 int ret;
699 u8 regval;
700
701 if (!pdata) {
702 dev_err(&pdev->dev, "platform_data not available\n");
703 return -EINVAL;
704 }
705 madc = kzalloc(sizeof(*madc), GFP_KERNEL);
706 if (!madc)
707 return -ENOMEM;
708
709 /*
710 * Phoenix provides 2 interrupt lines. The first one is connected to
711 * the OMAP. The other one can be connected to the other processor such
712 * as modem. Hence two separate ISR and IMR registers.
713 */
714 madc->imr = (pdata->irq_line == 1) ?
715 TWL4030_MADC_IMR1 : TWL4030_MADC_IMR2;
716 madc->isr = (pdata->irq_line == 1) ?
717 TWL4030_MADC_ISR1 : TWL4030_MADC_ISR2;
718 ret = twl4030_madc_set_power(madc, 1);
719 if (ret < 0)
720 goto err_power;
721 ret = twl4030_madc_set_current_generator(madc, 0, 1);
722 if (ret < 0)
723 goto err_current_generator;
724
725 ret = twl_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE,
726 &regval, TWL4030_BCI_BCICTL1);
727 if (ret) {
728 dev_err(&pdev->dev, "unable to read reg BCI CTL1 0x%X\n",
729 TWL4030_BCI_BCICTL1);
730 goto err_i2c;
731 }
732 regval |= TWL4030_BCI_MESBAT;
733 ret = twl_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE,
734 regval, TWL4030_BCI_BCICTL1);
735 if (ret) {
736 dev_err(&pdev->dev, "unable to write reg BCI Ctl1 0x%X\n",
737 TWL4030_BCI_BCICTL1);
738 goto err_i2c;
739 }
740 platform_set_drvdata(pdev, madc);
741 mutex_init(&madc->lock);
742 ret = request_threaded_irq(platform_get_irq(pdev, 0), NULL,
743 twl4030_madc_threaded_irq_handler,
744 IRQF_TRIGGER_RISING, "twl4030_madc", madc);
745 if (ret) {
746 dev_dbg(&pdev->dev, "could not request irq\n");
747 goto err_irq;
748 }
749 twl4030_madc = madc;
750 return 0;
751err_irq:
752 platform_set_drvdata(pdev, NULL);
753err_i2c:
754 twl4030_madc_set_current_generator(madc, 0, 0);
755err_current_generator:
756 twl4030_madc_set_power(madc, 0);
757err_power:
758 kfree(madc);
759
760 return ret;
761}
762
763static int __devexit twl4030_madc_remove(struct platform_device *pdev)
764{
765 struct twl4030_madc_data *madc = platform_get_drvdata(pdev);
766
767 free_irq(platform_get_irq(pdev, 0), madc);
768 platform_set_drvdata(pdev, NULL);
769 twl4030_madc_set_current_generator(madc, 0, 0);
770 twl4030_madc_set_power(madc, 0);
771 kfree(madc);
772
773 return 0;
774}
775
776static struct platform_driver twl4030_madc_driver = {
777 .probe = twl4030_madc_probe,
778 .remove = __exit_p(twl4030_madc_remove),
779 .driver = {
780 .name = "twl4030_madc",
781 .owner = THIS_MODULE,
782 },
783};
784
785static int __init twl4030_madc_init(void)
786{
787 return platform_driver_register(&twl4030_madc_driver);
788}
789
790module_init(twl4030_madc_init);
791
792static void __exit twl4030_madc_exit(void)
793{
794 platform_driver_unregister(&twl4030_madc_driver);
795}
796
797module_exit(twl4030_madc_exit);
798
799MODULE_DESCRIPTION("TWL4030 ADC driver");
800MODULE_LICENSE("GPL");
801MODULE_AUTHOR("J Keerthy");
802MODULE_ALIAS("platform:twl4030_madc");
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 92b85e28a15e..38ffbd50a0d2 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -60,6 +60,7 @@ static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x
60 input_report_abs(idev, ABS_X, x); 60 input_report_abs(idev, ABS_X, x);
61 input_report_abs(idev, ABS_Y, y); 61 input_report_abs(idev, ABS_Y, y);
62 input_report_abs(idev, ABS_PRESSURE, pressure); 62 input_report_abs(idev, ABS_PRESSURE, pressure);
63 input_report_key(idev, BTN_TOUCH, 1);
63 input_sync(idev); 64 input_sync(idev);
64} 65}
65 66
@@ -68,6 +69,7 @@ static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
68 struct input_dev *idev = ts->idev; 69 struct input_dev *idev = ts->idev;
69 70
70 input_report_abs(idev, ABS_PRESSURE, 0); 71 input_report_abs(idev, ABS_PRESSURE, 0);
72 input_report_key(idev, BTN_TOUCH, 0);
71 input_sync(idev); 73 input_sync(idev);
72} 74}
73 75
@@ -384,7 +386,8 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
384 idev->open = ucb1x00_ts_open; 386 idev->open = ucb1x00_ts_open;
385 idev->close = ucb1x00_ts_close; 387 idev->close = ucb1x00_ts_close;
386 388
387 __set_bit(EV_ABS, idev->evbit); 389 idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY);
390 idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
388 391
389 input_set_drvdata(idev, ts); 392 input_set_drvdata(idev, ts);
390 393
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c
index 348052aa5dbf..d698703dbd46 100644
--- a/drivers/mfd/vx855.c
+++ b/drivers/mfd/vx855.c
@@ -122,6 +122,7 @@ static struct pci_device_id vx855_pci_tbl[] = {
122 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, 122 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
123 { 0, } 123 { 0, }
124}; 124};
125MODULE_DEVICE_TABLE(pci, vx855_pci_tbl);
125 126
126static struct pci_driver vx855_pci_driver = { 127static struct pci_driver vx855_pci_driver = {
127 .name = "vx855", 128 .name = "vx855",
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index d2ecc2435736..529d65ba5353 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -38,7 +38,6 @@ static int wl1273_core_remove(struct i2c_client *client)
38 dev_dbg(&client->dev, "%s\n", __func__); 38 dev_dbg(&client->dev, "%s\n", __func__);
39 39
40 mfd_remove_devices(&client->dev); 40 mfd_remove_devices(&client->dev);
41 i2c_set_clientdata(client, NULL);
42 kfree(core); 41 kfree(core);
43 42
44 return 0; 43 return 0;
@@ -79,8 +78,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
79 78
80 cell = &core->cells[children]; 79 cell = &core->cells[children];
81 cell->name = "wl1273_fm_radio"; 80 cell->name = "wl1273_fm_radio";
82 cell->platform_data = &core; 81 cell->mfd_data = &core;
83 cell->data_size = sizeof(core);
84 children++; 82 children++;
85 83
86 if (pdata->children & WL1273_CODEC_CHILD) { 84 if (pdata->children & WL1273_CODEC_CHILD) {
@@ -88,8 +86,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
88 86
89 dev_dbg(&client->dev, "%s: Have codec.\n", __func__); 87 dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
90 cell->name = "wl1273-codec"; 88 cell->name = "wl1273-codec";
91 cell->platform_data = &core; 89 cell->mfd_data = &core;
92 cell->data_size = sizeof(core);
93 children++; 90 children++;
94 } 91 }
95 92
@@ -104,7 +101,6 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
104 return 0; 101 return 0;
105 102
106err: 103err:
107 i2c_set_clientdata(client, NULL);
108 pdata->free_resources(); 104 pdata->free_resources();
109 kfree(core); 105 kfree(core);
110 106
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index 3853fa8e7cc2..a06cbc739716 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -51,17 +51,25 @@ static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
51 int bytes, void *src) 51 int bytes, void *src)
52{ 52{
53 struct i2c_client *i2c = wm831x->control_data; 53 struct i2c_client *i2c = wm831x->control_data;
54 unsigned char msg[bytes + 2]; 54 struct i2c_msg xfer[2];
55 int ret; 55 int ret;
56 56
57 reg = cpu_to_be16(reg); 57 reg = cpu_to_be16(reg);
58 memcpy(&msg[0], &reg, 2);
59 memcpy(&msg[2], src, bytes);
60 58
61 ret = i2c_master_send(i2c, msg, bytes + 2); 59 xfer[0].addr = i2c->addr;
60 xfer[0].flags = 0;
61 xfer[0].len = 2;
62 xfer[0].buf = (char *)&reg;
63
64 xfer[1].addr = i2c->addr;
65 xfer[1].flags = I2C_M_NOSTART;
66 xfer[1].len = bytes;
67 xfer[1].buf = (char *)src;
68
69 ret = i2c_transfer(i2c->adapter, xfer, 2);
62 if (ret < 0) 70 if (ret < 0)
63 return ret; 71 return ret;
64 if (ret < bytes + 2) 72 if (ret != 2)
65 return -EIO; 73 return -EIO;
66 74
67 return 0; 75 return 0;
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index f7192d438aab..a5cd17e18d09 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -26,15 +26,6 @@
26 26
27#include <linux/delay.h> 27#include <linux/delay.h>
28 28
29/*
30 * Since generic IRQs don't currently support interrupt controllers on
31 * interrupt driven buses we don't use genirq but instead provide an
32 * interface that looks very much like the standard ones. This leads
33 * to some bodges, including storing interrupt handler information in
34 * the static irq_data table we use to look up the data for individual
35 * interrupts, but hopefully won't last too long.
36 */
37
38struct wm831x_irq_data { 29struct wm831x_irq_data {
39 int primary; 30 int primary;
40 int reg; 31 int reg;
@@ -361,6 +352,10 @@ static void wm831x_irq_sync_unlock(struct irq_data *data)
361 /* If there's been a change in the mask write it back 352 /* If there's been a change in the mask write it back
362 * to the hardware. */ 353 * to the hardware. */
363 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { 354 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) {
355 dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n",
356 WM831X_INTERRUPT_STATUS_1_MASK + i,
357 wm831x->irq_masks_cur[i]);
358
364 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; 359 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i];
365 wm831x_reg_write(wm831x, 360 wm831x_reg_write(wm831x,
366 WM831X_INTERRUPT_STATUS_1_MASK + i, 361 WM831X_INTERRUPT_STATUS_1_MASK + i,
@@ -371,7 +366,7 @@ static void wm831x_irq_sync_unlock(struct irq_data *data)
371 mutex_unlock(&wm831x->irq_lock); 366 mutex_unlock(&wm831x->irq_lock);
372} 367}
373 368
374static void wm831x_irq_unmask(struct irq_data *data) 369static void wm831x_irq_enable(struct irq_data *data)
375{ 370{
376 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 371 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
377 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, 372 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
@@ -380,7 +375,7 @@ static void wm831x_irq_unmask(struct irq_data *data)
380 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 375 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
381} 376}
382 377
383static void wm831x_irq_mask(struct irq_data *data) 378static void wm831x_irq_disable(struct irq_data *data)
384{ 379{
385 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 380 struct wm831x *wm831x = irq_data_get_irq_chip_data(data);
386 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, 381 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x,
@@ -426,8 +421,8 @@ static struct irq_chip wm831x_irq_chip = {
426 .name = "wm831x", 421 .name = "wm831x",
427 .irq_bus_lock = wm831x_irq_lock, 422 .irq_bus_lock = wm831x_irq_lock,
428 .irq_bus_sync_unlock = wm831x_irq_sync_unlock, 423 .irq_bus_sync_unlock = wm831x_irq_sync_unlock,
429 .irq_mask = wm831x_irq_mask, 424 .irq_disable = wm831x_irq_disable,
430 .irq_unmask = wm831x_irq_unmask, 425 .irq_enable = wm831x_irq_enable,
431 .irq_set_type = wm831x_irq_set_type, 426 .irq_set_type = wm831x_irq_set_type,
432}; 427};
433 428
@@ -449,6 +444,18 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
449 goto out; 444 goto out;
450 } 445 }
451 446
447 /* The touch interrupts are visible in the primary register as
448 * an optimisation; open code this to avoid complicating the
449 * main handling loop and so we can also skip iterating the
450 * descriptors.
451 */
452 if (primary & WM831X_TCHPD_INT)
453 handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD);
454 if (primary & WM831X_TCHDATA_INT)
455 handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA);
456 if (primary & (WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT))
457 goto out;
458
452 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { 459 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
453 int offset = wm831x_irqs[i].reg - 1; 460 int offset = wm831x_irqs[i].reg - 1;
454 461
@@ -481,6 +488,9 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
481 } 488 }
482 489
483out: 490out:
491 /* Touchscreen interrupts are handled specially in the driver */
492 status_regs[0] &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
493
484 for (i = 0; i < ARRAY_SIZE(status_regs); i++) { 494 for (i = 0; i < ARRAY_SIZE(status_regs); i++) {
485 if (status_regs[i]) 495 if (status_regs[i])
486 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i, 496 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i,
@@ -517,6 +527,14 @@ int wm831x_irq_init(struct wm831x *wm831x, int irq)
517 return 0; 527 return 0;
518 } 528 }
519 529
530 if (pdata->irq_cmos)
531 i = 0;
532 else
533 i = WM831X_IRQ_OD;
534
535 wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG,
536 WM831X_IRQ_OD, i);
537
520 /* Try to flag /IRQ as a wake source; there are a number of 538 /* Try to flag /IRQ as a wake source; there are a number of
521 * unconditional wake sources in the PMIC so this isn't 539 * unconditional wake sources in the PMIC so this isn't
522 * conditional but we don't actually care *too* much if it 540 * conditional but we don't actually care *too* much if it
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 0a8f772be88c..eed8e4f7a5a1 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -14,6 +14,7 @@
14 14
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/pm.h>
17#include <linux/spi/spi.h> 18#include <linux/spi/spi.h>
18 19
19#include <linux/mfd/wm831x/core.h> 20#include <linux/mfd/wm831x/core.h>
@@ -113,22 +114,27 @@ static int __devexit wm831x_spi_remove(struct spi_device *spi)
113 return 0; 114 return 0;
114} 115}
115 116
116static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m) 117static int wm831x_spi_suspend(struct device *dev)
117{ 118{
118 struct wm831x *wm831x = dev_get_drvdata(&spi->dev); 119 struct wm831x *wm831x = dev_get_drvdata(dev);
119 120
120 return wm831x_device_suspend(wm831x); 121 return wm831x_device_suspend(wm831x);
121} 122}
122 123
124static const struct dev_pm_ops wm831x_spi_pm = {
125 .freeze = wm831x_spi_suspend,
126 .suspend = wm831x_spi_suspend,
127};
128
123static struct spi_driver wm8310_spi_driver = { 129static struct spi_driver wm8310_spi_driver = {
124 .driver = { 130 .driver = {
125 .name = "wm8310", 131 .name = "wm8310",
126 .bus = &spi_bus_type, 132 .bus = &spi_bus_type,
127 .owner = THIS_MODULE, 133 .owner = THIS_MODULE,
134 .pm = &wm831x_spi_pm,
128 }, 135 },
129 .probe = wm831x_spi_probe, 136 .probe = wm831x_spi_probe,
130 .remove = __devexit_p(wm831x_spi_remove), 137 .remove = __devexit_p(wm831x_spi_remove),
131 .suspend = wm831x_spi_suspend,
132}; 138};
133 139
134static struct spi_driver wm8311_spi_driver = { 140static struct spi_driver wm8311_spi_driver = {
@@ -136,10 +142,10 @@ static struct spi_driver wm8311_spi_driver = {
136 .name = "wm8311", 142 .name = "wm8311",
137 .bus = &spi_bus_type, 143 .bus = &spi_bus_type,
138 .owner = THIS_MODULE, 144 .owner = THIS_MODULE,
145 .pm = &wm831x_spi_pm,
139 }, 146 },
140 .probe = wm831x_spi_probe, 147 .probe = wm831x_spi_probe,
141 .remove = __devexit_p(wm831x_spi_remove), 148 .remove = __devexit_p(wm831x_spi_remove),
142 .suspend = wm831x_spi_suspend,
143}; 149};
144 150
145static struct spi_driver wm8312_spi_driver = { 151static struct spi_driver wm8312_spi_driver = {
@@ -147,10 +153,10 @@ static struct spi_driver wm8312_spi_driver = {
147 .name = "wm8312", 153 .name = "wm8312",
148 .bus = &spi_bus_type, 154 .bus = &spi_bus_type,
149 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
156 .pm = &wm831x_spi_pm,
150 }, 157 },
151 .probe = wm831x_spi_probe, 158 .probe = wm831x_spi_probe,
152 .remove = __devexit_p(wm831x_spi_remove), 159 .remove = __devexit_p(wm831x_spi_remove),
153 .suspend = wm831x_spi_suspend,
154}; 160};
155 161
156static struct spi_driver wm8320_spi_driver = { 162static struct spi_driver wm8320_spi_driver = {
@@ -158,10 +164,10 @@ static struct spi_driver wm8320_spi_driver = {
158 .name = "wm8320", 164 .name = "wm8320",
159 .bus = &spi_bus_type, 165 .bus = &spi_bus_type,
160 .owner = THIS_MODULE, 166 .owner = THIS_MODULE,
167 .pm = &wm831x_spi_pm,
161 }, 168 },
162 .probe = wm831x_spi_probe, 169 .probe = wm831x_spi_probe,
163 .remove = __devexit_p(wm831x_spi_remove), 170 .remove = __devexit_p(wm831x_spi_remove),
164 .suspend = wm831x_spi_suspend,
165}; 171};
166 172
167static struct spi_driver wm8321_spi_driver = { 173static struct spi_driver wm8321_spi_driver = {
@@ -169,10 +175,10 @@ static struct spi_driver wm8321_spi_driver = {
169 .name = "wm8321", 175 .name = "wm8321",
170 .bus = &spi_bus_type, 176 .bus = &spi_bus_type,
171 .owner = THIS_MODULE, 177 .owner = THIS_MODULE,
178 .pm = &wm831x_spi_pm,
172 }, 179 },
173 .probe = wm831x_spi_probe, 180 .probe = wm831x_spi_probe,
174 .remove = __devexit_p(wm831x_spi_remove), 181 .remove = __devexit_p(wm831x_spi_remove),
175 .suspend = wm831x_spi_suspend,
176}; 182};
177 183
178static struct spi_driver wm8325_spi_driver = { 184static struct spi_driver wm8325_spi_driver = {
@@ -180,10 +186,10 @@ static struct spi_driver wm8325_spi_driver = {
180 .name = "wm8325", 186 .name = "wm8325",
181 .bus = &spi_bus_type, 187 .bus = &spi_bus_type,
182 .owner = THIS_MODULE, 188 .owner = THIS_MODULE,
189 .pm = &wm831x_spi_pm,
183 }, 190 },
184 .probe = wm831x_spi_probe, 191 .probe = wm831x_spi_probe,
185 .remove = __devexit_p(wm831x_spi_remove), 192 .remove = __devexit_p(wm831x_spi_remove),
186 .suspend = wm831x_spi_suspend,
187}; 193};
188 194
189static struct spi_driver wm8326_spi_driver = { 195static struct spi_driver wm8326_spi_driver = {
@@ -191,10 +197,10 @@ static struct spi_driver wm8326_spi_driver = {
191 .name = "wm8326", 197 .name = "wm8326",
192 .bus = &spi_bus_type, 198 .bus = &spi_bus_type,
193 .owner = THIS_MODULE, 199 .owner = THIS_MODULE,
200 .pm = &wm831x_spi_pm,
194 }, 201 },
195 .probe = wm831x_spi_probe, 202 .probe = wm831x_spi_probe,
196 .remove = __devexit_p(wm831x_spi_remove), 203 .remove = __devexit_p(wm831x_spi_remove),
197 .suspend = wm831x_spi_suspend,
198}; 204};
199 205
200static int __init wm831x_spi_init(void) 206static int __init wm831x_spi_init(void)
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 1bfef4846b07..3a6e78cb0384 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -245,7 +245,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400)
245{ 245{
246 struct mfd_cell cell = { 246 struct mfd_cell cell = {
247 .name = "wm8400-codec", 247 .name = "wm8400-codec",
248 .driver_data = wm8400, 248 .mfd_data = wm8400,
249 }; 249 };
250 250
251 return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); 251 return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index f4016a075fd6..e198d40292e7 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -40,10 +40,8 @@ static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
40 return ret; 40 return ret;
41 41
42 for (i = 0; i < bytes / 2; i++) { 42 for (i = 0; i < bytes / 2; i++) {
43 buf[i] = be16_to_cpu(buf[i]);
44
45 dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n", 43 dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
46 buf[i], reg + i, reg + i); 44 be16_to_cpu(buf[i]), reg + i, reg + i);
47 } 45 }
48 46
49 return 0; 47 return 0;
@@ -69,7 +67,7 @@ int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
69 if (ret < 0) 67 if (ret < 0)
70 return ret; 68 return ret;
71 else 69 else
72 return val; 70 return be16_to_cpu(val);
73} 71}
74EXPORT_SYMBOL_GPL(wm8994_reg_read); 72EXPORT_SYMBOL_GPL(wm8994_reg_read);
75 73
@@ -79,7 +77,7 @@ EXPORT_SYMBOL_GPL(wm8994_reg_read);
79 * @wm8994: Device to read from 77 * @wm8994: Device to read from
80 * @reg: First register 78 * @reg: First register
81 * @count: Number of registers 79 * @count: Number of registers
82 * @buf: Buffer to fill. 80 * @buf: Buffer to fill. The data will be returned big endian.
83 */ 81 */
84int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 82int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
85 int count, u16 *buf) 83 int count, u16 *buf)
@@ -97,9 +95,9 @@ int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
97EXPORT_SYMBOL_GPL(wm8994_bulk_read); 95EXPORT_SYMBOL_GPL(wm8994_bulk_read);
98 96
99static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, 97static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
100 int bytes, void *src) 98 int bytes, const void *src)
101{ 99{
102 u16 *buf = src; 100 const u16 *buf = src;
103 int i; 101 int i;
104 102
105 BUG_ON(bytes % 2); 103 BUG_ON(bytes % 2);
@@ -107,9 +105,7 @@ static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
107 105
108 for (i = 0; i < bytes / 2; i++) { 106 for (i = 0; i < bytes / 2; i++) {
109 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n", 107 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
110 buf[i], reg + i, reg + i); 108 be16_to_cpu(buf[i]), reg + i, reg + i);
111
112 buf[i] = cpu_to_be16(buf[i]);
113 } 109 }
114 110
115 return wm8994->write_dev(wm8994, reg, bytes, src); 111 return wm8994->write_dev(wm8994, reg, bytes, src);
@@ -127,6 +123,8 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
127{ 123{
128 int ret; 124 int ret;
129 125
126 val = cpu_to_be16(val);
127
130 mutex_lock(&wm8994->io_lock); 128 mutex_lock(&wm8994->io_lock);
131 129
132 ret = wm8994_write(wm8994, reg, 2, &val); 130 ret = wm8994_write(wm8994, reg, 2, &val);
@@ -138,6 +136,29 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
138EXPORT_SYMBOL_GPL(wm8994_reg_write); 136EXPORT_SYMBOL_GPL(wm8994_reg_write);
139 137
140/** 138/**
139 * wm8994_bulk_write: Write multiple WM8994 registers
140 *
141 * @wm8994: Device to write to
142 * @reg: First register
143 * @count: Number of registers
144 * @buf: Buffer to write from. Data must be big-endian formatted.
145 */
146int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
147 int count, const u16 *buf)
148{
149 int ret;
150
151 mutex_lock(&wm8994->io_lock);
152
153 ret = wm8994_write(wm8994, reg, count * 2, buf);
154
155 mutex_unlock(&wm8994->io_lock);
156
157 return ret;
158}
159EXPORT_SYMBOL_GPL(wm8994_bulk_write);
160
161/**
141 * wm8994_set_bits: Set the value of a bitfield in a WM8994 register 162 * wm8994_set_bits: Set the value of a bitfield in a WM8994 register
142 * 163 *
143 * @wm8994: Device to write to. 164 * @wm8994: Device to write to.
@@ -157,9 +178,13 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
157 if (ret < 0) 178 if (ret < 0)
158 goto out; 179 goto out;
159 180
181 r = be16_to_cpu(r);
182
160 r &= ~mask; 183 r &= ~mask;
161 r |= val; 184 r |= val;
162 185
186 r = cpu_to_be16(r);
187
163 ret = wm8994_write(wm8994, reg, 2, &r); 188 ret = wm8994_write(wm8994, reg, 2, &r);
164 189
165out: 190out:
@@ -271,6 +296,11 @@ static int wm8994_suspend(struct device *dev)
271 if (ret < 0) 296 if (ret < 0)
272 dev_err(dev, "Failed to save LDO registers: %d\n", ret); 297 dev_err(dev, "Failed to save LDO registers: %d\n", ret);
273 298
299 /* Explicitly put the device into reset in case regulators
300 * don't get disabled in order to ensure consistent restart.
301 */
302 wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, 0x8994);
303
274 wm8994->suspended = true; 304 wm8994->suspended = true;
275 305
276 ret = regulator_bulk_disable(wm8994->num_supplies, 306 ret = regulator_bulk_disable(wm8994->num_supplies,
@@ -552,25 +582,29 @@ static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
552 return 0; 582 return 0;
553} 583}
554 584
555/* Currently we allocate the write buffer on the stack; this is OK for
556 * small writes - if we need to do large writes this will need to be
557 * revised.
558 */
559static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, 585static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
560 int bytes, void *src) 586 int bytes, const void *src)
561{ 587{
562 struct i2c_client *i2c = wm8994->control_data; 588 struct i2c_client *i2c = wm8994->control_data;
563 unsigned char msg[bytes + 2]; 589 struct i2c_msg xfer[2];
564 int ret; 590 int ret;
565 591
566 reg = cpu_to_be16(reg); 592 reg = cpu_to_be16(reg);
567 memcpy(&msg[0], &reg, 2);
568 memcpy(&msg[2], src, bytes);
569 593
570 ret = i2c_master_send(i2c, msg, bytes + 2); 594 xfer[0].addr = i2c->addr;
595 xfer[0].flags = 0;
596 xfer[0].len = 2;
597 xfer[0].buf = (char *)&reg;
598
599 xfer[1].addr = i2c->addr;
600 xfer[1].flags = I2C_M_NOSTART;
601 xfer[1].len = bytes;
602 xfer[1].buf = (char *)src;
603
604 ret = i2c_transfer(i2c->adapter, xfer, 2);
571 if (ret < 0) 605 if (ret < 0)
572 return ret; 606 return ret;
573 if (ret < bytes + 2) 607 if (ret != 2)
574 return -EIO; 608 return -EIO;
575 609
576 return 0; 610 return 0;
@@ -612,7 +646,8 @@ static const struct i2c_device_id wm8994_i2c_id[] = {
612}; 646};
613MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); 647MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
614 648
615UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); 649static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume,
650 NULL);
616 651
617static struct i2c_driver wm8994_i2c_driver = { 652static struct i2c_driver wm8994_i2c_driver = {
618 .driver = { 653 .driver = {
diff --git a/drivers/mfd/wm8994-irq.c b/drivers/mfd/wm8994-irq.c
index 29e8faf9c01c..1e3bf4a2ff8e 100644
--- a/drivers/mfd/wm8994-irq.c
+++ b/drivers/mfd/wm8994-irq.c
@@ -182,7 +182,7 @@ static void wm8994_irq_sync_unlock(struct irq_data *data)
182 mutex_unlock(&wm8994->irq_lock); 182 mutex_unlock(&wm8994->irq_lock);
183} 183}
184 184
185static void wm8994_irq_unmask(struct irq_data *data) 185static void wm8994_irq_enable(struct irq_data *data)
186{ 186{
187 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); 187 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
188 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, 188 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994,
@@ -191,7 +191,7 @@ static void wm8994_irq_unmask(struct irq_data *data)
191 wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 191 wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
192} 192}
193 193
194static void wm8994_irq_mask(struct irq_data *data) 194static void wm8994_irq_disable(struct irq_data *data)
195{ 195{
196 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); 196 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data);
197 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, 197 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994,
@@ -204,8 +204,8 @@ static struct irq_chip wm8994_irq_chip = {
204 .name = "wm8994", 204 .name = "wm8994",
205 .irq_bus_lock = wm8994_irq_lock, 205 .irq_bus_lock = wm8994_irq_lock,
206 .irq_bus_sync_unlock = wm8994_irq_sync_unlock, 206 .irq_bus_sync_unlock = wm8994_irq_sync_unlock,
207 .irq_mask = wm8994_irq_mask, 207 .irq_disable = wm8994_irq_disable,
208 .irq_unmask = wm8994_irq_unmask, 208 .irq_enable = wm8994_irq_enable,
209}; 209};
210 210
211/* The processing of the primary interrupt occurs in a thread so that 211/* The processing of the primary interrupt occurs in a thread so that
@@ -225,9 +225,11 @@ static irqreturn_t wm8994_irq_thread(int irq, void *data)
225 return IRQ_NONE; 225 return IRQ_NONE;
226 } 226 }
227 227
228 /* Apply masking */ 228 /* Bit swap and apply masking */
229 for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) 229 for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) {
230 status[i] = be16_to_cpu(status[i]);
230 status[i] &= ~wm8994->irq_masks_cur[i]; 231 status[i] &= ~wm8994->irq_masks_cur[i];
232 }
231 233
232 /* Report */ 234 /* Report */
233 for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) { 235 for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) {