aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/hwmon/twl4030-madc-hwmon45
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c11
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c10
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c10
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c6
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c7
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c7
-rw-r--r--arch/x86/platform/olpc/olpc-xo1.c42
-rw-r--r--drivers/dma/timb_dma.c3
-rw-r--r--drivers/gpio/Kconfig7
-rw-r--r--drivers/gpio/janz-ttl.c3
-rw-r--r--drivers/gpio/rdc321x-gpio.c3
-rw-r--r--drivers/gpio/sch_gpio.c57
-rw-r--r--drivers/gpio/timbgpio.c6
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/jz4740-hwmon.c4
-rw-r--r--drivers/hwmon/twl4030-madc-hwmon.c157
-rw-r--r--drivers/i2c/busses/i2c-ocores.c3
-rw-r--r--drivers/i2c/busses/i2c-xiic.c3
-rw-r--r--drivers/input/misc/88pm860x_onkey.c2
-rw-r--r--drivers/input/misc/twl4030-vibra.c3
-rw-r--r--drivers/leds/leds-88pm860x.c60
-rw-r--r--drivers/leds/leds-mc13783.c7
-rw-r--r--drivers/media/radio/radio-timb.c3
-rw-r--r--drivers/media/radio/radio-wl1273.c2
-rw-r--r--drivers/media/video/timblogiw.c3
-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
-rw-r--r--drivers/mmc/host/tmio_mmc.c34
-rw-r--r--drivers/mtd/nand/tmio_nand.c11
-rw-r--r--drivers/net/can/janz-ican3.c3
-rw-r--r--drivers/net/ks8842.c3
-rw-r--r--drivers/power/jz4740-battery.c4
-rw-r--r--drivers/regulator/88pm8607.c46
-rw-r--r--drivers/regulator/Kconfig18
-rw-r--r--drivers/regulator/Makefile3
-rw-r--r--drivers/regulator/ab3100.c3
-rw-r--r--drivers/regulator/max8997.c1213
-rw-r--r--drivers/regulator/mc13783-regulator.c7
-rw-r--r--drivers/regulator/mc13892-regulator.c7
-rw-r--r--drivers/regulator/tps6105x-regulator.c196
-rw-r--r--drivers/regulator/twl-regulator.c24
-rw-r--r--drivers/spi/xilinx_spi.c3
-rw-r--r--drivers/usb/host/ohci-tmio.c8
-rw-r--r--drivers/video/backlight/88pm860x_bl.c34
-rw-r--r--drivers/video/tmiofb.c28
-rw-r--r--drivers/w1/masters/ds1wm.c13
-rw-r--r--drivers/watchdog/rdc321x_wdt.c3
-rw-r--r--include/linux/i2c/twl.h2
-rw-r--r--include/linux/i2c/twl4030-madc.h141
-rw-r--r--include/linux/mfd/88pm860x.h20
-rw-r--r--include/linux/mfd/ab8500.h4
-rw-r--r--include/linux/mfd/ab8500/gpadc.h32
-rw-r--r--include/linux/mfd/ab8500/sysctrl.h254
-rw-r--r--include/linux/mfd/abx500.h1
-rw-r--r--include/linux/mfd/core.h54
-rw-r--r--include/linux/mfd/max8997-private.h347
-rw-r--r--include/linux/mfd/max8997.h114
-rw-r--r--include/linux/mfd/mc13xxx.h3
-rw-r--r--include/linux/mfd/tps6105x.h101
-rw-r--r--include/linux/mfd/wm831x/pdata.h6
-rw-r--r--include/linux/mfd/wm8994/core.h4
-rw-r--r--include/linux/pci_ids.h1
-rw-r--r--sound/soc/codecs/cq93vc.c3
-rw-r--r--sound/soc/codecs/twl4030.c6
-rw-r--r--sound/soc/codecs/wl1273.c3
-rw-r--r--sound/soc/codecs/wm8400.c3
-rw-r--r--sound/soc/davinci/davinci-vcif.c2
110 files changed, 6059 insertions, 785 deletions
diff --git a/Documentation/hwmon/twl4030-madc-hwmon b/Documentation/hwmon/twl4030-madc-hwmon
new file mode 100644
index 000000000000..ef7984317cec
--- /dev/null
+++ b/Documentation/hwmon/twl4030-madc-hwmon
@@ -0,0 +1,45 @@
1Kernel driver twl4030-madc
2=========================
3
4Supported chips:
5 * Texas Instruments TWL4030
6 Prefix: 'twl4030-madc'
7
8
9Authors:
10 J Keerthy <j-keerthy@ti.com>
11
12Description
13-----------
14
15The Texas Instruments TWL4030 is a Power Management and Audio Circuit. Among
16other things it contains a 10-bit A/D converter MADC. The converter has 16
17channels which can be used in different modes.
18
19
20See this table for the meaning of the different channels
21
22Channel Signal
23------------------------------------------
240 Battery type(BTYPE)
251 BCI: Battery temperature (BTEMP)
262 GP analog input
273 GP analog input
284 GP analog input
295 GP analog input
306 GP analog input
317 GP analog input
328 BCI: VBUS voltage(VBUS)
339 Backup Battery voltage (VBKP)
3410 BCI: Battery charger current (ICHG)
3511 BCI: Battery charger voltage (VCHG)
3612 BCI: Main battery voltage (VBAT)
3713 Reserved
3814 Reserved
3915 VRUSB Supply/Speaker left/Speaker right polarization level
40
41
42The Sysfs nodes will represent the voltage in the units of mV,
43the temperature channel shows the converted temperature in
44degree celcius. The Battery charging current channel represents
45battery charging current in mA.
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 614b3c00c4a0..6e1accf93f81 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -232,10 +232,13 @@ static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
232}; 232};
233 233
234/* MC13783 */ 234/* MC13783 */
235static struct mc13xxx_platform_data mc13783_pdata __initdata = { 235static struct mc13xxx_platform_data mc13783_pdata = {
236 .regulators = mx27_3ds_regulators, 236 .regulators = {
237 .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), 237 .regulators = mx27_3ds_regulators,
238 .flags = MC13XXX_USE_REGULATOR, 238 .num_regulators = ARRAY_SIZE(mx27_3ds_regulators),
239
240 },
241 .flags = MC13783_USE_REGULATOR,
239}; 242};
240 243
241/* SPI */ 244/* SPI */
diff --git a/arch/arm/mach-imx/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 38c77084b615..4cbce6d0fef1 100644
--- a/arch/arm/mach-imx/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -263,10 +263,12 @@ static struct mc13xxx_regulator_init_data pcm038_regulators[] = {
263}; 263};
264 264
265static struct mc13xxx_platform_data pcm038_pmic = { 265static struct mc13xxx_platform_data pcm038_pmic = {
266 .regulators = pcm038_regulators, 266 .regulators = {
267 .num_regulators = ARRAY_SIZE(pcm038_regulators), 267 .regulators = pcm038_regulators,
268 .flags = MC13XXX_USE_ADC | MC13XXX_USE_REGULATOR | 268 .num_regulators = ARRAY_SIZE(pcm038_regulators),
269 MC13XXX_USE_TOUCHSCREEN, 269 },
270 .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR |
271 MC13783_USE_TOUCHSCREEN,
270}; 272};
271 273
272static struct spi_board_info pcm038_spi_board_info[] __initdata = { 274static struct spi_board_info pcm038_spi_board_info[] __initdata = {
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 544d3e414f58..034be624d35c 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -488,10 +488,12 @@ static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
488}; 488};
489 489
490/* MC13783 */ 490/* MC13783 */
491static struct mc13xxx_platform_data mc13783_pdata __initdata = { 491static struct mc13xxx_platform_data mc13783_pdata = {
492 .regulators = mx31_3ds_regulators, 492 .regulators = {
493 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), 493 .regulators = mx31_3ds_regulators,
494 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_TOUCHSCREEN 494 .num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
495 },
496 .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
495}; 497};
496 498
497/* SPI */ 499/* SPI */
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
index 6f3692bccb8a..3a021b01161d 100644
--- a/arch/arm/mach-mx3/mach-mx31moboard.c
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -268,8 +268,10 @@ static struct mc13783_leds_platform_data moboard_leds = {
268}; 268};
269 269
270static struct mc13xxx_platform_data moboard_pmic = { 270static struct mc13xxx_platform_data moboard_pmic = {
271 .regulators = moboard_regulators, 271 .regulators = {
272 .num_regulators = ARRAY_SIZE(moboard_regulators), 272 .regulators = moboard_regulators,
273 .num_regulators = ARRAY_SIZE(moboard_regulators),
274 },
273 .leds = &moboard_leds, 275 .leds = &moboard_leds,
274 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC | 276 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC |
275 MC13XXX_USE_ADC | MC13XXX_USE_LED, 277 MC13XXX_USE_ADC | MC13XXX_USE_LED,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 62c78de1aa51..56702c5e577f 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -550,6 +550,12 @@ static struct regulator_init_data sdp4430_vusb = {
550 }, 550 },
551}; 551};
552 552
553static struct regulator_init_data sdp4430_clk32kg = {
554 .constraints = {
555 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
556 },
557};
558
553static struct twl4030_platform_data sdp4430_twldata = { 559static struct twl4030_platform_data sdp4430_twldata = {
554 .irq_base = TWL6030_IRQ_BASE, 560 .irq_base = TWL6030_IRQ_BASE,
555 .irq_end = TWL6030_IRQ_END, 561 .irq_end = TWL6030_IRQ_END,
@@ -565,6 +571,7 @@ static struct twl4030_platform_data sdp4430_twldata = {
565 .vaux1 = &sdp4430_vaux1, 571 .vaux1 = &sdp4430_vaux1,
566 .vaux2 = &sdp4430_vaux2, 572 .vaux2 = &sdp4430_vaux2,
567 .vaux3 = &sdp4430_vaux3, 573 .vaux3 = &sdp4430_vaux3,
574 .clk32kg = &sdp4430_clk32kg,
568 .usb = &omap4_usbphy_data 575 .usb = &omap4_usbphy_data
569}; 576};
570 577
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index 209cffbee4e0..c936c6d7ded0 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -411,6 +411,12 @@ static struct regulator_init_data omap4_panda_vusb = {
411 }, 411 },
412}; 412};
413 413
414static struct regulator_init_data omap4_panda_clk32kg = {
415 .constraints = {
416 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
417 },
418};
419
414static struct twl4030_platform_data omap4_panda_twldata = { 420static struct twl4030_platform_data omap4_panda_twldata = {
415 .irq_base = TWL6030_IRQ_BASE, 421 .irq_base = TWL6030_IRQ_BASE,
416 .irq_end = TWL6030_IRQ_END, 422 .irq_end = TWL6030_IRQ_END,
@@ -426,6 +432,7 @@ static struct twl4030_platform_data omap4_panda_twldata = {
426 .vaux1 = &omap4_panda_vaux1, 432 .vaux1 = &omap4_panda_vaux1,
427 .vaux2 = &omap4_panda_vaux2, 433 .vaux2 = &omap4_panda_vaux2,
428 .vaux3 = &omap4_panda_vaux3, 434 .vaux3 = &omap4_panda_vaux3,
435 .clk32kg = &omap4_panda_clk32kg,
429 .usb = &omap4_usbphy_data, 436 .usb = &omap4_usbphy_data,
430}; 437};
431 438
diff --git a/arch/x86/platform/olpc/olpc-xo1.c b/arch/x86/platform/olpc/olpc-xo1.c
index 127775696d6c..99513642a0e6 100644
--- a/arch/x86/platform/olpc/olpc-xo1.c
+++ b/arch/x86/platform/olpc/olpc-xo1.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/mfd/core.h>
18 19
19#include <asm/io.h> 20#include <asm/io.h>
20#include <asm/olpc.h> 21#include <asm/olpc.h>
@@ -56,25 +57,24 @@ static void xo1_power_off(void)
56static int __devinit olpc_xo1_probe(struct platform_device *pdev) 57static int __devinit olpc_xo1_probe(struct platform_device *pdev)
57{ 58{
58 struct resource *res; 59 struct resource *res;
60 int err;
59 61
60 /* don't run on non-XOs */ 62 /* don't run on non-XOs */
61 if (!machine_is_olpc()) 63 if (!machine_is_olpc())
62 return -ENODEV; 64 return -ENODEV;
63 65
66 err = mfd_cell_enable(pdev);
67 if (err)
68 return err;
69
64 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 70 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
65 if (!res) { 71 if (!res) {
66 dev_err(&pdev->dev, "can't fetch device resource info\n"); 72 dev_err(&pdev->dev, "can't fetch device resource info\n");
67 return -EIO; 73 return -EIO;
68 } 74 }
69 75 if (strcmp(pdev->name, "olpc-xo1-pms") == 0)
70 if (!request_region(res->start, resource_size(res), DRV_NAME)) {
71 dev_err(&pdev->dev, "can't request region\n");
72 return -EIO;
73 }
74
75 if (strcmp(pdev->name, "cs5535-pms") == 0)
76 pms_base = res->start; 76 pms_base = res->start;
77 else if (strcmp(pdev->name, "cs5535-acpi") == 0) 77 else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0)
78 acpi_base = res->start; 78 acpi_base = res->start;
79 79
80 /* If we have both addresses, we can override the poweroff hook */ 80 /* If we have both addresses, we can override the poweroff hook */
@@ -88,14 +88,11 @@ static int __devinit olpc_xo1_probe(struct platform_device *pdev)
88 88
89static int __devexit olpc_xo1_remove(struct platform_device *pdev) 89static int __devexit olpc_xo1_remove(struct platform_device *pdev)
90{ 90{
91 struct resource *r; 91 mfd_cell_disable(pdev);
92
93 r = platform_get_resource(pdev, IORESOURCE_IO, 0);
94 release_region(r->start, resource_size(r));
95 92
96 if (strcmp(pdev->name, "cs5535-pms") == 0) 93 if (strcmp(pdev->name, "olpc-xo1-pms") == 0)
97 pms_base = 0; 94 pms_base = 0;
98 else if (strcmp(pdev->name, "cs5535-acpi") == 0) 95 else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0)
99 acpi_base = 0; 96 acpi_base = 0;
100 97
101 pm_power_off = NULL; 98 pm_power_off = NULL;
@@ -104,7 +101,7 @@ static int __devexit olpc_xo1_remove(struct platform_device *pdev)
104 101
105static struct platform_driver cs5535_pms_drv = { 102static struct platform_driver cs5535_pms_drv = {
106 .driver = { 103 .driver = {
107 .name = "cs5535-pms", 104 .name = "olpc-xo1-pms",
108 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
109 }, 106 },
110 .probe = olpc_xo1_probe, 107 .probe = olpc_xo1_probe,
@@ -113,7 +110,7 @@ static struct platform_driver cs5535_pms_drv = {
113 110
114static struct platform_driver cs5535_acpi_drv = { 111static struct platform_driver cs5535_acpi_drv = {
115 .driver = { 112 .driver = {
116 .name = "cs5535-acpi", 113 .name = "olpc-xo1-acpi",
117 .owner = THIS_MODULE, 114 .owner = THIS_MODULE,
118 }, 115 },
119 .probe = olpc_xo1_probe, 116 .probe = olpc_xo1_probe,
@@ -124,26 +121,27 @@ static int __init olpc_xo1_init(void)
124{ 121{
125 int r; 122 int r;
126 123
127 r = platform_driver_register(&cs5535_pms_drv); 124 r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms");
128 if (r) 125 if (r)
129 return r; 126 return r;
130 127
131 r = platform_driver_register(&cs5535_acpi_drv); 128 r = mfd_shared_platform_driver_register(&cs5535_acpi_drv,
129 "cs5535-acpi");
132 if (r) 130 if (r)
133 platform_driver_unregister(&cs5535_pms_drv); 131 mfd_shared_platform_driver_unregister(&cs5535_pms_drv);
134 132
135 return r; 133 return r;
136} 134}
137 135
138static void __exit olpc_xo1_exit(void) 136static void __exit olpc_xo1_exit(void)
139{ 137{
140 platform_driver_unregister(&cs5535_acpi_drv); 138 mfd_shared_platform_driver_unregister(&cs5535_acpi_drv);
141 platform_driver_unregister(&cs5535_pms_drv); 139 mfd_shared_platform_driver_unregister(&cs5535_pms_drv);
142} 140}
143 141
144MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); 142MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>");
145MODULE_LICENSE("GPL"); 143MODULE_LICENSE("GPL");
146MODULE_ALIAS("platform:olpc-xo1"); 144MODULE_ALIAS("platform:cs5535-pms");
147 145
148module_init(olpc_xo1_init); 146module_init(olpc_xo1_init);
149module_exit(olpc_xo1_exit); 147module_exit(olpc_xo1_exit);
diff --git a/drivers/dma/timb_dma.c b/drivers/dma/timb_dma.c
index f69f90a61873..d2c75feff7df 100644
--- a/drivers/dma/timb_dma.c
+++ b/drivers/dma/timb_dma.c
@@ -27,6 +27,7 @@
27#include <linux/io.h> 27#include <linux/io.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/mfd/core.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31 32
32#include <linux/timb_dma.h> 33#include <linux/timb_dma.h>
@@ -684,7 +685,7 @@ static irqreturn_t td_irq(int irq, void *devid)
684 685
685static int __devinit td_probe(struct platform_device *pdev) 686static int __devinit td_probe(struct platform_device *pdev)
686{ 687{
687 struct timb_dma_platform_data *pdata = pdev->dev.platform_data; 688 struct timb_dma_platform_data *pdata = mfd_get_data(pdev);
688 struct timb_dma *td; 689 struct timb_dma *td;
689 struct resource *iomem; 690 struct resource *iomem;
690 int irq; 691 int irq;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index b46442d7d66e..d8d0cda2641d 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -100,18 +100,21 @@ config GPIO_VR41XX
100 Say yes here to support the NEC VR4100 series General-purpose I/O Uint 100 Say yes here to support the NEC VR4100 series General-purpose I/O Uint
101 101
102config GPIO_SCH 102config GPIO_SCH
103 tristate "Intel SCH GPIO" 103 tristate "Intel SCH/TunnelCreek GPIO"
104 depends on GPIOLIB && PCI && X86 104 depends on GPIOLIB && PCI && X86
105 select MFD_CORE 105 select MFD_CORE
106 select LPC_SCH 106 select LPC_SCH
107 help 107 help
108 Say yes here to support GPIO interface on Intel Poulsbo SCH. 108 Say yes here to support GPIO interface on Intel Poulsbo SCH
109 or Intel Tunnel Creek processor.
109 The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are 110 The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are
110 powered by the core power rail and are turned off during sleep 111 powered by the core power rail and are turned off during sleep
111 modes (S3 and higher). The remaining four GPIOs are powered by 112 modes (S3 and higher). The remaining four GPIOs are powered by
112 the Intel SCH suspend power supply. These GPIOs remain 113 the Intel SCH suspend power supply. These GPIOs remain
113 active during S3. The suspend powered GPIOs can be used to wake the 114 active during S3. The suspend powered GPIOs can be used to wake the
114 system from the Suspend-to-RAM state. 115 system from the Suspend-to-RAM state.
116 The Intel Tunnel Creek processor has 5 GPIOs powered by the
117 core power rail and 9 from suspend power supply.
115 118
116 This driver can also be built as a module. If so, the module 119 This driver can also be built as a module. If so, the module
117 will be called sch-gpio. 120 will be called sch-gpio.
diff --git a/drivers/gpio/janz-ttl.c b/drivers/gpio/janz-ttl.c
index 813ac077e5d7..2514fb075f4a 100644
--- a/drivers/gpio/janz-ttl.c
+++ b/drivers/gpio/janz-ttl.c
@@ -15,6 +15,7 @@
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h>
18#include <linux/io.h> 19#include <linux/io.h>
19#include <linux/gpio.h> 20#include <linux/gpio.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -149,7 +150,7 @@ static int __devinit ttl_probe(struct platform_device *pdev)
149 struct resource *res; 150 struct resource *res;
150 int ret; 151 int ret;
151 152
152 pdata = pdev->dev.platform_data; 153 pdata = mfd_get_data(pdev);
153 if (!pdata) { 154 if (!pdata) {
154 dev_err(dev, "no platform data\n"); 155 dev_err(dev, "no platform data\n");
155 ret = -ENXIO; 156 ret = -ENXIO;
diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c
index 897e0577e65e..a9bda881935a 100644
--- a/drivers/gpio/rdc321x-gpio.c
+++ b/drivers/gpio/rdc321x-gpio.c
@@ -27,6 +27,7 @@
27#include <linux/pci.h> 27#include <linux/pci.h>
28#include <linux/gpio.h> 28#include <linux/gpio.h>
29#include <linux/mfd/rdc321x.h> 29#include <linux/mfd/rdc321x.h>
30#include <linux/mfd/core.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31 32
32struct rdc321x_gpio { 33struct rdc321x_gpio {
@@ -135,7 +136,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev)
135 struct rdc321x_gpio *rdc321x_gpio_dev; 136 struct rdc321x_gpio *rdc321x_gpio_dev;
136 struct rdc321x_gpio_pdata *pdata; 137 struct rdc321x_gpio_pdata *pdata;
137 138
138 pdata = platform_get_drvdata(pdev); 139 pdata = mfd_get_data(pdev);
139 if (!pdata) { 140 if (!pdata) {
140 dev_err(&pdev->dev, "no platform data supplied\n"); 141 dev_err(&pdev->dev, "no platform data supplied\n");
141 return -ENODEV; 142 return -ENODEV;
diff --git a/drivers/gpio/sch_gpio.c b/drivers/gpio/sch_gpio.c
index 583521352c16..56060421cdff 100644
--- a/drivers/gpio/sch_gpio.c
+++ b/drivers/gpio/sch_gpio.c
@@ -25,6 +25,7 @@
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/acpi.h> 26#include <linux/acpi.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/pci_ids.h>
28 29
29#include <linux/gpio.h> 30#include <linux/gpio.h>
30 31
@@ -187,7 +188,11 @@ static struct gpio_chip sch_gpio_resume = {
187static int __devinit sch_gpio_probe(struct platform_device *pdev) 188static int __devinit sch_gpio_probe(struct platform_device *pdev)
188{ 189{
189 struct resource *res; 190 struct resource *res;
190 int err; 191 int err, id;
192
193 id = pdev->id;
194 if (!id)
195 return -ENODEV;
191 196
192 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 197 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
193 if (!res) 198 if (!res)
@@ -198,12 +203,40 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev)
198 203
199 gpio_ba = res->start; 204 gpio_ba = res->start;
200 205
201 sch_gpio_core.base = 0; 206 switch (id) {
202 sch_gpio_core.ngpio = 10; 207 case PCI_DEVICE_ID_INTEL_SCH_LPC:
203 sch_gpio_core.dev = &pdev->dev; 208 sch_gpio_core.base = 0;
209 sch_gpio_core.ngpio = 10;
210
211 sch_gpio_resume.base = 10;
212 sch_gpio_resume.ngpio = 4;
213
214 /*
215 * GPIO[6:0] enabled by default
216 * GPIO7 is configured by the CMC as SLPIOVR
217 * Enable GPIO[9:8] core powered gpios explicitly
218 */
219 outb(0x3, gpio_ba + CGEN + 1);
220 /*
221 * SUS_GPIO[2:0] enabled by default
222 * Enable SUS_GPIO3 resume powered gpio explicitly
223 */
224 outb(0x8, gpio_ba + RGEN);
225 break;
226
227 case PCI_DEVICE_ID_INTEL_ITC_LPC:
228 sch_gpio_core.base = 0;
229 sch_gpio_core.ngpio = 5;
230
231 sch_gpio_resume.base = 5;
232 sch_gpio_resume.ngpio = 9;
233 break;
234
235 default:
236 return -ENODEV;
237 }
204 238
205 sch_gpio_resume.base = 10; 239 sch_gpio_core.dev = &pdev->dev;
206 sch_gpio_resume.ngpio = 4;
207 sch_gpio_resume.dev = &pdev->dev; 240 sch_gpio_resume.dev = &pdev->dev;
208 241
209 err = gpiochip_add(&sch_gpio_core); 242 err = gpiochip_add(&sch_gpio_core);
@@ -214,18 +247,6 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev)
214 if (err < 0) 247 if (err < 0)
215 goto err_sch_gpio_resume; 248 goto err_sch_gpio_resume;
216 249
217 /*
218 * GPIO[6:0] enabled by default
219 * GPIO7 is configured by the CMC as SLPIOVR
220 * Enable GPIO[9:8] core powered gpios explicitly
221 */
222 outb(0x3, gpio_ba + CGEN + 1);
223 /*
224 * SUS_GPIO[2:0] enabled by default
225 * Enable SUS_GPIO3 resume powered gpio explicitly
226 */
227 outb(0x8, gpio_ba + RGEN);
228
229 return 0; 250 return 0;
230 251
231err_sch_gpio_resume: 252err_sch_gpio_resume:
diff --git a/drivers/gpio/timbgpio.c b/drivers/gpio/timbgpio.c
index 58c8f30352dd..ffcd815b8b8b 100644
--- a/drivers/gpio/timbgpio.c
+++ b/drivers/gpio/timbgpio.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/mfd/core.h>
26#include <linux/irq.h> 27#include <linux/irq.h>
27#include <linux/io.h> 28#include <linux/io.h>
28#include <linux/timb_gpio.h> 29#include <linux/timb_gpio.h>
@@ -228,7 +229,7 @@ static int __devinit timbgpio_probe(struct platform_device *pdev)
228 struct gpio_chip *gc; 229 struct gpio_chip *gc;
229 struct timbgpio *tgpio; 230 struct timbgpio *tgpio;
230 struct resource *iomem; 231 struct resource *iomem;
231 struct timbgpio_platform_data *pdata = pdev->dev.platform_data; 232 struct timbgpio_platform_data *pdata = mfd_get_data(pdev);
232 int irq = platform_get_irq(pdev, 0); 233 int irq = platform_get_irq(pdev, 0);
233 234
234 if (!pdata || pdata->nr_pins > 32) { 235 if (!pdata || pdata->nr_pins > 32) {
@@ -319,14 +320,13 @@ err_mem:
319static int __devexit timbgpio_remove(struct platform_device *pdev) 320static int __devexit timbgpio_remove(struct platform_device *pdev)
320{ 321{
321 int err; 322 int err;
322 struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
323 struct timbgpio *tgpio = platform_get_drvdata(pdev); 323 struct timbgpio *tgpio = platform_get_drvdata(pdev);
324 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 324 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
325 int irq = platform_get_irq(pdev, 0); 325 int irq = platform_get_irq(pdev, 0);
326 326
327 if (irq >= 0 && tgpio->irq_base > 0) { 327 if (irq >= 0 && tgpio->irq_base > 0) {
328 int i; 328 int i;
329 for (i = 0; i < pdata->nr_pins; i++) { 329 for (i = 0; i < tgpio->gpio.ngpio; i++) {
330 set_irq_chip(tgpio->irq_base + i, NULL); 330 set_irq_chip(tgpio->irq_base + i, NULL);
331 set_irq_chip_data(tgpio->irq_base + i, NULL); 331 set_irq_chip_data(tgpio->irq_base + i, NULL);
332 } 332 }
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e4bd13b3cd8b..81131eda5544 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -1047,6 +1047,16 @@ config SENSORS_TMP421
1047 This driver can also be built as a module. If so, the module 1047 This driver can also be built as a module. If so, the module
1048 will be called tmp421. 1048 will be called tmp421.
1049 1049
1050config SENSORS_TWL4030_MADC
1051 tristate "Texas Instruments TWL4030 MADC Hwmon"
1052 depends on TWL4030_MADC
1053 help
1054 If you say yes here you get hwmon support for triton
1055 TWL4030-MADC.
1056
1057 This driver can also be built as a module. If so it will be called
1058 twl4030-madc-hwmon.
1059
1050config SENSORS_VIA_CPUTEMP 1060config SENSORS_VIA_CPUTEMP
1051 tristate "VIA CPU temperature sensor" 1061 tristate "VIA CPU temperature sensor"
1052 depends on X86 1062 depends on X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 54ca5939d028..967d0ea9447f 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
104obj-$(CONFIG_SENSORS_TMP102) += tmp102.o 104obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
105obj-$(CONFIG_SENSORS_TMP401) += tmp401.o 105obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
106obj-$(CONFIG_SENSORS_TMP421) += tmp421.o 106obj-$(CONFIG_SENSORS_TMP421) += tmp421.o
107obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
107obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o 108obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
108obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 109obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
109obj-$(CONFIG_SENSORS_VT1211) += vt1211.o 110obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
diff --git a/drivers/hwmon/jz4740-hwmon.c b/drivers/hwmon/jz4740-hwmon.c
index 1c8b3d9e2051..fea292d43407 100644
--- a/drivers/hwmon/jz4740-hwmon.c
+++ b/drivers/hwmon/jz4740-hwmon.c
@@ -32,7 +32,7 @@ struct jz4740_hwmon {
32 32
33 int irq; 33 int irq;
34 34
35 struct mfd_cell *cell; 35 const struct mfd_cell *cell;
36 struct device *hwmon; 36 struct device *hwmon;
37 37
38 struct completion read_completion; 38 struct completion read_completion;
@@ -112,7 +112,7 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
112 return -ENOMEM; 112 return -ENOMEM;
113 } 113 }
114 114
115 hwmon->cell = pdev->dev.platform_data; 115 hwmon->cell = mfd_get_cell(pdev);
116 116
117 hwmon->irq = platform_get_irq(pdev, 0); 117 hwmon->irq = platform_get_irq(pdev, 0);
118 if (hwmon->irq < 0) { 118 if (hwmon->irq < 0) {
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c
new file mode 100644
index 000000000000..97e22bef85ab
--- /dev/null
+++ b/drivers/hwmon/twl4030-madc-hwmon.c
@@ -0,0 +1,157 @@
1/*
2 *
3 * TWL4030 MADC Hwmon driver-This driver monitors the real time
4 * conversion of analog signals like battery temperature,
5 * battery type, battery level etc. User can ask for the conversion on a
6 * particular channel using the sysfs nodes.
7 *
8 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
9 * J Keerthy <j-keerthy@ti.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/kernel.h>
29#include <linux/i2c/twl.h>
30#include <linux/device.h>
31#include <linux/platform_device.h>
32#include <linux/i2c/twl4030-madc.h>
33#include <linux/hwmon.h>
34#include <linux/hwmon-sysfs.h>
35#include <linux/stddef.h>
36#include <linux/sysfs.h>
37#include <linux/err.h>
38#include <linux/types.h>
39
40/*
41 * sysfs hook function
42 */
43static ssize_t madc_read(struct device *dev,
44 struct device_attribute *devattr, char *buf)
45{
46 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
47 struct twl4030_madc_request req;
48 long val;
49
50 req.channels = (1 << attr->index);
51 req.method = TWL4030_MADC_SW2;
52 req.func_cb = NULL;
53 val = twl4030_madc_conversion(&req);
54 if (val < 0)
55 return val;
56
57 return sprintf(buf, "%d\n", req.rbuf[attr->index]);
58}
59
60/* sysfs nodes to read individual channels from user side */
61static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, madc_read, NULL, 0);
62static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, madc_read, NULL, 1);
63static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, madc_read, NULL, 2);
64static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, madc_read, NULL, 3);
65static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, madc_read, NULL, 4);
66static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, madc_read, NULL, 5);
67static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, madc_read, NULL, 6);
68static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, madc_read, NULL, 7);
69static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, madc_read, NULL, 8);
70static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, madc_read, NULL, 9);
71static SENSOR_DEVICE_ATTR(curr10_input, S_IRUGO, madc_read, NULL, 10);
72static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11);
73static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12);
74static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15);
75
76static struct attribute *twl4030_madc_attributes[] = {
77 &sensor_dev_attr_in0_input.dev_attr.attr,
78 &sensor_dev_attr_temp1_input.dev_attr.attr,
79 &sensor_dev_attr_in2_input.dev_attr.attr,
80 &sensor_dev_attr_in3_input.dev_attr.attr,
81 &sensor_dev_attr_in4_input.dev_attr.attr,
82 &sensor_dev_attr_in5_input.dev_attr.attr,
83 &sensor_dev_attr_in6_input.dev_attr.attr,
84 &sensor_dev_attr_in7_input.dev_attr.attr,
85 &sensor_dev_attr_in8_input.dev_attr.attr,
86 &sensor_dev_attr_in9_input.dev_attr.attr,
87 &sensor_dev_attr_curr10_input.dev_attr.attr,
88 &sensor_dev_attr_in11_input.dev_attr.attr,
89 &sensor_dev_attr_in12_input.dev_attr.attr,
90 &sensor_dev_attr_in15_input.dev_attr.attr,
91 NULL
92};
93
94static const struct attribute_group twl4030_madc_group = {
95 .attrs = twl4030_madc_attributes,
96};
97
98static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev)
99{
100 int ret;
101 int status;
102 struct device *hwmon;
103
104 ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group);
105 if (ret)
106 goto err_sysfs;
107 hwmon = hwmon_device_register(&pdev->dev);
108 if (IS_ERR(hwmon)) {
109 dev_err(&pdev->dev, "hwmon_device_register failed.\n");
110 status = PTR_ERR(hwmon);
111 goto err_reg;
112 }
113
114 return 0;
115
116err_reg:
117 sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
118err_sysfs:
119
120 return ret;
121}
122
123static int __devexit twl4030_madc_hwmon_remove(struct platform_device *pdev)
124{
125 hwmon_device_unregister(&pdev->dev);
126 sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
127
128 return 0;
129}
130
131static struct platform_driver twl4030_madc_hwmon_driver = {
132 .probe = twl4030_madc_hwmon_probe,
133 .remove = __exit_p(twl4030_madc_hwmon_remove),
134 .driver = {
135 .name = "twl4030_madc_hwmon",
136 .owner = THIS_MODULE,
137 },
138};
139
140static int __init twl4030_madc_hwmon_init(void)
141{
142 return platform_driver_register(&twl4030_madc_hwmon_driver);
143}
144
145module_init(twl4030_madc_hwmon_init);
146
147static void __exit twl4030_madc_hwmon_exit(void)
148{
149 platform_driver_unregister(&twl4030_madc_hwmon_driver);
150}
151
152module_exit(twl4030_madc_hwmon_exit);
153
154MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver");
155MODULE_LICENSE("GPL");
156MODULE_AUTHOR("J Keerthy");
157MODULE_ALIAS("twl4030_madc_hwmon");
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 1b46a9d9f907..fee1a2613861 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -49,6 +49,7 @@
49#include <linux/init.h> 49#include <linux/init.h>
50#include <linux/errno.h> 50#include <linux/errno.h>
51#include <linux/platform_device.h> 51#include <linux/platform_device.h>
52#include <linux/mfd/core.h>
52#include <linux/i2c.h> 53#include <linux/i2c.h>
53#include <linux/interrupt.h> 54#include <linux/interrupt.h>
54#include <linux/wait.h> 55#include <linux/wait.h>
@@ -305,7 +306,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
305 return -EIO; 306 return -EIO;
306 } 307 }
307 308
308 pdata = pdev->dev.platform_data; 309 pdata = mfd_get_data(pdev);
309 if (pdata) { 310 if (pdata) {
310 i2c->regstep = pdata->regstep; 311 i2c->regstep = pdata->regstep;
311 i2c->clock_khz = pdata->clock_khz; 312 i2c->clock_khz = pdata->clock_khz;
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index a9c419e075a5..9fbd7e6fe32e 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -34,6 +34,7 @@
34#include <linux/errno.h> 34#include <linux/errno.h>
35#include <linux/delay.h> 35#include <linux/delay.h>
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/mfd/core.h>
37#include <linux/i2c.h> 38#include <linux/i2c.h>
38#include <linux/interrupt.h> 39#include <linux/interrupt.h>
39#include <linux/wait.h> 40#include <linux/wait.h>
@@ -704,7 +705,7 @@ static int __devinit xiic_i2c_probe(struct platform_device *pdev)
704 if (irq < 0) 705 if (irq < 0)
705 goto resource_missing; 706 goto resource_missing;
706 707
707 pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data; 708 pdata = mfd_get_data(pdev);
708 if (!pdata) 709 if (!pdata)
709 return -EINVAL; 710 return -EINVAL;
710 711
diff --git a/drivers/input/misc/88pm860x_onkey.c b/drivers/input/misc/88pm860x_onkey.c
index 4cc82826ea6b..3dca3c14510e 100644
--- a/drivers/input/misc/88pm860x_onkey.c
+++ b/drivers/input/misc/88pm860x_onkey.c
@@ -74,7 +74,7 @@ static int __devinit pm860x_onkey_probe(struct platform_device *pdev)
74 info->chip = chip; 74 info->chip = chip;
75 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 75 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
76 info->dev = &pdev->dev; 76 info->dev = &pdev->dev;
77 info->irq = irq + chip->irq_base; 77 info->irq = irq;
78 78
79 info->idev = input_allocate_device(); 79 info->idev = input_allocate_device();
80 if (!info->idev) { 80 if (!info->idev) {
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index 014dd4ad0d4f..6a11694e3fc7 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -29,6 +29,7 @@
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <linux/i2c/twl.h> 30#include <linux/i2c/twl.h>
31#include <linux/mfd/twl4030-codec.h> 31#include <linux/mfd/twl4030-codec.h>
32#include <linux/mfd/core.h>
32#include <linux/input.h> 33#include <linux/input.h>
33#include <linux/slab.h> 34#include <linux/slab.h>
34 35
@@ -196,7 +197,7 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
196 197
197static int __devinit twl4030_vibra_probe(struct platform_device *pdev) 198static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
198{ 199{
199 struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; 200 struct twl4030_codec_vibra_data *pdata = mfd_get_data(pdev);
200 struct vibra_info *info; 201 struct vibra_info *info;
201 int ret; 202 int ret;
202 203
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index e672b44ee172..416def84d045 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -17,6 +17,7 @@
17#include <linux/leds.h> 17#include <linux/leds.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/workqueue.h> 19#include <linux/workqueue.h>
20#include <linux/mfd/core.h>
20#include <linux/mfd/88pm860x.h> 21#include <linux/mfd/88pm860x.h>
21 22
22#define LED_PWM_SHIFT (3) 23#define LED_PWM_SHIFT (3)
@@ -118,7 +119,8 @@ static void pm860x_led_work(struct work_struct *work)
118 119
119 struct pm860x_led *led; 120 struct pm860x_led *led;
120 struct pm860x_chip *chip; 121 struct pm860x_chip *chip;
121 int mask; 122 unsigned char buf[3];
123 int mask, ret;
122 124
123 led = container_of(work, struct pm860x_led, work); 125 led = container_of(work, struct pm860x_led, work);
124 chip = led->chip; 126 chip = led->chip;
@@ -128,16 +130,27 @@ static void pm860x_led_work(struct work_struct *work)
128 pm860x_set_bits(led->i2c, __led_off(led->port), 130 pm860x_set_bits(led->i2c, __led_off(led->port),
129 LED_CURRENT_MASK, led->iset); 131 LED_CURRENT_MASK, led->iset);
130 } 132 }
133 pm860x_set_bits(led->i2c, __blink_off(led->port),
134 LED_BLINK_MASK, LED_ON_CONTINUOUS);
131 mask = __blink_ctl_mask(led->port); 135 mask = __blink_ctl_mask(led->port);
132 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask); 136 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
133 } else if (led->brightness == 0) {
134 pm860x_set_bits(led->i2c, __led_off(led->port),
135 LED_CURRENT_MASK, 0);
136 mask = __blink_ctl_mask(led->port);
137 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
138 } 137 }
139 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK, 138 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK,
140 led->brightness); 139 led->brightness);
140
141 if (led->brightness == 0) {
142 pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf);
143 ret = buf[0] & LED_PWM_MASK;
144 ret |= buf[1] & LED_PWM_MASK;
145 ret |= buf[2] & LED_PWM_MASK;
146 if (ret == 0) {
147 /* unset current since no led is lighting */
148 pm860x_set_bits(led->i2c, __led_off(led->port),
149 LED_CURRENT_MASK, 0);
150 mask = __blink_ctl_mask(led->port);
151 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
152 }
153 }
141 led->current_brightness = led->brightness; 154 led->current_brightness = led->brightness;
142 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 155 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
143 __led_off(led->port), led->brightness); 156 __led_off(led->port), led->brightness);
@@ -153,31 +166,12 @@ static void pm860x_led_set(struct led_classdev *cdev,
153 schedule_work(&data->work); 166 schedule_work(&data->work);
154} 167}
155 168
156static int __check_device(struct pm860x_led_pdata *pdata, char *name)
157{
158 struct pm860x_led_pdata *p = pdata;
159 int ret = -EINVAL;
160
161 while (p && p->id) {
162 if ((p->id != PM8606_ID_LED) || (p->flags < 0))
163 break;
164
165 if (!strncmp(name, pm860x_led_name[p->flags],
166 MFD_NAME_SIZE)) {
167 ret = (int)p->flags;
168 break;
169 }
170 p++;
171 }
172 return ret;
173}
174
175static int pm860x_led_probe(struct platform_device *pdev) 169static int pm860x_led_probe(struct platform_device *pdev)
176{ 170{
177 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 171 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
178 struct pm860x_platform_data *pm860x_pdata;
179 struct pm860x_led_pdata *pdata; 172 struct pm860x_led_pdata *pdata;
180 struct pm860x_led *data; 173 struct pm860x_led *data;
174 struct mfd_cell *cell;
181 struct resource *res; 175 struct resource *res;
182 int ret; 176 int ret;
183 177
@@ -187,10 +181,11 @@ static int pm860x_led_probe(struct platform_device *pdev)
187 return -EINVAL; 181 return -EINVAL;
188 } 182 }
189 183
190 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
191 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
192 pdata = pm860x_pdata->led; 186 return -ENODEV;
193 } else { 187 pdata = cell->mfd_data;
188 if (pdata == NULL) {
194 dev_err(&pdev->dev, "No platform data!\n"); 189 dev_err(&pdev->dev, "No platform data!\n");
195 return -EINVAL; 190 return -EINVAL;
196 } 191 }
@@ -198,12 +193,12 @@ static int pm860x_led_probe(struct platform_device *pdev)
198 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); 193 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL);
199 if (data == NULL) 194 if (data == NULL)
200 return -ENOMEM; 195 return -ENOMEM;
201 strncpy(data->name, res->name, MFD_NAME_SIZE); 196 strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
202 dev_set_drvdata(&pdev->dev, data); 197 dev_set_drvdata(&pdev->dev, data);
203 data->chip = chip; 198 data->chip = chip;
204 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 199 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
205 data->iset = pdata->iset; 200 data->iset = pdata->iset;
206 data->port = __check_device(pdata, data->name); 201 data->port = pdata->flags;
207 if (data->port < 0) { 202 if (data->port < 0) {
208 dev_err(&pdev->dev, "check device failed\n"); 203 dev_err(&pdev->dev, "check device failed\n");
209 kfree(data); 204 kfree(data);
@@ -221,6 +216,7 @@ static int pm860x_led_probe(struct platform_device *pdev)
221 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 216 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
222 goto out; 217 goto out;
223 } 218 }
219 pm860x_led_set(&data->cdev, 0);
224 return 0; 220 return 0;
225out: 221out:
226 kfree(data); 222 kfree(data);
diff --git a/drivers/leds/leds-mc13783.c b/drivers/leds/leds-mc13783.c
index f05bb08d0f09..06a5bb484707 100644
--- a/drivers/leds/leds-mc13783.c
+++ b/drivers/leds/leds-mc13783.c
@@ -22,6 +22,7 @@
22#include <linux/leds.h> 22#include <linux/leds.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <linux/mfd/mc13783.h> 24#include <linux/mfd/mc13783.h>
25#include <linux/mfd/core.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26 27
27struct mc13783_led { 28struct mc13783_led {
@@ -183,7 +184,7 @@ static int __devinit mc13783_led_setup(struct mc13783_led *led, int max_current)
183 184
184static int __devinit mc13783_leds_prepare(struct platform_device *pdev) 185static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
185{ 186{
186 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 187 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
187 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 188 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
188 int ret = 0; 189 int ret = 0;
189 int reg = 0; 190 int reg = 0;
@@ -264,7 +265,7 @@ out:
264 265
265static int __devinit mc13783_led_probe(struct platform_device *pdev) 266static int __devinit mc13783_led_probe(struct platform_device *pdev)
266{ 267{
267 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 268 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
268 struct mc13783_led_platform_data *led_cur; 269 struct mc13783_led_platform_data *led_cur;
269 struct mc13783_led *led, *led_dat; 270 struct mc13783_led *led, *led_dat;
270 int ret, i; 271 int ret, i;
@@ -351,7 +352,7 @@ err_free:
351 352
352static int __devexit mc13783_led_remove(struct platform_device *pdev) 353static int __devexit mc13783_led_remove(struct platform_device *pdev)
353{ 354{
354 struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 355 struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
355 struct mc13783_led *led = platform_get_drvdata(pdev); 356 struct mc13783_led *led = platform_get_drvdata(pdev);
356 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 357 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
357 int i; 358 int i;
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c
index a185610b376b..1e3a8dd820a4 100644
--- a/drivers/media/radio/radio-timb.c
+++ b/drivers/media/radio/radio-timb.c
@@ -21,6 +21,7 @@
21#include <media/v4l2-ioctl.h> 21#include <media/v4l2-ioctl.h>
22#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/mfd/core.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/i2c.h> 27#include <linux/i2c.h>
@@ -148,7 +149,7 @@ static const struct v4l2_file_operations timbradio_fops = {
148 149
149static int __devinit timbradio_probe(struct platform_device *pdev) 150static int __devinit timbradio_probe(struct platform_device *pdev)
150{ 151{
151 struct timb_radio_platform_data *pdata = pdev->dev.platform_data; 152 struct timb_radio_platform_data *pdata = mfd_get_data(pdev);
152 struct timbradio *tr; 153 struct timbradio *tr;
153 int err; 154 int err;
154 155
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 7ecc8e657663..4698eb00b59f 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -2138,7 +2138,7 @@ static int wl1273_fm_radio_remove(struct platform_device *pdev)
2138 2138
2139static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev) 2139static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
2140{ 2140{
2141 struct wl1273_core **core = pdev->dev.platform_data; 2141 struct wl1273_core **core = mfd_get_data(pdev);
2142 struct wl1273_device *radio; 2142 struct wl1273_device *radio;
2143 struct v4l2_ctrl *ctrl; 2143 struct v4l2_ctrl *ctrl;
2144 int r = 0; 2144 int r = 0;
diff --git a/drivers/media/video/timblogiw.c b/drivers/media/video/timblogiw.c
index fc611ebeb82c..84d4c7c83435 100644
--- a/drivers/media/video/timblogiw.c
+++ b/drivers/media/video/timblogiw.c
@@ -24,6 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/dmaengine.h> 26#include <linux/dmaengine.h>
27#include <linux/mfd/core.h>
27#include <linux/scatterlist.h> 28#include <linux/scatterlist.h>
28#include <linux/interrupt.h> 29#include <linux/interrupt.h>
29#include <linux/list.h> 30#include <linux/list.h>
@@ -790,7 +791,7 @@ static int __devinit timblogiw_probe(struct platform_device *pdev)
790{ 791{
791 int err; 792 int err;
792 struct timblogiw *lw = NULL; 793 struct timblogiw *lw = NULL;
793 struct timb_video_platform_data *pdata = pdev->dev.platform_data; 794 struct timb_video_platform_data *pdata = mfd_get_data(pdev);
794 795
795 if (!pdata) { 796 if (!pdata) {
796 dev_err(&pdev->dev, "No platform data\n"); 797 dev_err(&pdev->dev, "No platform data\n");
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++) {
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index ac52eb65395e..ab1adeabdd22 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -303,8 +303,7 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
303 303
304static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 304static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
305{ 305{
306 struct mfd_cell *cell = host->pdev->dev.platform_data; 306 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
307 struct tmio_mmc_data *pdata = cell->driver_data;
308 307
309 /* 308 /*
310 * Testing on sh-mobile showed that SDIO IRQs are unmasked when 309 * Testing on sh-mobile showed that SDIO IRQs are unmasked when
@@ -327,8 +326,7 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
327 326
328static void tmio_mmc_clk_start(struct tmio_mmc_host *host) 327static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
329{ 328{
330 struct mfd_cell *cell = host->pdev->dev.platform_data; 329 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
331 struct tmio_mmc_data *pdata = cell->driver_data;
332 330
333 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | 331 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
334 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); 332 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
@@ -669,8 +667,7 @@ out:
669static irqreturn_t tmio_mmc_irq(int irq, void *devid) 667static irqreturn_t tmio_mmc_irq(int irq, void *devid)
670{ 668{
671 struct tmio_mmc_host *host = devid; 669 struct tmio_mmc_host *host = devid;
672 struct mfd_cell *cell = host->pdev->dev.platform_data; 670 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
673 struct tmio_mmc_data *pdata = cell->driver_data;
674 unsigned int ireg, irq_mask, status; 671 unsigned int ireg, irq_mask, status;
675 unsigned int sdio_ireg, sdio_irq_mask, sdio_status; 672 unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
676 673
@@ -799,8 +796,7 @@ static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
799 struct scatterlist *sg = host->sg_ptr, *sg_tmp; 796 struct scatterlist *sg = host->sg_ptr, *sg_tmp;
800 struct dma_async_tx_descriptor *desc = NULL; 797 struct dma_async_tx_descriptor *desc = NULL;
801 struct dma_chan *chan = host->chan_rx; 798 struct dma_chan *chan = host->chan_rx;
802 struct mfd_cell *cell = host->pdev->dev.platform_data; 799 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
803 struct tmio_mmc_data *pdata = cell->driver_data;
804 dma_cookie_t cookie; 800 dma_cookie_t cookie;
805 int ret, i; 801 int ret, i;
806 bool aligned = true, multiple = true; 802 bool aligned = true, multiple = true;
@@ -869,8 +865,7 @@ static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
869 struct scatterlist *sg = host->sg_ptr, *sg_tmp; 865 struct scatterlist *sg = host->sg_ptr, *sg_tmp;
870 struct dma_async_tx_descriptor *desc = NULL; 866 struct dma_async_tx_descriptor *desc = NULL;
871 struct dma_chan *chan = host->chan_tx; 867 struct dma_chan *chan = host->chan_tx;
872 struct mfd_cell *cell = host->pdev->dev.platform_data; 868 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
873 struct tmio_mmc_data *pdata = cell->driver_data;
874 dma_cookie_t cookie; 869 dma_cookie_t cookie;
875 int ret, i; 870 int ret, i;
876 bool aligned = true, multiple = true; 871 bool aligned = true, multiple = true;
@@ -1063,8 +1058,7 @@ static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
1063static int tmio_mmc_start_data(struct tmio_mmc_host *host, 1058static int tmio_mmc_start_data(struct tmio_mmc_host *host,
1064 struct mmc_data *data) 1059 struct mmc_data *data)
1065{ 1060{
1066 struct mfd_cell *cell = host->pdev->dev.platform_data; 1061 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
1067 struct tmio_mmc_data *pdata = cell->driver_data;
1068 1062
1069 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", 1063 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
1070 data->blksz, data->blocks); 1064 data->blksz, data->blocks);
@@ -1169,8 +1163,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
1169static int tmio_mmc_get_ro(struct mmc_host *mmc) 1163static int tmio_mmc_get_ro(struct mmc_host *mmc)
1170{ 1164{
1171 struct tmio_mmc_host *host = mmc_priv(mmc); 1165 struct tmio_mmc_host *host = mmc_priv(mmc);
1172 struct mfd_cell *cell = host->pdev->dev.platform_data; 1166 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
1173 struct tmio_mmc_data *pdata = cell->driver_data;
1174 1167
1175 return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || 1168 return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
1176 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1; 1169 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1;
@@ -1179,8 +1172,7 @@ static int tmio_mmc_get_ro(struct mmc_host *mmc)
1179static int tmio_mmc_get_cd(struct mmc_host *mmc) 1172static int tmio_mmc_get_cd(struct mmc_host *mmc)
1180{ 1173{
1181 struct tmio_mmc_host *host = mmc_priv(mmc); 1174 struct tmio_mmc_host *host = mmc_priv(mmc);
1182 struct mfd_cell *cell = host->pdev->dev.platform_data; 1175 struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
1183 struct tmio_mmc_data *pdata = cell->driver_data;
1184 1176
1185 if (!pdata->get_cd) 1177 if (!pdata->get_cd)
1186 return -ENOSYS; 1178 return -ENOSYS;
@@ -1199,7 +1191,7 @@ static const struct mmc_host_ops tmio_mmc_ops = {
1199#ifdef CONFIG_PM 1191#ifdef CONFIG_PM
1200static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) 1192static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
1201{ 1193{
1202 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1194 const struct mfd_cell *cell = mfd_get_cell(dev);
1203 struct mmc_host *mmc = platform_get_drvdata(dev); 1195 struct mmc_host *mmc = platform_get_drvdata(dev);
1204 int ret; 1196 int ret;
1205 1197
@@ -1214,7 +1206,7 @@ static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
1214 1206
1215static int tmio_mmc_resume(struct platform_device *dev) 1207static int tmio_mmc_resume(struct platform_device *dev)
1216{ 1208{
1217 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1209 const struct mfd_cell *cell = mfd_get_cell(dev);
1218 struct mmc_host *mmc = platform_get_drvdata(dev); 1210 struct mmc_host *mmc = platform_get_drvdata(dev);
1219 int ret = 0; 1211 int ret = 0;
1220 1212
@@ -1237,7 +1229,7 @@ out:
1237 1229
1238static int __devinit tmio_mmc_probe(struct platform_device *dev) 1230static int __devinit tmio_mmc_probe(struct platform_device *dev)
1239{ 1231{
1240 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1232 const struct mfd_cell *cell = mfd_get_cell(dev);
1241 struct tmio_mmc_data *pdata; 1233 struct tmio_mmc_data *pdata;
1242 struct resource *res_ctl; 1234 struct resource *res_ctl;
1243 struct tmio_mmc_host *host; 1235 struct tmio_mmc_host *host;
@@ -1252,7 +1244,7 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
1252 if (!res_ctl) 1244 if (!res_ctl)
1253 goto out; 1245 goto out;
1254 1246
1255 pdata = cell->driver_data; 1247 pdata = mfd_get_data(dev);
1256 if (!pdata || !pdata->hclk) 1248 if (!pdata || !pdata->hclk)
1257 goto out; 1249 goto out;
1258 1250
@@ -1352,7 +1344,7 @@ out:
1352 1344
1353static int __devexit tmio_mmc_remove(struct platform_device *dev) 1345static int __devexit tmio_mmc_remove(struct platform_device *dev)
1354{ 1346{
1355 struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1347 const struct mfd_cell *cell = mfd_get_cell(dev);
1356 struct mmc_host *mmc = platform_get_drvdata(dev); 1348 struct mmc_host *mmc = platform_get_drvdata(dev);
1357 1349
1358 platform_set_drvdata(dev, NULL); 1350 platform_set_drvdata(dev, NULL);
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c
index 3041d1f7ae3f..38fb16771f85 100644
--- a/drivers/mtd/nand/tmio_nand.c
+++ b/drivers/mtd/nand/tmio_nand.c
@@ -319,7 +319,7 @@ static int tmio_nand_correct_data(struct mtd_info *mtd, unsigned char *buf,
319 319
320static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio) 320static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
321{ 321{
322 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 322 const struct mfd_cell *cell = mfd_get_cell(dev);
323 int ret; 323 int ret;
324 324
325 if (cell->enable) { 325 if (cell->enable) {
@@ -363,7 +363,7 @@ static int tmio_hw_init(struct platform_device *dev, struct tmio_nand *tmio)
363 363
364static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio) 364static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
365{ 365{
366 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 366 const struct mfd_cell *cell = mfd_get_cell(dev);
367 367
368 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE); 368 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE);
369 if (cell->disable) 369 if (cell->disable)
@@ -372,8 +372,7 @@ static void tmio_hw_stop(struct platform_device *dev, struct tmio_nand *tmio)
372 372
373static int tmio_probe(struct platform_device *dev) 373static int tmio_probe(struct platform_device *dev)
374{ 374{
375 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 375 struct tmio_nand_data *data = mfd_get_data(dev);
376 struct tmio_nand_data *data = cell->driver_data;
377 struct resource *fcr = platform_get_resource(dev, 376 struct resource *fcr = platform_get_resource(dev,
378 IORESOURCE_MEM, 0); 377 IORESOURCE_MEM, 0);
379 struct resource *ccr = platform_get_resource(dev, 378 struct resource *ccr = platform_get_resource(dev,
@@ -516,7 +515,7 @@ static int tmio_remove(struct platform_device *dev)
516#ifdef CONFIG_PM 515#ifdef CONFIG_PM
517static int tmio_suspend(struct platform_device *dev, pm_message_t state) 516static int tmio_suspend(struct platform_device *dev, pm_message_t state)
518{ 517{
519 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 518 const struct mfd_cell *cell = mfd_get_cell(dev);
520 519
521 if (cell->suspend) 520 if (cell->suspend)
522 cell->suspend(dev); 521 cell->suspend(dev);
@@ -527,7 +526,7 @@ static int tmio_suspend(struct platform_device *dev, pm_message_t state)
527 526
528static int tmio_resume(struct platform_device *dev) 527static int tmio_resume(struct platform_device *dev)
529{ 528{
530 struct mfd_cell *cell = dev_get_platdata(&dev->dev); 529 const struct mfd_cell *cell = mfd_get_cell(dev);
531 530
532 /* FIXME - is this required or merely another attack of the broken 531 /* FIXME - is this required or merely another attack of the broken
533 * SHARP platform? Looks suspicious. 532 * SHARP platform? Looks suspicious.
diff --git a/drivers/net/can/janz-ican3.c b/drivers/net/can/janz-ican3.c
index 366f5cc050ae..102b16c6cc97 100644
--- a/drivers/net/can/janz-ican3.c
+++ b/drivers/net/can/janz-ican3.c
@@ -15,6 +15,7 @@
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/mfd/core.h>
18 19
19#include <linux/netdevice.h> 20#include <linux/netdevice.h>
20#include <linux/can.h> 21#include <linux/can.h>
@@ -1643,7 +1644,7 @@ static int __devinit ican3_probe(struct platform_device *pdev)
1643 struct device *dev; 1644 struct device *dev;
1644 int ret; 1645 int ret;
1645 1646
1646 pdata = pdev->dev.platform_data; 1647 pdata = mfd_get_data(pdev);
1647 if (!pdata) 1648 if (!pdata)
1648 return -ENXIO; 1649 return -ENXIO;
1649 1650
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
index 928b2b83cef5..efd44afeae83 100644
--- a/drivers/net/ks8842.c
+++ b/drivers/net/ks8842.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/mfd/core.h>
29#include <linux/netdevice.h> 30#include <linux/netdevice.h>
30#include <linux/etherdevice.h> 31#include <linux/etherdevice.h>
31#include <linux/ethtool.h> 32#include <linux/ethtool.h>
@@ -1145,7 +1146,7 @@ static int __devinit ks8842_probe(struct platform_device *pdev)
1145 struct resource *iomem; 1146 struct resource *iomem;
1146 struct net_device *netdev; 1147 struct net_device *netdev;
1147 struct ks8842_adapter *adapter; 1148 struct ks8842_adapter *adapter;
1148 struct ks8842_platform_data *pdata = pdev->dev.platform_data; 1149 struct ks8842_platform_data *pdata = mfd_get_data(pdev);
1149 u16 id; 1150 u16 id;
1150 unsigned i; 1151 unsigned i;
1151 1152
diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c
index 02414db6a94c..763f894ed188 100644
--- a/drivers/power/jz4740-battery.c
+++ b/drivers/power/jz4740-battery.c
@@ -39,7 +39,7 @@ struct jz_battery {
39 int irq; 39 int irq;
40 int charge_irq; 40 int charge_irq;
41 41
42 struct mfd_cell *cell; 42 const struct mfd_cell *cell;
43 43
44 int status; 44 int status;
45 long voltage; 45 long voltage;
@@ -258,7 +258,7 @@ static int __devinit jz_battery_probe(struct platform_device *pdev)
258 return -ENOMEM; 258 return -ENOMEM;
259 } 259 }
260 260
261 jz_battery->cell = pdev->dev.platform_data; 261 jz_battery->cell = mfd_get_cell(pdev);
262 262
263 jz_battery->irq = platform_get_irq(pdev, 0); 263 jz_battery->irq = platform_get_irq(pdev, 0);
264 if (jz_battery->irq < 0) { 264 if (jz_battery->irq < 0) {
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index dd6308499bd4..859251250b55 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -15,6 +15,7 @@
15#include <linux/platform_device.h> 15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h> 16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h> 17#include <linux/regulator/machine.h>
18#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 19#include <linux/mfd/88pm860x.h>
19 20
20struct pm8607_regulator_info { 21struct pm8607_regulator_info {
@@ -394,47 +395,48 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
394 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), 395 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6),
395}; 396};
396 397
397static inline struct pm8607_regulator_info *find_regulator_info(int id) 398static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
398{ 399{
399 struct pm8607_regulator_info *info; 400 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
401 struct pm8607_regulator_info *info = NULL;
402 struct regulator_init_data *pdata;
403 struct mfd_cell *cell;
400 int i; 404 int i;
401 405
406 cell = pdev->dev.platform_data;
407 if (cell == NULL)
408 return -ENODEV;
409 pdata = cell->mfd_data;
410 if (pdata == NULL)
411 return -EINVAL;
412
402 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { 413 for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
403 info = &pm8607_regulator_info[i]; 414 info = &pm8607_regulator_info[i];
404 if (info->desc.id == id) 415 if (!strcmp(info->desc.name, pdata->constraints.name))
405 return info; 416 break;
406 } 417 }
407 return NULL; 418 if (i > ARRAY_SIZE(pm8607_regulator_info)) {
408} 419 dev_err(&pdev->dev, "Failed to find regulator %s\n",
409 420 pdata->constraints.name);
410static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
411{
412 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
413 struct pm860x_platform_data *pdata = chip->dev->platform_data;
414 struct pm8607_regulator_info *info = NULL;
415
416 info = find_regulator_info(pdev->id);
417 if (info == NULL) {
418 dev_err(&pdev->dev, "invalid regulator ID specified\n");
419 return -EINVAL; 421 return -EINVAL;
420 } 422 }
421 423
422 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 424 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
423 info->chip = chip; 425 info->chip = chip;
424 426
427 /* check DVC ramp slope double */
428 if (!strcmp(info->desc.name, "BUCK3"))
429 if (info->chip->buck3_double)
430 info->slope_double = 1;
431
425 info->regulator = regulator_register(&info->desc, &pdev->dev, 432 info->regulator = regulator_register(&info->desc, &pdev->dev,
426 pdata->regulator[pdev->id], info); 433 pdata, info);
427 if (IS_ERR(info->regulator)) { 434 if (IS_ERR(info->regulator)) {
428 dev_err(&pdev->dev, "failed to register regulator %s\n", 435 dev_err(&pdev->dev, "failed to register regulator %s\n",
429 info->desc.name); 436 info->desc.name);
430 return PTR_ERR(info->regulator); 437 return PTR_ERR(info->regulator);
431 } 438 }
432 439
433 /* check DVC ramp slope double */
434 if (info->desc.id == PM8607_ID_BUCK3)
435 if (info->chip->buck3_double)
436 info->slope_double = 1;
437
438 platform_set_drvdata(pdev, info); 440 platform_set_drvdata(pdev, info);
439 return 0; 441 return 0;
440} 442}
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e1d943619ab8..de75f67f4cc3 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -108,6 +108,15 @@ config REGULATOR_MAX8952
108 via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS 108 via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS
109 modes ranging from 0.77V to 1.40V by 0.01V steps. 109 modes ranging from 0.77V to 1.40V by 0.01V steps.
110 110
111config REGULATOR_MAX8997
112 tristate "Maxim 8997/8966 regulator"
113 depends on MFD_MAX8997
114 help
115 This driver controls a Maxim 8997/8966 regulator
116 via I2C bus. The provided regulator is suitable for S5PC110,
117 S5PV210, and Exynos-4 chips to control VCC_CORE and
118 VCC_USIM voltages.
119
111config REGULATOR_MAX8998 120config REGULATOR_MAX8998
112 tristate "Maxim 8998 voltage regulator" 121 tristate "Maxim 8998 voltage regulator"
113 depends on MFD_MAX8998 122 depends on MFD_MAX8998
@@ -214,6 +223,15 @@ config REGULATOR_AB3100
214 AB3100 analog baseband dealing with power regulators 223 AB3100 analog baseband dealing with power regulators
215 for the system. 224 for the system.
216 225
226config REGULATOR_TPS6105X
227 tristate "TI TPS6105X Power regulators"
228 depends on TPS6105X
229 default y if TPS6105X
230 help
231 This driver supports TPS61050/TPS61052 voltage regulator chips.
232 It is a single boost converter primarily for white LEDs and
233 audio amplifiers.
234
217config REGULATOR_TPS65023 235config REGULATOR_TPS65023
218 tristate "TI TPS65023 Power regulators" 236 tristate "TI TPS65023 Power regulators"
219 depends on I2C 237 depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 0b5e88c2b8d7..d72a42756778 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
18obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 18obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
19obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o 19obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
20obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o 20obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o
21obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
21obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o 22obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
22obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 23obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
23obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 24obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
@@ -33,7 +34,7 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
33obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o 34obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
34obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o 35obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
35obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o 36obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
36 37obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
37obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o 38obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
38obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o 39obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
39obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o 40obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index ed6feaf9398d..2dec589a8908 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -17,6 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/regulator/driver.h> 18#include <linux/regulator/driver.h>
19#include <linux/mfd/abx500.h> 19#include <linux/mfd/abx500.h>
20#include <linux/mfd/core.h>
20 21
21/* LDO registers and some handy masking definitions for AB3100 */ 22/* LDO registers and some handy masking definitions for AB3100 */
22#define AB3100_LDO_A 0x40 23#define AB3100_LDO_A 0x40
@@ -576,7 +577,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
576 577
577static int __devinit ab3100_regulators_probe(struct platform_device *pdev) 578static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
578{ 579{
579 struct ab3100_platform_data *plfdata = pdev->dev.platform_data; 580 struct ab3100_platform_data *plfdata = mfd_get_data(pdev);
580 int err = 0; 581 int err = 0;
581 u8 data; 582 u8 data;
582 int i; 583 int i;
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
new file mode 100644
index 000000000000..01ef7e9903bb
--- /dev/null
+++ b/drivers/regulator/max8997.c
@@ -0,0 +1,1213 @@
1/*
2 * max8997.c - Regulator driver for the Maxim 8997/8966
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/bug.h>
25#include <linux/delay.h>
26#include <linux/err.h>
27#include <linux/gpio.h>
28#include <linux/slab.h>
29#include <linux/platform_device.h>
30#include <linux/regulator/driver.h>
31#include <linux/regulator/machine.h>
32#include <linux/mfd/max8997.h>
33#include <linux/mfd/max8997-private.h>
34
35struct max8997_data {
36 struct device *dev;
37 struct max8997_dev *iodev;
38 int num_regulators;
39 struct regulator_dev **rdev;
40 int ramp_delay; /* in mV/us */
41
42 u8 buck1_vol[8];
43 u8 buck2_vol[8];
44 u8 buck5_vol[8];
45 int buck125_gpioindex;
46
47 u8 saved_states[MAX8997_REG_MAX];
48};
49
50static inline void max8997_set_gpio(struct max8997_data *max8997)
51{
52 struct max8997_platform_data *pdata =
53 dev_get_platdata(max8997->iodev->dev);
54 int set3 = (max8997->buck125_gpioindex) & 0x1;
55 int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1;
56 int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1;
57
58 gpio_set_value(pdata->buck125_gpios[0], set1);
59 gpio_set_value(pdata->buck125_gpios[1], set2);
60 gpio_set_value(pdata->buck125_gpios[2], set3);
61}
62
63struct voltage_map_desc {
64 int min;
65 int max;
66 int step;
67 unsigned int n_bits;
68};
69
70/* Voltage maps in mV */
71static const struct voltage_map_desc ldo_voltage_map_desc = {
72 .min = 800, .max = 3950, .step = 50, .n_bits = 6,
73}; /* LDO1 ~ 18, 21 all */
74
75static const struct voltage_map_desc buck1245_voltage_map_desc = {
76 .min = 650, .max = 2225, .step = 25, .n_bits = 6,
77}; /* Buck1, 2, 4, 5 */
78
79static const struct voltage_map_desc buck37_voltage_map_desc = {
80 .min = 750, .max = 3900, .step = 50, .n_bits = 6,
81}; /* Buck3, 7 */
82
83/* current map in mA */
84static const struct voltage_map_desc charger_current_map_desc = {
85 .min = 200, .max = 950, .step = 50, .n_bits = 4,
86};
87
88static const struct voltage_map_desc topoff_current_map_desc = {
89 .min = 50, .max = 200, .step = 10, .n_bits = 4,
90};
91
92static const struct voltage_map_desc *reg_voltage_map[] = {
93 [MAX8997_LDO1] = &ldo_voltage_map_desc,
94 [MAX8997_LDO2] = &ldo_voltage_map_desc,
95 [MAX8997_LDO3] = &ldo_voltage_map_desc,
96 [MAX8997_LDO4] = &ldo_voltage_map_desc,
97 [MAX8997_LDO5] = &ldo_voltage_map_desc,
98 [MAX8997_LDO6] = &ldo_voltage_map_desc,
99 [MAX8997_LDO7] = &ldo_voltage_map_desc,
100 [MAX8997_LDO8] = &ldo_voltage_map_desc,
101 [MAX8997_LDO9] = &ldo_voltage_map_desc,
102 [MAX8997_LDO10] = &ldo_voltage_map_desc,
103 [MAX8997_LDO11] = &ldo_voltage_map_desc,
104 [MAX8997_LDO12] = &ldo_voltage_map_desc,
105 [MAX8997_LDO13] = &ldo_voltage_map_desc,
106 [MAX8997_LDO14] = &ldo_voltage_map_desc,
107 [MAX8997_LDO15] = &ldo_voltage_map_desc,
108 [MAX8997_LDO16] = &ldo_voltage_map_desc,
109 [MAX8997_LDO17] = &ldo_voltage_map_desc,
110 [MAX8997_LDO18] = &ldo_voltage_map_desc,
111 [MAX8997_LDO21] = &ldo_voltage_map_desc,
112 [MAX8997_BUCK1] = &buck1245_voltage_map_desc,
113 [MAX8997_BUCK2] = &buck1245_voltage_map_desc,
114 [MAX8997_BUCK3] = &buck37_voltage_map_desc,
115 [MAX8997_BUCK4] = &buck1245_voltage_map_desc,
116 [MAX8997_BUCK5] = &buck1245_voltage_map_desc,
117 [MAX8997_BUCK6] = NULL,
118 [MAX8997_BUCK7] = &buck37_voltage_map_desc,
119 [MAX8997_EN32KHZ_AP] = NULL,
120 [MAX8997_EN32KHZ_CP] = NULL,
121 [MAX8997_ENVICHG] = NULL,
122 [MAX8997_ESAFEOUT1] = NULL,
123 [MAX8997_ESAFEOUT2] = NULL,
124 [MAX8997_CHARGER_CV] = NULL,
125 [MAX8997_CHARGER] = &charger_current_map_desc,
126 [MAX8997_CHARGER_TOPOFF] = &topoff_current_map_desc,
127};
128
129static inline int max8997_get_rid(struct regulator_dev *rdev)
130{
131 return rdev_get_id(rdev);
132}
133
134static int max8997_list_voltage_safeout(struct regulator_dev *rdev,
135 unsigned int selector)
136{
137 int rid = max8997_get_rid(rdev);
138
139 if (rid == MAX8997_ESAFEOUT1 || rid == MAX8997_ESAFEOUT2) {
140 switch (selector) {
141 case 0:
142 return 4850000;
143 case 1:
144 return 4900000;
145 case 2:
146 return 4950000;
147 case 3:
148 return 3300000;
149 default:
150 return -EINVAL;
151 }
152 }
153
154 return -EINVAL;
155}
156
157static int max8997_list_voltage_charger_cv(struct regulator_dev *rdev,
158 unsigned int selector)
159{
160 int rid = max8997_get_rid(rdev);
161
162 if (rid != MAX8997_CHARGER_CV)
163 goto err;
164
165 switch (selector) {
166 case 0x00:
167 return 4200000;
168 case 0x01 ... 0x0E:
169 return 4000000 + 20000 * (selector - 0x01);
170 case 0x0F:
171 return 4350000;
172 default:
173 return -EINVAL;
174 }
175err:
176 return -EINVAL;
177}
178
179static int max8997_list_voltage(struct regulator_dev *rdev,
180 unsigned int selector)
181{
182 const struct voltage_map_desc *desc;
183 int rid = max8997_get_rid(rdev);
184 int val;
185
186 if (rid >= ARRAY_SIZE(reg_voltage_map) ||
187 rid < 0)
188 return -EINVAL;
189
190 desc = reg_voltage_map[rid];
191 if (desc == NULL)
192 return -EINVAL;
193
194 val = desc->min + desc->step * selector;
195 if (val > desc->max)
196 return -EINVAL;
197
198 return val * 1000;
199}
200
201static int max8997_get_enable_register(struct regulator_dev *rdev,
202 int *reg, int *mask, int *pattern)
203{
204 int rid = max8997_get_rid(rdev);
205
206 switch (rid) {
207 case MAX8997_LDO1 ... MAX8997_LDO21:
208 *reg = MAX8997_REG_LDO1CTRL + (rid - MAX8997_LDO1);
209 *mask = 0xC0;
210 *pattern = 0xC0;
211 break;
212 case MAX8997_BUCK1:
213 *reg = MAX8997_REG_BUCK1CTRL;
214 *mask = 0x01;
215 *pattern = 0x01;
216 break;
217 case MAX8997_BUCK2:
218 *reg = MAX8997_REG_BUCK2CTRL;
219 *mask = 0x01;
220 *pattern = 0x01;
221 break;
222 case MAX8997_BUCK3:
223 *reg = MAX8997_REG_BUCK3CTRL;
224 *mask = 0x01;
225 *pattern = 0x01;
226 break;
227 case MAX8997_BUCK4:
228 *reg = MAX8997_REG_BUCK4CTRL;
229 *mask = 0x01;
230 *pattern = 0x01;
231 break;
232 case MAX8997_BUCK5:
233 *reg = MAX8997_REG_BUCK5CTRL;
234 *mask = 0x01;
235 *pattern = 0x01;
236 break;
237 case MAX8997_BUCK6:
238 *reg = MAX8997_REG_BUCK6CTRL;
239 *mask = 0x01;
240 *pattern = 0x01;
241 break;
242 case MAX8997_BUCK7:
243 *reg = MAX8997_REG_BUCK7CTRL;
244 *mask = 0x01;
245 *pattern = 0x01;
246 break;
247 case MAX8997_EN32KHZ_AP ... MAX8997_EN32KHZ_CP:
248 *reg = MAX8997_REG_MAINCON1;
249 *mask = 0x01 << (rid - MAX8997_EN32KHZ_AP);
250 *pattern = 0x01 << (rid - MAX8997_EN32KHZ_AP);
251 break;
252 case MAX8997_ENVICHG:
253 *reg = MAX8997_REG_MBCCTRL1;
254 *mask = 0x80;
255 *pattern = 0x80;
256 break;
257 case MAX8997_ESAFEOUT1 ... MAX8997_ESAFEOUT2:
258 *reg = MAX8997_REG_SAFEOUTCTRL;
259 *mask = 0x40 << (rid - MAX8997_ESAFEOUT1);
260 *pattern = 0x40 << (rid - MAX8997_ESAFEOUT1);
261 break;
262 case MAX8997_CHARGER:
263 *reg = MAX8997_REG_MBCCTRL2;
264 *mask = 0x40;
265 *pattern = 0x40;
266 break;
267 default:
268 /* Not controllable or not exists */
269 return -EINVAL;
270 break;
271 }
272
273 return 0;
274}
275
276static int max8997_reg_is_enabled(struct regulator_dev *rdev)
277{
278 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
279 struct i2c_client *i2c = max8997->iodev->i2c;
280 int ret, reg, mask, pattern;
281 u8 val;
282
283 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
284 if (ret == -EINVAL)
285 return 1; /* "not controllable" */
286 else if (ret)
287 return ret;
288
289 ret = max8997_read_reg(i2c, reg, &val);
290 if (ret)
291 return ret;
292
293 return (val & mask) == pattern;
294}
295
296static int max8997_reg_enable(struct regulator_dev *rdev)
297{
298 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
299 struct i2c_client *i2c = max8997->iodev->i2c;
300 int ret, reg, mask, pattern;
301
302 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
303 if (ret)
304 return ret;
305
306 return max8997_update_reg(i2c, reg, pattern, mask);
307}
308
309static int max8997_reg_disable(struct regulator_dev *rdev)
310{
311 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
312 struct i2c_client *i2c = max8997->iodev->i2c;
313 int ret, reg, mask, pattern;
314
315 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
316 if (ret)
317 return ret;
318
319 return max8997_update_reg(i2c, reg, ~pattern, mask);
320}
321
322static int max8997_get_voltage_register(struct regulator_dev *rdev,
323 int *_reg, int *_shift, int *_mask)
324{
325 int rid = max8997_get_rid(rdev);
326 int reg, shift = 0, mask = 0x3f;
327
328 switch (rid) {
329 case MAX8997_LDO1 ... MAX8997_LDO21:
330 reg = MAX8997_REG_LDO1CTRL + (rid - MAX8997_LDO1);
331 break;
332 case MAX8997_BUCK1:
333 reg = MAX8997_REG_BUCK1DVS1;
334 break;
335 case MAX8997_BUCK2:
336 reg = MAX8997_REG_BUCK2DVS1;
337 break;
338 case MAX8997_BUCK3:
339 reg = MAX8997_REG_BUCK3DVS;
340 break;
341 case MAX8997_BUCK4:
342 reg = MAX8997_REG_BUCK4DVS;
343 break;
344 case MAX8997_BUCK5:
345 reg = MAX8997_REG_BUCK5DVS1;
346 break;
347 case MAX8997_BUCK7:
348 reg = MAX8997_REG_BUCK7DVS;
349 break;
350 case MAX8997_ESAFEOUT1 ... MAX8997_ESAFEOUT2:
351 reg = MAX8997_REG_SAFEOUTCTRL;
352 shift = (rid == MAX8997_ESAFEOUT2) ? 2 : 0;
353 mask = 0x3;
354 break;
355 case MAX8997_CHARGER_CV:
356 reg = MAX8997_REG_MBCCTRL3;
357 shift = 0;
358 mask = 0xf;
359 break;
360 case MAX8997_CHARGER:
361 reg = MAX8997_REG_MBCCTRL4;
362 shift = 0;
363 mask = 0xf;
364 break;
365 case MAX8997_CHARGER_TOPOFF:
366 reg = MAX8997_REG_MBCCTRL5;
367 shift = 0;
368 mask = 0xf;
369 break;
370 default:
371 return -EINVAL;
372 }
373
374 *_reg = reg;
375 *_shift = shift;
376 *_mask = mask;
377
378 return 0;
379}
380
381static int max8997_get_voltage(struct regulator_dev *rdev)
382{
383 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
384 struct max8997_platform_data *pdata =
385 dev_get_platdata(max8997->iodev->dev);
386 struct i2c_client *i2c = max8997->iodev->i2c;
387 int reg, shift, mask, ret;
388 int rid = max8997_get_rid(rdev);
389 u8 val;
390
391 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
392 if (ret)
393 return ret;
394
395 if ((rid == MAX8997_BUCK1 && pdata->buck1_gpiodvs) ||
396 (rid == MAX8997_BUCK2 && pdata->buck2_gpiodvs) ||
397 (rid == MAX8997_BUCK5 && pdata->buck5_gpiodvs))
398 reg += max8997->buck125_gpioindex;
399
400 ret = max8997_read_reg(i2c, reg, &val);
401 if (ret)
402 return ret;
403
404 val >>= shift;
405 val &= mask;
406
407 if (rdev->desc && rdev->desc->ops && rdev->desc->ops->list_voltage)
408 return rdev->desc->ops->list_voltage(rdev, val);
409
410 /*
411 * max8997_list_voltage returns value for any rdev with voltage_map,
412 * which works for "CHARGER" and "CHARGER TOPOFF" that do not have
413 * list_voltage ops (they are current regulators).
414 */
415 return max8997_list_voltage(rdev, val);
416}
417
418static inline int max8997_get_voltage_proper_val(
419 const struct voltage_map_desc *desc,
420 int min_vol, int max_vol)
421{
422 int i = 0;
423
424 if (desc == NULL)
425 return -EINVAL;
426
427 if (max_vol < desc->min || min_vol > desc->max)
428 return -EINVAL;
429
430 while (desc->min + desc->step * i < min_vol &&
431 desc->min + desc->step * i < desc->max)
432 i++;
433
434 if (desc->min + desc->step * i > max_vol)
435 return -EINVAL;
436
437 if (i >= (1 << desc->n_bits))
438 return -EINVAL;
439
440 return i;
441}
442
443static int max8997_set_voltage_charger_cv(struct regulator_dev *rdev,
444 int min_uV, int max_uV, unsigned *selector)
445{
446 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
447 struct i2c_client *i2c = max8997->iodev->i2c;
448 int rid = max8997_get_rid(rdev);
449 int lb, ub;
450 int reg, shift = 0, mask, ret = 0;
451 u8 val = 0x0;
452
453 if (rid != MAX8997_CHARGER_CV)
454 return -EINVAL;
455
456 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
457 if (ret)
458 return ret;
459
460 if (max_uV < 4000000 || min_uV > 4350000)
461 return -EINVAL;
462
463 if (min_uV <= 4000000) {
464 if (max_uV >= 4000000)
465 return -EINVAL;
466 else
467 val = 0x1;
468 } else if (min_uV <= 4200000 && max_uV >= 4200000)
469 val = 0x0;
470 else {
471 lb = (min_uV - 4000001) / 20000 + 2;
472 ub = (max_uV - 4000000) / 20000 + 1;
473
474 if (lb > ub)
475 return -EINVAL;
476
477 if (lb < 0xf)
478 val = lb;
479 else {
480 if (ub >= 0xf)
481 val = 0xf;
482 else
483 return -EINVAL;
484 }
485 }
486
487 *selector = val;
488
489 ret = max8997_update_reg(i2c, reg, val << shift, mask);
490
491 return ret;
492}
493
494/*
495 * For LDO1 ~ LDO21, BUCK1~5, BUCK7, CHARGER, CHARGER_TOPOFF
496 * BUCK1, 2, and 5 are available if they are not controlled by gpio
497 */
498static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev,
499 int min_uV, int max_uV, unsigned *selector)
500{
501 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
502 struct i2c_client *i2c = max8997->iodev->i2c;
503 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
504 const struct voltage_map_desc *desc;
505 int rid = max8997_get_rid(rdev);
506 int reg, shift = 0, mask, ret;
507 int i;
508 u8 org;
509
510 switch (rid) {
511 case MAX8997_LDO1 ... MAX8997_LDO21:
512 break;
513 case MAX8997_BUCK1 ... MAX8997_BUCK5:
514 break;
515 case MAX8997_BUCK6:
516 return -EINVAL;
517 case MAX8997_BUCK7:
518 break;
519 case MAX8997_CHARGER:
520 break;
521 case MAX8997_CHARGER_TOPOFF:
522 break;
523 default:
524 return -EINVAL;
525 }
526
527 desc = reg_voltage_map[rid];
528
529 i = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
530 if (i < 0)
531 return i;
532
533 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
534 if (ret)
535 return ret;
536
537 max8997_read_reg(i2c, reg, &org);
538 org = (org & mask) >> shift;
539
540 ret = max8997_update_reg(i2c, reg, i << shift, mask << shift);
541 *selector = i;
542
543 if (rid == MAX8997_BUCK1 || rid == MAX8997_BUCK2 ||
544 rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) {
545 /* If the voltage is increasing */
546 if (org < i)
547 udelay(desc->step * (i - org) / max8997->ramp_delay);
548 }
549
550 return ret;
551}
552
553/*
554 * Assess the damage on the voltage setting of BUCK1,2,5 by the change.
555 *
556 * When GPIO-DVS mode is used for multiple bucks, changing the voltage value
557 * of one of the bucks may affect that of another buck, which is the side
558 * effect of the change (set_voltage). This function examines the GPIO-DVS
559 * configurations and checks whether such side-effect exists.
560 */
561static int max8997_assess_side_effect(struct regulator_dev *rdev,
562 u8 new_val, int *best)
563{
564 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
565 struct max8997_platform_data *pdata =
566 dev_get_platdata(max8997->iodev->dev);
567 int rid = max8997_get_rid(rdev);
568 u8 *buckx_val[3];
569 bool buckx_gpiodvs[3];
570 int side_effect[8];
571 int min_side_effect = INT_MAX;
572 int i;
573
574 *best = -1;
575
576 switch (rid) {
577 case MAX8997_BUCK1:
578 rid = 0;
579 break;
580 case MAX8997_BUCK2:
581 rid = 1;
582 break;
583 case MAX8997_BUCK5:
584 rid = 2;
585 break;
586 default:
587 return -EINVAL;
588 }
589
590 buckx_val[0] = max8997->buck1_vol;
591 buckx_val[1] = max8997->buck2_vol;
592 buckx_val[2] = max8997->buck5_vol;
593 buckx_gpiodvs[0] = pdata->buck1_gpiodvs;
594 buckx_gpiodvs[1] = pdata->buck2_gpiodvs;
595 buckx_gpiodvs[2] = pdata->buck5_gpiodvs;
596
597 for (i = 0; i < 8; i++) {
598 int others;
599
600 if (new_val != (buckx_val[rid])[i]) {
601 side_effect[i] = -1;
602 continue;
603 }
604
605 side_effect[i] = 0;
606 for (others = 0; others < 3; others++) {
607 int diff;
608
609 if (others == rid)
610 continue;
611 if (buckx_gpiodvs[others] == false)
612 continue; /* Not affected */
613 diff = (buckx_val[others])[i] -
614 (buckx_val[others])[max8997->buck125_gpioindex];
615 if (diff > 0)
616 side_effect[i] += diff;
617 else if (diff < 0)
618 side_effect[i] -= diff;
619 }
620 if (side_effect[i] == 0) {
621 *best = i;
622 return 0; /* NO SIDE EFFECT! Use This! */
623 }
624 if (side_effect[i] < min_side_effect) {
625 min_side_effect = side_effect[i];
626 *best = i;
627 }
628 }
629
630 if (*best == -1)
631 return -EINVAL;
632
633 return side_effect[*best];
634}
635
636/*
637 * For Buck 1 ~ 5 and 7. If it is not controlled by GPIO, this calls
638 * max8997_set_voltage_ldobuck to do the job.
639 */
640static int max8997_set_voltage_buck(struct regulator_dev *rdev,
641 int min_uV, int max_uV, unsigned *selector)
642{
643 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
644 struct max8997_platform_data *pdata =
645 dev_get_platdata(max8997->iodev->dev);
646 int rid = max8997_get_rid(rdev);
647 const struct voltage_map_desc *desc;
648 int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg;
649 bool gpio_dvs_mode = false;
650 int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
651
652 if (rid < MAX8997_BUCK1 || rid > MAX8997_BUCK7)
653 return -EINVAL;
654
655 switch (rid) {
656 case MAX8997_BUCK1:
657 if (pdata->buck1_gpiodvs)
658 gpio_dvs_mode = true;
659 break;
660 case MAX8997_BUCK2:
661 if (pdata->buck2_gpiodvs)
662 gpio_dvs_mode = true;
663 break;
664 case MAX8997_BUCK5:
665 if (pdata->buck5_gpiodvs)
666 gpio_dvs_mode = true;
667 break;
668 }
669
670 if (!gpio_dvs_mode)
671 return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV,
672 selector);
673
674 desc = reg_voltage_map[rid];
675 new_val = max8997_get_voltage_proper_val(desc, min_vol, max_vol);
676 if (new_val < 0)
677 return new_val;
678
679 tmp_dmg = INT_MAX;
680 tmp_idx = -1;
681 tmp_val = -1;
682 do {
683 damage = max8997_assess_side_effect(rdev, new_val, &new_idx);
684 if (damage == 0)
685 goto out;
686
687 if (tmp_dmg > damage) {
688 tmp_idx = new_idx;
689 tmp_val = new_val;
690 tmp_dmg = damage;
691 }
692
693 new_val++;
694 } while (desc->min + desc->step + new_val <= desc->max);
695
696 new_idx = tmp_idx;
697 new_val = tmp_val;
698
699 if (pdata->ignore_gpiodvs_side_effect == false)
700 return -EINVAL;
701
702 dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:"
703 " %d -> %d\n", max8997->buck125_gpioindex, tmp_idx);
704
705out:
706 if (new_idx < 0 || new_val < 0)
707 return -EINVAL;
708
709 max8997->buck125_gpioindex = new_idx;
710 max8997_set_gpio(max8997);
711 *selector = new_val;
712
713 return 0;
714}
715
716static const int safeoutvolt[] = {
717 3300000,
718 4850000,
719 4900000,
720 4950000,
721};
722
723/* For SAFEOUT1 and SAFEOUT2 */
724static int max8997_set_voltage_safeout(struct regulator_dev *rdev,
725 int min_uV, int max_uV, unsigned *selector)
726{
727 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
728 struct i2c_client *i2c = max8997->iodev->i2c;
729 int rid = max8997_get_rid(rdev);
730 int reg, shift = 0, mask, ret;
731 int i = 0;
732 u8 val;
733
734 if (rid != MAX8997_ESAFEOUT1 && rid != MAX8997_ESAFEOUT2)
735 return -EINVAL;
736
737 for (i = 0; i < ARRAY_SIZE(safeoutvolt); i++) {
738 if (min_uV <= safeoutvolt[i] &&
739 max_uV >= safeoutvolt[i])
740 break;
741 }
742
743 if (i >= ARRAY_SIZE(safeoutvolt))
744 return -EINVAL;
745
746 if (i == 0)
747 val = 0x3;
748 else
749 val = i - 1;
750
751 ret = max8997_get_voltage_register(rdev, &reg, &shift, &mask);
752 if (ret)
753 return ret;
754
755 ret = max8997_update_reg(i2c, reg, val << shift, mask << shift);
756 *selector = val;
757
758 return ret;
759}
760
761static int max8997_reg_enable_suspend(struct regulator_dev *rdev)
762{
763 return 0;
764}
765
766static int max8997_reg_disable_suspend(struct regulator_dev *rdev)
767{
768 struct max8997_data *max8997 = rdev_get_drvdata(rdev);
769 struct i2c_client *i2c = max8997->iodev->i2c;
770 int ret, reg, mask, pattern;
771 int rid = max8997_get_rid(rdev);
772
773 ret = max8997_get_enable_register(rdev, &reg, &mask, &pattern);
774 if (ret)
775 return ret;
776
777 max8997_read_reg(i2c, reg, &max8997->saved_states[rid]);
778
779 if (rid == MAX8997_LDO1 ||
780 rid == MAX8997_LDO10 ||
781 rid == MAX8997_LDO21) {
782 dev_dbg(&rdev->dev, "Conditional Power-Off for %s\n",
783 rdev->desc->name);
784 return max8997_update_reg(i2c, reg, 0x40, mask);
785 }
786
787 dev_dbg(&rdev->dev, "Full Power-Off for %s (%xh -> %xh)\n",
788 rdev->desc->name, max8997->saved_states[rid] & mask,
789 (~pattern) & mask);
790 return max8997_update_reg(i2c, reg, ~pattern, mask);
791}
792
793static struct regulator_ops max8997_ldo_ops = {
794 .list_voltage = max8997_list_voltage,
795 .is_enabled = max8997_reg_is_enabled,
796 .enable = max8997_reg_enable,
797 .disable = max8997_reg_disable,
798 .get_voltage = max8997_get_voltage,
799 .set_voltage = max8997_set_voltage_ldobuck,
800 .set_suspend_enable = max8997_reg_enable_suspend,
801 .set_suspend_disable = max8997_reg_disable_suspend,
802};
803
804static struct regulator_ops max8997_buck_ops = {
805 .list_voltage = max8997_list_voltage,
806 .is_enabled = max8997_reg_is_enabled,
807 .enable = max8997_reg_enable,
808 .disable = max8997_reg_disable,
809 .get_voltage = max8997_get_voltage,
810 .set_voltage = max8997_set_voltage_buck,
811 .set_suspend_enable = max8997_reg_enable_suspend,
812 .set_suspend_disable = max8997_reg_disable_suspend,
813};
814
815static struct regulator_ops max8997_fixedvolt_ops = {
816 .list_voltage = max8997_list_voltage,
817 .is_enabled = max8997_reg_is_enabled,
818 .enable = max8997_reg_enable,
819 .disable = max8997_reg_disable,
820 .set_suspend_enable = max8997_reg_enable_suspend,
821 .set_suspend_disable = max8997_reg_disable_suspend,
822};
823
824static struct regulator_ops max8997_safeout_ops = {
825 .list_voltage = max8997_list_voltage_safeout,
826 .is_enabled = max8997_reg_is_enabled,
827 .enable = max8997_reg_enable,
828 .disable = max8997_reg_disable,
829 .get_voltage = max8997_get_voltage,
830 .set_voltage = max8997_set_voltage_safeout,
831 .set_suspend_enable = max8997_reg_enable_suspend,
832 .set_suspend_disable = max8997_reg_disable_suspend,
833};
834
835static struct regulator_ops max8997_fixedstate_ops = {
836 .list_voltage = max8997_list_voltage_charger_cv,
837 .get_voltage = max8997_get_voltage,
838 .set_voltage = max8997_set_voltage_charger_cv,
839};
840
841static int max8997_set_voltage_ldobuck_wrap(struct regulator_dev *rdev,
842 int min_uV, int max_uV)
843{
844 unsigned dummy;
845
846 return max8997_set_voltage_ldobuck(rdev, min_uV, max_uV, &dummy);
847}
848
849
850static struct regulator_ops max8997_charger_ops = {
851 .is_enabled = max8997_reg_is_enabled,
852 .enable = max8997_reg_enable,
853 .disable = max8997_reg_disable,
854 .get_current_limit = max8997_get_voltage,
855 .set_current_limit = max8997_set_voltage_ldobuck_wrap,
856};
857
858static struct regulator_ops max8997_charger_fixedstate_ops = {
859 .is_enabled = max8997_reg_is_enabled,
860 .get_current_limit = max8997_get_voltage,
861 .set_current_limit = max8997_set_voltage_ldobuck_wrap,
862};
863
864#define regulator_desc_ldo(num) { \
865 .name = "LDO"#num, \
866 .id = MAX8997_LDO##num, \
867 .ops = &max8997_ldo_ops, \
868 .type = REGULATOR_VOLTAGE, \
869 .owner = THIS_MODULE, \
870}
871#define regulator_desc_buck(num) { \
872 .name = "BUCK"#num, \
873 .id = MAX8997_BUCK##num, \
874 .ops = &max8997_buck_ops, \
875 .type = REGULATOR_VOLTAGE, \
876 .owner = THIS_MODULE, \
877}
878
879static struct regulator_desc regulators[] = {
880 regulator_desc_ldo(1),
881 regulator_desc_ldo(2),
882 regulator_desc_ldo(3),
883 regulator_desc_ldo(4),
884 regulator_desc_ldo(5),
885 regulator_desc_ldo(6),
886 regulator_desc_ldo(7),
887 regulator_desc_ldo(8),
888 regulator_desc_ldo(9),
889 regulator_desc_ldo(10),
890 regulator_desc_ldo(11),
891 regulator_desc_ldo(12),
892 regulator_desc_ldo(13),
893 regulator_desc_ldo(14),
894 regulator_desc_ldo(15),
895 regulator_desc_ldo(16),
896 regulator_desc_ldo(17),
897 regulator_desc_ldo(18),
898 regulator_desc_ldo(21),
899 regulator_desc_buck(1),
900 regulator_desc_buck(2),
901 regulator_desc_buck(3),
902 regulator_desc_buck(4),
903 regulator_desc_buck(5),
904 {
905 .name = "BUCK6",
906 .id = MAX8997_BUCK6,
907 .ops = &max8997_fixedvolt_ops,
908 .type = REGULATOR_VOLTAGE,
909 .owner = THIS_MODULE,
910 },
911 regulator_desc_buck(7),
912 {
913 .name = "EN32KHz AP",
914 .id = MAX8997_EN32KHZ_AP,
915 .ops = &max8997_fixedvolt_ops,
916 .type = REGULATOR_VOLTAGE,
917 .owner = THIS_MODULE,
918 }, {
919 .name = "EN32KHz CP",
920 .id = MAX8997_EN32KHZ_CP,
921 .ops = &max8997_fixedvolt_ops,
922 .type = REGULATOR_VOLTAGE,
923 .owner = THIS_MODULE,
924 }, {
925 .name = "ENVICHG",
926 .id = MAX8997_ENVICHG,
927 .ops = &max8997_fixedvolt_ops,
928 .type = REGULATOR_VOLTAGE,
929 .owner = THIS_MODULE,
930 }, {
931 .name = "ESAFEOUT1",
932 .id = MAX8997_ESAFEOUT1,
933 .ops = &max8997_safeout_ops,
934 .type = REGULATOR_VOLTAGE,
935 .owner = THIS_MODULE,
936 }, {
937 .name = "ESAFEOUT2",
938 .id = MAX8997_ESAFEOUT2,
939 .ops = &max8997_safeout_ops,
940 .type = REGULATOR_VOLTAGE,
941 .owner = THIS_MODULE,
942 }, {
943 .name = "CHARGER CV",
944 .id = MAX8997_CHARGER_CV,
945 .ops = &max8997_fixedstate_ops,
946 .type = REGULATOR_VOLTAGE,
947 .owner = THIS_MODULE,
948 }, {
949 .name = "CHARGER",
950 .id = MAX8997_CHARGER,
951 .ops = &max8997_charger_ops,
952 .type = REGULATOR_CURRENT,
953 .owner = THIS_MODULE,
954 }, {
955 .name = "CHARGER TOPOFF",
956 .id = MAX8997_CHARGER_TOPOFF,
957 .ops = &max8997_charger_fixedstate_ops,
958 .type = REGULATOR_CURRENT,
959 .owner = THIS_MODULE,
960 },
961};
962
963static __devinit int max8997_pmic_probe(struct platform_device *pdev)
964{
965 struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
966 struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
967 struct regulator_dev **rdev;
968 struct max8997_data *max8997;
969 struct i2c_client *i2c;
970 int i, ret, size;
971 u8 max_buck1 = 0, max_buck2 = 0, max_buck5 = 0;
972
973 if (!pdata) {
974 dev_err(pdev->dev.parent, "No platform init data supplied.\n");
975 return -ENODEV;
976 }
977
978 max8997 = kzalloc(sizeof(struct max8997_data), GFP_KERNEL);
979 if (!max8997)
980 return -ENOMEM;
981
982 size = sizeof(struct regulator_dev *) * pdata->num_regulators;
983 max8997->rdev = kzalloc(size, GFP_KERNEL);
984 if (!max8997->rdev) {
985 kfree(max8997);
986 return -ENOMEM;
987 }
988
989 rdev = max8997->rdev;
990 max8997->dev = &pdev->dev;
991 max8997->iodev = iodev;
992 max8997->num_regulators = pdata->num_regulators;
993 platform_set_drvdata(pdev, max8997);
994 i2c = max8997->iodev->i2c;
995
996 max8997->buck125_gpioindex = pdata->buck125_default_idx;
997
998 for (i = 0; i < 8; i++) {
999 max8997->buck1_vol[i] = ret =
1000 max8997_get_voltage_proper_val(
1001 &buck1245_voltage_map_desc,
1002 pdata->buck1_voltage[i] / 1000,
1003 pdata->buck1_voltage[i] / 1000 +
1004 buck1245_voltage_map_desc.step);
1005 if (ret < 0)
1006 goto err_alloc;
1007
1008 max8997->buck2_vol[i] = ret =
1009 max8997_get_voltage_proper_val(
1010 &buck1245_voltage_map_desc,
1011 pdata->buck2_voltage[i] / 1000,
1012 pdata->buck2_voltage[i] / 1000 +
1013 buck1245_voltage_map_desc.step);
1014 if (ret < 0)
1015 goto err_alloc;
1016
1017 max8997->buck5_vol[i] = ret =
1018 max8997_get_voltage_proper_val(
1019 &buck1245_voltage_map_desc,
1020 pdata->buck5_voltage[i] / 1000,
1021 pdata->buck5_voltage[i] / 1000 +
1022 buck1245_voltage_map_desc.step);
1023 if (ret < 0)
1024 goto err_alloc;
1025
1026 if (max_buck1 < max8997->buck1_vol[i])
1027 max_buck1 = max8997->buck1_vol[i];
1028 if (max_buck2 < max8997->buck2_vol[i])
1029 max_buck2 = max8997->buck2_vol[i];
1030 if (max_buck5 < max8997->buck5_vol[i])
1031 max_buck5 = max8997->buck5_vol[i];
1032 }
1033
1034 /* For the safety, set max voltage before setting up */
1035 for (i = 0; i < 8; i++) {
1036 max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1),
1037 max_buck1, 0x3f);
1038 max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
1039 max_buck2, 0x3f);
1040 max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
1041 max_buck5, 0x3f);
1042 }
1043
1044 /*
1045 * If buck 1, 2, and 5 do not care DVS GPIO settings, ignore them.
1046 * If at least one of them cares, set gpios.
1047 */
1048 if (pdata->buck1_gpiodvs || pdata->buck2_gpiodvs ||
1049 pdata->buck5_gpiodvs) {
1050 bool gpio1set = false, gpio2set = false;
1051
1052 if (!gpio_is_valid(pdata->buck125_gpios[0]) ||
1053 !gpio_is_valid(pdata->buck125_gpios[1]) ||
1054 !gpio_is_valid(pdata->buck125_gpios[2])) {
1055 dev_err(&pdev->dev, "GPIO NOT VALID\n");
1056 ret = -EINVAL;
1057 goto err_alloc;
1058 }
1059
1060 ret = gpio_request(pdata->buck125_gpios[0],
1061 "MAX8997 SET1");
1062 if (ret == -EBUSY)
1063 dev_warn(&pdev->dev, "Duplicated gpio request"
1064 " on SET1\n");
1065 else if (ret)
1066 goto err_alloc;
1067 else
1068 gpio1set = true;
1069
1070 ret = gpio_request(pdata->buck125_gpios[1],
1071 "MAX8997 SET2");
1072 if (ret == -EBUSY)
1073 dev_warn(&pdev->dev, "Duplicated gpio request"
1074 " on SET2\n");
1075 else if (ret) {
1076 if (gpio1set)
1077 gpio_free(pdata->buck125_gpios[0]);
1078 goto err_alloc;
1079 } else
1080 gpio2set = true;
1081
1082 ret = gpio_request(pdata->buck125_gpios[2],
1083 "MAX8997 SET3");
1084 if (ret == -EBUSY)
1085 dev_warn(&pdev->dev, "Duplicated gpio request"
1086 " on SET3\n");
1087 else if (ret) {
1088 if (gpio1set)
1089 gpio_free(pdata->buck125_gpios[0]);
1090 if (gpio2set)
1091 gpio_free(pdata->buck125_gpios[1]);
1092 goto err_alloc;
1093 }
1094
1095 gpio_direction_output(pdata->buck125_gpios[0],
1096 (max8997->buck125_gpioindex >> 2)
1097 & 0x1); /* SET1 */
1098 gpio_direction_output(pdata->buck125_gpios[1],
1099 (max8997->buck125_gpioindex >> 1)
1100 & 0x1); /* SET2 */
1101 gpio_direction_output(pdata->buck125_gpios[2],
1102 (max8997->buck125_gpioindex >> 0)
1103 & 0x1); /* SET3 */
1104 ret = 0;
1105 }
1106
1107 /* DVS-GPIO disabled */
1108 max8997_update_reg(i2c, MAX8997_REG_BUCK1CTRL, (pdata->buck1_gpiodvs) ?
1109 (1 << 1) : (0 << 1), 1 << 1);
1110 max8997_update_reg(i2c, MAX8997_REG_BUCK2CTRL, (pdata->buck2_gpiodvs) ?
1111 (1 << 1) : (0 << 1), 1 << 1);
1112 max8997_update_reg(i2c, MAX8997_REG_BUCK5CTRL, (pdata->buck5_gpiodvs) ?
1113 (1 << 1) : (0 << 1), 1 << 1);
1114
1115 /* Initialize all the DVS related BUCK registers */
1116 for (i = 0; i < 8; i++) {
1117 max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1),
1118 max8997->buck1_vol[i],
1119 0x3f);
1120 max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
1121 max8997->buck2_vol[i],
1122 0x3f);
1123 max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
1124 max8997->buck5_vol[i],
1125 0x3f);
1126 }
1127
1128 for (i = 0; i < pdata->num_regulators; i++) {
1129 const struct voltage_map_desc *desc;
1130 int id = pdata->regulators[i].id;
1131
1132 desc = reg_voltage_map[id];
1133 if (desc)
1134 regulators[id].n_voltages =
1135 (desc->max - desc->min) / desc->step + 1;
1136 else if (id == MAX8997_ESAFEOUT1 || id == MAX8997_ESAFEOUT2)
1137 regulators[id].n_voltages = 4;
1138 else if (id == MAX8997_CHARGER_CV)
1139 regulators[id].n_voltages = 16;
1140
1141 rdev[i] = regulator_register(&regulators[id], max8997->dev,
1142 pdata->regulators[i].initdata, max8997);
1143 if (IS_ERR(rdev[i])) {
1144 ret = PTR_ERR(rdev[i]);
1145 dev_err(max8997->dev, "regulator init failed for %d\n",
1146 id);
1147 rdev[i] = NULL;
1148 goto err;
1149 }
1150 }
1151
1152 /* Misc Settings */
1153 max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
1154 max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
1155
1156 return 0;
1157err:
1158 for (i = 0; i < max8997->num_regulators; i++)
1159 if (rdev[i])
1160 regulator_unregister(rdev[i]);
1161err_alloc:
1162 kfree(max8997->rdev);
1163 kfree(max8997);
1164
1165 return ret;
1166}
1167
1168static int __devexit max8997_pmic_remove(struct platform_device *pdev)
1169{
1170 struct max8997_data *max8997 = platform_get_drvdata(pdev);
1171 struct regulator_dev **rdev = max8997->rdev;
1172 int i;
1173
1174 for (i = 0; i < max8997->num_regulators; i++)
1175 if (rdev[i])
1176 regulator_unregister(rdev[i]);
1177
1178 kfree(max8997->rdev);
1179 kfree(max8997);
1180
1181 return 0;
1182}
1183
1184static const struct platform_device_id max8997_pmic_id[] = {
1185 { "max8997-pmic", 0},
1186 { },
1187};
1188
1189static struct platform_driver max8997_pmic_driver = {
1190 .driver = {
1191 .name = "max8997-pmic",
1192 .owner = THIS_MODULE,
1193 },
1194 .probe = max8997_pmic_probe,
1195 .remove = __devexit_p(max8997_pmic_remove),
1196 .id_table = max8997_pmic_id,
1197};
1198
1199static int __init max8997_pmic_init(void)
1200{
1201 return platform_driver_register(&max8997_pmic_driver);
1202}
1203subsys_initcall(max8997_pmic_init);
1204
1205static void __exit max8997_pmic_cleanup(void)
1206{
1207 platform_driver_unregister(&max8997_pmic_driver);
1208}
1209module_exit(max8997_pmic_cleanup);
1210
1211MODULE_DESCRIPTION("MAXIM 8997/8966 Regulator Driver");
1212MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
1213MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/mc13783-regulator.c b/drivers/regulator/mc13783-regulator.c
index 3e5d0c3b4e53..23249cb0a8bd 100644
--- a/drivers/regulator/mc13783-regulator.c
+++ b/drivers/regulator/mc13783-regulator.c
@@ -15,6 +15,7 @@
15#include <linux/regulator/driver.h> 15#include <linux/regulator/driver.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/mfd/core.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/err.h> 21#include <linux/err.h>
@@ -336,8 +337,7 @@ static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
336{ 337{
337 struct mc13xxx_regulator_priv *priv; 338 struct mc13xxx_regulator_priv *priv;
338 struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); 339 struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
339 struct mc13783_regulator_platform_data *pdata = 340 struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev);
340 dev_get_platdata(&pdev->dev);
341 struct mc13783_regulator_init_data *init_data; 341 struct mc13783_regulator_init_data *init_data;
342 int i, ret; 342 int i, ret;
343 343
@@ -381,8 +381,7 @@ err:
381static int __devexit mc13783_regulator_remove(struct platform_device *pdev) 381static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
382{ 382{
383 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 383 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
384 struct mc13783_regulator_platform_data *pdata = 384 struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev);
385 dev_get_platdata(&pdev->dev);
386 int i; 385 int i;
387 386
388 platform_set_drvdata(pdev, NULL); 387 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/regulator/mc13892-regulator.c b/drivers/regulator/mc13892-regulator.c
index 1b8f7398a4a8..6f15168e5ed4 100644
--- a/drivers/regulator/mc13892-regulator.c
+++ b/drivers/regulator/mc13892-regulator.c
@@ -15,6 +15,7 @@
15#include <linux/regulator/driver.h> 15#include <linux/regulator/driver.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/mfd/core.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/err.h> 21#include <linux/err.h>
@@ -520,8 +521,7 @@ static int __devinit mc13892_regulator_probe(struct platform_device *pdev)
520{ 521{
521 struct mc13xxx_regulator_priv *priv; 522 struct mc13xxx_regulator_priv *priv;
522 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); 523 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
523 struct mc13xxx_regulator_platform_data *pdata = 524 struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev);
524 dev_get_platdata(&pdev->dev);
525 struct mc13xxx_regulator_init_data *init_data; 525 struct mc13xxx_regulator_init_data *init_data;
526 int i, ret; 526 int i, ret;
527 u32 val; 527 u32 val;
@@ -595,8 +595,7 @@ err_free:
595static int __devexit mc13892_regulator_remove(struct platform_device *pdev) 595static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
596{ 596{
597 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 597 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
598 struct mc13xxx_regulator_platform_data *pdata = 598 struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev);
599 dev_get_platdata(&pdev->dev);
600 int i; 599 int i;
601 600
602 platform_set_drvdata(pdev, NULL); 601 platform_set_drvdata(pdev, NULL);
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c
new file mode 100644
index 000000000000..1661499feda4
--- /dev/null
+++ b/drivers/regulator/tps6105x-regulator.c
@@ -0,0 +1,196 @@
1/*
2 * Driver for TPS61050/61052 boost converters, typically used for white LEDs
3 * or audio amplifiers.
4 *
5 * Copyright (C) 2011 ST-Ericsson SA
6 * Written on behalf of Linaro for ST-Ericsson
7 *
8 * Author: Linus Walleij <linus.walleij@linaro.org>
9 *
10 * License terms: GNU General Public License (GPL) version 2
11 */
12
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/err.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/regulator/driver.h>
20#include <linux/mfd/core.h>
21#include <linux/mfd/tps6105x.h>
22
23static const int tps6105x_voltages[] = {
24 4500000,
25 5000000,
26 5250000,
27 5000000, /* There is an additional 5V */
28};
29
30static int tps6105x_regulator_enable(struct regulator_dev *rdev)
31{
32 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
33 int ret;
34
35 /* Activate voltage mode */
36 ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
37 TPS6105X_REG0_MODE_MASK,
38 TPS6105X_REG0_MODE_VOLTAGE << TPS6105X_REG0_MODE_SHIFT);
39 if (ret)
40 return ret;
41
42 return 0;
43}
44
45static int tps6105x_regulator_disable(struct regulator_dev *rdev)
46{
47 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
48 int ret;
49
50 /* Set into shutdown mode */
51 ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
52 TPS6105X_REG0_MODE_MASK,
53 TPS6105X_REG0_MODE_SHUTDOWN << TPS6105X_REG0_MODE_SHIFT);
54 if (ret)
55 return ret;
56
57 return 0;
58}
59
60static int tps6105x_regulator_is_enabled(struct regulator_dev *rdev)
61{
62 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
63 u8 regval;
64 int ret;
65
66 ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
67 if (ret)
68 return ret;
69 regval &= TPS6105X_REG0_MODE_MASK;
70 regval >>= TPS6105X_REG0_MODE_SHIFT;
71
72 if (regval == TPS6105X_REG0_MODE_VOLTAGE)
73 return 1;
74
75 return 0;
76}
77
78static int tps6105x_regulator_get_voltage_sel(struct regulator_dev *rdev)
79{
80 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
81 u8 regval;
82 int ret;
83
84 ret = tps6105x_get(tps6105x, TPS6105X_REG_0, &regval);
85 if (ret)
86 return ret;
87
88 regval &= TPS6105X_REG0_VOLTAGE_MASK;
89 regval >>= TPS6105X_REG0_VOLTAGE_SHIFT;
90 return (int) regval;
91}
92
93static int tps6105x_regulator_set_voltage_sel(struct regulator_dev *rdev,
94 unsigned selector)
95{
96 struct tps6105x *tps6105x = rdev_get_drvdata(rdev);
97 int ret;
98
99 ret = tps6105x_mask_and_set(tps6105x, TPS6105X_REG_0,
100 TPS6105X_REG0_VOLTAGE_MASK,
101 selector << TPS6105X_REG0_VOLTAGE_SHIFT);
102 if (ret)
103 return ret;
104
105 return 0;
106}
107
108static int tps6105x_regulator_list_voltage(struct regulator_dev *rdev,
109 unsigned selector)
110{
111 if (selector >= ARRAY_SIZE(tps6105x_voltages))
112 return -EINVAL;
113
114 return tps6105x_voltages[selector];
115}
116
117static struct regulator_ops tps6105x_regulator_ops = {
118 .enable = tps6105x_regulator_enable,
119 .disable = tps6105x_regulator_disable,
120 .is_enabled = tps6105x_regulator_is_enabled,
121 .get_voltage_sel = tps6105x_regulator_get_voltage_sel,
122 .set_voltage_sel = tps6105x_regulator_set_voltage_sel,
123 .list_voltage = tps6105x_regulator_list_voltage,
124};
125
126static struct regulator_desc tps6105x_regulator_desc = {
127 .name = "tps6105x-boost",
128 .ops = &tps6105x_regulator_ops,
129 .type = REGULATOR_VOLTAGE,
130 .id = 0,
131 .owner = THIS_MODULE,
132 .n_voltages = ARRAY_SIZE(tps6105x_voltages),
133};
134
135/*
136 * Registers the chip as a voltage regulator
137 */
138static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
139{
140 struct tps6105x *tps6105x = mfd_get_data(pdev);
141 struct tps6105x_platform_data *pdata = tps6105x->pdata;
142 int ret;
143
144 /* This instance is not set for regulator mode so bail out */
145 if (pdata->mode != TPS6105X_MODE_VOLTAGE) {
146 dev_info(&pdev->dev,
147 "chip not in voltage mode mode, exit probe \n");
148 return 0;
149 }
150
151 /* Register regulator with framework */
152 tps6105x->regulator = regulator_register(&tps6105x_regulator_desc,
153 &tps6105x->client->dev,
154 pdata->regulator_data, tps6105x);
155 if (IS_ERR(tps6105x->regulator)) {
156 ret = PTR_ERR(tps6105x->regulator);
157 dev_err(&tps6105x->client->dev,
158 "failed to register regulator\n");
159 return ret;
160 }
161
162 return 0;
163}
164
165static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
166{
167 struct tps6105x *tps6105x = platform_get_drvdata(pdev);
168 regulator_unregister(tps6105x->regulator);
169 return 0;
170}
171
172static struct platform_driver tps6105x_regulator_driver = {
173 .driver = {
174 .name = "tps6105x-regulator",
175 .owner = THIS_MODULE,
176 },
177 .probe = tps6105x_regulator_probe,
178 .remove = __devexit_p(tps6105x_regulator_remove),
179};
180
181static __init int tps6105x_regulator_init(void)
182{
183 return platform_driver_register(&tps6105x_regulator_driver);
184}
185subsys_initcall(tps6105x_regulator_init);
186
187static __exit void tps6105x_regulator_exit(void)
188{
189 platform_driver_unregister(&tps6105x_regulator_driver);
190}
191module_exit(tps6105x_regulator_exit);
192
193MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
194MODULE_DESCRIPTION("TPS6105x regulator driver");
195MODULE_LICENSE("GPL v2");
196MODULE_ALIAS("platform:tps6105x-regulator");
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index bd332cf1cc3f..6a292852a358 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -475,6 +475,13 @@ static struct regulator_ops twlfixed_ops = {
475 .get_status = twlreg_get_status, 475 .get_status = twlreg_get_status,
476}; 476};
477 477
478static struct regulator_ops twl6030_fixed_resource = {
479 .enable = twlreg_enable,
480 .disable = twlreg_disable,
481 .is_enabled = twlreg_is_enabled,
482 .get_status = twlreg_get_status,
483};
484
478/*----------------------------------------------------------------------*/ 485/*----------------------------------------------------------------------*/
479 486
480#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ 487#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
@@ -538,6 +545,20 @@ static struct regulator_ops twlfixed_ops = {
538 }, \ 545 }, \
539 } 546 }
540 547
548#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay, remap_conf) { \
549 .base = offset, \
550 .id = num, \
551 .delay = turnon_delay, \
552 .remap = remap_conf, \
553 .desc = { \
554 .name = #label, \
555 .id = TWL6030_REG_##label, \
556 .ops = &twl6030_fixed_resource, \
557 .type = REGULATOR_VOLTAGE, \
558 .owner = THIS_MODULE, \
559 }, \
560 }
561
541/* 562/*
542 * We list regulators here if systems need some level of 563 * We list regulators here if systems need some level of
543 * software control over them after boot. 564 * software control over them after boot.
@@ -577,7 +598,8 @@ static struct twlreg_info twl_regs[] = {
577 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), 598 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21),
578 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), 599 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21),
579 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), 600 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21),
580 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21) 601 TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21),
602 TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21),
581}; 603};
582 604
583static int __devinit twlreg_probe(struct platform_device *pdev) 605static int __devinit twlreg_probe(struct platform_device *pdev)
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index 4d2c75df886c..c69c6f2c2c5c 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -18,6 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/of.h> 19#include <linux/of.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/mfd/core.h>
21#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
22#include <linux/spi/spi_bitbang.h> 23#include <linux/spi/spi_bitbang.h>
23#include <linux/spi/xilinx_spi.h> 24#include <linux/spi/xilinx_spi.h>
@@ -470,7 +471,7 @@ static int __devinit xilinx_spi_probe(struct platform_device *dev)
470 struct spi_master *master; 471 struct spi_master *master;
471 u8 i; 472 u8 i;
472 473
473 pdata = dev->dev.platform_data; 474 pdata = mfd_get_data(dev);
474 if (pdata) { 475 if (pdata) {
475 num_cs = pdata->num_chipselect; 476 num_cs = pdata->num_chipselect;
476 little_endian = pdata->little_endian; 477 little_endian = pdata->little_endian;
diff --git a/drivers/usb/host/ohci-tmio.c b/drivers/usb/host/ohci-tmio.c
index 8dabe8e31d8c..3558491dd87d 100644
--- a/drivers/usb/host/ohci-tmio.c
+++ b/drivers/usb/host/ohci-tmio.c
@@ -185,7 +185,7 @@ static struct platform_driver ohci_hcd_tmio_driver;
185 185
186static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev) 186static int __devinit ohci_hcd_tmio_drv_probe(struct platform_device *dev)
187{ 187{
188 struct mfd_cell *cell = dev->dev.platform_data; 188 const struct mfd_cell *cell = mfd_get_cell(dev);
189 struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0); 189 struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
190 struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1); 190 struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1);
191 struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2); 191 struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2);
@@ -274,7 +274,7 @@ static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
274{ 274{
275 struct usb_hcd *hcd = platform_get_drvdata(dev); 275 struct usb_hcd *hcd = platform_get_drvdata(dev);
276 struct tmio_hcd *tmio = hcd_to_tmio(hcd); 276 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
277 struct mfd_cell *cell = dev->dev.platform_data; 277 const struct mfd_cell *cell = mfd_get_cell(dev);
278 278
279 usb_remove_hcd(hcd); 279 usb_remove_hcd(hcd);
280 tmio_stop_hc(dev); 280 tmio_stop_hc(dev);
@@ -293,7 +293,7 @@ static int __devexit ohci_hcd_tmio_drv_remove(struct platform_device *dev)
293#ifdef CONFIG_PM 293#ifdef CONFIG_PM
294static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state) 294static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t state)
295{ 295{
296 struct mfd_cell *cell = dev->dev.platform_data; 296 const struct mfd_cell *cell = mfd_get_cell(dev);
297 struct usb_hcd *hcd = platform_get_drvdata(dev); 297 struct usb_hcd *hcd = platform_get_drvdata(dev);
298 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 298 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
299 struct tmio_hcd *tmio = hcd_to_tmio(hcd); 299 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
@@ -326,7 +326,7 @@ static int ohci_hcd_tmio_drv_suspend(struct platform_device *dev, pm_message_t s
326 326
327static int ohci_hcd_tmio_drv_resume(struct platform_device *dev) 327static int ohci_hcd_tmio_drv_resume(struct platform_device *dev)
328{ 328{
329 struct mfd_cell *cell = dev->dev.platform_data; 329 const struct mfd_cell *cell = mfd_get_cell(dev);
330 struct usb_hcd *hcd = platform_get_drvdata(dev); 330 struct usb_hcd *hcd = platform_get_drvdata(dev);
331 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 331 struct ohci_hcd *ohci = hcd_to_ohci(hcd);
332 struct tmio_hcd *tmio = hcd_to_tmio(hcd); 332 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index e59623a15f3f..c8b520e9a11a 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -12,11 +12,12 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h>
15#include <linux/fb.h> 16#include <linux/fb.h>
16#include <linux/i2c.h> 17#include <linux/i2c.h>
17#include <linux/backlight.h> 18#include <linux/backlight.h>
19#include <linux/mfd/core.h>
18#include <linux/mfd/88pm860x.h> 20#include <linux/mfd/88pm860x.h>
19#include <linux/slab.h>
20 21
21#define MAX_BRIGHTNESS (0xFF) 22#define MAX_BRIGHTNESS (0xFF)
22#define MIN_BRIGHTNESS (0) 23#define MIN_BRIGHTNESS (0)
@@ -161,32 +162,13 @@ static const struct backlight_ops pm860x_backlight_ops = {
161 .get_brightness = pm860x_backlight_get_brightness, 162 .get_brightness = pm860x_backlight_get_brightness,
162}; 163};
163 164
164static int __check_device(struct pm860x_backlight_pdata *pdata, char *name)
165{
166 struct pm860x_backlight_pdata *p = pdata;
167 int ret = -EINVAL;
168
169 while (p && p->id) {
170 if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0))
171 break;
172
173 if (!strncmp(name, pm860x_backlight_name[p->flags],
174 MFD_NAME_SIZE)) {
175 ret = (int)p->flags;
176 break;
177 }
178 p++;
179 }
180 return ret;
181}
182
183static int pm860x_backlight_probe(struct platform_device *pdev) 165static int pm860x_backlight_probe(struct platform_device *pdev)
184{ 166{
185 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 167 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
186 struct pm860x_platform_data *pm860x_pdata;
187 struct pm860x_backlight_pdata *pdata = NULL; 168 struct pm860x_backlight_pdata *pdata = NULL;
188 struct pm860x_backlight_data *data; 169 struct pm860x_backlight_data *data;
189 struct backlight_device *bl; 170 struct backlight_device *bl;
171 struct mfd_cell *cell;
190 struct resource *res; 172 struct resource *res;
191 struct backlight_properties props; 173 struct backlight_properties props;
192 unsigned char value; 174 unsigned char value;
@@ -199,10 +181,10 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
199 return -EINVAL; 181 return -EINVAL;
200 } 182 }
201 183
202 if (pdev->dev.parent->platform_data) { 184 cell = pdev->dev.platform_data;
203 pm860x_pdata = pdev->dev.parent->platform_data; 185 if (cell == NULL)
204 pdata = pm860x_pdata->backlight; 186 return -ENODEV;
205 } 187 pdata = cell->mfd_data;
206 if (pdata == NULL) { 188 if (pdata == NULL) {
207 dev_err(&pdev->dev, "platform data isn't assigned to " 189 dev_err(&pdev->dev, "platform data isn't assigned to "
208 "backlight\n"); 190 "backlight\n");
@@ -219,7 +201,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)
219 data->current_brightness = MAX_BRIGHTNESS; 201 data->current_brightness = MAX_BRIGHTNESS;
220 data->pwm = pdata->pwm; 202 data->pwm = pdata->pwm;
221 data->iset = pdata->iset; 203 data->iset = pdata->iset;
222 data->port = __check_device(pdata, name); 204 data->port = pdata->flags;
223 if (data->port < 0) { 205 if (data->port < 0) {
224 dev_err(&pdev->dev, "wrong platform data is assigned"); 206 dev_err(&pdev->dev, "wrong platform data is assigned");
225 kfree(data); 207 kfree(data);
diff --git a/drivers/video/tmiofb.c b/drivers/video/tmiofb.c
index dfef88c803d4..9710bf8caeae 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/tmiofb.c
@@ -250,8 +250,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info)
250 */ 250 */
251static int tmiofb_hw_stop(struct platform_device *dev) 251static int tmiofb_hw_stop(struct platform_device *dev)
252{ 252{
253 struct mfd_cell *cell = dev->dev.platform_data; 253 struct tmio_fb_data *data = mfd_get_data(dev);
254 struct tmio_fb_data *data = cell->driver_data;
255 struct fb_info *info = platform_get_drvdata(dev); 254 struct fb_info *info = platform_get_drvdata(dev);
256 struct tmiofb_par *par = info->par; 255 struct tmiofb_par *par = info->par;
257 256
@@ -268,7 +267,7 @@ static int tmiofb_hw_stop(struct platform_device *dev)
268 */ 267 */
269static int tmiofb_hw_init(struct platform_device *dev) 268static int tmiofb_hw_init(struct platform_device *dev)
270{ 269{
271 struct mfd_cell *cell = dev->dev.platform_data; 270 const struct mfd_cell *cell = mfd_get_cell(dev);
272 struct fb_info *info = platform_get_drvdata(dev); 271 struct fb_info *info = platform_get_drvdata(dev);
273 struct tmiofb_par *par = info->par; 272 struct tmiofb_par *par = info->par;
274 const struct resource *nlcr = &cell->resources[0]; 273 const struct resource *nlcr = &cell->resources[0];
@@ -312,8 +311,7 @@ static int tmiofb_hw_init(struct platform_device *dev)
312 */ 311 */
313static void tmiofb_hw_mode(struct platform_device *dev) 312static void tmiofb_hw_mode(struct platform_device *dev)
314{ 313{
315 struct mfd_cell *cell = dev->dev.platform_data; 314 struct tmio_fb_data *data = mfd_get_data(dev);
316 struct tmio_fb_data *data = cell->driver_data;
317 struct fb_info *info = platform_get_drvdata(dev); 315 struct fb_info *info = platform_get_drvdata(dev);
318 struct fb_videomode *mode = info->mode; 316 struct fb_videomode *mode = info->mode;
319 struct tmiofb_par *par = info->par; 317 struct tmiofb_par *par = info->par;
@@ -559,9 +557,8 @@ static int tmiofb_ioctl(struct fb_info *fbi,
559static struct fb_videomode * 557static struct fb_videomode *
560tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) 558tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)
561{ 559{
562 struct mfd_cell *cell = 560 struct tmio_fb_data *data =
563 info->device->platform_data; 561 mfd_get_data(to_platform_device(info->device));
564 struct tmio_fb_data *data = cell->driver_data;
565 struct fb_videomode *best = NULL; 562 struct fb_videomode *best = NULL;
566 int i; 563 int i;
567 564
@@ -581,9 +578,8 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
581{ 578{
582 579
583 struct fb_videomode *mode; 580 struct fb_videomode *mode;
584 struct mfd_cell *cell = 581 struct tmio_fb_data *data =
585 info->device->platform_data; 582 mfd_get_data(to_platform_device(info->device));
586 struct tmio_fb_data *data = cell->driver_data;
587 583
588 mode = tmiofb_find_mode(info, var); 584 mode = tmiofb_find_mode(info, var);
589 if (!mode || var->bits_per_pixel > 16) 585 if (!mode || var->bits_per_pixel > 16)
@@ -683,8 +679,8 @@ static struct fb_ops tmiofb_ops = {
683 679
684static int __devinit tmiofb_probe(struct platform_device *dev) 680static int __devinit tmiofb_probe(struct platform_device *dev)
685{ 681{
686 struct mfd_cell *cell = dev->dev.platform_data; 682 const struct mfd_cell *cell = mfd_get_cell(dev);
687 struct tmio_fb_data *data = cell->driver_data; 683 struct tmio_fb_data *data = mfd_get_data(dev);
688 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); 684 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);
689 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); 685 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);
690 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); 686 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2);
@@ -811,7 +807,7 @@ err_ioremap_ccr:
811 807
812static int __devexit tmiofb_remove(struct platform_device *dev) 808static int __devexit tmiofb_remove(struct platform_device *dev)
813{ 809{
814 struct mfd_cell *cell = dev->dev.platform_data; 810 const struct mfd_cell *cell = mfd_get_cell(dev);
815 struct fb_info *info = platform_get_drvdata(dev); 811 struct fb_info *info = platform_get_drvdata(dev);
816 int irq = platform_get_irq(dev, 0); 812 int irq = platform_get_irq(dev, 0);
817 struct tmiofb_par *par; 813 struct tmiofb_par *par;
@@ -941,7 +937,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
941#ifdef CONFIG_FB_TMIO_ACCELL 937#ifdef CONFIG_FB_TMIO_ACCELL
942 struct tmiofb_par *par = info->par; 938 struct tmiofb_par *par = info->par;
943#endif 939#endif
944 struct mfd_cell *cell = dev->dev.platform_data; 940 const struct mfd_cell *cell = mfd_get_cell(dev);
945 int retval = 0; 941 int retval = 0;
946 942
947 console_lock(); 943 console_lock();
@@ -973,7 +969,7 @@ static int tmiofb_suspend(struct platform_device *dev, pm_message_t state)
973static int tmiofb_resume(struct platform_device *dev) 969static int tmiofb_resume(struct platform_device *dev)
974{ 970{
975 struct fb_info *info = platform_get_drvdata(dev); 971 struct fb_info *info = platform_get_drvdata(dev);
976 struct mfd_cell *cell = dev->dev.platform_data; 972 const struct mfd_cell *cell = mfd_get_cell(dev);
977 int retval = 0; 973 int retval = 0;
978 974
979 console_lock(); 975 console_lock();
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 6b85e7fefa43..95921b77cf86 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -90,7 +90,7 @@ struct ds1wm_data {
90 void __iomem *map; 90 void __iomem *map;
91 int bus_shift; /* # of shifts to calc register offsets */ 91 int bus_shift; /* # of shifts to calc register offsets */
92 struct platform_device *pdev; 92 struct platform_device *pdev;
93 struct mfd_cell *cell; 93 const struct mfd_cell *cell;
94 int irq; 94 int irq;
95 int active_high; 95 int active_high;
96 int slave_present; 96 int slave_present;
@@ -216,7 +216,7 @@ static int ds1wm_find_divisor(int gclk)
216static void ds1wm_up(struct ds1wm_data *ds1wm_data) 216static void ds1wm_up(struct ds1wm_data *ds1wm_data)
217{ 217{
218 int divisor; 218 int divisor;
219 struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data; 219 struct ds1wm_driver_data *plat = mfd_get_data(ds1wm_data->pdev);
220 220
221 if (ds1wm_data->cell->enable) 221 if (ds1wm_data->cell->enable)
222 ds1wm_data->cell->enable(ds1wm_data->pdev); 222 ds1wm_data->cell->enable(ds1wm_data->pdev);
@@ -330,16 +330,11 @@ static int ds1wm_probe(struct platform_device *pdev)
330 struct ds1wm_data *ds1wm_data; 330 struct ds1wm_data *ds1wm_data;
331 struct ds1wm_driver_data *plat; 331 struct ds1wm_driver_data *plat;
332 struct resource *res; 332 struct resource *res;
333 struct mfd_cell *cell;
334 int ret; 333 int ret;
335 334
336 if (!pdev) 335 if (!pdev)
337 return -ENODEV; 336 return -ENODEV;
338 337
339 cell = pdev->dev.platform_data;
340 if (!cell)
341 return -ENODEV;
342
343 ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); 338 ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
344 if (!ds1wm_data) 339 if (!ds1wm_data)
345 return -ENOMEM; 340 return -ENOMEM;
@@ -356,13 +351,13 @@ static int ds1wm_probe(struct platform_device *pdev)
356 ret = -ENOMEM; 351 ret = -ENOMEM;
357 goto err0; 352 goto err0;
358 } 353 }
359 plat = cell->driver_data; 354 plat = mfd_get_data(pdev);
360 355
361 /* calculate bus shift from mem resource */ 356 /* calculate bus shift from mem resource */
362 ds1wm_data->bus_shift = resource_size(res) >> 3; 357 ds1wm_data->bus_shift = resource_size(res) >> 3;
363 358
364 ds1wm_data->pdev = pdev; 359 ds1wm_data->pdev = pdev;
365 ds1wm_data->cell = cell; 360 ds1wm_data->cell = mfd_get_cell(pdev);
366 361
367 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 362 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
368 if (!res) { 363 if (!res) {
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c
index 3939e53f5f98..d8e725082fdc 100644
--- a/drivers/watchdog/rdc321x_wdt.c
+++ b/drivers/watchdog/rdc321x_wdt.c
@@ -37,6 +37,7 @@
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/mfd/rdc321x.h> 39#include <linux/mfd/rdc321x.h>
40#include <linux/mfd/core.h>
40 41
41#define RDC_WDT_MASK 0x80000000 /* Mask */ 42#define RDC_WDT_MASK 0x80000000 /* Mask */
42#define RDC_WDT_EN 0x00800000 /* Enable bit */ 43#define RDC_WDT_EN 0x00800000 /* Enable bit */
@@ -231,7 +232,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev)
231 struct resource *r; 232 struct resource *r;
232 struct rdc321x_wdt_pdata *pdata; 233 struct rdc321x_wdt_pdata *pdata;
233 234
234 pdata = platform_get_drvdata(pdev); 235 pdata = mfd_get_data(pdev);
235 if (!pdata) { 236 if (!pdata) {
236 dev_err(&pdev->dev, "no platform data supplied\n"); 237 dev_err(&pdev->dev, "no platform data supplied\n");
237 return -ENODEV; 238 return -ENODEV;
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 58afd9d2c438..0c0d1ae79981 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -698,6 +698,7 @@ struct twl4030_platform_data {
698 struct regulator_init_data *vana; 698 struct regulator_init_data *vana;
699 struct regulator_init_data *vcxio; 699 struct regulator_init_data *vcxio;
700 struct regulator_init_data *vusb; 700 struct regulator_init_data *vusb;
701 struct regulator_init_data *clk32kg;
701}; 702};
702 703
703/*----------------------------------------------------------------------*/ 704/*----------------------------------------------------------------------*/
@@ -777,5 +778,6 @@ static inline int twl4030charger_usb_en(int enable) { return 0; }
777 778
778/* INTERNAL LDOs */ 779/* INTERNAL LDOs */
779#define TWL6030_REG_VRTC 47 780#define TWL6030_REG_VRTC 47
781#define TWL6030_REG_CLK32KG 48
780 782
781#endif /* End of __TWL4030_H */ 783#endif /* End of __TWL4030_H */
diff --git a/include/linux/i2c/twl4030-madc.h b/include/linux/i2c/twl4030-madc.h
new file mode 100644
index 000000000000..6427d298fbfc
--- /dev/null
+++ b/include/linux/i2c/twl4030-madc.h
@@ -0,0 +1,141 @@
1/*
2 * twl4030_madc.h - Header for TWL4030 MADC
3 *
4 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
5 * J Keerthy <j-keerthy@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#ifndef _TWL4030_MADC_H
24#define _TWL4030_MADC_H
25
26struct twl4030_madc_conversion_method {
27 u8 sel;
28 u8 avg;
29 u8 rbase;
30 u8 ctrl;
31};
32
33#define TWL4030_MADC_MAX_CHANNELS 16
34
35
36/*
37 * twl4030_madc_request- madc request packet for channel conversion
38 * @channels: 16 bit bitmap for individual channels
39 * @do_avgP: sample the input channel for 4 consecutive cycles
40 * @method: RT, SW1, SW2
41 * @type: Polling or interrupt based method
42 */
43
44struct twl4030_madc_request {
45 unsigned long channels;
46 u16 do_avg;
47 u16 method;
48 u16 type;
49 bool active;
50 bool result_pending;
51 int rbuf[TWL4030_MADC_MAX_CHANNELS];
52 void (*func_cb)(int len, int channels, int *buf);
53};
54
55enum conversion_methods {
56 TWL4030_MADC_RT,
57 TWL4030_MADC_SW1,
58 TWL4030_MADC_SW2,
59 TWL4030_MADC_NUM_METHODS
60};
61
62enum sample_type {
63 TWL4030_MADC_WAIT,
64 TWL4030_MADC_IRQ_ONESHOT,
65 TWL4030_MADC_IRQ_REARM
66};
67
68#define TWL4030_MADC_CTRL1 0x00
69#define TWL4030_MADC_CTRL2 0x01
70
71#define TWL4030_MADC_RTSELECT_LSB 0x02
72#define TWL4030_MADC_SW1SELECT_LSB 0x06
73#define TWL4030_MADC_SW2SELECT_LSB 0x0A
74
75#define TWL4030_MADC_RTAVERAGE_LSB 0x04
76#define TWL4030_MADC_SW1AVERAGE_LSB 0x08
77#define TWL4030_MADC_SW2AVERAGE_LSB 0x0C
78
79#define TWL4030_MADC_CTRL_SW1 0x12
80#define TWL4030_MADC_CTRL_SW2 0x13
81
82#define TWL4030_MADC_RTCH0_LSB 0x17
83#define TWL4030_MADC_GPCH0_LSB 0x37
84
85#define TWL4030_MADC_MADCON (1 << 0) /* MADC power on */
86#define TWL4030_MADC_BUSY (1 << 0) /* MADC busy */
87/* MADC conversion completion */
88#define TWL4030_MADC_EOC_SW (1 << 1)
89/* MADC SWx start conversion */
90#define TWL4030_MADC_SW_START (1 << 5)
91#define TWL4030_MADC_ADCIN0 (1 << 0)
92#define TWL4030_MADC_ADCIN1 (1 << 1)
93#define TWL4030_MADC_ADCIN2 (1 << 2)
94#define TWL4030_MADC_ADCIN3 (1 << 3)
95#define TWL4030_MADC_ADCIN4 (1 << 4)
96#define TWL4030_MADC_ADCIN5 (1 << 5)
97#define TWL4030_MADC_ADCIN6 (1 << 6)
98#define TWL4030_MADC_ADCIN7 (1 << 7)
99#define TWL4030_MADC_ADCIN8 (1 << 8)
100#define TWL4030_MADC_ADCIN9 (1 << 9)
101#define TWL4030_MADC_ADCIN10 (1 << 10)
102#define TWL4030_MADC_ADCIN11 (1 << 11)
103#define TWL4030_MADC_ADCIN12 (1 << 12)
104#define TWL4030_MADC_ADCIN13 (1 << 13)
105#define TWL4030_MADC_ADCIN14 (1 << 14)
106#define TWL4030_MADC_ADCIN15 (1 << 15)
107
108/* Fixed channels */
109#define TWL4030_MADC_BTEMP TWL4030_MADC_ADCIN1
110#define TWL4030_MADC_VBUS TWL4030_MADC_ADCIN8
111#define TWL4030_MADC_VBKB TWL4030_MADC_ADCIN9
112#define TWL4030_MADC_ICHG TWL4030_MADC_ADCIN10
113#define TWL4030_MADC_VCHG TWL4030_MADC_ADCIN11
114#define TWL4030_MADC_VBAT TWL4030_MADC_ADCIN12
115
116/* Step size and prescaler ratio */
117#define TEMP_STEP_SIZE 147
118#define TEMP_PSR_R 100
119#define CURR_STEP_SIZE 147
120#define CURR_PSR_R1 44
121#define CURR_PSR_R2 88
122
123#define TWL4030_BCI_BCICTL1 0x23
124#define TWL4030_BCI_CGAIN 0x020
125#define TWL4030_BCI_MESBAT (1 << 1)
126#define TWL4030_BCI_TYPEN (1 << 4)
127#define TWL4030_BCI_ITHEN (1 << 3)
128
129#define REG_BCICTL2 0x024
130#define TWL4030_BCI_ITHSENS 0x007
131
132struct twl4030_madc_user_parms {
133 int channel;
134 int average;
135 int status;
136 u16 result;
137};
138
139int twl4030_madc_conversion(struct twl4030_madc_request *conv);
140int twl4030_get_madc_conversion(int channel_no);
141#endif
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 4db1fbd8969e..8fba7972ff5f 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -131,9 +131,11 @@ enum {
131 PM8607_ID_LDO8, 131 PM8607_ID_LDO8,
132 PM8607_ID_LDO9, 132 PM8607_ID_LDO9,
133 PM8607_ID_LDO10, 133 PM8607_ID_LDO10,
134 PM8607_ID_LDO11,
134 PM8607_ID_LDO12, 135 PM8607_ID_LDO12,
135 PM8607_ID_LDO13, 136 PM8607_ID_LDO13,
136 PM8607_ID_LDO14, 137 PM8607_ID_LDO14,
138 PM8607_ID_LDO15,
137 139
138 PM8607_ID_RG_MAX, 140 PM8607_ID_RG_MAX,
139}; 141};
@@ -310,8 +312,6 @@ struct pm860x_chip {
310 312
311}; 313};
312 314
313#define PM8607_MAX_REGULATOR PM8607_ID_RG_MAX /* 3 Bucks, 13 LDOs */
314
315enum { 315enum {
316 GI2C_PORT = 0, 316 GI2C_PORT = 0,
317 PI2C_PORT, 317 PI2C_PORT,
@@ -351,23 +351,31 @@ struct pm860x_platform_data {
351 struct pm860x_led_pdata *led; 351 struct pm860x_led_pdata *led;
352 struct pm860x_touch_pdata *touch; 352 struct pm860x_touch_pdata *touch;
353 struct pm860x_power_pdata *power; 353 struct pm860x_power_pdata *power;
354 struct regulator_init_data *regulator;
354 355
355 unsigned short companion_addr; /* I2C address of companion chip */ 356 unsigned short companion_addr; /* I2C address of companion chip */
356 int i2c_port; /* Controlled by GI2C or PI2C */ 357 int i2c_port; /* Controlled by GI2C or PI2C */
357 int irq_mode; /* Clear interrupt by read/write(0/1) */ 358 int irq_mode; /* Clear interrupt by read/write(0/1) */
358 int irq_base; /* IRQ base number of 88pm860x */ 359 int irq_base; /* IRQ base number of 88pm860x */
359 struct regulator_init_data *regulator[PM8607_MAX_REGULATOR]; 360 int num_leds;
361 int num_backlights;
362 int num_regulators;
360}; 363};
361 364
362extern char pm860x_backlight_name[][MFD_NAME_SIZE];
363extern char pm860x_led_name[][MFD_NAME_SIZE];
364
365extern int pm860x_reg_read(struct i2c_client *, int); 365extern int pm860x_reg_read(struct i2c_client *, int);
366extern int pm860x_reg_write(struct i2c_client *, int, unsigned char); 366extern int pm860x_reg_write(struct i2c_client *, int, unsigned char);
367extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *); 367extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *);
368extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *); 368extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *);
369extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, 369extern int pm860x_set_bits(struct i2c_client *, int, unsigned char,
370 unsigned char); 370 unsigned char);
371extern int pm860x_page_reg_read(struct i2c_client *, int);
372extern int pm860x_page_reg_write(struct i2c_client *, int, unsigned char);
373extern int pm860x_page_bulk_read(struct i2c_client *, int, int,
374 unsigned char *);
375extern int pm860x_page_bulk_write(struct i2c_client *, int, int,
376 unsigned char *);
377extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char,
378 unsigned char);
371 379
372extern int pm860x_device_init(struct pm860x_chip *chip, 380extern int pm860x_device_init(struct pm860x_chip *chip,
373 struct pm860x_platform_data *pdata) __devinit ; 381 struct pm860x_platform_data *pdata) __devinit ;
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h
index 37f56b7c4c15..56f8dea72152 100644
--- a/include/linux/mfd/ab8500.h
+++ b/include/linux/mfd/ab8500.h
@@ -111,8 +111,8 @@
111 * @dev: parent device 111 * @dev: parent device
112 * @lock: read/write operations lock 112 * @lock: read/write operations lock
113 * @irq_lock: genirq bus lock 113 * @irq_lock: genirq bus lock
114 * @revision: chip revision
115 * @irq: irq line 114 * @irq: irq line
115 * @chip_id: chip revision id
116 * @write: register write 116 * @write: register write
117 * @read: register read 117 * @read: register read
118 * @rx_buf: rx buf for SPI 118 * @rx_buf: rx buf for SPI
@@ -124,7 +124,7 @@ struct ab8500 {
124 struct device *dev; 124 struct device *dev;
125 struct mutex lock; 125 struct mutex lock;
126 struct mutex irq_lock; 126 struct mutex irq_lock;
127 int revision; 127
128 int irq_base; 128 int irq_base;
129 int irq; 129 int irq;
130 u8 chip_id; 130 u8 chip_id;
diff --git a/include/linux/mfd/ab8500/gpadc.h b/include/linux/mfd/ab8500/gpadc.h
new file mode 100644
index 000000000000..46b954011f16
--- /dev/null
+++ b/include/linux/mfd/ab8500/gpadc.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2010 ST-Ericsson SA
3 * Licensed under GPLv2.
4 *
5 * Author: Arun R Murthy <arun.murthy@stericsson.com>
6 * Author: Daniel Willerud <daniel.willerud@stericsson.com>
7 */
8
9#ifndef _AB8500_GPADC_H
10#define _AB8500_GPADC_H
11
12/* GPADC source: From datasheet(ADCSwSel[4:0] in GPADCCtrl2) */
13#define BAT_CTRL 0x01
14#define BTEMP_BALL 0x02
15#define MAIN_CHARGER_V 0x03
16#define ACC_DETECT1 0x04
17#define ACC_DETECT2 0x05
18#define ADC_AUX1 0x06
19#define ADC_AUX2 0x07
20#define MAIN_BAT_V 0x08
21#define VBUS_V 0x09
22#define MAIN_CHARGER_C 0x0A
23#define USB_CHARGER_C 0x0B
24#define BK_BAT_V 0x0C
25#define DIE_TEMP 0x0D
26
27struct ab8500_gpadc;
28
29struct ab8500_gpadc *ab8500_gpadc_get(char *name);
30int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input);
31
32#endif /* _AB8500_GPADC_H */
diff --git a/include/linux/mfd/ab8500/sysctrl.h b/include/linux/mfd/ab8500/sysctrl.h
new file mode 100644
index 000000000000..10da0291f8f8
--- /dev/null
+++ b/include/linux/mfd/ab8500/sysctrl.h
@@ -0,0 +1,254 @@
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#ifndef __AB8500_SYSCTRL_H
7#define __AB8500_SYSCTRL_H
8
9#include <linux/bitops.h>
10
11#ifdef CONFIG_AB8500_CORE
12
13int ab8500_sysctrl_read(u16 reg, u8 *value);
14int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value);
15
16#else
17
18static inline int ab8500_sysctrl_read(u16 reg, u8 *value)
19{
20 return 0;
21}
22
23static inline int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value)
24{
25 return 0;
26}
27
28#endif /* CONFIG_AB8500_CORE */
29
30static inline int ab8500_sysctrl_set(u16 reg, u8 bits)
31{
32 return ab8500_sysctrl_write(reg, bits, bits);
33}
34
35static inline int ab8500_sysctrl_clear(u16 reg, u8 bits)
36{
37 return ab8500_sysctrl_write(reg, bits, 0);
38}
39
40/* Registers */
41#define AB8500_TURNONSTATUS 0x100
42#define AB8500_RESETSTATUS 0x101
43#define AB8500_PONKEY1PRESSSTATUS 0x102
44#define AB8500_SYSCLKREQSTATUS 0x142
45#define AB8500_STW4500CTRL1 0x180
46#define AB8500_STW4500CTRL2 0x181
47#define AB8500_STW4500CTRL3 0x200
48#define AB8500_MAINWDOGCTRL 0x201
49#define AB8500_MAINWDOGTIMER 0x202
50#define AB8500_LOWBAT 0x203
51#define AB8500_BATTOK 0x204
52#define AB8500_SYSCLKTIMER 0x205
53#define AB8500_SMPSCLKCTRL 0x206
54#define AB8500_SMPSCLKSEL1 0x207
55#define AB8500_SMPSCLKSEL2 0x208
56#define AB8500_SMPSCLKSEL3 0x209
57#define AB8500_SYSULPCLKCONF 0x20A
58#define AB8500_SYSULPCLKCTRL1 0x20B
59#define AB8500_SYSCLKCTRL 0x20C
60#define AB8500_SYSCLKREQ1VALID 0x20D
61#define AB8500_SYSTEMCTRLSUP 0x20F
62#define AB8500_SYSCLKREQ1RFCLKBUF 0x210
63#define AB8500_SYSCLKREQ2RFCLKBUF 0x211
64#define AB8500_SYSCLKREQ3RFCLKBUF 0x212
65#define AB8500_SYSCLKREQ4RFCLKBUF 0x213
66#define AB8500_SYSCLKREQ5RFCLKBUF 0x214
67#define AB8500_SYSCLKREQ6RFCLKBUF 0x215
68#define AB8500_SYSCLKREQ7RFCLKBUF 0x216
69#define AB8500_SYSCLKREQ8RFCLKBUF 0x217
70#define AB8500_DITHERCLKCTRL 0x220
71#define AB8500_SWATCTRL 0x230
72#define AB8500_HIQCLKCTRL 0x232
73#define AB8500_VSIMSYSCLKCTRL 0x233
74
75/* Bits */
76#define AB8500_TURNONSTATUS_PORNVBAT BIT(0)
77#define AB8500_TURNONSTATUS_PONKEY1DBF BIT(1)
78#define AB8500_TURNONSTATUS_PONKEY2DBF BIT(2)
79#define AB8500_TURNONSTATUS_RTCALARM BIT(3)
80#define AB8500_TURNONSTATUS_MAINCHDET BIT(4)
81#define AB8500_TURNONSTATUS_VBUSDET BIT(5)
82#define AB8500_TURNONSTATUS_USBIDDETECT BIT(6)
83
84#define AB8500_RESETSTATUS_RESETN4500NSTATUS BIT(0)
85#define AB8500_RESETSTATUS_SWRESETN4500NSTATUS BIT(2)
86
87#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_MASK 0x7F
88#define AB8500_PONKEY1PRESSSTATUS_PONKEY1PRESSTIME_SHIFT 0
89
90#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ1STATUS BIT(0)
91#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ2STATUS BIT(1)
92#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ3STATUS BIT(2)
93#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ4STATUS BIT(3)
94#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ5STATUS BIT(4)
95#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ6STATUS BIT(5)
96#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ7STATUS BIT(6)
97#define AB8500_SYSCLKREQSTATUS_SYSCLKREQ8STATUS BIT(7)
98
99#define AB8500_STW4500CTRL1_SWOFF BIT(0)
100#define AB8500_STW4500CTRL1_SWRESET4500N BIT(1)
101#define AB8500_STW4500CTRL1_THDB8500SWOFF BIT(2)
102
103#define AB8500_STW4500CTRL2_RESETNVAUX1VALID BIT(0)
104#define AB8500_STW4500CTRL2_RESETNVAUX2VALID BIT(1)
105#define AB8500_STW4500CTRL2_RESETNVAUX3VALID BIT(2)
106#define AB8500_STW4500CTRL2_RESETNVMODVALID BIT(3)
107#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY1VALID BIT(4)
108#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY2VALID BIT(5)
109#define AB8500_STW4500CTRL2_RESETNVEXTSUPPLY3VALID BIT(6)
110#define AB8500_STW4500CTRL2_RESETNVSMPS1VALID BIT(7)
111
112#define AB8500_STW4500CTRL3_CLK32KOUT2DIS BIT(0)
113#define AB8500_STW4500CTRL3_RESETAUDN BIT(1)
114#define AB8500_STW4500CTRL3_RESETDENCN BIT(2)
115#define AB8500_STW4500CTRL3_THSDENA BIT(3)
116
117#define AB8500_MAINWDOGCTRL_MAINWDOGENA BIT(0)
118#define AB8500_MAINWDOGCTRL_MAINWDOGKICK BIT(1)
119#define AB8500_MAINWDOGCTRL_WDEXPTURNONVALID BIT(4)
120
121#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_MASK 0x7F
122#define AB8500_MAINWDOGTIMER_MAINWDOGTIMER_SHIFT 0
123
124#define AB8500_LOWBAT_LOWBATENA BIT(0)
125#define AB8500_LOWBAT_LOWBAT_MASK 0x7E
126#define AB8500_LOWBAT_LOWBAT_SHIFT 1
127
128#define AB8500_BATTOK_BATTOKSEL0THF_MASK 0x0F
129#define AB8500_BATTOK_BATTOKSEL0THF_SHIFT 0
130#define AB8500_BATTOK_BATTOKSEL1THF_MASK 0xF0
131#define AB8500_BATTOK_BATTOKSEL1THF_SHIFT 4
132
133#define AB8500_SYSCLKTIMER_SYSCLKTIMER_MASK 0x0F
134#define AB8500_SYSCLKTIMER_SYSCLKTIMER_SHIFT 0
135#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_MASK 0xF0
136#define AB8500_SYSCLKTIMER_SYSCLKTIMERADJ_SHIFT 4
137
138#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_MASK 0x03
139#define AB8500_SMPSCLKCTRL_SMPSCLKINTSEL_SHIFT 0
140#define AB8500_SMPSCLKCTRL_3M2CLKINTENA BIT(2)
141
142#define AB8500_SMPSCLKSEL1_VARMCLKSEL_MASK 0x07
143#define AB8500_SMPSCLKSEL1_VARMCLKSEL_SHIFT 0
144#define AB8500_SMPSCLKSEL1_VAPECLKSEL_MASK 0x38
145#define AB8500_SMPSCLKSEL1_VAPECLKSEL_SHIFT 3
146
147#define AB8500_SMPSCLKSEL2_VMODCLKSEL_MASK 0x07
148#define AB8500_SMPSCLKSEL2_VMODCLKSEL_SHIFT 0
149#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_MASK 0x38
150#define AB8500_SMPSCLKSEL2_VSMPS1CLKSEL_SHIFT 3
151
152#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_MASK 0x07
153#define AB8500_SMPSCLKSEL3_VSMPS2CLKSEL_SHIFT 0
154#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_MASK 0x38
155#define AB8500_SMPSCLKSEL3_VSMPS3CLKSEL_SHIFT 3
156
157#define AB8500_SYSULPCLKCONF_ULPCLKCONF_MASK 0x03
158#define AB8500_SYSULPCLKCONF_ULPCLKCONF_SHIFT 0
159#define AB8500_SYSULPCLKCONF_CLK27MHZSTRE BIT(2)
160#define AB8500_SYSULPCLKCONF_TVOUTCLKDELN BIT(3)
161#define AB8500_SYSULPCLKCONF_TVOUTCLKINV BIT(4)
162#define AB8500_SYSULPCLKCONF_ULPCLKSTRE BIT(5)
163#define AB8500_SYSULPCLKCONF_CLK27MHZBUFENA BIT(6)
164#define AB8500_SYSULPCLKCONF_CLK27MHZPDENA BIT(7)
165
166#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_MASK 0x03
167#define AB8500_SYSULPCLKCTRL1_SYSULPCLKINTSEL_SHIFT 0
168#define AB8500_SYSULPCLKCTRL1_ULPCLKREQ BIT(2)
169#define AB8500_SYSULPCLKCTRL1_4500SYSCLKREQ BIT(3)
170#define AB8500_SYSULPCLKCTRL1_AUDIOCLKENA BIT(4)
171#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF2REQ BIT(5)
172#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF3REQ BIT(6)
173#define AB8500_SYSULPCLKCTRL1_SYSCLKBUF4REQ BIT(7)
174
175#define AB8500_SYSCLKCTRL_TVOUTPLLENA BIT(0)
176#define AB8500_SYSCLKCTRL_TVOUTCLKENA BIT(1)
177#define AB8500_SYSCLKCTRL_USBCLKENA BIT(2)
178
179#define AB8500_SYSCLKREQ1VALID_SYSCLKREQ1VALID BIT(0)
180#define AB8500_SYSCLKREQ1VALID_ULPCLKREQ1VALID BIT(1)
181#define AB8500_SYSCLKREQ1VALID_USBSYSCLKREQ1VALID BIT(2)
182
183#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_MASK 0x03
184#define AB8500_SYSTEMCTRLSUP_EXTSUP12LPNCLKSEL_SHIFT 0
185#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_MASK 0x0C
186#define AB8500_SYSTEMCTRLSUP_EXTSUP3LPNCLKSEL_SHIFT 2
187#define AB8500_SYSTEMCTRLSUP_INTDB8500NOD BIT(4)
188
189#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF2 BIT(2)
190#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF3 BIT(3)
191#define AB8500_SYSCLKREQ1RFCLKBUF_SYSCLKREQ1RFCLKBUF4 BIT(4)
192
193#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF2 BIT(2)
194#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF3 BIT(3)
195#define AB8500_SYSCLKREQ2RFCLKBUF_SYSCLKREQ2RFCLKBUF4 BIT(4)
196
197#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF2 BIT(2)
198#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF3 BIT(3)
199#define AB8500_SYSCLKREQ3RFCLKBUF_SYSCLKREQ3RFCLKBUF4 BIT(4)
200
201#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF2 BIT(2)
202#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF3 BIT(3)
203#define AB8500_SYSCLKREQ4RFCLKBUF_SYSCLKREQ4RFCLKBUF4 BIT(4)
204
205#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF2 BIT(2)
206#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF3 BIT(3)
207#define AB8500_SYSCLKREQ5RFCLKBUF_SYSCLKREQ5RFCLKBUF4 BIT(4)
208
209#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF2 BIT(2)
210#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF3 BIT(3)
211#define AB8500_SYSCLKREQ6RFCLKBUF_SYSCLKREQ6RFCLKBUF4 BIT(4)
212
213#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF2 BIT(2)
214#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF3 BIT(3)
215#define AB8500_SYSCLKREQ7RFCLKBUF_SYSCLKREQ7RFCLKBUF4 BIT(4)
216
217#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF2 BIT(2)
218#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF3 BIT(3)
219#define AB8500_SYSCLKREQ8RFCLKBUF_SYSCLKREQ8RFCLKBUF4 BIT(4)
220
221#define AB8500_DITHERCLKCTRL_VARMDITHERENA BIT(0)
222#define AB8500_DITHERCLKCTRL_VSMPS3DITHERENA BIT(1)
223#define AB8500_DITHERCLKCTRL_VSMPS1DITHERENA BIT(2)
224#define AB8500_DITHERCLKCTRL_VSMPS2DITHERENA BIT(3)
225#define AB8500_DITHERCLKCTRL_VMODDITHERENA BIT(4)
226#define AB8500_DITHERCLKCTRL_VAPEDITHERENA BIT(5)
227#define AB8500_DITHERCLKCTRL_DITHERDEL_MASK 0xC0
228#define AB8500_DITHERCLKCTRL_DITHERDEL_SHIFT 6
229
230#define AB8500_SWATCTRL_UPDATERF BIT(0)
231#define AB8500_SWATCTRL_SWATENABLE BIT(1)
232#define AB8500_SWATCTRL_RFOFFTIMER_MASK 0x1C
233#define AB8500_SWATCTRL_RFOFFTIMER_SHIFT 2
234#define AB8500_SWATCTRL_SWATBIT5 BIT(6)
235
236#define AB8500_HIQCLKCTRL_SYSCLKREQ1HIQENAVALID BIT(0)
237#define AB8500_HIQCLKCTRL_SYSCLKREQ2HIQENAVALID BIT(1)
238#define AB8500_HIQCLKCTRL_SYSCLKREQ3HIQENAVALID BIT(2)
239#define AB8500_HIQCLKCTRL_SYSCLKREQ4HIQENAVALID BIT(3)
240#define AB8500_HIQCLKCTRL_SYSCLKREQ5HIQENAVALID BIT(4)
241#define AB8500_HIQCLKCTRL_SYSCLKREQ6HIQENAVALID BIT(5)
242#define AB8500_HIQCLKCTRL_SYSCLKREQ7HIQENAVALID BIT(6)
243#define AB8500_HIQCLKCTRL_SYSCLKREQ8HIQENAVALID BIT(7)
244
245#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ1VALID BIT(0)
246#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ2VALID BIT(1)
247#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ3VALID BIT(2)
248#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ4VALID BIT(3)
249#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ5VALID BIT(4)
250#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ6VALID BIT(5)
251#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ7VALID BIT(6)
252#define AB8500_VSIMSYSCLKCTRL_VSIMSYSCLKREQ8VALID BIT(7)
253
254#endif /* __AB8500_SYSCTRL_H */
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 67bd6f7ecf32..7d9b6ae1c203 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -186,7 +186,6 @@ struct abx500_init_settings {
186struct ab3550_platform_data { 186struct ab3550_platform_data {
187 struct {unsigned int base; unsigned int count; } irq; 187 struct {unsigned int base; unsigned int count; } irq;
188 void *dev_data[AB3550_NUM_DEVICES]; 188 void *dev_data[AB3550_NUM_DEVICES];
189 size_t dev_data_sz[AB3550_NUM_DEVICES];
190 struct abx500_init_settings *init_settings; 189 struct abx500_init_settings *init_settings;
191 unsigned int init_settings_sz; 190 unsigned int init_settings_sz;
192}; 191};
diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h
index 835996e167e1..1408bf8eed5f 100644
--- a/include/linux/mfd/core.h
+++ b/include/linux/mfd/core.h
@@ -25,22 +25,20 @@ struct mfd_cell {
25 const char *name; 25 const char *name;
26 int id; 26 int id;
27 27
28 /* refcounting for multiple drivers to use a single cell */
29 atomic_t *usage_count;
28 int (*enable)(struct platform_device *dev); 30 int (*enable)(struct platform_device *dev);
29 int (*disable)(struct platform_device *dev); 31 int (*disable)(struct platform_device *dev);
32
30 int (*suspend)(struct platform_device *dev); 33 int (*suspend)(struct platform_device *dev);
31 int (*resume)(struct platform_device *dev); 34 int (*resume)(struct platform_device *dev);
32 35
33 /* driver-specific data for MFD-aware "cell" drivers */ 36 /* mfd_data can be used to pass data to client drivers */
34 void *driver_data; 37 void *mfd_data;
35
36 /* platform_data can be used to either pass data to "generic"
37 driver or as a hook to mfd_cell for the "cell" drivers */
38 void *platform_data;
39 size_t data_size;
40 38
41 /* 39 /*
42 * This resources can be specified relatively to the parent device. 40 * These resources can be specified relative to the parent device.
43 * For accessing device you should use resources from device 41 * For accessing hardware you should use resources from the platform dev
44 */ 42 */
45 int num_resources; 43 int num_resources;
46 const struct resource *resources; 44 const struct resource *resources;
@@ -55,11 +53,47 @@ struct mfd_cell {
55 bool pm_runtime_no_callbacks; 53 bool pm_runtime_no_callbacks;
56}; 54};
57 55
56/*
57 * Convenience functions for clients using shared cells. Refcounting
58 * happens automatically, with the cell's enable/disable callbacks
59 * being called only when a device is first being enabled or no other
60 * clients are making use of it.
61 */
62extern int mfd_cell_enable(struct platform_device *pdev);
63extern int mfd_cell_disable(struct platform_device *pdev);
64
65/*
66 * Given a platform device that's been created by mfd_add_devices(), fetch
67 * the mfd_cell that created it.
68 */
69static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev)
70{
71 return pdev->dev.platform_data;
72}
73
74/*
75 * Given a platform device that's been created by mfd_add_devices(), fetch
76 * the .mfd_data entry from the mfd_cell that created it.
77 */
78static inline void *mfd_get_data(struct platform_device *pdev)
79{
80 return mfd_get_cell(pdev)->mfd_data;
81}
82
58extern int mfd_add_devices(struct device *parent, int id, 83extern int mfd_add_devices(struct device *parent, int id,
59 const struct mfd_cell *cells, int n_devs, 84 struct mfd_cell *cells, int n_devs,
60 struct resource *mem_base, 85 struct resource *mem_base,
61 int irq_base); 86 int irq_base);
62 87
63extern void mfd_remove_devices(struct device *parent); 88extern void mfd_remove_devices(struct device *parent);
64 89
90/*
91 * For MFD drivers with clients sharing access to resources, these create
92 * multiple platform devices per cell. Contention handling must still be
93 * handled via drivers (ie, with enable/disable hooks).
94 */
95extern int mfd_shared_platform_driver_register(struct platform_driver *drv,
96 const char *cellname);
97extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv);
98
65#endif 99#endif
diff --git a/include/linux/mfd/max8997-private.h b/include/linux/mfd/max8997-private.h
new file mode 100644
index 000000000000..93a9477e075f
--- /dev/null
+++ b/include/linux/mfd/max8997-private.h
@@ -0,0 +1,347 @@
1/*
2 * max8997.h - Voltage regulator driver for the Maxim 8997
3 *
4 * Copyright (C) 2010 Samsung Electrnoics
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
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
22#ifndef __LINUX_MFD_MAX8997_PRIV_H
23#define __LINUX_MFD_MAX8997_PRIV_H
24
25#include <linux/i2c.h>
26
27enum max8997_pmic_reg {
28 MAX8997_REG_PMIC_ID0 = 0x00,
29 MAX8997_REG_PMIC_ID1 = 0x01,
30 MAX8997_REG_INTSRC = 0x02,
31 MAX8997_REG_INT1 = 0x03,
32 MAX8997_REG_INT2 = 0x04,
33 MAX8997_REG_INT3 = 0x05,
34 MAX8997_REG_INT4 = 0x06,
35
36 MAX8997_REG_INT1MSK = 0x08,
37 MAX8997_REG_INT2MSK = 0x09,
38 MAX8997_REG_INT3MSK = 0x0a,
39 MAX8997_REG_INT4MSK = 0x0b,
40
41 MAX8997_REG_STATUS1 = 0x0d,
42 MAX8997_REG_STATUS2 = 0x0e,
43 MAX8997_REG_STATUS3 = 0x0f,
44 MAX8997_REG_STATUS4 = 0x10,
45
46 MAX8997_REG_MAINCON1 = 0x13,
47 MAX8997_REG_MAINCON2 = 0x14,
48 MAX8997_REG_BUCKRAMP = 0x15,
49
50 MAX8997_REG_BUCK1CTRL = 0x18,
51 MAX8997_REG_BUCK1DVS1 = 0x19,
52 MAX8997_REG_BUCK1DVS2 = 0x1a,
53 MAX8997_REG_BUCK1DVS3 = 0x1b,
54 MAX8997_REG_BUCK1DVS4 = 0x1c,
55 MAX8997_REG_BUCK1DVS5 = 0x1d,
56 MAX8997_REG_BUCK1DVS6 = 0x1e,
57 MAX8997_REG_BUCK1DVS7 = 0x1f,
58 MAX8997_REG_BUCK1DVS8 = 0x20,
59 MAX8997_REG_BUCK2CTRL = 0x21,
60 MAX8997_REG_BUCK2DVS1 = 0x22,
61 MAX8997_REG_BUCK2DVS2 = 0x23,
62 MAX8997_REG_BUCK2DVS3 = 0x24,
63 MAX8997_REG_BUCK2DVS4 = 0x25,
64 MAX8997_REG_BUCK2DVS5 = 0x26,
65 MAX8997_REG_BUCK2DVS6 = 0x27,
66 MAX8997_REG_BUCK2DVS7 = 0x28,
67 MAX8997_REG_BUCK2DVS8 = 0x29,
68 MAX8997_REG_BUCK3CTRL = 0x2a,
69 MAX8997_REG_BUCK3DVS = 0x2b,
70 MAX8997_REG_BUCK4CTRL = 0x2c,
71 MAX8997_REG_BUCK4DVS = 0x2d,
72 MAX8997_REG_BUCK5CTRL = 0x2e,
73 MAX8997_REG_BUCK5DVS1 = 0x2f,
74 MAX8997_REG_BUCK5DVS2 = 0x30,
75 MAX8997_REG_BUCK5DVS3 = 0x31,
76 MAX8997_REG_BUCK5DVS4 = 0x32,
77 MAX8997_REG_BUCK5DVS5 = 0x33,
78 MAX8997_REG_BUCK5DVS6 = 0x34,
79 MAX8997_REG_BUCK5DVS7 = 0x35,
80 MAX8997_REG_BUCK5DVS8 = 0x36,
81 MAX8997_REG_BUCK6CTRL = 0x37,
82 MAX8997_REG_BUCK6BPSKIPCTRL = 0x38,
83 MAX8997_REG_BUCK7CTRL = 0x39,
84 MAX8997_REG_BUCK7DVS = 0x3a,
85 MAX8997_REG_LDO1CTRL = 0x3b,
86 MAX8997_REG_LDO2CTRL = 0x3c,
87 MAX8997_REG_LDO3CTRL = 0x3d,
88 MAX8997_REG_LDO4CTRL = 0x3e,
89 MAX8997_REG_LDO5CTRL = 0x3f,
90 MAX8997_REG_LDO6CTRL = 0x40,
91 MAX8997_REG_LDO7CTRL = 0x41,
92 MAX8997_REG_LDO8CTRL = 0x42,
93 MAX8997_REG_LDO9CTRL = 0x43,
94 MAX8997_REG_LDO10CTRL = 0x44,
95 MAX8997_REG_LDO11CTRL = 0x45,
96 MAX8997_REG_LDO12CTRL = 0x46,
97 MAX8997_REG_LDO13CTRL = 0x47,
98 MAX8997_REG_LDO14CTRL = 0x48,
99 MAX8997_REG_LDO15CTRL = 0x49,
100 MAX8997_REG_LDO16CTRL = 0x4a,
101 MAX8997_REG_LDO17CTRL = 0x4b,
102 MAX8997_REG_LDO18CTRL = 0x4c,
103 MAX8997_REG_LDO21CTRL = 0x4d,
104
105 MAX8997_REG_MBCCTRL1 = 0x50,
106 MAX8997_REG_MBCCTRL2 = 0x51,
107 MAX8997_REG_MBCCTRL3 = 0x52,
108 MAX8997_REG_MBCCTRL4 = 0x53,
109 MAX8997_REG_MBCCTRL5 = 0x54,
110 MAX8997_REG_MBCCTRL6 = 0x55,
111 MAX8997_REG_OTPCGHCVS = 0x56,
112
113 MAX8997_REG_SAFEOUTCTRL = 0x5a,
114
115 MAX8997_REG_LBCNFG1 = 0x5e,
116 MAX8997_REG_LBCNFG2 = 0x5f,
117 MAX8997_REG_BBCCTRL = 0x60,
118
119 MAX8997_REG_FLASH1_CUR = 0x63, /* 0x63 ~ 0x6e for FLASH */
120 MAX8997_REG_FLASH2_CUR = 0x64,
121 MAX8997_REG_MOVIE_CUR = 0x65,
122 MAX8997_REG_GSMB_CUR = 0x66,
123 MAX8997_REG_BOOST_CNTL = 0x67,
124 MAX8997_REG_LEN_CNTL = 0x68,
125 MAX8997_REG_FLASH_CNTL = 0x69,
126 MAX8997_REG_WDT_CNTL = 0x6a,
127 MAX8997_REG_MAXFLASH1 = 0x6b,
128 MAX8997_REG_MAXFLASH2 = 0x6c,
129 MAX8997_REG_FLASHSTATUS = 0x6d,
130 MAX8997_REG_FLASHSTATUSMASK = 0x6e,
131
132 MAX8997_REG_GPIOCNTL1 = 0x70,
133 MAX8997_REG_GPIOCNTL2 = 0x71,
134 MAX8997_REG_GPIOCNTL3 = 0x72,
135 MAX8997_REG_GPIOCNTL4 = 0x73,
136 MAX8997_REG_GPIOCNTL5 = 0x74,
137 MAX8997_REG_GPIOCNTL6 = 0x75,
138 MAX8997_REG_GPIOCNTL7 = 0x76,
139 MAX8997_REG_GPIOCNTL8 = 0x77,
140 MAX8997_REG_GPIOCNTL9 = 0x78,
141 MAX8997_REG_GPIOCNTL10 = 0x79,
142 MAX8997_REG_GPIOCNTL11 = 0x7a,
143 MAX8997_REG_GPIOCNTL12 = 0x7b,
144
145 MAX8997_REG_LDO1CONFIG = 0x80,
146 MAX8997_REG_LDO2CONFIG = 0x81,
147 MAX8997_REG_LDO3CONFIG = 0x82,
148 MAX8997_REG_LDO4CONFIG = 0x83,
149 MAX8997_REG_LDO5CONFIG = 0x84,
150 MAX8997_REG_LDO6CONFIG = 0x85,
151 MAX8997_REG_LDO7CONFIG = 0x86,
152 MAX8997_REG_LDO8CONFIG = 0x87,
153 MAX8997_REG_LDO9CONFIG = 0x88,
154 MAX8997_REG_LDO10CONFIG = 0x89,
155 MAX8997_REG_LDO11CONFIG = 0x8a,
156 MAX8997_REG_LDO12CONFIG = 0x8b,
157 MAX8997_REG_LDO13CONFIG = 0x8c,
158 MAX8997_REG_LDO14CONFIG = 0x8d,
159 MAX8997_REG_LDO15CONFIG = 0x8e,
160 MAX8997_REG_LDO16CONFIG = 0x8f,
161 MAX8997_REG_LDO17CONFIG = 0x90,
162 MAX8997_REG_LDO18CONFIG = 0x91,
163 MAX8997_REG_LDO21CONFIG = 0x92,
164
165 MAX8997_REG_DVSOKTIMER1 = 0x97,
166 MAX8997_REG_DVSOKTIMER2 = 0x98,
167 MAX8997_REG_DVSOKTIMER4 = 0x99,
168 MAX8997_REG_DVSOKTIMER5 = 0x9a,
169
170 MAX8997_REG_PMIC_END = 0x9b,
171};
172
173enum max8997_muic_reg {
174 MAX8997_MUIC_REG_ID = 0x0,
175 MAX8997_MUIC_REG_INT1 = 0x1,
176 MAX8997_MUIC_REG_INT2 = 0x2,
177 MAX8997_MUIC_REG_INT3 = 0x3,
178 MAX8997_MUIC_REG_STATUS1 = 0x4,
179 MAX8997_MUIC_REG_STATUS2 = 0x5,
180 MAX8997_MUIC_REG_STATUS3 = 0x6,
181 MAX8997_MUIC_REG_INTMASK1 = 0x7,
182 MAX8997_MUIC_REG_INTMASK2 = 0x8,
183 MAX8997_MUIC_REG_INTMASK3 = 0x9,
184 MAX8997_MUIC_REG_CDETCTRL = 0xa,
185
186 MAX8997_MUIC_REG_CONTROL1 = 0xc,
187 MAX8997_MUIC_REG_CONTROL2 = 0xd,
188 MAX8997_MUIC_REG_CONTROL3 = 0xe,
189
190 MAX8997_MUIC_REG_END = 0xf,
191};
192
193enum max8997_haptic_reg {
194 MAX8997_HAPTIC_REG_GENERAL = 0x00,
195 MAX8997_HAPTIC_REG_CONF1 = 0x01,
196 MAX8997_HAPTIC_REG_CONF2 = 0x02,
197 MAX8997_HAPTIC_REG_DRVCONF = 0x03,
198 MAX8997_HAPTIC_REG_CYCLECONF1 = 0x04,
199 MAX8997_HAPTIC_REG_CYCLECONF2 = 0x05,
200 MAX8997_HAPTIC_REG_SIGCONF1 = 0x06,
201 MAX8997_HAPTIC_REG_SIGCONF2 = 0x07,
202 MAX8997_HAPTIC_REG_SIGCONF3 = 0x08,
203 MAX8997_HAPTIC_REG_SIGCONF4 = 0x09,
204 MAX8997_HAPTIC_REG_SIGDC1 = 0x0a,
205 MAX8997_HAPTIC_REG_SIGDC2 = 0x0b,
206 MAX8997_HAPTIC_REG_SIGPWMDC1 = 0x0c,
207 MAX8997_HAPTIC_REG_SIGPWMDC2 = 0x0d,
208 MAX8997_HAPTIC_REG_SIGPWMDC3 = 0x0e,
209 MAX8997_HAPTIC_REG_SIGPWMDC4 = 0x0f,
210 MAX8997_HAPTIC_REG_MTR_REV = 0x10,
211
212 MAX8997_HAPTIC_REG_END = 0x11,
213};
214
215/* slave addr = 0x0c: using "2nd part" of rev4 datasheet */
216enum max8997_rtc_reg {
217 MAX8997_RTC_CTRLMASK = 0x02,
218 MAX8997_RTC_CTRL = 0x03,
219 MAX8997_RTC_UPDATE1 = 0x04,
220 MAX8997_RTC_UPDATE2 = 0x05,
221 MAX8997_RTC_WTSR_SMPL = 0x06,
222
223 MAX8997_RTC_SEC = 0x10,
224 MAX8997_RTC_MIN = 0x11,
225 MAX8997_RTC_HOUR = 0x12,
226 MAX8997_RTC_DAY_OF_WEEK = 0x13,
227 MAX8997_RTC_MONTH = 0x14,
228 MAX8997_RTC_YEAR = 0x15,
229 MAX8997_RTC_DAY_OF_MONTH = 0x16,
230 MAX8997_RTC_ALARM1_SEC = 0x17,
231 MAX8997_RTC_ALARM1_MIN = 0x18,
232 MAX8997_RTC_ALARM1_HOUR = 0x19,
233 MAX8997_RTC_ALARM1_DAY_OF_WEEK = 0x1a,
234 MAX8997_RTC_ALARM1_MONTH = 0x1b,
235 MAX8997_RTC_ALARM1_YEAR = 0x1c,
236 MAX8997_RTC_ALARM1_DAY_OF_MONTH = 0x1d,
237 MAX8997_RTC_ALARM2_SEC = 0x1e,
238 MAX8997_RTC_ALARM2_MIN = 0x1f,
239 MAX8997_RTC_ALARM2_HOUR = 0x20,
240 MAX8997_RTC_ALARM2_DAY_OF_WEEK = 0x21,
241 MAX8997_RTC_ALARM2_MONTH = 0x22,
242 MAX8997_RTC_ALARM2_YEAR = 0x23,
243 MAX8997_RTC_ALARM2_DAY_OF_MONTH = 0x24,
244};
245
246enum max8997_irq_source {
247 PMIC_INT1 = 0,
248 PMIC_INT2,
249 PMIC_INT3,
250 PMIC_INT4,
251
252 FUEL_GAUGE, /* Ignored (MAX17042 driver handles) */
253
254 MUIC_INT1,
255 MUIC_INT2,
256 MUIC_INT3,
257
258 GPIO_LOW, /* Not implemented */
259 GPIO_HI, /* Not implemented */
260
261 FLASH_STATUS, /* Not implemented */
262
263 MAX8997_IRQ_GROUP_NR,
264};
265
266enum max8997_irq {
267 MAX8997_PMICIRQ_PWRONR,
268 MAX8997_PMICIRQ_PWRONF,
269 MAX8997_PMICIRQ_PWRON1SEC,
270 MAX8997_PMICIRQ_JIGONR,
271 MAX8997_PMICIRQ_JIGONF,
272 MAX8997_PMICIRQ_LOWBAT2,
273 MAX8997_PMICIRQ_LOWBAT1,
274
275 MAX8997_PMICIRQ_JIGR,
276 MAX8997_PMICIRQ_JIGF,
277 MAX8997_PMICIRQ_MR,
278 MAX8997_PMICIRQ_DVS1OK,
279 MAX8997_PMICIRQ_DVS2OK,
280 MAX8997_PMICIRQ_DVS3OK,
281 MAX8997_PMICIRQ_DVS4OK,
282
283 MAX8997_PMICIRQ_CHGINS,
284 MAX8997_PMICIRQ_CHGRM,
285 MAX8997_PMICIRQ_DCINOVP,
286 MAX8997_PMICIRQ_TOPOFFR,
287 MAX8997_PMICIRQ_CHGRSTF,
288 MAX8997_PMICIRQ_MBCHGTMEXPD,
289
290 MAX8997_PMICIRQ_RTC60S,
291 MAX8997_PMICIRQ_RTCA1,
292 MAX8997_PMICIRQ_RTCA2,
293 MAX8997_PMICIRQ_SMPL_INT,
294 MAX8997_PMICIRQ_RTC1S,
295 MAX8997_PMICIRQ_WTSR,
296
297 MAX8997_MUICIRQ_ADCError,
298 MAX8997_MUICIRQ_ADCLow,
299 MAX8997_MUICIRQ_ADC,
300
301 MAX8997_MUICIRQ_VBVolt,
302 MAX8997_MUICIRQ_DBChg,
303 MAX8997_MUICIRQ_DCDTmr,
304 MAX8997_MUICIRQ_ChgDetRun,
305 MAX8997_MUICIRQ_ChgTyp,
306
307 MAX8997_MUICIRQ_OVP,
308
309 MAX8997_IRQ_NR,
310};
311
312#define MAX8997_REG_BUCK1DVS(x) (MAX8997_REG_BUCK1DVS1 + (x) - 1)
313#define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1)
314#define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1)
315
316struct max8997_dev {
317 struct device *dev;
318 struct i2c_client *i2c; /* 0xcc / PMIC, Battery Control, and FLASH */
319 struct i2c_client *rtc; /* slave addr 0x0c */
320 struct i2c_client *haptic; /* slave addr 0x90 */
321 struct i2c_client *muic; /* slave addr 0x4a */
322 struct mutex iolock;
323
324 int type;
325 struct platform_device *battery; /* battery control (not fuel gauge) */
326
327 bool wakeup;
328
329 /* For hibernation */
330 u8 reg_dump[MAX8997_REG_PMIC_END + MAX8997_MUIC_REG_END +
331 MAX8997_HAPTIC_REG_END];
332};
333
334enum max8997_types {
335 TYPE_MAX8997,
336 TYPE_MAX8966,
337};
338
339extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest);
340extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count,
341 u8 *buf);
342extern int max8997_write_reg(struct i2c_client *i2c, u8 reg, u8 value);
343extern int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count,
344 u8 *buf);
345extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask);
346
347#endif /* __LINUX_MFD_MAX8997_PRIV_H */
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
new file mode 100644
index 000000000000..cb671b3451bf
--- /dev/null
+++ b/include/linux/mfd/max8997.h
@@ -0,0 +1,114 @@
1/*
2 * max8997.h - Driver for the Maxim 8997/8966
3 *
4 * Copyright (C) 2009-2010 Samsung Electrnoics
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
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.h
22 *
23 * MAX8997 has PMIC, MUIC, HAPTIC, RTC, FLASH, and Fuel Gauge devices.
24 * Except Fuel Gauge, every device shares the same I2C bus and included in
25 * this mfd driver. Although the fuel gauge is included in the chip, it is
26 * excluded from the driver because a) it has a different I2C bus from
27 * others and b) it can be enabled simply by using MAX17042 driver.
28 */
29
30#ifndef __LINUX_MFD_MAX8998_H
31#define __LINUX_MFD_MAX8998_H
32
33#include <linux/regulator/consumer.h>
34
35/* MAX8997/8966 regulator IDs */
36enum max8998_regulators {
37 MAX8997_LDO1 = 0,
38 MAX8997_LDO2,
39 MAX8997_LDO3,
40 MAX8997_LDO4,
41 MAX8997_LDO5,
42 MAX8997_LDO6,
43 MAX8997_LDO7,
44 MAX8997_LDO8,
45 MAX8997_LDO9,
46 MAX8997_LDO10,
47 MAX8997_LDO11,
48 MAX8997_LDO12,
49 MAX8997_LDO13,
50 MAX8997_LDO14,
51 MAX8997_LDO15,
52 MAX8997_LDO16,
53 MAX8997_LDO17,
54 MAX8997_LDO18,
55 MAX8997_LDO21,
56 MAX8997_BUCK1,
57 MAX8997_BUCK2,
58 MAX8997_BUCK3,
59 MAX8997_BUCK4,
60 MAX8997_BUCK5,
61 MAX8997_BUCK6,
62 MAX8997_BUCK7,
63 MAX8997_EN32KHZ_AP,
64 MAX8997_EN32KHZ_CP,
65 MAX8997_ENVICHG,
66 MAX8997_ESAFEOUT1,
67 MAX8997_ESAFEOUT2,
68 MAX8997_CHARGER_CV, /* control MBCCV of MBCCTRL3 */
69 MAX8997_CHARGER, /* charger current, MBCCTRL4 */
70 MAX8997_CHARGER_TOPOFF, /* MBCCTRL5 */
71
72 MAX8997_REG_MAX,
73};
74
75struct max8997_regulator_data {
76 int id;
77 struct regulator_init_data *initdata;
78};
79
80struct max8997_platform_data {
81 bool wakeup;
82 /* IRQ: Not implemented */
83 /* ---- PMIC ---- */
84 struct max8997_regulator_data *regulators;
85 int num_regulators;
86
87 /*
88 * SET1~3 DVS GPIOs control Buck1, 2, and 5 simultaneously. Therefore,
89 * With buckx_gpiodvs enabled, the buckx cannot be controlled
90 * independently. To control buckx (of 1, 2, and 5) independently,
91 * disable buckx_gpiodvs and control with BUCKxDVS1 register.
92 *
93 * When buckx_gpiodvs and bucky_gpiodvs are both enabled, set_voltage
94 * on buckx will change the voltage of bucky at the same time.
95 *
96 */
97 bool ignore_gpiodvs_side_effect;
98 int buck125_gpios[3]; /* GPIO of [0]SET1, [1]SET2, [2]SET3 */
99 int buck125_default_idx; /* Default value of SET1, 2, 3 */
100 unsigned int buck1_voltage[8]; /* buckx_voltage in uV */
101 bool buck1_gpiodvs;
102 unsigned int buck2_voltage[8];
103 bool buck2_gpiodvs;
104 unsigned int buck5_voltage[8];
105 bool buck5_gpiodvs;
106
107 /* MUIC: Not implemented */
108 /* HAPTIC: Not implemented */
109 /* RTC: Not implemented */
110 /* Flash: Not implemented */
111 /* Charger control: Not implemented */
112};
113
114#endif /* __LINUX_MFD_MAX8998_H */
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index a1d391b40e68..c064beaaccb7 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -146,8 +146,7 @@ struct mc13xxx_platform_data {
146#define MC13XXX_USE_LED (1 << 5) 146#define MC13XXX_USE_LED (1 << 5)
147 unsigned int flags; 147 unsigned int flags;
148 148
149 int num_regulators; 149 struct mc13xxx_regulator_platform_data regulators;
150 struct mc13xxx_regulator_init_data *regulators;
151 struct mc13xxx_leds_platform_data *leds; 150 struct mc13xxx_leds_platform_data *leds;
152}; 151};
153 152
diff --git a/include/linux/mfd/tps6105x.h b/include/linux/mfd/tps6105x.h
new file mode 100644
index 000000000000..386743dd931c
--- /dev/null
+++ b/include/linux/mfd/tps6105x.h
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2011 ST-Ericsson SA
3 * Written on behalf of Linaro for ST-Ericsson
4 *
5 * Author: Linus Walleij <linus.walleij@linaro.org>
6 *
7 * License terms: GNU General Public License (GPL) version 2
8 */
9#ifndef MFD_TPS6105X_H
10#define MFD_TPS6105X_H
11
12#include <linux/i2c.h>
13#include <linux/regulator/machine.h>
14
15/*
16 * Register definitions to all subdrivers
17 */
18#define TPS6105X_REG_0 0x00
19#define TPS6105X_REG0_MODE_SHIFT 6
20#define TPS6105X_REG0_MODE_MASK (0x03<<6)
21/* These defines for both reg0 and reg1 */
22#define TPS6105X_REG0_MODE_SHUTDOWN 0x00
23#define TPS6105X_REG0_MODE_TORCH 0x01
24#define TPS6105X_REG0_MODE_TORCH_FLASH 0x02
25#define TPS6105X_REG0_MODE_VOLTAGE 0x03
26#define TPS6105X_REG0_VOLTAGE_SHIFT 4
27#define TPS6105X_REG0_VOLTAGE_MASK (3<<4)
28#define TPS6105X_REG0_VOLTAGE_450 0
29#define TPS6105X_REG0_VOLTAGE_500 1
30#define TPS6105X_REG0_VOLTAGE_525 2
31#define TPS6105X_REG0_VOLTAGE_500_2 3
32#define TPS6105X_REG0_DIMMING_SHIFT 3
33#define TPS6105X_REG0_TORCHC_SHIFT 0
34#define TPS6105X_REG0_TORCHC_MASK (7<<0)
35#define TPS6105X_REG0_TORCHC_0 0x00
36#define TPS6105X_REG0_TORCHC_50 0x01
37#define TPS6105X_REG0_TORCHC_75 0x02
38#define TPS6105X_REG0_TORCHC_100 0x03
39#define TPS6105X_REG0_TORCHC_150 0x04
40#define TPS6105X_REG0_TORCHC_200 0x05
41#define TPS6105X_REG0_TORCHC_250_400 0x06
42#define TPS6105X_REG0_TORCHC_250_500 0x07
43#define TPS6105X_REG_1 0x01
44#define TPS6105X_REG1_MODE_SHIFT 6
45#define TPS6105X_REG1_MODE_MASK (0x03<<6)
46#define TPS6105X_REG1_MODE_SHUTDOWN 0x00
47#define TPS6105X_REG1_MODE_TORCH 0x01
48#define TPS6105X_REG1_MODE_TORCH_FLASH 0x02
49#define TPS6105X_REG1_MODE_VOLTAGE 0x03
50#define TPS6105X_REG_2 0x02
51#define TPS6105X_REG_3 0x03
52
53/**
54 * enum tps6105x_mode - desired mode for the TPS6105x
55 * @TPS6105X_MODE_SHUTDOWN: this instance is inactive, not used for anything
56 * @TPS61905X_MODE_TORCH: this instance is used as a LED, usually a while
57 * LED, for example as backlight or flashlight. If this is set, the
58 * TPS6105X will register to the LED framework
59 * @TPS6105X_MODE_TORCH_FLASH: this instance is used as a flashgun, usually
60 * in a camera
61 * @TPS6105X_MODE_VOLTAGE: this instance is used as a voltage regulator and
62 * will register to the regulator framework
63 */
64enum tps6105x_mode {
65 TPS6105X_MODE_SHUTDOWN,
66 TPS6105X_MODE_TORCH,
67 TPS6105X_MODE_TORCH_FLASH,
68 TPS6105X_MODE_VOLTAGE,
69};
70
71/**
72 * struct tps6105x_platform_data - TPS61905x platform data
73 * @mode: what mode this instance shall be operated in,
74 * this is not selectable at runtime
75 * @regulator_data: initialization data for the voltage
76 * regulator if used as a voltage source
77 */
78struct tps6105x_platform_data {
79 enum tps6105x_mode mode;
80 struct regulator_init_data *regulator_data;
81};
82
83/**
84 * struct tps6105x - state holder for the TPS6105x drivers
85 * @mutex: mutex to serialize I2C accesses
86 * @i2c_client: corresponding I2C client
87 * @regulator: regulator device if used in voltage mode
88 */
89struct tps6105x {
90 struct tps6105x_platform_data *pdata;
91 struct mutex lock;
92 struct i2c_client *client;
93 struct regulator_dev *regulator;
94};
95
96extern int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value);
97extern int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf);
98extern int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg,
99 u8 bitmask, u8 bitvalues);
100
101#endif
diff --git a/include/linux/mfd/wm831x/pdata.h b/include/linux/mfd/wm831x/pdata.h
index 173086d42af4..afe4db49402d 100644
--- a/include/linux/mfd/wm831x/pdata.h
+++ b/include/linux/mfd/wm831x/pdata.h
@@ -104,11 +104,17 @@ struct wm831x_watchdog_pdata {
104#define WM831X_MAX_ISINK 2 104#define WM831X_MAX_ISINK 2
105 105
106struct wm831x_pdata { 106struct wm831x_pdata {
107 /** Used to distinguish multiple WM831x chips */
108 int wm831x_num;
109
107 /** Called before subdevices are set up */ 110 /** Called before subdevices are set up */
108 int (*pre_init)(struct wm831x *wm831x); 111 int (*pre_init)(struct wm831x *wm831x);
109 /** Called after subdevices are set up */ 112 /** Called after subdevices are set up */
110 int (*post_init)(struct wm831x *wm831x); 113 int (*post_init)(struct wm831x *wm831x);
111 114
115 /** Put the /IRQ line into CMOS mode */
116 bool irq_cmos;
117
112 int irq_base; 118 int irq_base;
113 int gpio_base; 119 int gpio_base;
114 struct wm831x_backlight_pdata *backlight; 120 struct wm831x_backlight_pdata *backlight;
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h
index ef4f0b6083a3..f0b69cdae41c 100644
--- a/include/linux/mfd/wm8994/core.h
+++ b/include/linux/mfd/wm8994/core.h
@@ -59,7 +59,7 @@ struct wm8994 {
59 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, 59 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg,
60 int bytes, void *dest); 60 int bytes, void *dest);
61 int (*write_dev)(struct wm8994 *wm8994, unsigned short reg, 61 int (*write_dev)(struct wm8994 *wm8994, unsigned short reg,
62 int bytes, void *src); 62 int bytes, const void *src);
63 63
64 void *control_data; 64 void *control_data;
65 65
@@ -88,6 +88,8 @@ int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
88 unsigned short mask, unsigned short val); 88 unsigned short mask, unsigned short val);
89int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 89int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
90 int count, u16 *buf); 90 int count, u16 *buf);
91int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
92 int count, const u16 *buf);
91 93
92 94
93/* Helper to save on boilerplate */ 95/* Helper to save on boilerplate */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index bda221dfaf0a..11fd38151cc9 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2737,6 +2737,7 @@
2737#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 2737#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
2738#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 2738#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119
2739#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a 2739#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a
2740#define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186
2740#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 2741#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
2741#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 2742#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5
2742#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca 2743#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 347a567b01e1..b8066ef10bb0 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -153,7 +153,8 @@ static int cq93vc_resume(struct snd_soc_codec *codec)
153 153
154static int cq93vc_probe(struct snd_soc_codec *codec) 154static int cq93vc_probe(struct snd_soc_codec *codec)
155{ 155{
156 struct davinci_vc *davinci_vc = snd_soc_codec_get_drvdata(codec); 156 struct davinci_vc *davinci_vc =
157 mfd_get_data(to_platform_device(codec->dev));
157 158
158 davinci_vc->cq93vc.codec = codec; 159 davinci_vc->cq93vc.codec = codec;
159 codec->control_data = davinci_vc; 160 codec->control_data = davinci_vc;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index e4d464b937d6..8512800f6326 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -26,6 +26,7 @@
26#include <linux/pm.h> 26#include <linux/pm.h>
27#include <linux/i2c.h> 27#include <linux/i2c.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/mfd/core.h>
29#include <linux/i2c/twl.h> 30#include <linux/i2c/twl.h>
30#include <linux/slab.h> 31#include <linux/slab.h>
31#include <sound/core.h> 32#include <sound/core.h>
@@ -732,7 +733,8 @@ static int aif_event(struct snd_soc_dapm_widget *w,
732 733
733static void headset_ramp(struct snd_soc_codec *codec, int ramp) 734static void headset_ramp(struct snd_soc_codec *codec, int ramp)
734{ 735{
735 struct twl4030_codec_audio_data *pdata = codec->dev->platform_data; 736 struct twl4030_codec_audio_data *pdata =
737 mfd_get_data(to_platform_device(codec->dev));
736 unsigned char hs_gain, hs_pop; 738 unsigned char hs_gain, hs_pop;
737 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 739 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
738 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 740 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -2297,7 +2299,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = {
2297 2299
2298static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2300static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2299{ 2301{
2300 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; 2302 struct twl4030_codec_audio_data *pdata = mfd_get_data(pdev);
2301 2303
2302 if (!pdata) { 2304 if (!pdata) {
2303 dev_err(&pdev->dev, "platform_data is missing\n"); 2305 dev_err(&pdev->dev, "platform_data is missing\n");
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 861b28f543d2..1ad0d5aecece 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -436,7 +436,8 @@ EXPORT_SYMBOL_GPL(wl1273_get_format);
436 436
437static int wl1273_probe(struct snd_soc_codec *codec) 437static int wl1273_probe(struct snd_soc_codec *codec)
438{ 438{
439 struct wl1273_core **core = codec->dev->platform_data; 439 struct wl1273_core **core =
440 mfd_get_data(to_platform_device(codec->dev));
440 struct wl1273_priv *wl1273; 441 struct wl1273_priv *wl1273;
441 int r; 442 int r;
442 443
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 3c3bc079167e..736b785e3756 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -22,6 +22,7 @@
22#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
23#include <linux/mfd/wm8400-audio.h> 23#include <linux/mfd/wm8400-audio.h>
24#include <linux/mfd/wm8400-private.h> 24#include <linux/mfd/wm8400-private.h>
25#include <linux/mfd/core.h>
25#include <sound/core.h> 26#include <sound/core.h>
26#include <sound/pcm.h> 27#include <sound/pcm.h>
27#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
@@ -1377,7 +1378,7 @@ static void wm8400_probe_deferred(struct work_struct *work)
1377 1378
1378static int wm8400_codec_probe(struct snd_soc_codec *codec) 1379static int wm8400_codec_probe(struct snd_soc_codec *codec)
1379{ 1380{
1380 struct wm8400 *wm8400 = dev_get_platdata(codec->dev); 1381 struct wm8400 *wm8400 = mfd_get_data(to_platform_device(codec->dev));
1381 struct wm8400_priv *priv; 1382 struct wm8400_priv *priv;
1382 int ret; 1383 int ret;
1383 u16 reg; 1384 u16 reg;
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c
index 9d2afccc3a2d..13e05a302a92 100644
--- a/sound/soc/davinci/davinci-vcif.c
+++ b/sound/soc/davinci/davinci-vcif.c
@@ -205,7 +205,7 @@ static struct snd_soc_dai_driver davinci_vcif_dai = {
205 205
206static int davinci_vcif_probe(struct platform_device *pdev) 206static int davinci_vcif_probe(struct platform_device *pdev)
207{ 207{
208 struct davinci_vc *davinci_vc = platform_get_drvdata(pdev); 208 struct davinci_vc *davinci_vc = mfd_get_data(pdev);
209 struct davinci_vcif_dev *davinci_vcif_dev; 209 struct davinci_vcif_dev *davinci_vcif_dev;
210 int ret; 210 int ret;
211 211