Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6

* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (90 commits)
mfd: Push byte swaps out of wm8994 bulk read path
mfd: Rename ab8500 gpadc header
mfd: Constify WM8994 write path
mfd: Push byte swap out of WM8994 bulk I/O
mfd: Avoid copying data in WM8994 I2C write
mfd: Remove copy from WM831x I2C write function
mfd: Staticise WM8994 PM ops
regulator: Add a subdriver for TI TPS6105x regulator portions v2
mfd: Add a core driver for TI TPS61050/TPS61052 chips v2
gpio: Add Tunnel Creek support to sch_gpio
mfd: Add Tunnel Creek support to lpc_sch
pci_ids: Add Intel Tunnel Creek LPC Bridge device ID.
regulator: MAX8997/8966 support
mfd: Add WM8994 bulk register write operation
mfd: Append additional read write on 88pm860x
mfd: Adopt mfd_data in 88pm860x input driver
mfd: Adopt mfd_data in 88pm860x regulator
mfd: Adopt mfd_data in 88pm860x led
mfd: Adopt mfd_data in 88pm860x backlight
mfd: Fix MAX8997 Kconfig entry typos
...

+6077 -803
+45
Documentation/hwmon/twl4030-madc-hwmon
··· 1 + Kernel driver twl4030-madc 2 + ========================= 3 + 4 + Supported chips: 5 + * Texas Instruments TWL4030 6 + Prefix: 'twl4030-madc' 7 + 8 + 9 + Authors: 10 + J Keerthy <j-keerthy@ti.com> 11 + 12 + Description 13 + ----------- 14 + 15 + The Texas Instruments TWL4030 is a Power Management and Audio Circuit. Among 16 + other things it contains a 10-bit A/D converter MADC. The converter has 16 17 + channels which can be used in different modes. 18 + 19 + 20 + See this table for the meaning of the different channels 21 + 22 + Channel Signal 23 + ------------------------------------------ 24 + 0 Battery type(BTYPE) 25 + 1 BCI: Battery temperature (BTEMP) 26 + 2 GP analog input 27 + 3 GP analog input 28 + 4 GP analog input 29 + 5 GP analog input 30 + 6 GP analog input 31 + 7 GP analog input 32 + 8 BCI: VBUS voltage(VBUS) 33 + 9 Backup Battery voltage (VBKP) 34 + 10 BCI: Battery charger current (ICHG) 35 + 11 BCI: Battery charger voltage (VCHG) 36 + 12 BCI: Main battery voltage (VBAT) 37 + 13 Reserved 38 + 14 Reserved 39 + 15 VRUSB Supply/Speaker left/Speaker right polarization level 40 + 41 + 42 + The Sysfs nodes will represent the voltage in the units of mV, 43 + the temperature channel shows the converted temperature in 44 + degree celcius. The Battery charging current channel represents 45 + battery charging current in mA.
+7 -4
arch/arm/mach-imx/mach-mx27_3ds.c
··· 232 232 }; 233 233 234 234 /* MC13783 */ 235 - static struct mc13xxx_platform_data mc13783_pdata __initdata = { 236 - .regulators = mx27_3ds_regulators, 237 - .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), 238 - .flags = MC13XXX_USE_REGULATOR, 235 + static struct mc13xxx_platform_data mc13783_pdata = { 236 + .regulators = { 237 + .regulators = mx27_3ds_regulators, 238 + .num_regulators = ARRAY_SIZE(mx27_3ds_regulators), 239 + 240 + }, 241 + .flags = MC13783_USE_REGULATOR, 239 242 }; 240 243 241 244 /* SPI */
+6 -4
arch/arm/mach-imx/mach-pcm038.c
··· 263 263 }; 264 264 265 265 static struct mc13xxx_platform_data pcm038_pmic = { 266 - .regulators = pcm038_regulators, 267 - .num_regulators = ARRAY_SIZE(pcm038_regulators), 268 - .flags = MC13XXX_USE_ADC | MC13XXX_USE_REGULATOR | 269 - MC13XXX_USE_TOUCHSCREEN, 266 + .regulators = { 267 + .regulators = pcm038_regulators, 268 + .num_regulators = ARRAY_SIZE(pcm038_regulators), 269 + }, 270 + .flags = MC13783_USE_ADC | MC13783_USE_REGULATOR | 271 + MC13783_USE_TOUCHSCREEN, 270 272 }; 271 273 272 274 static struct spi_board_info pcm038_spi_board_info[] __initdata = {
+6 -4
arch/arm/mach-mx3/mach-mx31_3ds.c
··· 488 488 }; 489 489 490 490 /* MC13783 */ 491 - static struct mc13xxx_platform_data mc13783_pdata __initdata = { 492 - .regulators = mx31_3ds_regulators, 493 - .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), 494 - .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_TOUCHSCREEN 491 + static struct mc13xxx_platform_data mc13783_pdata = { 492 + .regulators = { 493 + .regulators = mx31_3ds_regulators, 494 + .num_regulators = ARRAY_SIZE(mx31_3ds_regulators), 495 + }, 496 + .flags = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN, 495 497 }; 496 498 497 499 /* SPI */
+4 -2
arch/arm/mach-mx3/mach-mx31moboard.c
··· 268 268 }; 269 269 270 270 static struct mc13xxx_platform_data moboard_pmic = { 271 - .regulators = moboard_regulators, 272 - .num_regulators = ARRAY_SIZE(moboard_regulators), 271 + .regulators = { 272 + .regulators = moboard_regulators, 273 + .num_regulators = ARRAY_SIZE(moboard_regulators), 274 + }, 273 275 .leds = &moboard_leds, 274 276 .flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC | 275 277 MC13XXX_USE_ADC | MC13XXX_USE_LED,
+7
arch/arm/mach-omap2/board-4430sdp.c
··· 550 550 }, 551 551 }; 552 552 553 + static struct regulator_init_data sdp4430_clk32kg = { 554 + .constraints = { 555 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 556 + }, 557 + }; 558 + 553 559 static struct twl4030_platform_data sdp4430_twldata = { 554 560 .irq_base = TWL6030_IRQ_BASE, 555 561 .irq_end = TWL6030_IRQ_END, ··· 571 565 .vaux1 = &sdp4430_vaux1, 572 566 .vaux2 = &sdp4430_vaux2, 573 567 .vaux3 = &sdp4430_vaux3, 568 + .clk32kg = &sdp4430_clk32kg, 574 569 .usb = &omap4_usbphy_data 575 570 }; 576 571
+7
arch/arm/mach-omap2/board-omap4panda.c
··· 411 411 }, 412 412 }; 413 413 414 + static struct regulator_init_data omap4_panda_clk32kg = { 415 + .constraints = { 416 + .valid_ops_mask = REGULATOR_CHANGE_STATUS, 417 + }, 418 + }; 419 + 414 420 static struct twl4030_platform_data omap4_panda_twldata = { 415 421 .irq_base = TWL6030_IRQ_BASE, 416 422 .irq_end = TWL6030_IRQ_END, ··· 432 426 .vaux1 = &omap4_panda_vaux1, 433 427 .vaux2 = &omap4_panda_vaux2, 434 428 .vaux3 = &omap4_panda_vaux3, 429 + .clk32kg = &omap4_panda_clk32kg, 435 430 .usb = &omap4_usbphy_data, 436 431 }; 437 432
+20 -22
arch/x86/platform/olpc/olpc-xo1.c
··· 15 15 #include <linux/module.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/pm.h> 18 + #include <linux/mfd/core.h> 18 19 19 20 #include <asm/io.h> 20 21 #include <asm/olpc.h> ··· 57 56 static int __devinit olpc_xo1_probe(struct platform_device *pdev) 58 57 { 59 58 struct resource *res; 59 + int err; 60 60 61 61 /* don't run on non-XOs */ 62 62 if (!machine_is_olpc()) 63 63 return -ENODEV; 64 + 65 + err = mfd_cell_enable(pdev); 66 + if (err) 67 + return err; 64 68 65 69 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 66 70 if (!res) { 67 71 dev_err(&pdev->dev, "can't fetch device resource info\n"); 68 72 return -EIO; 69 73 } 70 - 71 - if (!request_region(res->start, resource_size(res), DRV_NAME)) { 72 - dev_err(&pdev->dev, "can't request region\n"); 73 - return -EIO; 74 - } 75 - 76 - if (strcmp(pdev->name, "cs5535-pms") == 0) 74 + if (strcmp(pdev->name, "olpc-xo1-pms") == 0) 77 75 pms_base = res->start; 78 - else if (strcmp(pdev->name, "cs5535-acpi") == 0) 76 + else if (strcmp(pdev->name, "olpc-xo1-ac-acpi") == 0) 79 77 acpi_base = res->start; 80 78 81 79 /* If we have both addresses, we can override the poweroff hook */ ··· 88 88 89 89 static int __devexit olpc_xo1_remove(struct platform_device *pdev) 90 90 { 91 - struct resource *r; 91 + mfd_cell_disable(pdev); 92 92 93 - r = platform_get_resource(pdev, IORESOURCE_IO, 0); 94 - release_region(r->start, resource_size(r)); 95 - 96 - if (strcmp(pdev->name, "cs5535-pms") == 0) 93 + if (strcmp(pdev->name, "olpc-xo1-pms") == 0) 97 94 pms_base = 0; 98 - else if (strcmp(pdev->name, "cs5535-acpi") == 0) 95 + else if (strcmp(pdev->name, "olpc-xo1-acpi") == 0) 99 96 acpi_base = 0; 100 97 101 98 pm_power_off = NULL; ··· 101 104 102 105 static struct platform_driver cs5535_pms_drv = { 103 106 .driver = { 104 - .name = "cs5535-pms", 107 + .name = "olpc-xo1-pms", 105 108 .owner = THIS_MODULE, 106 109 }, 107 110 .probe = olpc_xo1_probe, ··· 110 113 111 114 static struct platform_driver cs5535_acpi_drv = { 112 115 .driver = { 113 - .name = "cs5535-acpi", 116 + .name = "olpc-xo1-acpi", 114 117 .owner = THIS_MODULE, 115 118 }, 116 119 .probe = olpc_xo1_probe, ··· 121 124 { 122 125 int r; 123 126 124 - r = platform_driver_register(&cs5535_pms_drv); 127 + r = mfd_shared_platform_driver_register(&cs5535_pms_drv, "cs5535-pms"); 125 128 if (r) 126 129 return r; 127 130 128 - r = platform_driver_register(&cs5535_acpi_drv); 131 + r = mfd_shared_platform_driver_register(&cs5535_acpi_drv, 132 + "cs5535-acpi"); 129 133 if (r) 130 - platform_driver_unregister(&cs5535_pms_drv); 134 + mfd_shared_platform_driver_unregister(&cs5535_pms_drv); 131 135 132 136 return r; 133 137 } 134 138 135 139 static void __exit olpc_xo1_exit(void) 136 140 { 137 - platform_driver_unregister(&cs5535_acpi_drv); 138 - platform_driver_unregister(&cs5535_pms_drv); 141 + mfd_shared_platform_driver_unregister(&cs5535_acpi_drv); 142 + mfd_shared_platform_driver_unregister(&cs5535_pms_drv); 139 143 } 140 144 141 145 MODULE_AUTHOR("Daniel Drake <dsd@laptop.org>"); 142 146 MODULE_LICENSE("GPL"); 143 - MODULE_ALIAS("platform:olpc-xo1"); 147 + MODULE_ALIAS("platform:cs5535-pms"); 144 148 145 149 module_init(olpc_xo1_init); 146 150 module_exit(olpc_xo1_exit);
+2 -1
drivers/dma/timb_dma.c
··· 27 27 #include <linux/io.h> 28 28 #include <linux/module.h> 29 29 #include <linux/platform_device.h> 30 + #include <linux/mfd/core.h> 30 31 #include <linux/slab.h> 31 32 32 33 #include <linux/timb_dma.h> ··· 685 684 686 685 static int __devinit td_probe(struct platform_device *pdev) 687 686 { 688 - struct timb_dma_platform_data *pdata = pdev->dev.platform_data; 687 + struct timb_dma_platform_data *pdata = mfd_get_data(pdev); 689 688 struct timb_dma *td; 690 689 struct resource *iomem; 691 690 int irq;
+5 -2
drivers/gpio/Kconfig
··· 100 100 Say yes here to support the NEC VR4100 series General-purpose I/O Uint 101 101 102 102 config GPIO_SCH 103 - tristate "Intel SCH GPIO" 103 + tristate "Intel SCH/TunnelCreek GPIO" 104 104 depends on GPIOLIB && PCI && X86 105 105 select MFD_CORE 106 106 select LPC_SCH 107 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 110 The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are 110 111 powered by the core power rail and are turned off during sleep 111 112 modes (S3 and higher). The remaining four GPIOs are powered by 112 113 the Intel SCH suspend power supply. These GPIOs remain 113 114 active during S3. The suspend powered GPIOs can be used to wake the 114 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 119 This driver can also be built as a module. If so, the module 117 120 will be called sch-gpio.
+2 -1
drivers/gpio/janz-ttl.c
··· 15 15 #include <linux/interrupt.h> 16 16 #include <linux/delay.h> 17 17 #include <linux/platform_device.h> 18 + #include <linux/mfd/core.h> 18 19 #include <linux/io.h> 19 20 #include <linux/gpio.h> 20 21 #include <linux/slab.h> ··· 150 149 struct resource *res; 151 150 int ret; 152 151 153 - pdata = pdev->dev.platform_data; 152 + pdata = mfd_get_data(pdev); 154 153 if (!pdata) { 155 154 dev_err(dev, "no platform data\n"); 156 155 ret = -ENXIO;
+2 -1
drivers/gpio/rdc321x-gpio.c
··· 27 27 #include <linux/pci.h> 28 28 #include <linux/gpio.h> 29 29 #include <linux/mfd/rdc321x.h> 30 + #include <linux/mfd/core.h> 30 31 #include <linux/slab.h> 31 32 32 33 struct rdc321x_gpio { ··· 136 135 struct rdc321x_gpio *rdc321x_gpio_dev; 137 136 struct rdc321x_gpio_pdata *pdata; 138 137 139 - pdata = platform_get_drvdata(pdev); 138 + pdata = mfd_get_data(pdev); 140 139 if (!pdata) { 141 140 dev_err(&pdev->dev, "no platform data supplied\n"); 142 141 return -ENODEV;
+39 -18
drivers/gpio/sch_gpio.c
··· 25 25 #include <linux/errno.h> 26 26 #include <linux/acpi.h> 27 27 #include <linux/platform_device.h> 28 + #include <linux/pci_ids.h> 28 29 29 30 #include <linux/gpio.h> 30 31 ··· 188 187 static int __devinit sch_gpio_probe(struct platform_device *pdev) 189 188 { 190 189 struct resource *res; 191 - int err; 190 + int err, id; 191 + 192 + id = pdev->id; 193 + if (!id) 194 + return -ENODEV; 192 195 193 196 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 194 197 if (!res) ··· 203 198 204 199 gpio_ba = res->start; 205 200 206 - sch_gpio_core.base = 0; 207 - sch_gpio_core.ngpio = 10; 208 - sch_gpio_core.dev = &pdev->dev; 201 + switch (id) { 202 + case PCI_DEVICE_ID_INTEL_SCH_LPC: 203 + sch_gpio_core.base = 0; 204 + sch_gpio_core.ngpio = 10; 209 205 210 - sch_gpio_resume.base = 10; 211 - sch_gpio_resume.ngpio = 4; 206 + sch_gpio_resume.base = 10; 207 + sch_gpio_resume.ngpio = 4; 208 + 209 + /* 210 + * GPIO[6:0] enabled by default 211 + * GPIO7 is configured by the CMC as SLPIOVR 212 + * Enable GPIO[9:8] core powered gpios explicitly 213 + */ 214 + outb(0x3, gpio_ba + CGEN + 1); 215 + /* 216 + * SUS_GPIO[2:0] enabled by default 217 + * Enable SUS_GPIO3 resume powered gpio explicitly 218 + */ 219 + outb(0x8, gpio_ba + RGEN); 220 + break; 221 + 222 + case PCI_DEVICE_ID_INTEL_ITC_LPC: 223 + sch_gpio_core.base = 0; 224 + sch_gpio_core.ngpio = 5; 225 + 226 + sch_gpio_resume.base = 5; 227 + sch_gpio_resume.ngpio = 9; 228 + break; 229 + 230 + default: 231 + return -ENODEV; 232 + } 233 + 234 + sch_gpio_core.dev = &pdev->dev; 212 235 sch_gpio_resume.dev = &pdev->dev; 213 236 214 237 err = gpiochip_add(&sch_gpio_core); ··· 246 213 err = gpiochip_add(&sch_gpio_resume); 247 214 if (err < 0) 248 215 goto err_sch_gpio_resume; 249 - 250 - /* 251 - * GPIO[6:0] enabled by default 252 - * GPIO7 is configured by the CMC as SLPIOVR 253 - * Enable GPIO[9:8] core powered gpios explicitly 254 - */ 255 - outb(0x3, gpio_ba + CGEN + 1); 256 - /* 257 - * SUS_GPIO[2:0] enabled by default 258 - * Enable SUS_GPIO3 resume powered gpio explicitly 259 - */ 260 - outb(0x8, gpio_ba + RGEN); 261 216 262 217 return 0; 263 218
+3 -3
drivers/gpio/timbgpio.c
··· 23 23 #include <linux/module.h> 24 24 #include <linux/gpio.h> 25 25 #include <linux/platform_device.h> 26 + #include <linux/mfd/core.h> 26 27 #include <linux/irq.h> 27 28 #include <linux/io.h> 28 29 #include <linux/timb_gpio.h> ··· 229 228 struct gpio_chip *gc; 230 229 struct timbgpio *tgpio; 231 230 struct resource *iomem; 232 - struct timbgpio_platform_data *pdata = pdev->dev.platform_data; 231 + struct timbgpio_platform_data *pdata = mfd_get_data(pdev); 233 232 int irq = platform_get_irq(pdev, 0); 234 233 235 234 if (!pdata || pdata->nr_pins > 32) { ··· 320 319 static int __devexit timbgpio_remove(struct platform_device *pdev) 321 320 { 322 321 int err; 323 - struct timbgpio_platform_data *pdata = pdev->dev.platform_data; 324 322 struct timbgpio *tgpio = platform_get_drvdata(pdev); 325 323 struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 326 324 int irq = platform_get_irq(pdev, 0); 327 325 328 326 if (irq >= 0 && tgpio->irq_base > 0) { 329 327 int i; 330 - for (i = 0; i < pdata->nr_pins; i++) { 328 + for (i = 0; i < tgpio->gpio.ngpio; i++) { 331 329 set_irq_chip(tgpio->irq_base + i, NULL); 332 330 set_irq_chip_data(tgpio->irq_base + i, NULL); 333 331 }
+10
drivers/hwmon/Kconfig
··· 1047 1047 This driver can also be built as a module. If so, the module 1048 1048 will be called tmp421. 1049 1049 1050 + config 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 + 1050 1060 config SENSORS_VIA_CPUTEMP 1051 1061 tristate "VIA CPU temperature sensor" 1052 1062 depends on X86
+1
drivers/hwmon/Makefile
··· 104 104 obj-$(CONFIG_SENSORS_TMP102) += tmp102.o 105 105 obj-$(CONFIG_SENSORS_TMP401) += tmp401.o 106 106 obj-$(CONFIG_SENSORS_TMP421) += tmp421.o 107 + obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o 107 108 obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o 108 109 obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 109 110 obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
+2 -2
drivers/hwmon/jz4740-hwmon.c
··· 32 32 33 33 int irq; 34 34 35 - struct mfd_cell *cell; 35 + const struct mfd_cell *cell; 36 36 struct device *hwmon; 37 37 38 38 struct completion read_completion; ··· 112 112 return -ENOMEM; 113 113 } 114 114 115 - hwmon->cell = pdev->dev.platform_data; 115 + hwmon->cell = mfd_get_cell(pdev); 116 116 117 117 hwmon->irq = platform_get_irq(pdev, 0); 118 118 if (hwmon->irq < 0) {
+157
drivers/hwmon/twl4030-madc-hwmon.c
··· 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 + */ 43 + static 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 */ 61 + static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, madc_read, NULL, 0); 62 + static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, madc_read, NULL, 1); 63 + static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, madc_read, NULL, 2); 64 + static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, madc_read, NULL, 3); 65 + static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, madc_read, NULL, 4); 66 + static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, madc_read, NULL, 5); 67 + static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, madc_read, NULL, 6); 68 + static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, madc_read, NULL, 7); 69 + static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, madc_read, NULL, 8); 70 + static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, madc_read, NULL, 9); 71 + static SENSOR_DEVICE_ATTR(curr10_input, S_IRUGO, madc_read, NULL, 10); 72 + static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11); 73 + static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12); 74 + static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15); 75 + 76 + static 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 + 94 + static const struct attribute_group twl4030_madc_group = { 95 + .attrs = twl4030_madc_attributes, 96 + }; 97 + 98 + static 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 + 116 + err_reg: 117 + sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group); 118 + err_sysfs: 119 + 120 + return ret; 121 + } 122 + 123 + static 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 + 131 + static 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 + 140 + static int __init twl4030_madc_hwmon_init(void) 141 + { 142 + return platform_driver_register(&twl4030_madc_hwmon_driver); 143 + } 144 + 145 + module_init(twl4030_madc_hwmon_init); 146 + 147 + static void __exit twl4030_madc_hwmon_exit(void) 148 + { 149 + platform_driver_unregister(&twl4030_madc_hwmon_driver); 150 + } 151 + 152 + module_exit(twl4030_madc_hwmon_exit); 153 + 154 + MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); 155 + MODULE_LICENSE("GPL"); 156 + MODULE_AUTHOR("J Keerthy"); 157 + MODULE_ALIAS("twl4030_madc_hwmon");
+2 -1
drivers/i2c/busses/i2c-ocores.c
··· 49 49 #include <linux/init.h> 50 50 #include <linux/errno.h> 51 51 #include <linux/platform_device.h> 52 + #include <linux/mfd/core.h> 52 53 #include <linux/i2c.h> 53 54 #include <linux/interrupt.h> 54 55 #include <linux/wait.h> ··· 306 305 return -EIO; 307 306 } 308 307 309 - pdata = pdev->dev.platform_data; 308 + pdata = mfd_get_data(pdev); 310 309 if (pdata) { 311 310 i2c->regstep = pdata->regstep; 312 311 i2c->clock_khz = pdata->clock_khz;
+2 -1
drivers/i2c/busses/i2c-xiic.c
··· 34 34 #include <linux/errno.h> 35 35 #include <linux/delay.h> 36 36 #include <linux/platform_device.h> 37 + #include <linux/mfd/core.h> 37 38 #include <linux/i2c.h> 38 39 #include <linux/interrupt.h> 39 40 #include <linux/wait.h> ··· 705 704 if (irq < 0) 706 705 goto resource_missing; 707 706 708 - pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data; 707 + pdata = mfd_get_data(pdev); 709 708 if (!pdata) 710 709 return -EINVAL; 711 710
+1 -1
drivers/input/misc/88pm860x_onkey.c
··· 74 74 info->chip = chip; 75 75 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 76 76 info->dev = &pdev->dev; 77 - info->irq = irq + chip->irq_base; 77 + info->irq = irq; 78 78 79 79 info->idev = input_allocate_device(); 80 80 if (!info->idev) {
+2 -1
drivers/input/misc/twl4030-vibra.c
··· 29 29 #include <linux/workqueue.h> 30 30 #include <linux/i2c/twl.h> 31 31 #include <linux/mfd/twl4030-codec.h> 32 + #include <linux/mfd/core.h> 32 33 #include <linux/input.h> 33 34 #include <linux/slab.h> 34 35 ··· 197 196 198 197 static int __devinit twl4030_vibra_probe(struct platform_device *pdev) 199 198 { 200 - struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data; 199 + struct twl4030_codec_vibra_data *pdata = mfd_get_data(pdev); 201 200 struct vibra_info *info; 202 201 int ret; 203 202
+28 -32
drivers/leds/leds-88pm860x.c
··· 17 17 #include <linux/leds.h> 18 18 #include <linux/slab.h> 19 19 #include <linux/workqueue.h> 20 + #include <linux/mfd/core.h> 20 21 #include <linux/mfd/88pm860x.h> 21 22 22 23 #define LED_PWM_SHIFT (3) ··· 119 118 120 119 struct pm860x_led *led; 121 120 struct pm860x_chip *chip; 122 - int mask; 121 + unsigned char buf[3]; 122 + int mask, ret; 123 123 124 124 led = container_of(work, struct pm860x_led, work); 125 125 chip = led->chip; ··· 130 128 pm860x_set_bits(led->i2c, __led_off(led->port), 131 129 LED_CURRENT_MASK, led->iset); 132 130 } 131 + pm860x_set_bits(led->i2c, __blink_off(led->port), 132 + LED_BLINK_MASK, LED_ON_CONTINUOUS); 133 133 mask = __blink_ctl_mask(led->port); 134 134 pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask); 135 - } else if (led->brightness == 0) { 136 - pm860x_set_bits(led->i2c, __led_off(led->port), 137 - LED_CURRENT_MASK, 0); 138 - mask = __blink_ctl_mask(led->port); 139 - pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0); 140 135 } 141 136 pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK, 142 137 led->brightness); 138 + 139 + if (led->brightness == 0) { 140 + pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf); 141 + ret = buf[0] & LED_PWM_MASK; 142 + ret |= buf[1] & LED_PWM_MASK; 143 + ret |= buf[2] & LED_PWM_MASK; 144 + if (ret == 0) { 145 + /* unset current since no led is lighting */ 146 + pm860x_set_bits(led->i2c, __led_off(led->port), 147 + LED_CURRENT_MASK, 0); 148 + mask = __blink_ctl_mask(led->port); 149 + pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0); 150 + } 151 + } 143 152 led->current_brightness = led->brightness; 144 153 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 145 154 __led_off(led->port), led->brightness); ··· 166 153 schedule_work(&data->work); 167 154 } 168 155 169 - static int __check_device(struct pm860x_led_pdata *pdata, char *name) 170 - { 171 - struct pm860x_led_pdata *p = pdata; 172 - int ret = -EINVAL; 173 - 174 - while (p && p->id) { 175 - if ((p->id != PM8606_ID_LED) || (p->flags < 0)) 176 - break; 177 - 178 - if (!strncmp(name, pm860x_led_name[p->flags], 179 - MFD_NAME_SIZE)) { 180 - ret = (int)p->flags; 181 - break; 182 - } 183 - p++; 184 - } 185 - return ret; 186 - } 187 - 188 156 static int pm860x_led_probe(struct platform_device *pdev) 189 157 { 190 158 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 191 - struct pm860x_platform_data *pm860x_pdata; 192 159 struct pm860x_led_pdata *pdata; 193 160 struct pm860x_led *data; 161 + struct mfd_cell *cell; 194 162 struct resource *res; 195 163 int ret; 196 164 ··· 181 187 return -EINVAL; 182 188 } 183 189 184 - if (pdev->dev.parent->platform_data) { 185 - pm860x_pdata = pdev->dev.parent->platform_data; 186 - pdata = pm860x_pdata->led; 187 - } else { 190 + cell = pdev->dev.platform_data; 191 + if (cell == NULL) 192 + return -ENODEV; 193 + pdata = cell->mfd_data; 194 + if (pdata == NULL) { 188 195 dev_err(&pdev->dev, "No platform data!\n"); 189 196 return -EINVAL; 190 197 } ··· 193 198 data = kzalloc(sizeof(struct pm860x_led), GFP_KERNEL); 194 199 if (data == NULL) 195 200 return -ENOMEM; 196 - strncpy(data->name, res->name, MFD_NAME_SIZE); 201 + strncpy(data->name, res->name, MFD_NAME_SIZE - 1); 197 202 dev_set_drvdata(&pdev->dev, data); 198 203 data->chip = chip; 199 204 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 200 205 data->iset = pdata->iset; 201 - data->port = __check_device(pdata, data->name); 206 + data->port = pdata->flags; 202 207 if (data->port < 0) { 203 208 dev_err(&pdev->dev, "check device failed\n"); 204 209 kfree(data); ··· 216 221 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 217 222 goto out; 218 223 } 224 + pm860x_led_set(&data->cdev, 0); 219 225 return 0; 220 226 out: 221 227 kfree(data);
+4 -3
drivers/leds/leds-mc13783.c
··· 22 22 #include <linux/leds.h> 23 23 #include <linux/workqueue.h> 24 24 #include <linux/mfd/mc13783.h> 25 + #include <linux/mfd/core.h> 25 26 #include <linux/slab.h> 26 27 27 28 struct mc13783_led { ··· 184 183 185 184 static int __devinit mc13783_leds_prepare(struct platform_device *pdev) 186 185 { 187 - struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 186 + struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev); 188 187 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 189 188 int ret = 0; 190 189 int reg = 0; ··· 265 264 266 265 static int __devinit mc13783_led_probe(struct platform_device *pdev) 267 266 { 268 - struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 267 + struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev); 269 268 struct mc13783_led_platform_data *led_cur; 270 269 struct mc13783_led *led, *led_dat; 271 270 int ret, i; ··· 352 351 353 352 static int __devexit mc13783_led_remove(struct platform_device *pdev) 354 353 { 355 - struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev); 354 + struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev); 356 355 struct mc13783_led *led = platform_get_drvdata(pdev); 357 356 struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent); 358 357 int i;
+2 -1
drivers/media/radio/radio-timb.c
··· 21 21 #include <media/v4l2-ioctl.h> 22 22 #include <media/v4l2-device.h> 23 23 #include <linux/platform_device.h> 24 + #include <linux/mfd/core.h> 24 25 #include <linux/interrupt.h> 25 26 #include <linux/slab.h> 26 27 #include <linux/i2c.h> ··· 149 148 150 149 static int __devinit timbradio_probe(struct platform_device *pdev) 151 150 { 152 - struct timb_radio_platform_data *pdata = pdev->dev.platform_data; 151 + struct timb_radio_platform_data *pdata = mfd_get_data(pdev); 153 152 struct timbradio *tr; 154 153 int err; 155 154
+1 -1
drivers/media/radio/radio-wl1273.c
··· 2138 2138 2139 2139 static 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 2142 struct wl1273_device *radio; 2143 2143 struct v4l2_ctrl *ctrl; 2144 2144 int r = 0;
+2 -1
drivers/media/video/timblogiw.c
··· 24 24 #include <linux/platform_device.h> 25 25 #include <linux/slab.h> 26 26 #include <linux/dmaengine.h> 27 + #include <linux/mfd/core.h> 27 28 #include <linux/scatterlist.h> 28 29 #include <linux/interrupt.h> 29 30 #include <linux/list.h> ··· 791 790 { 792 791 int err; 793 792 struct timblogiw *lw = NULL; 794 - struct timb_video_platform_data *pdata = pdev->dev.platform_data; 793 + struct timb_video_platform_data *pdata = mfd_get_data(pdev); 795 794 796 795 if (!pdata) { 797 796 dev_err(&pdev->dev, "No platform data\n");
+321 -280
drivers/mfd/88pm860x-core.c
··· 17 17 #include <linux/platform_device.h> 18 18 #include <linux/mfd/core.h> 19 19 #include <linux/mfd/88pm860x.h> 20 + #include <linux/regulator/machine.h> 20 21 21 22 #define INT_STATUS_NUM 3 22 23 23 - char pm860x_backlight_name[][MFD_NAME_SIZE] = { 24 - "backlight-0", 25 - "backlight-1", 26 - "backlight-2", 27 - }; 28 - EXPORT_SYMBOL(pm860x_backlight_name); 29 - 30 - char 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 - }; 38 - EXPORT_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 - 48 - static struct resource backlight_resources[] = { 49 - PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT1, WLED1A), 50 - PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT2, WLED2A), 51 - PM8606_BACKLIGHT_RESOURCE(PM8606_BACKLIGHT3, WLED3A), 24 + static struct resource bk_resources[] __initdata = { 25 + {PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,}, 26 + {PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,}, 27 + {PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,}, 52 28 }; 53 29 54 - #define PM8606_BACKLIGHT_DEVS(_i) \ 55 - { \ 56 - .name = "88pm860x-backlight", \ 57 - .num_resources = 1, \ 58 - .resources = &backlight_resources[_i], \ 59 - .id = _i, \ 60 - } 61 - 62 - static struct mfd_cell backlight_devs[] = { 63 - PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT1), 64 - PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT2), 65 - PM8606_BACKLIGHT_DEVS(PM8606_BACKLIGHT3), 30 + static struct resource led_resources[] __initdata = { 31 + {PM8606_LED1_RED, PM8606_LED1_RED, "led0-red", IORESOURCE_IO,}, 32 + {PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,}, 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,}, 66 37 }; 67 38 68 - #define PM8606_LED_RESOURCE(_i, _x) \ 69 - { \ 70 - .name = pm860x_led_name[_i], \ 71 - .start = PM8606_##_x, \ 72 - .end = PM8606_##_x, \ 73 - .flags = IORESOURCE_IO, \ 74 - } 75 - 76 - static 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), 39 + static struct resource regulator_resources[] __initdata = { 40 + {PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,}, 41 + {PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,}, 42 + {PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,}, 43 + {PM8607_ID_LDO1, PM8607_ID_LDO1, "ldo-01", IORESOURCE_IO,}, 44 + {PM8607_ID_LDO2, PM8607_ID_LDO2, "ldo-02", IORESOURCE_IO,}, 45 + {PM8607_ID_LDO3, PM8607_ID_LDO3, "ldo-03", IORESOURCE_IO,}, 46 + {PM8607_ID_LDO4, PM8607_ID_LDO4, "ldo-04", IORESOURCE_IO,}, 47 + {PM8607_ID_LDO5, PM8607_ID_LDO5, "ldo-05", IORESOURCE_IO,}, 48 + {PM8607_ID_LDO6, PM8607_ID_LDO6, "ldo-06", IORESOURCE_IO,}, 49 + {PM8607_ID_LDO7, PM8607_ID_LDO7, "ldo-07", IORESOURCE_IO,}, 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,}, 83 58 }; 84 59 85 - #define PM8606_LED_DEVS(_i) \ 86 - { \ 87 - .name = "88pm860x-led", \ 88 - .num_resources = 1, \ 89 - .resources = &led_resources[_i], \ 90 - .id = _i, \ 91 - } 92 - 93 - static 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), 60 + static struct resource touch_resources[] __initdata = { 61 + {PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,}, 100 62 }; 101 63 102 - static struct resource touch_resources[] = { 103 - { 104 - .start = PM8607_IRQ_PEN, 105 - .end = PM8607_IRQ_PEN, 106 - .flags = IORESOURCE_IRQ, 107 - }, 64 + static struct resource onkey_resources[] __initdata = { 65 + {PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,}, 108 66 }; 109 67 110 - static struct mfd_cell touch_devs[] = { 111 - { 112 - .name = "88pm860x-touch", 113 - .num_resources = 1, 114 - .resources = &touch_resources[0], 115 - }, 68 + static struct resource codec_resources[] __initdata = { 69 + /* Headset microphone insertion or removal */ 70 + {PM8607_IRQ_MICIN, PM8607_IRQ_MICIN, "micin", IORESOURCE_IRQ,}, 71 + /* Hook-switch press or release */ 72 + {PM8607_IRQ_HOOK, PM8607_IRQ_HOOK, "hook", IORESOURCE_IRQ,}, 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,}, 116 77 }; 117 78 118 - #define PM8607_REG_RESOURCE(_start, _end) \ 119 - { \ 120 - .start = PM8607_##_start, \ 121 - .end = PM8607_##_end, \ 122 - .flags = IORESOURCE_IO, \ 123 - } 79 + static struct resource battery_resources[] __initdata = { 80 + {PM8607_IRQ_CC, PM8607_IRQ_CC, "columb counter", IORESOURCE_IRQ,}, 81 + {PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery", IORESOURCE_IRQ,}, 82 + }; 124 83 125 - static 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 - }, 84 + static struct resource charger_resources[] __initdata = { 85 + {PM8607_IRQ_CHG, PM8607_IRQ_CHG, "charger detect", IORESOURCE_IRQ,}, 86 + {PM8607_IRQ_CHG_DONE, PM8607_IRQ_CHG_DONE, "charging done", IORESOURCE_IRQ,}, 87 + {PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout", IORESOURCE_IRQ,}, 88 + {PM8607_IRQ_GPADC1, PM8607_IRQ_GPADC1, "battery temperature", IORESOURCE_IRQ,}, 89 + {PM8607_IRQ_VBAT, PM8607_IRQ_VBAT, "battery voltage", IORESOURCE_IRQ,}, 90 + {PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage", IORESOURCE_IRQ,}, 91 + }; 92 + 93 + static struct mfd_cell bk_devs[] __initdata = { 94 + {"88pm860x-backlight", 0,}, 95 + {"88pm860x-backlight", 1,}, 96 + {"88pm860x-backlight", 2,}, 97 + }; 98 + 99 + static struct mfd_cell led_devs[] __initdata = { 100 + {"88pm860x-led", 0,}, 101 + {"88pm860x-led", 1,}, 102 + {"88pm860x-led", 2,}, 103 + {"88pm860x-led", 3,}, 104 + {"88pm860x-led", 4,}, 105 + {"88pm860x-led", 5,}, 106 + }; 107 + 108 + static struct mfd_cell regulator_devs[] __initdata = { 109 + {"88pm860x-regulator", 0,}, 110 + {"88pm860x-regulator", 1,}, 111 + {"88pm860x-regulator", 2,}, 112 + {"88pm860x-regulator", 3,}, 113 + {"88pm860x-regulator", 4,}, 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,}, 127 + }; 128 + 129 + static struct mfd_cell touch_devs[] __initdata = { 130 + {"88pm860x-touch", -1,}, 131 + }; 132 + 133 + static struct mfd_cell onkey_devs[] __initdata = { 134 + {"88pm860x-onkey", -1,}, 135 + }; 136 + 137 + static struct mfd_cell codec_devs[] __initdata = { 138 + {"88pm860x-codec", -1,}, 132 139 }; 133 140 134 141 static struct mfd_cell power_devs[] = { 135 - { 136 - .name = "88pm860x-power", 137 - .num_resources = 1, 138 - .resources = &power_supply_resources[0], 139 - .id = -1, 140 - }, 142 + {"88pm860x-battery", -1,}, 143 + {"88pm860x-charger", -1,}, 141 144 }; 142 145 143 - static struct resource onkey_resources[] = { 144 - { 145 - .name = "88pm860x-onkey", 146 - .start = PM8607_IRQ_ONKEY, 147 - .end = PM8607_IRQ_ONKEY, 148 - .flags = IORESOURCE_IRQ, 149 - }, 150 - }; 151 - 152 - static struct mfd_cell onkey_devs[] = { 153 - { 154 - .name = "88pm860x-onkey", 155 - .num_resources = 1, 156 - .resources = &onkey_resources[0], 157 - .id = -1, 158 - }, 159 - }; 160 - 161 - static struct resource codec_resources[] = { 162 - { 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 - }; 188 - 189 - static struct mfd_cell codec_devs[] = { 190 - { 191 - .name = "88pm860x-codec", 192 - .num_resources = ARRAY_SIZE(codec_resources), 193 - .resources = &codec_resources[0], 194 - .id = -1, 195 - }, 196 - }; 197 - 198 - static struct resource regulator_resources[] = { 199 - PM8607_REG_RESOURCE(BUCK1, BUCK1), 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 - }; 216 - 217 - #define PM8607_REG_DEVS(_id) \ 218 - { \ 219 - .name = "88pm860x-regulator", \ 220 - .num_resources = 1, \ 221 - .resources = &regulator_resources[PM8607_ID_##_id], \ 222 - .id = PM8607_ID_##_id, \ 223 - } 224 - 225 - static 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 - }; 146 + static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)]; 147 + static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)]; 148 + static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)]; 149 + static struct pm860x_touch_pdata touch_pdata; 150 + static struct pm860x_power_pdata power_pdata; 243 151 244 152 struct pm860x_irq_data { 245 153 int reg; ··· 503 595 free_irq(chip->core_irq, chip); 504 596 } 505 597 506 - static void __devinit device_8606_init(struct pm860x_chip *chip, 507 - struct i2c_client *i2c, 508 - struct pm860x_platform_data *pdata) 598 + static void __devinit device_bk_init(struct pm860x_chip *chip, 599 + struct i2c_client *i2c, 600 + struct pm860x_platform_data *pdata) 601 + { 602 + int ret; 603 + int i, j, id; 604 + 605 + if ((pdata == NULL) || (pdata->backlight == NULL)) 606 + return; 607 + 608 + if (pdata->num_backlights > ARRAY_SIZE(bk_devs)) 609 + pdata->num_backlights = ARRAY_SIZE(bk_devs); 610 + 611 + for (i = 0; i < pdata->num_backlights; i++) { 612 + memcpy(&bk_pdata[i], &pdata->backlight[i], 613 + sizeof(struct pm860x_backlight_pdata)); 614 + bk_devs[i].mfd_data = &bk_pdata[i]; 615 + 616 + for (j = 0; j < ARRAY_SIZE(bk_devs); j++) { 617 + id = bk_resources[j].start; 618 + if (bk_pdata[i].flags != id) 619 + continue; 620 + 621 + bk_devs[i].num_resources = 1; 622 + bk_devs[i].resources = &bk_resources[j]; 623 + ret = mfd_add_devices(chip->dev, 0, 624 + &bk_devs[i], 1, 625 + &bk_resources[j], 0); 626 + if (ret < 0) { 627 + dev_err(chip->dev, "Failed to add " 628 + "backlight subdev\n"); 629 + return; 630 + } 631 + } 632 + } 633 + } 634 + 635 + static void __devinit device_led_init(struct pm860x_chip *chip, 636 + struct i2c_client *i2c, 637 + struct pm860x_platform_data *pdata) 638 + { 639 + int ret; 640 + int i, j, id; 641 + 642 + if ((pdata == NULL) || (pdata->led == NULL)) 643 + return; 644 + 645 + if (pdata->num_leds > ARRAY_SIZE(led_devs)) 646 + pdata->num_leds = ARRAY_SIZE(led_devs); 647 + 648 + for (i = 0; i < pdata->num_leds; i++) { 649 + memcpy(&led_pdata[i], &pdata->led[i], 650 + sizeof(struct pm860x_led_pdata)); 651 + led_devs[i].mfd_data = &led_pdata[i]; 652 + 653 + for (j = 0; j < ARRAY_SIZE(led_devs); j++) { 654 + id = led_resources[j].start; 655 + if (led_pdata[i].flags != id) 656 + continue; 657 + 658 + led_devs[i].num_resources = 1; 659 + led_devs[i].resources = &led_resources[j], 660 + ret = mfd_add_devices(chip->dev, 0, 661 + &led_devs[i], 1, 662 + &led_resources[j], 0); 663 + if (ret < 0) { 664 + dev_err(chip->dev, "Failed to add " 665 + "led subdev\n"); 666 + return; 667 + } 668 + } 669 + } 670 + } 671 + 672 + static void __devinit device_regulator_init(struct pm860x_chip *chip, 673 + struct i2c_client *i2c, 674 + struct pm860x_platform_data *pdata) 675 + { 676 + struct regulator_init_data *initdata; 677 + int ret; 678 + int i, j; 679 + 680 + if ((pdata == NULL) || (pdata->regulator == NULL)) 681 + return; 682 + 683 + if (pdata->num_regulators > ARRAY_SIZE(regulator_devs)) 684 + pdata->num_regulators = ARRAY_SIZE(regulator_devs); 685 + 686 + for (i = 0, j = -1; i < pdata->num_regulators; i++) { 687 + initdata = &pdata->regulator[i]; 688 + if (strstr(initdata->constraints.name, "BUCK")) { 689 + sscanf(initdata->constraints.name, "BUCK%d", &j); 690 + /* BUCK1 ~ BUCK3 */ 691 + if ((j < 1) || (j > 3)) { 692 + dev_err(chip->dev, "Failed to add constraint " 693 + "(%s)\n", initdata->constraints.name); 694 + goto out; 695 + } 696 + j = (j - 1) + PM8607_ID_BUCK1; 697 + } 698 + if (strstr(initdata->constraints.name, "LDO")) { 699 + sscanf(initdata->constraints.name, "LDO%d", &j); 700 + /* LDO1 ~ LDO15 */ 701 + if ((j < 1) || (j > 15)) { 702 + dev_err(chip->dev, "Failed to add constraint " 703 + "(%s)\n", initdata->constraints.name); 704 + goto out; 705 + } 706 + j = (j - 1) + PM8607_ID_LDO1; 707 + } 708 + if (j == -1) { 709 + dev_err(chip->dev, "Failed to add constraint (%s)\n", 710 + initdata->constraints.name); 711 + goto out; 712 + } 713 + memcpy(&regulator_pdata[i], &pdata->regulator[i], 714 + sizeof(struct regulator_init_data)); 715 + regulator_devs[i].mfd_data = &regulator_pdata[i]; 716 + regulator_devs[i].num_resources = 1; 717 + regulator_devs[i].resources = &regulator_resources[j]; 718 + 719 + ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1, 720 + &regulator_resources[j], 0); 721 + if (ret < 0) { 722 + dev_err(chip->dev, "Failed to add regulator subdev\n"); 723 + goto out; 724 + } 725 + } 726 + out: 727 + return; 728 + } 729 + 730 + static void __devinit device_touch_init(struct pm860x_chip *chip, 731 + struct i2c_client *i2c, 732 + struct pm860x_platform_data *pdata) 509 733 { 510 734 int ret; 511 735 512 - if (pdata && pdata->backlight) { 513 - ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], 514 - ARRAY_SIZE(backlight_devs), 515 - &backlight_resources[0], 0); 516 - if (ret < 0) { 517 - dev_err(chip->dev, "Failed to add backlight " 518 - "subdev\n"); 519 - goto out_dev; 520 - } 521 - } 736 + if ((pdata == NULL) || (pdata->touch == NULL)) 737 + return; 522 738 523 - if (pdata && pdata->led) { 524 - ret = mfd_add_devices(chip->dev, 0, &led_devs[0], 525 - ARRAY_SIZE(led_devs), 526 - &led_resources[0], 0); 527 - if (ret < 0) { 528 - dev_err(chip->dev, "Failed to add led " 529 - "subdev\n"); 530 - goto out_dev; 531 - } 532 - } 533 - return; 534 - out_dev: 535 - mfd_remove_devices(chip->dev); 536 - device_irq_exit(chip); 739 + memcpy(&touch_pdata, pdata->touch, sizeof(struct pm860x_touch_pdata)); 740 + touch_devs[0].mfd_data = &touch_pdata; 741 + touch_devs[0].num_resources = ARRAY_SIZE(touch_resources); 742 + touch_devs[0].resources = &touch_resources[0]; 743 + ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], 744 + ARRAY_SIZE(touch_devs), &touch_resources[0], 745 + chip->irq_base); 746 + if (ret < 0) 747 + dev_err(chip->dev, "Failed to add touch subdev\n"); 748 + } 749 + 750 + static void __devinit device_power_init(struct pm860x_chip *chip, 751 + struct i2c_client *i2c, 752 + struct pm860x_platform_data *pdata) 753 + { 754 + int ret; 755 + 756 + if ((pdata == NULL) || (pdata->power == NULL)) 757 + return; 758 + 759 + memcpy(&power_pdata, pdata->power, sizeof(struct pm860x_power_pdata)); 760 + power_devs[0].mfd_data = &power_pdata; 761 + power_devs[0].num_resources = ARRAY_SIZE(battery_resources); 762 + power_devs[0].resources = &battery_resources[0], 763 + ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, 764 + &battery_resources[0], chip->irq_base); 765 + if (ret < 0) 766 + dev_err(chip->dev, "Failed to add battery subdev\n"); 767 + 768 + power_devs[1].mfd_data = &power_pdata; 769 + power_devs[1].num_resources = ARRAY_SIZE(charger_resources); 770 + power_devs[1].resources = &charger_resources[0], 771 + ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, 772 + &charger_resources[0], chip->irq_base); 773 + if (ret < 0) 774 + dev_err(chip->dev, "Failed to add charger subdev\n"); 775 + } 776 + 777 + static void __devinit device_onkey_init(struct pm860x_chip *chip, 778 + struct i2c_client *i2c, 779 + struct pm860x_platform_data *pdata) 780 + { 781 + int ret; 782 + 783 + onkey_devs[0].num_resources = ARRAY_SIZE(onkey_resources); 784 + onkey_devs[0].resources = &onkey_resources[0], 785 + ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], 786 + ARRAY_SIZE(onkey_devs), &onkey_resources[0], 787 + chip->irq_base); 788 + if (ret < 0) 789 + dev_err(chip->dev, "Failed to add onkey subdev\n"); 790 + } 791 + 792 + static void __devinit device_codec_init(struct pm860x_chip *chip, 793 + struct i2c_client *i2c, 794 + struct pm860x_platform_data *pdata) 795 + { 796 + int ret; 797 + 798 + codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); 799 + codec_devs[0].resources = &codec_resources[0], 800 + ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], 801 + ARRAY_SIZE(codec_devs), &codec_resources[0], 0); 802 + if (ret < 0) 803 + dev_err(chip->dev, "Failed to add codec subdev\n"); 537 804 } 538 805 539 806 static void __devinit device_8607_init(struct pm860x_chip *chip, ··· 766 683 if (ret < 0) 767 684 goto out; 768 685 769 - ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0], 770 - ARRAY_SIZE(regulator_devs), 771 - &regulator_resources[0], 0); 772 - if (ret < 0) { 773 - dev_err(chip->dev, "Failed to add regulator subdev\n"); 774 - goto out_dev; 775 - } 776 - 777 - if (pdata && pdata->touch) { 778 - ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], 779 - ARRAY_SIZE(touch_devs), 780 - &touch_resources[0], 0); 781 - if (ret < 0) { 782 - dev_err(chip->dev, "Failed to add touch " 783 - "subdev\n"); 784 - goto out_dev; 785 - } 786 - } 787 - 788 - if (pdata && pdata->power) { 789 - ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 790 - ARRAY_SIZE(power_devs), 791 - &power_supply_resources[0], 0); 792 - if (ret < 0) { 793 - dev_err(chip->dev, "Failed to add power supply " 794 - "subdev\n"); 795 - goto out_dev; 796 - } 797 - } 798 - 799 - ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], 800 - ARRAY_SIZE(onkey_devs), 801 - &onkey_resources[0], 0); 802 - if (ret < 0) { 803 - dev_err(chip->dev, "Failed to add onkey subdev\n"); 804 - goto out_dev; 805 - } 806 - 807 - ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], 808 - ARRAY_SIZE(codec_devs), 809 - &codec_resources[0], 0); 810 - if (ret < 0) { 811 - dev_err(chip->dev, "Failed to add codec subdev\n"); 812 - goto out_dev; 813 - } 814 - return; 815 - out_dev: 816 - mfd_remove_devices(chip->dev); 817 - device_irq_exit(chip); 686 + device_regulator_init(chip, i2c, pdata); 687 + device_onkey_init(chip, i2c, pdata); 688 + device_touch_init(chip, i2c, pdata); 689 + device_power_init(chip, i2c, pdata); 690 + device_codec_init(chip, i2c, pdata); 818 691 out: 819 692 return; 820 693 } ··· 782 743 783 744 switch (chip->id) { 784 745 case CHIP_PM8606: 785 - device_8606_init(chip, chip->client, pdata); 746 + device_bk_init(chip, chip->client, pdata); 747 + device_led_init(chip, chip->client, pdata); 786 748 break; 787 749 case CHIP_PM8607: 788 750 device_8607_init(chip, chip->client, pdata); ··· 793 753 if (chip->companion) { 794 754 switch (chip->id) { 795 755 case CHIP_PM8607: 796 - device_8606_init(chip, chip->companion, pdata); 756 + device_bk_init(chip, chip->companion, pdata); 757 + device_led_init(chip, chip->companion, pdata); 797 758 break; 798 759 case CHIP_PM8606: 799 760 device_8607_init(chip, chip->companion, pdata);
+103
drivers/mfd/88pm860x-i2c.c
··· 126 126 } 127 127 EXPORT_SYMBOL(pm860x_set_bits); 128 128 129 + int 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 + } 148 + EXPORT_SYMBOL(pm860x_page_reg_read); 149 + 150 + int 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 + } 167 + EXPORT_SYMBOL(pm860x_page_reg_write); 168 + 169 + int 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 + } 186 + EXPORT_SYMBOL(pm860x_page_bulk_read); 187 + 188 + int 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 + } 205 + EXPORT_SYMBOL(pm860x_page_bulk_write); 206 + 207 + int 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); 225 + out: 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 + } 231 + EXPORT_SYMBOL(pm860x_page_set_bits); 129 232 130 233 static const struct i2c_device_id pm860x_id_table[] = { 131 234 { "88PM860x", 0 },
+40
drivers/mfd/Kconfig
··· 129 129 To compile this driver as a module, choose M here: the 130 130 module will be called ucb1400_core. 131 131 132 + config 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 + 132 143 config TPS65010 133 144 tristate "TPS6501x Power Management chips" 134 145 depends on I2C && GPIOLIB ··· 188 177 boards, providing power management, RTC, GPIO, keypad, a 189 178 high speed USB OTG transceiver, an audio codec (on most 190 179 versions) and many other features. 180 + 181 + config TWL4030_MADC 182 + tristate "Texas Instruments TWL4030 MADC" 183 + depends on TWL4030_CORE 184 + help 185 + This driver provides support for triton TWL4030-MADC. The 186 + driver supports both RT and SW conversion methods. 187 + 188 + This driver can be built as a module. If so it will be 189 + named twl4030-madc 191 190 192 191 config TWL4030_POWER 193 192 bool "Support power resources on TWL4030 family chips" ··· 324 303 a Power Management IC. This driver provies common support for 325 304 accessing the device, additional drivers must be enabled in order 326 305 to use the functionality of the device. 306 + 307 + config MFD_MAX8997 308 + bool "Maxim Semiconductor MAX8997/8966 PMIC Support" 309 + depends on I2C=y && GENERIC_HARDIRQS 310 + select MFD_CORE 311 + help 312 + Say yes here to support for Maxim Semiconductor MAX8998/8966. 313 + This is a Power Management IC with RTC, Flash, Fuel Gauge, Haptic, 314 + MUIC controls on chip. 315 + This driver provides common support for accessing the device; 316 + additional drivers must be enabled in order to use the functionality 317 + of the device. 327 318 328 319 config MFD_MAX8998 329 320 bool "Maxim Semiconductor MAX8998/National LP3974 PMIC Support" ··· 566 533 help 567 534 Select this option if you want debug information using the debug 568 535 filesystem, debugfs. 536 + 537 + config AB8500_GPADC 538 + bool "AB8500 GPADC driver" 539 + depends on AB8500_CORE && REGULATOR_AB8500 540 + default y 541 + help 542 + AB8500 GPADC driver used to convert Acc and battery/ac/usb voltage 569 543 570 544 config AB3550_CORE 571 545 bool "ST-Ericsson AB3550 Mixed Signal Circuit core functions"
+5 -1
drivers/mfd/Makefile
··· 33 33 obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o 34 34 obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o 35 35 36 + obj-$(CONFIG_TPS6105X) += tps6105x.o 36 37 obj-$(CONFIG_TPS65010) += tps65010.o 37 38 obj-$(CONFIG_TPS6507X) += tps6507x.o 38 39 obj-$(CONFIG_MENELAUS) += menelaus.o 39 40 40 41 obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o 42 + obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o 41 43 obj-$(CONFIG_TWL4030_POWER) += twl4030-power.o 42 44 obj-$(CONFIG_TWL4030_CODEC) += twl4030-codec.o 43 45 obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o ··· 63 61 obj-$(CONFIG_PMIC_DA903X) += da903x.o 64 62 max8925-objs := max8925-core.o max8925-i2c.o 65 63 obj-$(CONFIG_MFD_MAX8925) += max8925.o 64 + obj-$(CONFIG_MFD_MAX8997) += max8997.o 66 65 obj-$(CONFIG_MFD_MAX8998) += max8998.o max8998-irq.o 67 66 68 67 pcf50633-objs := pcf50633-core.o pcf50633-irq.o ··· 74 71 obj-$(CONFIG_AB3100_CORE) += ab3100-core.o 75 72 obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o 76 73 obj-$(CONFIG_AB3550_CORE) += ab3550-core.o 77 - obj-$(CONFIG_AB8500_CORE) += ab8500-core.o 74 + obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o 78 75 obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o 79 76 obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o 77 + obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o 80 78 obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o 81 79 obj-$(CONFIG_PMIC_ADP5520) += adp5520.o 82 80 obj-$(CONFIG_LPC_SCH) += lpc_sch.o
+4 -6
drivers/mfd/ab3100-core.c
··· 613 613 ab3100_get_priv.ab3100 = ab3100; 614 614 ab3100_get_priv.mode = false; 615 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 617 &ab3100_get_set_reg_fops); 618 618 if (!ab3100_get_reg_file) { 619 619 err = -ENOMEM; ··· 623 623 ab3100_set_priv.ab3100 = ab3100; 624 624 ab3100_set_priv.mode = true; 625 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 627 &ab3100_get_set_reg_fops); 628 628 if (!ab3100_set_reg_file) { 629 629 err = -ENOMEM; ··· 949 949 goto exit_no_ops; 950 950 951 951 /* Set up and register the platform devices. */ 952 - for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) { 953 - ab3100_devs[i].platform_data = ab3100_plf_data; 954 - ab3100_devs[i].data_size = sizeof(struct ab3100_platform_data); 955 - } 952 + for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) 953 + ab3100_devs[i].mfd_data = ab3100_plf_data; 956 954 957 955 err = mfd_add_devices(&client->dev, 0, ab3100_devs, 958 956 ARRAY_SIZE(ab3100_devs), NULL, 0);
+5 -7
drivers/mfd/ab3550-core.c
··· 1053 1053 goto exit_destroy_dir; 1054 1054 1055 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 1057 if (!ab3550_bank_file) 1058 1058 goto exit_destroy_reg; 1059 1059 1060 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 1062 if (!ab3550_address_file) 1063 1063 goto exit_destroy_bank; 1064 1064 1065 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 1067 if (!ab3550_val_file) 1068 1068 goto exit_destroy_address; 1069 1069 ··· 1320 1320 goto exit_no_ops; 1321 1321 1322 1322 /* Set up and register the platform devices. */ 1323 - for (i = 0; i < AB3550_NUM_DEVICES; i++) { 1324 - ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i]; 1325 - ab3550_devs[i].data_size = ab3550_plf_data->dev_data_sz[i]; 1326 - } 1323 + for (i = 0; i < AB3550_NUM_DEVICES; i++) 1324 + ab3550_devs[i].mfd_data = ab3550_plf_data->dev_data[i]; 1327 1325 1328 1326 err = mfd_add_devices(&client->dev, 0, ab3550_devs, 1329 1327 ARRAY_SIZE(ab3550_devs), NULL,
+52 -4
drivers/mfd/ab8500-core.c
··· 4 4 * License Terms: GNU General Public License v2 5 5 * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> 6 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 10 #include <linux/kernel.h> ··· 90 90 #define AB8500_IT_MASK24_REG 0x57 91 91 92 92 #define AB8500_REV_REG 0x80 93 + #define AB8500_SWITCH_OFF_STATUS 0x00 93 94 94 95 /* 95 96 * Map interrupt numbers to the LATCH and MASK register offsets, Interrupt ··· 653 652 return sprintf(buf, "%#x\n", ab8500 ? ab8500->chip_id : -EINVAL); 654 653 } 655 654 655 + /* 656 + * ab8500 has switched off due to (SWITCH_OFF_STATUS): 657 + * 0x01 Swoff bit programming 658 + * 0x02 Thermal protection activation 659 + * 0x04 Vbat lower then BattOk falling threshold 660 + * 0x08 Watchdog expired 661 + * 0x10 Non presence of 32kHz clock 662 + * 0x20 Battery level lower than power on reset threshold 663 + * 0x40 Power on key 1 pressed longer than 10 seconds 664 + * 0x80 DB8500 thermal shutdown 665 + */ 666 + static ssize_t show_switch_off_status(struct device *dev, 667 + struct device_attribute *attr, char *buf) 668 + { 669 + int ret; 670 + u8 value; 671 + struct ab8500 *ab8500; 672 + 673 + ab8500 = dev_get_drvdata(dev); 674 + ret = get_register_interruptible(ab8500, AB8500_RTC, 675 + AB8500_SWITCH_OFF_STATUS, &value); 676 + if (ret < 0) 677 + return ret; 678 + return sprintf(buf, "%#x\n", value); 679 + } 680 + 656 681 static DEVICE_ATTR(chip_id, S_IRUGO, show_chip_id, NULL); 682 + static DEVICE_ATTR(switch_off_status, S_IRUGO, show_switch_off_status, NULL); 657 683 658 684 static struct attribute *ab8500_sysfs_entries[] = { 659 685 &dev_attr_chip_id.attr, 686 + &dev_attr_switch_off_status.attr, 660 687 NULL, 661 688 }; 662 689 ··· 715 686 * 0x10 - Cut 1.0 716 687 * 0x11 - Cut 1.1 717 688 * 0x20 - Cut 2.0 689 + * 0x30 - Cut 3.0 718 690 */ 719 - if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20) { 720 - ab8500->revision = value; 691 + if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20 || 692 + value == 0x30) { 721 693 dev_info(ab8500->dev, "detected chip, revision: %#x\n", value); 722 694 } else { 723 695 dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value); 724 696 return -EINVAL; 725 697 } 726 698 ab8500->chip_id = value; 699 + 700 + /* 701 + * ab8500 has switched off due to (SWITCH_OFF_STATUS): 702 + * 0x01 Swoff bit programming 703 + * 0x02 Thermal protection activation 704 + * 0x04 Vbat lower then BattOk falling threshold 705 + * 0x08 Watchdog expired 706 + * 0x10 Non presence of 32kHz clock 707 + * 0x20 Battery level lower than power on reset threshold 708 + * 0x40 Power on key 1 pressed longer than 10 seconds 709 + * 0x80 DB8500 thermal shutdown 710 + */ 711 + 712 + ret = get_register_interruptible(ab8500, AB8500_RTC, 713 + AB8500_SWITCH_OFF_STATUS, &value); 714 + if (ret < 0) 715 + return ret; 716 + dev_info(ab8500->dev, "switch off status: %#x", value); 727 717 728 718 if (plat && plat->init) 729 719 plat->init(ab8500); ··· 812 764 return 0; 813 765 } 814 766 815 - MODULE_AUTHOR("Srinidhi Kasagar, Rabin Vincent"); 767 + MODULE_AUTHOR("Mattias Wallin, Srinidhi Kasagar, Rabin Vincent"); 816 768 MODULE_DESCRIPTION("AB8500 MFD core"); 817 769 MODULE_LICENSE("GPL v2");
+3 -3
drivers/mfd/ab8500-debugfs.c
··· 585 585 goto exit_destroy_dir; 586 586 587 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 589 if (!ab8500_bank_file) 590 590 goto exit_destroy_reg; 591 591 592 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 594 &ab8500_address_fops); 595 595 if (!ab8500_address_file) 596 596 goto exit_destroy_bank; 597 597 598 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 600 if (!ab8500_val_file) 601 601 goto exit_destroy_address; 602 602
+614
drivers/mfd/ab8500-gpadc.c
··· 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 + 84 + enum 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 + */ 97 + struct 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 + */ 114 + struct 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 + 124 + static 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 + */ 130 + struct 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 + } 141 + EXPORT_SYMBOL(ab8500_gpadc_get); 142 + 143 + static 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 + */ 240 + int 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 + 352 + out: 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 + } 367 + EXPORT_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 + */ 379 + static 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 + 388 + static 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 + 398 + static 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 + 520 + static 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; 566 + fail_irq: 567 + free_irq(gpadc->irq, gpadc); 568 + fail: 569 + kfree(gpadc); 570 + gpadc = NULL; 571 + return ret; 572 + } 573 + 574 + static 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 + 589 + static 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 + 598 + static int __init ab8500_gpadc_init(void) 599 + { 600 + return platform_driver_register(&ab8500_gpadc_driver); 601 + } 602 + 603 + static void __exit ab8500_gpadc_exit(void) 604 + { 605 + platform_driver_unregister(&ab8500_gpadc_driver); 606 + } 607 + 608 + subsys_initcall_sync(ab8500_gpadc_init); 609 + module_exit(ab8500_gpadc_exit); 610 + 611 + MODULE_LICENSE("GPL v2"); 612 + MODULE_AUTHOR("Arun R Murthy, Daniel Willerud, Johan Palsson"); 613 + MODULE_ALIAS("platform:ab8500_gpadc"); 614 + MODULE_DESCRIPTION("AB8500 GPADC driver");
+80
drivers/mfd/ab8500-sysctrl.c
··· 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 + 13 + static struct device *sysctrl_dev; 14 + 15 + static inline bool valid_bank(u8 bank) 16 + { 17 + return ((bank == AB8500_SYS_CTRL1_BLOCK) || 18 + (bank == AB8500_SYS_CTRL2_BLOCK)); 19 + } 20 + 21 + int 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 + 36 + int 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 + 51 + static int __devinit ab8500_sysctrl_probe(struct platform_device *pdev) 52 + { 53 + sysctrl_dev = &pdev->dev; 54 + return 0; 55 + } 56 + 57 + static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev) 58 + { 59 + sysctrl_dev = NULL; 60 + return 0; 61 + } 62 + 63 + static 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 + 72 + static int __init ab8500_sysctrl_init(void) 73 + { 74 + return platform_driver_register(&ab8500_sysctrl_driver); 75 + } 76 + subsys_initcall(ab8500_sysctrl_init); 77 + 78 + MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com"); 79 + MODULE_DESCRIPTION("AB8500 system control driver"); 80 + MODULE_LICENSE("GPL v2");
+7 -8
drivers/mfd/adp5520.c
··· 321 321 } 322 322 323 323 #ifdef CONFIG_PM 324 - static int adp5520_suspend(struct i2c_client *client, 325 - pm_message_t state) 324 + static int adp5520_suspend(struct device *dev) 326 325 { 326 + struct i2c_client *client = to_i2c_client(dev); 327 327 struct adp5520_chip *chip = dev_get_drvdata(&client->dev); 328 328 329 329 adp5520_clr_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); 330 330 return 0; 331 331 } 332 332 333 - static int adp5520_resume(struct i2c_client *client) 333 + static int adp5520_resume(struct device *dev) 334 334 { 335 + struct i2c_client *client = to_i2c_client(dev); 335 336 struct adp5520_chip *chip = dev_get_drvdata(&client->dev); 336 337 337 338 adp5520_set_bits(chip->dev, ADP5520_MODE_STATUS, ADP5520_nSTNBY); 338 339 return 0; 339 340 } 340 - #else 341 - #define adp5520_suspend NULL 342 - #define adp5520_resume NULL 343 341 #endif 342 + 343 + static SIMPLE_DEV_PM_OPS(adp5520_pm, adp5520_suspend, adp5520_resume); 344 344 345 345 static const struct i2c_device_id adp5520_id[] = { 346 346 { "pmic-adp5520", ID_ADP5520 }, ··· 353 353 .driver = { 354 354 .name = "adp5520", 355 355 .owner = THIS_MODULE, 356 + .pm = &adp5520_pm, 356 357 }, 357 358 .probe = adp5520_probe, 358 359 .remove = __devexit_p(adp5520_remove), 359 - .suspend = adp5520_suspend, 360 - .resume = adp5520_resume, 361 360 .id_table = adp5520_id, 362 361 }; 363 362
+2 -8
drivers/mfd/asic3.c
··· 682 682 .name = "ds1wm", 683 683 .enable = ds1wm_enable, 684 684 .disable = ds1wm_disable, 685 - .driver_data = &ds1wm_pdata, 685 + .mfd_data = &ds1wm_pdata, 686 686 .num_resources = ARRAY_SIZE(ds1wm_resources), 687 687 .resources = ds1wm_resources, 688 688 }; ··· 783 783 .name = "tmio-mmc", 784 784 .enable = asic3_mmc_enable, 785 785 .disable = asic3_mmc_disable, 786 - .driver_data = &asic3_mmc_data, 786 + .mfd_data = &asic3_mmc_data, 787 787 .num_resources = ARRAY_SIZE(asic3_mmc_resources), 788 788 .resources = asic3_mmc_resources, 789 789 }; ··· 810 810 ds1wm_resources[0].start >>= asic->bus_shift; 811 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 813 /* MMC */ 817 814 asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) + 818 815 mem_sdio->start, 0x400 >> asic->bus_shift); ··· 820 823 } 821 824 asic3_mmc_resources[0].start >>= asic->bus_shift; 822 825 asic3_mmc_resources[0].end >>= asic->bus_shift; 823 - 824 - asic3_cell_mmc.platform_data = &asic3_cell_mmc; 825 - asic3_cell_mmc.data_size = sizeof(asic3_cell_mmc); 826 826 827 827 ret = mfd_add_devices(&pdev->dev, pdev->id, 828 828 &asic3_cell_ds1wm, 1, mem, asic->irq_base);
+37
drivers/mfd/cs5535-mfd.c
··· 39 39 NR_BARS, 40 40 }; 41 41 42 + static 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 + 60 + static 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 + 42 73 static __devinitdata struct resource cs5535_mfd_resources[NR_BARS]; 43 74 44 75 static __devinitdata struct mfd_cell cs5535_mfd_cells[] = { ··· 96 65 .name = "cs5535-pms", 97 66 .num_resources = 1, 98 67 .resources = &cs5535_mfd_resources[PMS_BAR], 68 + 69 + .enable = cs5535_mfd_res_enable, 70 + .disable = cs5535_mfd_res_disable, 99 71 }, 100 72 { 101 73 .id = ACPI_BAR, 102 74 .name = "cs5535-acpi", 103 75 .num_resources = 1, 104 76 .resources = &cs5535_mfd_resources[ACPI_BAR], 77 + 78 + .enable = cs5535_mfd_res_enable, 79 + .disable = cs5535_mfd_res_disable, 105 80 }, 106 81 }; 107 82
+2 -2
drivers/mfd/davinci_voicecodec.c
··· 119 119 /* Voice codec interface client */ 120 120 cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; 121 121 cell->name = "davinci-vcif"; 122 - cell->driver_data = davinci_vc; 122 + cell->mfd_data = davinci_vc; 123 123 124 124 /* Voice codec CQ93VC client */ 125 125 cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; 126 126 cell->name = "cq93vc-codec"; 127 - cell->driver_data = davinci_vc; 127 + cell->mfd_data = davinci_vc; 128 128 129 129 ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, 130 130 DAVINCI_VC_CELLS, NULL, 0);
+1 -6
drivers/mfd/htc-pasic3.c
··· 117 117 .name = "ds1wm", 118 118 .enable = ds1wm_enable, 119 119 .disable = ds1wm_disable, 120 - .driver_data = &ds1wm_pdata, 120 + .mfd_data = &ds1wm_pdata, 121 121 .num_resources = 2, 122 122 .resources = ds1wm_resources, 123 123 }; ··· 165 165 ds1wm_pdata.clock_rate = pdata->clock_rate; 166 166 /* the first 5 PASIC3 registers control the DS1WM */ 167 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 168 ret = mfd_add_devices(&pdev->dev, pdev->id, 171 169 &ds1wm_cell, 1, r, irq); 172 170 if (ret < 0) ··· 172 174 } 173 175 174 176 if (pdata && pdata->led_pdata) { 175 - led_cell.driver_data = pdata->led_pdata; 176 - led_cell.platform_data = &led_cell; 177 - led_cell.data_size = sizeof(ds1wm_cell); 178 177 ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); 179 178 if (ret < 0) 180 179 dev_warn(dev, "failed to register LED device\n");
+1 -2
drivers/mfd/janz-cmodio.c
··· 86 86 87 87 /* Add platform data */ 88 88 pdata->modno = modno; 89 - cell->platform_data = pdata; 90 - cell->data_size = sizeof(*pdata); 89 + cell->mfd_data = pdata; 91 90 92 91 /* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */ 93 92 res->flags = IORESOURCE_MEM;
-4
drivers/mfd/jz4740-adc.c
··· 232 232 .name = "jz4740-hwmon", 233 233 .num_resources = ARRAY_SIZE(jz4740_hwmon_resources), 234 234 .resources = jz4740_hwmon_resources, 235 - .platform_data = (void *)&jz4740_adc_cells[0], 236 - .data_size = sizeof(struct mfd_cell), 237 235 238 236 .enable = jz4740_adc_cell_enable, 239 237 .disable = jz4740_adc_cell_disable, ··· 241 243 .name = "jz4740-battery", 242 244 .num_resources = ARRAY_SIZE(jz4740_battery_resources), 243 245 .resources = jz4740_battery_resources, 244 - .platform_data = (void *)&jz4740_adc_cells[1], 245 - .data_size = sizeof(struct mfd_cell), 246 246 247 247 .enable = jz4740_adc_cell_enable, 248 248 .disable = jz4740_adc_cell_disable,
+6 -1
drivers/mfd/lpc_sch.c
··· 61 61 62 62 static struct pci_device_id lpc_sch_ids[] = { 63 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 65 { 0, } 65 66 }; 66 67 MODULE_DEVICE_TABLE(pci, lpc_sch_ids); ··· 71 70 { 72 71 unsigned int base_addr_cfg; 73 72 unsigned short base_addr; 73 + int i; 74 74 75 75 pci_read_config_dword(dev, SMBASE, &base_addr_cfg); 76 76 if (!(base_addr_cfg & (1 << 31))) { ··· 101 99 gpio_sch_resource.start = base_addr; 102 100 gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; 103 101 104 - return mfd_add_devices(&dev->dev, -1, 102 + for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) 103 + lpc_sch_cells[i].id = id->device; 104 + 105 + return mfd_add_devices(&dev->dev, 0, 105 106 lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); 106 107 } 107 108
+427
drivers/mfd/max8997.c
··· 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 + 38 + static 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 + 47 + int 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 + } 62 + EXPORT_SYMBOL_GPL(max8997_read_reg); 63 + 64 + int 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 + } 77 + EXPORT_SYMBOL_GPL(max8997_bulk_read); 78 + 79 + int 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 + } 89 + EXPORT_SYMBOL_GPL(max8997_write_reg); 90 + 91 + int 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 + } 104 + EXPORT_SYMBOL_GPL(max8997_bulk_write); 105 + 106 + int 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 + } 121 + EXPORT_SYMBOL_GPL(max8997_update_reg); 122 + 123 + static 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 + 169 + err_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); 174 + err: 175 + kfree(max8997); 176 + return ret; 177 + } 178 + 179 + static 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 + 192 + static const struct i2c_device_id max8997_i2c_id[] = { 193 + { "max8997", TYPE_MAX8997 }, 194 + { "max8966", TYPE_MAX8966 }, 195 + { } 196 + }; 197 + MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); 198 + 199 + u8 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 + 324 + u8 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 + 334 + u8 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 + 352 + static 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 + 374 + static 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 + 396 + const struct dev_pm_ops max8997_pm = { 397 + .freeze = max8997_freeze, 398 + .restore = max8997_restore, 399 + }; 400 + 401 + static 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 + 412 + static 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 */ 417 + subsys_initcall(max8997_i2c_init); 418 + 419 + static void __exit max8997_i2c_exit(void) 420 + { 421 + i2c_del_driver(&max8997_i2c_driver); 422 + } 423 + module_exit(max8997_i2c_exit); 424 + 425 + MODULE_DESCRIPTION("MAXIM 8997 multi-function core driver"); 426 + MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 427 + MODULE_LICENSE("GPL");
+2 -2
drivers/mfd/max8998.c
··· 233 233 u8 val; 234 234 }; 235 235 #define SAVE_ITEM(x) { .addr = (x), .val = 0x0, } 236 - struct max8998_reg_dump max8998_dump[] = { 236 + static struct max8998_reg_dump max8998_dump[] = { 237 237 SAVE_ITEM(MAX8998_REG_IRQM1), 238 238 SAVE_ITEM(MAX8998_REG_IRQM2), 239 239 SAVE_ITEM(MAX8998_REG_IRQM3), ··· 298 298 return 0; 299 299 } 300 300 301 - const struct dev_pm_ops max8998_pm = { 301 + static const struct dev_pm_ops max8998_pm = { 302 302 .suspend = max8998_suspend, 303 303 .resume = max8998_resume, 304 304 .freeze = max8998_freeze,
+7 -14
drivers/mfd/mc13xxx-core.c
··· 683 683 EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion); 684 684 685 685 static 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 688 char buf[30]; 689 689 const char *name = mc13xxx_get_chipname(mc13xxx); 690 690 691 691 struct mfd_cell cell = { 692 - .platform_data = pdata, 693 - .data_size = pdata_size, 692 + .mfd_data = pdata, 694 693 }; 695 694 696 695 /* there is no asnprintf in the kernel :-( */ ··· 705 706 706 707 static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) 707 708 { 708 - return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); 709 + return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL); 709 710 } 710 711 711 712 static int mc13xxx_probe(struct spi_device *spi) ··· 763 764 mc13xxx_add_subdevice(mc13xxx, "%s-codec"); 764 765 765 766 if (pdata->flags & MC13XXX_USE_REGULATOR) { 766 - struct mc13xxx_regulator_platform_data regulator_pdata = { 767 - .num_regulators = pdata->num_regulators, 768 - .regulators = pdata->regulators, 769 - }; 770 - 771 767 mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", 772 - &regulator_pdata, sizeof(regulator_pdata)); 768 + &pdata->regulators); 773 769 } 774 770 775 771 if (pdata->flags & MC13XXX_USE_RTC) ··· 773 779 if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) 774 780 mc13xxx_add_subdevice(mc13xxx, "%s-ts"); 775 781 776 - if (pdata->flags & MC13XXX_USE_LED) { 777 - mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", 778 - pdata->leds, sizeof(*pdata->leds)); 779 - } 782 + if (pdata->flags & MC13XXX_USE_LED) 783 + mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", pdata->leds); 780 784 781 785 return 0; 782 786 } ··· 803 811 /* sentinel */ 804 812 } 805 813 }; 814 + MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); 806 815 807 816 static struct spi_driver mc13xxx_driver = { 808 817 .id_table = mc13xxx_device_id,
+124 -11
drivers/mfd/mfd-core.c
··· 18 18 #include <linux/pm_runtime.h> 19 19 #include <linux/slab.h> 20 20 21 + int 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 + } 36 + EXPORT_SYMBOL(mfd_cell_enable); 37 + 38 + int 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 + } 56 + EXPORT_SYMBOL(mfd_cell_disable); 57 + 21 58 static int mfd_add_device(struct device *parent, int id, 22 59 const struct mfd_cell *cell, 23 60 struct resource *mem_base, ··· 74 37 goto fail_device; 75 38 76 39 pdev->dev.parent = parent; 77 - platform_set_drvdata(pdev, cell->driver_data); 78 40 79 - if (cell->data_size) { 80 - ret = platform_device_add_data(pdev, 81 - cell->platform_data, cell->data_size); 82 - if (ret) 83 - goto fail_res; 84 - } 41 + ret = platform_device_add_data(pdev, cell, sizeof(*cell)); 42 + if (ret) 43 + goto fail_res; 85 44 86 45 for (r = 0; r < cell->num_resources; r++) { 87 46 res[r].name = cell->resources[r].name; ··· 133 100 } 134 101 135 102 int mfd_add_devices(struct device *parent, int id, 136 - const struct mfd_cell *cells, int n_devs, 103 + struct mfd_cell *cells, int n_devs, 137 104 struct resource *mem_base, 138 105 int irq_base) 139 106 { 140 107 int i; 141 108 int ret = 0; 109 + atomic_t *cnts; 110 + 111 + /* initialize reference counting for all cells */ 112 + cnts = kcalloc(sizeof(*cnts), n_devs, GFP_KERNEL); 113 + if (!cnts) 114 + return -ENOMEM; 142 115 143 116 for (i = 0; i < n_devs; i++) { 117 + atomic_set(&cnts[i], 0); 118 + cells[i].usage_count = &cnts[i]; 144 119 ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); 145 120 if (ret) 146 121 break; ··· 161 120 } 162 121 EXPORT_SYMBOL(mfd_add_devices); 163 122 164 - static int mfd_remove_devices_fn(struct device *dev, void *unused) 123 + static int mfd_remove_devices_fn(struct device *dev, void *c) 165 124 { 166 - platform_device_unregister(to_platform_device(dev)); 125 + struct platform_device *pdev = to_platform_device(dev); 126 + const struct mfd_cell *cell = mfd_get_cell(pdev); 127 + atomic_t **usage_count = c; 128 + 129 + /* find the base address of usage_count pointers (for freeing) */ 130 + if (!*usage_count || (cell->usage_count < *usage_count)) 131 + *usage_count = cell->usage_count; 132 + 133 + platform_device_unregister(pdev); 167 134 return 0; 168 135 } 169 136 170 137 void mfd_remove_devices(struct device *parent) 171 138 { 172 - device_for_each_child(parent, NULL, mfd_remove_devices_fn); 139 + atomic_t *cnts = NULL; 140 + 141 + device_for_each_child(parent, &cnts, mfd_remove_devices_fn); 142 + kfree(cnts); 173 143 } 174 144 EXPORT_SYMBOL(mfd_remove_devices); 145 + 146 + static int add_shared_platform_device(const char *cell, const char *name) 147 + { 148 + struct mfd_cell cell_entry; 149 + struct device *dev; 150 + struct platform_device *pdev; 151 + int err; 152 + 153 + /* check if we've already registered a device (don't fail if we have) */ 154 + if (bus_find_device_by_name(&platform_bus_type, NULL, name)) 155 + return 0; 156 + 157 + /* fetch the parent cell's device (should already be registered!) */ 158 + dev = bus_find_device_by_name(&platform_bus_type, NULL, cell); 159 + if (!dev) { 160 + printk(KERN_ERR "failed to find device for cell %s\n", cell); 161 + return -ENODEV; 162 + } 163 + pdev = to_platform_device(dev); 164 + memcpy(&cell_entry, mfd_get_cell(pdev), sizeof(cell_entry)); 165 + 166 + WARN_ON(!cell_entry.enable); 167 + 168 + cell_entry.name = name; 169 + err = mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0); 170 + if (err) 171 + dev_err(dev, "MFD add devices failed: %d\n", err); 172 + return err; 173 + } 174 + 175 + int mfd_shared_platform_driver_register(struct platform_driver *drv, 176 + const char *cellname) 177 + { 178 + int err; 179 + 180 + err = add_shared_platform_device(cellname, drv->driver.name); 181 + if (err) 182 + printk(KERN_ERR "failed to add platform device %s\n", 183 + drv->driver.name); 184 + 185 + err = platform_driver_register(drv); 186 + if (err) 187 + printk(KERN_ERR "failed to add platform driver %s\n", 188 + drv->driver.name); 189 + 190 + return err; 191 + } 192 + EXPORT_SYMBOL(mfd_shared_platform_driver_register); 193 + 194 + void mfd_shared_platform_driver_unregister(struct platform_driver *drv) 195 + { 196 + struct device *dev; 197 + 198 + dev = bus_find_device_by_name(&platform_bus_type, NULL, 199 + drv->driver.name); 200 + if (dev) 201 + platform_device_unregister(to_platform_device(dev)); 202 + 203 + platform_driver_unregister(drv); 204 + } 205 + EXPORT_SYMBOL(mfd_shared_platform_driver_unregister); 175 206 176 207 MODULE_LICENSE("GPL"); 177 208 MODULE_AUTHOR("Ian Molton, Dmitry Baryshkov");
+12 -12
drivers/mfd/pcf50633-core.c
··· 21 21 #include <linux/workqueue.h> 22 22 #include <linux/platform_device.h> 23 23 #include <linux/i2c.h> 24 + #include <linux/pm.h> 24 25 #include <linux/slab.h> 25 26 26 27 #include <linux/mfd/pcf50633/core.h> ··· 231 230 } 232 231 } 233 232 234 - #ifdef CONFIG_PM 235 - static int pcf50633_suspend(struct i2c_client *client, pm_message_t state) 233 + #ifdef CONFIG_PM_SLEEP 234 + static int pcf50633_suspend(struct device *dev) 236 235 { 237 - struct pcf50633 *pcf; 238 - pcf = i2c_get_clientdata(client); 236 + struct i2c_client *client = to_i2c_client(dev); 237 + struct pcf50633 *pcf = i2c_get_clientdata(client); 239 238 240 239 return pcf50633_irq_suspend(pcf); 241 240 } 242 241 243 - static int pcf50633_resume(struct i2c_client *client) 242 + static int pcf50633_resume(struct device *dev) 244 243 { 245 - struct pcf50633 *pcf; 246 - pcf = i2c_get_clientdata(client); 244 + struct i2c_client *client = to_i2c_client(dev); 245 + struct pcf50633 *pcf = i2c_get_clientdata(client); 247 246 248 247 return pcf50633_irq_resume(pcf); 249 248 } 250 - #else 251 - #define pcf50633_suspend NULL 252 - #define pcf50633_resume NULL 253 249 #endif 250 + 251 + static SIMPLE_DEV_PM_OPS(pcf50633_pm, pcf50633_suspend, pcf50633_resume); 254 252 255 253 static int __devinit pcf50633_probe(struct i2c_client *client, 256 254 const struct i2c_device_id *ids) ··· 360 360 {"pcf50633", 0x73}, 361 361 {/* end of list */} 362 362 }; 363 + MODULE_DEVICE_TABLE(i2c, pcf50633_id_table); 363 364 364 365 static struct i2c_driver pcf50633_driver = { 365 366 .driver = { 366 367 .name = "pcf50633", 368 + .pm = &pcf50633_pm, 367 369 }, 368 370 .id_table = pcf50633_id_table, 369 371 .probe = pcf50633_probe, 370 372 .remove = __devexit_p(pcf50633_remove), 371 - .suspend = pcf50633_suspend, 372 - .resume = pcf50633_resume, 373 373 }; 374 374 375 375 static int __init pcf50633_init(void)
+2 -2
drivers/mfd/rdc321x-southbridge.c
··· 61 61 .name = "rdc321x-wdt", 62 62 .resources = rdc321x_wdt_resource, 63 63 .num_resources = ARRAY_SIZE(rdc321x_wdt_resource), 64 - .driver_data = &rdc321x_wdt_pdata, 64 + .mfd_data = &rdc321x_wdt_pdata, 65 65 }, { 66 66 .name = "rdc321x-gpio", 67 67 .resources = rdc321x_gpio_resources, 68 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
+1 -3
drivers/mfd/sh_mobile_sdhi.c
··· 146 146 } 147 147 148 148 memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc)); 149 - priv->cell_mmc.driver_data = mmc_data; 150 - priv->cell_mmc.platform_data = &priv->cell_mmc; 151 - priv->cell_mmc.data_size = sizeof(priv->cell_mmc); 149 + priv->cell_mmc.mfd_data = mmc_data; 152 150 153 151 platform_set_drvdata(pdev, priv); 154 152
+2 -11
drivers/mfd/t7l66xb.c
··· 170 170 .name = "tmio-mmc", 171 171 .enable = t7l66xb_mmc_enable, 172 172 .disable = t7l66xb_mmc_disable, 173 - .driver_data = &t7166xb_mmc_data, 173 + .mfd_data = &t7166xb_mmc_data, 174 174 .num_resources = ARRAY_SIZE(t7l66xb_mmc_resources), 175 175 .resources = t7l66xb_mmc_resources, 176 176 }, ··· 383 383 384 384 t7l66xb_attach_irq(dev); 385 385 386 - t7l66xb_cells[T7L66XB_CELL_NAND].driver_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]); 386 + t7l66xb_cells[T7L66XB_CELL_NAND].mfd_data = pdata->nand_data; 396 387 397 388 ret = mfd_add_devices(&dev->dev, dev->id, 398 389 t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells),
+1 -6
drivers/mfd/tc6387xb.c
··· 131 131 .name = "tmio-mmc", 132 132 .enable = tc6387xb_mmc_enable, 133 133 .disable = tc6387xb_mmc_disable, 134 - .driver_data = &tc6387xb_mmc_data, 134 + .mfd_data = &tc6387xb_mmc_data, 135 135 .num_resources = ARRAY_SIZE(tc6387xb_mmc_resources), 136 136 .resources = tc6387xb_mmc_resources, 137 137 }, ··· 189 189 pdata->enable(dev); 190 190 191 191 printk(KERN_INFO "Toshiba tc6387xb initialised\n"); 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 192 198 193 ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, 199 194 ARRAY_SIZE(tc6387xb_cells), iomem, irq);
+3 -22
drivers/mfd/tc6393xb.c
··· 393 393 .name = "tmio-mmc", 394 394 .enable = tc6393xb_mmc_enable, 395 395 .resume = tc6393xb_mmc_resume, 396 - .driver_data = &tc6393xb_mmc_data, 396 + .mfd_data = &tc6393xb_mmc_data, 397 397 .num_resources = ARRAY_SIZE(tc6393xb_mmc_resources), 398 398 .resources = tc6393xb_mmc_resources, 399 399 }, ··· 693 693 goto err_setup; 694 694 } 695 695 696 - tc6393xb_cells[TC6393XB_CELL_NAND].driver_data = tcpd->nand_data; 697 - tc6393xb_cells[TC6393XB_CELL_NAND].platform_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]); 696 + tc6393xb_cells[TC6393XB_CELL_NAND].mfd_data = tcpd->nand_data; 697 + tc6393xb_cells[TC6393XB_CELL_FB].mfd_data = tcpd->fb_data; 717 698 718 699 ret = mfd_add_devices(&dev->dev, dev->id, 719 700 tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
+27 -54
drivers/mfd/timberdale.c
··· 384 384 .name = "timb-dma", 385 385 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 386 386 .resources = timberdale_dma_resources, 387 - .platform_data = &timb_dma_platform_data, 388 - .data_size = sizeof(timb_dma_platform_data), 387 + .mfd_data = &timb_dma_platform_data, 389 388 }, 390 389 { 391 390 .name = "timb-uart", ··· 395 396 .name = "xiic-i2c", 396 397 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 397 398 .resources = timberdale_xiic_resources, 398 - .platform_data = &timberdale_xiic_platform_data, 399 - .data_size = sizeof(timberdale_xiic_platform_data), 399 + .mfd_data = &timberdale_xiic_platform_data, 400 400 }, 401 401 { 402 402 .name = "timb-gpio", 403 403 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 404 404 .resources = timberdale_gpio_resources, 405 - .platform_data = &timberdale_gpio_platform_data, 406 - .data_size = sizeof(timberdale_gpio_platform_data), 405 + .mfd_data = &timberdale_gpio_platform_data, 407 406 }, 408 407 { 409 408 .name = "timb-video", 410 409 .num_resources = ARRAY_SIZE(timberdale_video_resources), 411 410 .resources = timberdale_video_resources, 412 - .platform_data = &timberdale_video_platform_data, 413 - .data_size = sizeof(timberdale_video_platform_data), 411 + .mfd_data = &timberdale_video_platform_data, 414 412 }, 415 413 { 416 414 .name = "timb-radio", 417 415 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 418 416 .resources = timberdale_radio_resources, 419 - .platform_data = &timberdale_radio_platform_data, 420 - .data_size = sizeof(timberdale_radio_platform_data), 417 + .mfd_data = &timberdale_radio_platform_data, 421 418 }, 422 419 { 423 420 .name = "xilinx_spi", 424 421 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 425 422 .resources = timberdale_spi_resources, 426 - .platform_data = &timberdale_xspi_platform_data, 427 - .data_size = sizeof(timberdale_xspi_platform_data), 423 + .mfd_data = &timberdale_xspi_platform_data, 428 424 }, 429 425 { 430 426 .name = "ks8842", 431 427 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 432 428 .resources = timberdale_eth_resources, 433 - .platform_data = &timberdale_ks8842_platform_data, 434 - .data_size = sizeof(timberdale_ks8842_platform_data) 429 + .mfd_data = &timberdale_ks8842_platform_data, 435 430 }, 436 431 }; 437 432 ··· 434 441 .name = "timb-dma", 435 442 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 436 443 .resources = timberdale_dma_resources, 437 - .platform_data = &timb_dma_platform_data, 438 - .data_size = sizeof(timb_dma_platform_data), 444 + .mfd_data = &timb_dma_platform_data, 439 445 }, 440 446 { 441 447 .name = "timb-uart", ··· 450 458 .name = "xiic-i2c", 451 459 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 452 460 .resources = timberdale_xiic_resources, 453 - .platform_data = &timberdale_xiic_platform_data, 454 - .data_size = sizeof(timberdale_xiic_platform_data), 461 + .mfd_data = &timberdale_xiic_platform_data, 455 462 }, 456 463 { 457 464 .name = "timb-gpio", 458 465 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 459 466 .resources = timberdale_gpio_resources, 460 - .platform_data = &timberdale_gpio_platform_data, 461 - .data_size = sizeof(timberdale_gpio_platform_data), 467 + .mfd_data = &timberdale_gpio_platform_data, 462 468 }, 463 469 { 464 470 .name = "timb-mlogicore", ··· 467 477 .name = "timb-video", 468 478 .num_resources = ARRAY_SIZE(timberdale_video_resources), 469 479 .resources = timberdale_video_resources, 470 - .platform_data = &timberdale_video_platform_data, 471 - .data_size = sizeof(timberdale_video_platform_data), 480 + .mfd_data = &timberdale_video_platform_data, 472 481 }, 473 482 { 474 483 .name = "timb-radio", 475 484 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 476 485 .resources = timberdale_radio_resources, 477 - .platform_data = &timberdale_radio_platform_data, 478 - .data_size = sizeof(timberdale_radio_platform_data), 486 + .mfd_data = &timberdale_radio_platform_data, 479 487 }, 480 488 { 481 489 .name = "xilinx_spi", 482 490 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 483 491 .resources = timberdale_spi_resources, 484 - .platform_data = &timberdale_xspi_platform_data, 485 - .data_size = sizeof(timberdale_xspi_platform_data), 492 + .mfd_data = &timberdale_xspi_platform_data, 486 493 }, 487 494 { 488 495 .name = "ks8842", 489 496 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 490 497 .resources = timberdale_eth_resources, 491 - .platform_data = &timberdale_ks8842_platform_data, 492 - .data_size = sizeof(timberdale_ks8842_platform_data) 498 + .mfd_data = &timberdale_ks8842_platform_data, 493 499 }, 494 500 }; 495 501 ··· 494 508 .name = "timb-dma", 495 509 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 496 510 .resources = timberdale_dma_resources, 497 - .platform_data = &timb_dma_platform_data, 498 - .data_size = sizeof(timb_dma_platform_data), 511 + .mfd_data = &timb_dma_platform_data, 499 512 }, 500 513 { 501 514 .name = "timb-uart", ··· 505 520 .name = "xiic-i2c", 506 521 .num_resources = ARRAY_SIZE(timberdale_xiic_resources), 507 522 .resources = timberdale_xiic_resources, 508 - .platform_data = &timberdale_xiic_platform_data, 509 - .data_size = sizeof(timberdale_xiic_platform_data), 523 + .mfd_data = &timberdale_xiic_platform_data, 510 524 }, 511 525 { 512 526 .name = "timb-gpio", 513 527 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 514 528 .resources = timberdale_gpio_resources, 515 - .platform_data = &timberdale_gpio_platform_data, 516 - .data_size = sizeof(timberdale_gpio_platform_data), 529 + .mfd_data = &timberdale_gpio_platform_data, 517 530 }, 518 531 { 519 532 .name = "timb-video", 520 533 .num_resources = ARRAY_SIZE(timberdale_video_resources), 521 534 .resources = timberdale_video_resources, 522 - .platform_data = &timberdale_video_platform_data, 523 - .data_size = sizeof(timberdale_video_platform_data), 535 + .mfd_data = &timberdale_video_platform_data, 524 536 }, 525 537 { 526 538 .name = "timb-radio", 527 539 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 528 540 .resources = timberdale_radio_resources, 529 - .platform_data = &timberdale_radio_platform_data, 530 - .data_size = sizeof(timberdale_radio_platform_data), 541 + .mfd_data = &timberdale_radio_platform_data, 531 542 }, 532 543 { 533 544 .name = "xilinx_spi", 534 545 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 535 546 .resources = timberdale_spi_resources, 536 - .platform_data = &timberdale_xspi_platform_data, 537 - .data_size = sizeof(timberdale_xspi_platform_data), 547 + .mfd_data = &timberdale_xspi_platform_data, 538 548 }, 539 549 }; 540 550 ··· 538 558 .name = "timb-dma", 539 559 .num_resources = ARRAY_SIZE(timberdale_dma_resources), 540 560 .resources = timberdale_dma_resources, 541 - .platform_data = &timb_dma_platform_data, 542 - .data_size = sizeof(timb_dma_platform_data), 561 + .mfd_data = &timb_dma_platform_data, 543 562 }, 544 563 { 545 564 .name = "timb-uart", ··· 549 570 .name = "ocores-i2c", 550 571 .num_resources = ARRAY_SIZE(timberdale_ocores_resources), 551 572 .resources = timberdale_ocores_resources, 552 - .platform_data = &timberdale_ocores_platform_data, 553 - .data_size = sizeof(timberdale_ocores_platform_data), 573 + .mfd_data = &timberdale_ocores_platform_data, 554 574 }, 555 575 { 556 576 .name = "timb-gpio", 557 577 .num_resources = ARRAY_SIZE(timberdale_gpio_resources), 558 578 .resources = timberdale_gpio_resources, 559 - .platform_data = &timberdale_gpio_platform_data, 560 - .data_size = sizeof(timberdale_gpio_platform_data), 579 + .mfd_data = &timberdale_gpio_platform_data, 561 580 }, 562 581 { 563 582 .name = "timb-video", 564 583 .num_resources = ARRAY_SIZE(timberdale_video_resources), 565 584 .resources = timberdale_video_resources, 566 - .platform_data = &timberdale_video_platform_data, 567 - .data_size = sizeof(timberdale_video_platform_data), 585 + .mfd_data = &timberdale_video_platform_data, 568 586 }, 569 587 { 570 588 .name = "timb-radio", 571 589 .num_resources = ARRAY_SIZE(timberdale_radio_resources), 572 590 .resources = timberdale_radio_resources, 573 - .platform_data = &timberdale_radio_platform_data, 574 - .data_size = sizeof(timberdale_radio_platform_data), 591 + .mfd_data = &timberdale_radio_platform_data, 575 592 }, 576 593 { 577 594 .name = "xilinx_spi", 578 595 .num_resources = ARRAY_SIZE(timberdale_spi_resources), 579 596 .resources = timberdale_spi_resources, 580 - .platform_data = &timberdale_xspi_platform_data, 581 - .data_size = sizeof(timberdale_xspi_platform_data), 597 + .mfd_data = &timberdale_xspi_platform_data, 582 598 }, 583 599 { 584 600 .name = "ks8842", 585 601 .num_resources = ARRAY_SIZE(timberdale_eth_resources), 586 602 .resources = timberdale_eth_resources, 587 - .platform_data = &timberdale_ks8842_platform_data, 588 - .data_size = sizeof(timberdale_ks8842_platform_data) 603 + .mfd_data = &timberdale_ks8842_platform_data, 589 604 }, 590 605 }; 591 606
+246
drivers/mfd/tps6105x.c
··· 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 + 28 + int 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 + } 42 + EXPORT_SYMBOL(tps6105x_set); 43 + 44 + int 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 + } 59 + EXPORT_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 + */ 65 + int 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); 80 + fail: 81 + mutex_unlock(&tps6105x->lock); 82 + if (ret < 0) 83 + return ret; 84 + 85 + return 0; 86 + } 87 + EXPORT_SYMBOL(tps6105x_mask_and_set); 88 + 89 + static 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 + */ 125 + static 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 + 136 + static 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 + 196 + fail: 197 + kfree(tps6105x); 198 + return ret; 199 + } 200 + 201 + static 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 + 216 + static const struct i2c_device_id tps6105x_id[] = { 217 + { "tps61050", 0 }, 218 + { "tps61052", 0 }, 219 + { } 220 + }; 221 + MODULE_DEVICE_TABLE(i2c, tps6105x_id); 222 + 223 + static 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 + 232 + static int __init tps6105x_init(void) 233 + { 234 + return i2c_add_driver(&tps6105x_driver); 235 + } 236 + subsys_initcall(tps6105x_init); 237 + 238 + static void __exit tps6105x_exit(void) 239 + { 240 + i2c_del_driver(&tps6105x_driver); 241 + } 242 + module_exit(tps6105x_exit); 243 + 244 + MODULE_AUTHOR("Linus Walleij"); 245 + MODULE_DESCRIPTION("TPS6105x White LED Boost Converter Driver"); 246 + MODULE_LICENSE("GPL v2");
+16 -10
drivers/mfd/tps6586x.c
··· 288 288 return tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET1, val, mask); 289 289 } 290 290 291 - static void tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base) 291 + static int tps6586x_gpio_init(struct tps6586x *tps6586x, int gpio_base) 292 292 { 293 - int ret; 294 - 295 293 if (!gpio_base) 296 - return; 294 + return 0; 297 295 298 296 tps6586x->gpio.owner = THIS_MODULE; 299 297 tps6586x->gpio.label = tps6586x->client->name; ··· 305 307 tps6586x->gpio.set = tps6586x_gpio_set; 306 308 tps6586x->gpio.get = tps6586x_gpio_get; 307 309 308 - ret = gpiochip_add(&tps6586x->gpio); 309 - if (ret) 310 - dev_warn(tps6586x->dev, "GPIO registration failed: %d\n", ret); 310 + return gpiochip_add(&tps6586x->gpio); 311 311 } 312 312 313 313 static int __remove_subdev(struct device *dev, void *unused) ··· 513 517 } 514 518 } 515 519 520 + ret = tps6586x_gpio_init(tps6586x, pdata->gpio_base); 521 + if (ret) { 522 + dev_err(&client->dev, "GPIO registration failed: %d\n", ret); 523 + goto err_gpio_init; 524 + } 525 + 516 526 ret = tps6586x_add_subdevs(tps6586x, pdata); 517 527 if (ret) { 518 528 dev_err(&client->dev, "add devices failed: %d\n", ret); 519 529 goto err_add_devs; 520 530 } 521 531 522 - tps6586x_gpio_init(tps6586x, pdata->gpio_base); 523 - 524 532 return 0; 525 533 526 534 err_add_devs: 535 + if (pdata->gpio_base) { 536 + ret = gpiochip_remove(&tps6586x->gpio); 537 + if (ret) 538 + dev_err(&client->dev, "Can't remove gpio chip: %d\n", 539 + ret); 540 + } 541 + err_gpio_init: 527 542 if (client->irq) 528 543 free_irq(client->irq, tps6586x); 529 544 err_irq_init: ··· 594 587 MODULE_DESCRIPTION("TPS6586X core driver"); 595 588 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 596 589 MODULE_LICENSE("GPL"); 597 -
+6 -2
drivers/mfd/twl-core.c
··· 721 721 722 722 } 723 723 724 - if (twl_has_watchdog()) { 724 + if (twl_has_watchdog() && twl_class_is_4030()) { 725 725 child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0); 726 726 if (IS_ERR(child)) 727 727 return PTR_ERR(child); 728 728 } 729 729 730 - if (twl_has_pwrbutton()) { 730 + if (twl_has_pwrbutton() && twl_class_is_4030()) { 731 731 child = add_child(1, "twl4030_pwrbutton", 732 732 NULL, 0, true, pdata->irq_base + 8 + 0, 0); 733 733 if (IS_ERR(child)) ··· 862 862 return PTR_ERR(child); 863 863 864 864 child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3); 865 + if (IS_ERR(child)) 866 + return PTR_ERR(child); 867 + 868 + child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg); 865 869 if (IS_ERR(child)) 866 870 return PTR_ERR(child); 867 871 }
+2 -4
drivers/mfd/twl4030-codec.c
··· 208 208 if (pdata->audio) { 209 209 cell = &codec->cells[childs]; 210 210 cell->name = "twl4030-codec"; 211 - cell->platform_data = pdata->audio; 212 - cell->data_size = sizeof(*pdata->audio); 211 + cell->mfd_data = pdata->audio; 213 212 childs++; 214 213 } 215 214 if (pdata->vibra) { 216 215 cell = &codec->cells[childs]; 217 216 cell->name = "twl4030-vibra"; 218 - cell->platform_data = pdata->vibra; 219 - cell->data_size = sizeof(*pdata->vibra); 217 + cell->mfd_data = pdata->vibra; 220 218 childs++; 221 219 } 222 220
+802
drivers/mfd/twl4030-madc.c
··· 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 + */ 58 + struct 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 + 66 + static struct twl4030_madc_data *twl4030_madc; 67 + 68 + struct twl4030_prescale_divider_ratios { 69 + s16 numerator; 70 + s16 denominator; 71 + }; 72 + 73 + static const struct twl4030_prescale_divider_ratios 74 + twl4030_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 + */ 97 + static int therm_tbl[] = { 98 + 30800, 29500, 28300, 27100, 99 + 26000, 24900, 23900, 22900, 22000, 21100, 20300, 19400, 18700, 17900, 100 + 17200, 16500, 15900, 15300, 14700, 14100, 13600, 13100, 12600, 12100, 101 + 11600, 11200, 10800, 10400, 10000, 9630, 9280, 8950, 8620, 8310, 102 + 8020, 7730, 7460, 7200, 6950, 6710, 6470, 6250, 6040, 5830, 103 + 5640, 5450, 5260, 5090, 4920, 4760, 4600, 4450, 4310, 4170, 104 + 4040, 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 + */ 115 + static 116 + const 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 + */ 142 + static 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 + */ 169 + static 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 + 194 + static 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 + */ 217 + static 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 + */ 283 + static 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 + */ 314 + static 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 + 336 + static 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 + 388 + err_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 + 415 + static 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 + */ 440 + static 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 + */ 472 + static 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 + */ 507 + int 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 + 590 + out: 591 + mutex_unlock(&twl4030_madc->lock); 592 + 593 + return ret; 594 + } 595 + EXPORT_SYMBOL_GPL(twl4030_madc_conversion); 596 + 597 + /* 598 + * Return channel value 599 + * Or < 0 on failure. 600 + */ 601 + int 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 + } 619 + EXPORT_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 + */ 631 + static 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 + */ 665 + static 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 + */ 694 + static 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; 751 + err_irq: 752 + platform_set_drvdata(pdev, NULL); 753 + err_i2c: 754 + twl4030_madc_set_current_generator(madc, 0, 0); 755 + err_current_generator: 756 + twl4030_madc_set_power(madc, 0); 757 + err_power: 758 + kfree(madc); 759 + 760 + return ret; 761 + } 762 + 763 + static 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 + 776 + static 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 + 785 + static int __init twl4030_madc_init(void) 786 + { 787 + return platform_driver_register(&twl4030_madc_driver); 788 + } 789 + 790 + module_init(twl4030_madc_init); 791 + 792 + static void __exit twl4030_madc_exit(void) 793 + { 794 + platform_driver_unregister(&twl4030_madc_driver); 795 + } 796 + 797 + module_exit(twl4030_madc_exit); 798 + 799 + MODULE_DESCRIPTION("TWL4030 ADC driver"); 800 + MODULE_LICENSE("GPL"); 801 + MODULE_AUTHOR("J Keerthy"); 802 + MODULE_ALIAS("platform:twl4030_madc");
+4 -1
drivers/mfd/ucb1x00-ts.c
··· 60 60 input_report_abs(idev, ABS_X, x); 61 61 input_report_abs(idev, ABS_Y, y); 62 62 input_report_abs(idev, ABS_PRESSURE, pressure); 63 + input_report_key(idev, BTN_TOUCH, 1); 63 64 input_sync(idev); 64 65 } 65 66 ··· 69 68 struct input_dev *idev = ts->idev; 70 69 71 70 input_report_abs(idev, ABS_PRESSURE, 0); 71 + input_report_key(idev, BTN_TOUCH, 0); 72 72 input_sync(idev); 73 73 } 74 74 ··· 386 384 idev->open = ucb1x00_ts_open; 387 385 idev->close = ucb1x00_ts_close; 388 386 389 - __set_bit(EV_ABS, idev->evbit); 387 + idev->evbit[0] = BIT_MASK(EV_ABS) | BIT_MASK(EV_KEY); 388 + idev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); 390 389 391 390 input_set_drvdata(idev, ts); 392 391
+1
drivers/mfd/vx855.c
··· 122 122 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, 123 123 { 0, } 124 124 }; 125 + MODULE_DEVICE_TABLE(pci, vx855_pci_tbl); 125 126 126 127 static struct pci_driver vx855_pci_driver = { 127 128 .name = "vx855",
+2 -6
drivers/mfd/wl1273-core.c
··· 38 38 dev_dbg(&client->dev, "%s\n", __func__); 39 39 40 40 mfd_remove_devices(&client->dev); 41 - i2c_set_clientdata(client, NULL); 42 41 kfree(core); 43 42 44 43 return 0; ··· 78 79 79 80 cell = &core->cells[children]; 80 81 cell->name = "wl1273_fm_radio"; 81 - cell->platform_data = &core; 82 - cell->data_size = sizeof(core); 82 + cell->mfd_data = &core; 83 83 children++; 84 84 85 85 if (pdata->children & WL1273_CODEC_CHILD) { ··· 86 88 87 89 dev_dbg(&client->dev, "%s: Have codec.\n", __func__); 88 90 cell->name = "wl1273-codec"; 89 - cell->platform_data = &core; 90 - cell->data_size = sizeof(core); 91 + cell->mfd_data = &core; 91 92 children++; 92 93 } 93 94 ··· 101 104 return 0; 102 105 103 106 err: 104 - i2c_set_clientdata(client, NULL); 105 107 pdata->free_resources(); 106 108 kfree(core); 107 109
+13 -5
drivers/mfd/wm831x-i2c.c
··· 51 51 int bytes, void *src) 52 52 { 53 53 struct i2c_client *i2c = wm831x->control_data; 54 - unsigned char msg[bytes + 2]; 54 + struct i2c_msg xfer[2]; 55 55 int ret; 56 56 57 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 70 if (ret < 0) 63 71 return ret; 64 - if (ret < bytes + 2) 72 + if (ret != 2) 65 73 return -EIO; 66 74 67 75 return 0;
+31 -13
drivers/mfd/wm831x-irq.c
··· 26 26 27 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 - 38 29 struct wm831x_irq_data { 39 30 int primary; 40 31 int reg; ··· 352 361 /* If there's been a change in the mask write it back 353 362 * to the hardware. */ 354 363 if (wm831x->irq_masks_cur[i] != wm831x->irq_masks_cache[i]) { 364 + dev_dbg(wm831x->dev, "IRQ mask sync: %x = %x\n", 365 + WM831X_INTERRUPT_STATUS_1_MASK + i, 366 + wm831x->irq_masks_cur[i]); 367 + 355 368 wm831x->irq_masks_cache[i] = wm831x->irq_masks_cur[i]; 356 369 wm831x_reg_write(wm831x, 357 370 WM831X_INTERRUPT_STATUS_1_MASK + i, ··· 366 371 mutex_unlock(&wm831x->irq_lock); 367 372 } 368 373 369 - static void wm831x_irq_unmask(struct irq_data *data) 374 + static void wm831x_irq_enable(struct irq_data *data) 370 375 { 371 376 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 372 377 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, ··· 375 380 wm831x->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 376 381 } 377 382 378 - static void wm831x_irq_mask(struct irq_data *data) 383 + static void wm831x_irq_disable(struct irq_data *data) 379 384 { 380 385 struct wm831x *wm831x = irq_data_get_irq_chip_data(data); 381 386 struct wm831x_irq_data *irq_data = irq_to_wm831x_irq(wm831x, ··· 421 426 .name = "wm831x", 422 427 .irq_bus_lock = wm831x_irq_lock, 423 428 .irq_bus_sync_unlock = wm831x_irq_sync_unlock, 424 - .irq_mask = wm831x_irq_mask, 425 - .irq_unmask = wm831x_irq_unmask, 429 + .irq_disable = wm831x_irq_disable, 430 + .irq_enable = wm831x_irq_enable, 426 431 .irq_set_type = wm831x_irq_set_type, 427 432 }; 428 433 ··· 443 448 primary); 444 449 goto out; 445 450 } 451 + 452 + /* The touch interrupts are visible in the primary register as 453 + * an optimisation; open code this to avoid complicating the 454 + * main handling loop and so we can also skip iterating the 455 + * descriptors. 456 + */ 457 + if (primary & WM831X_TCHPD_INT) 458 + handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD); 459 + if (primary & WM831X_TCHDATA_INT) 460 + handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA); 461 + if (primary & (WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT)) 462 + goto out; 446 463 447 464 for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { 448 465 int offset = wm831x_irqs[i].reg - 1; ··· 488 481 } 489 482 490 483 out: 484 + /* Touchscreen interrupts are handled specially in the driver */ 485 + status_regs[0] &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); 486 + 491 487 for (i = 0; i < ARRAY_SIZE(status_regs); i++) { 492 488 if (status_regs[i]) 493 489 wm831x_reg_write(wm831x, WM831X_INTERRUPT_STATUS_1 + i, ··· 526 516 "No interrupt base specified, no interrupts\n"); 527 517 return 0; 528 518 } 519 + 520 + if (pdata->irq_cmos) 521 + i = 0; 522 + else 523 + i = WM831X_IRQ_OD; 524 + 525 + wm831x_set_bits(wm831x, WM831X_IRQ_CONFIG, 526 + WM831X_IRQ_OD, i); 529 527 530 528 /* Try to flag /IRQ as a wake source; there are a number of 531 529 * unconditional wake sources in the PMIC so this isn't
+15 -9
drivers/mfd/wm831x-spi.c
··· 14 14 15 15 #include <linux/kernel.h> 16 16 #include <linux/module.h> 17 + #include <linux/pm.h> 17 18 #include <linux/spi/spi.h> 18 19 19 20 #include <linux/mfd/wm831x/core.h> ··· 114 113 return 0; 115 114 } 116 115 117 - static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m) 116 + static int wm831x_spi_suspend(struct device *dev) 118 117 { 119 - struct wm831x *wm831x = dev_get_drvdata(&spi->dev); 118 + struct wm831x *wm831x = dev_get_drvdata(dev); 120 119 121 120 return wm831x_device_suspend(wm831x); 122 121 } 122 + 123 + static const struct dev_pm_ops wm831x_spi_pm = { 124 + .freeze = wm831x_spi_suspend, 125 + .suspend = wm831x_spi_suspend, 126 + }; 123 127 124 128 static struct spi_driver wm8310_spi_driver = { 125 129 .driver = { 126 130 .name = "wm8310", 127 131 .bus = &spi_bus_type, 128 132 .owner = THIS_MODULE, 133 + .pm = &wm831x_spi_pm, 129 134 }, 130 135 .probe = wm831x_spi_probe, 131 136 .remove = __devexit_p(wm831x_spi_remove), 132 - .suspend = wm831x_spi_suspend, 133 137 }; 134 138 135 139 static struct spi_driver wm8311_spi_driver = { ··· 142 136 .name = "wm8311", 143 137 .bus = &spi_bus_type, 144 138 .owner = THIS_MODULE, 139 + .pm = &wm831x_spi_pm, 145 140 }, 146 141 .probe = wm831x_spi_probe, 147 142 .remove = __devexit_p(wm831x_spi_remove), 148 - .suspend = wm831x_spi_suspend, 149 143 }; 150 144 151 145 static struct spi_driver wm8312_spi_driver = { ··· 153 147 .name = "wm8312", 154 148 .bus = &spi_bus_type, 155 149 .owner = THIS_MODULE, 150 + .pm = &wm831x_spi_pm, 156 151 }, 157 152 .probe = wm831x_spi_probe, 158 153 .remove = __devexit_p(wm831x_spi_remove), 159 - .suspend = wm831x_spi_suspend, 160 154 }; 161 155 162 156 static struct spi_driver wm8320_spi_driver = { ··· 164 158 .name = "wm8320", 165 159 .bus = &spi_bus_type, 166 160 .owner = THIS_MODULE, 161 + .pm = &wm831x_spi_pm, 167 162 }, 168 163 .probe = wm831x_spi_probe, 169 164 .remove = __devexit_p(wm831x_spi_remove), 170 - .suspend = wm831x_spi_suspend, 171 165 }; 172 166 173 167 static struct spi_driver wm8321_spi_driver = { ··· 175 169 .name = "wm8321", 176 170 .bus = &spi_bus_type, 177 171 .owner = THIS_MODULE, 172 + .pm = &wm831x_spi_pm, 178 173 }, 179 174 .probe = wm831x_spi_probe, 180 175 .remove = __devexit_p(wm831x_spi_remove), 181 - .suspend = wm831x_spi_suspend, 182 176 }; 183 177 184 178 static struct spi_driver wm8325_spi_driver = { ··· 186 180 .name = "wm8325", 187 181 .bus = &spi_bus_type, 188 182 .owner = THIS_MODULE, 183 + .pm = &wm831x_spi_pm, 189 184 }, 190 185 .probe = wm831x_spi_probe, 191 186 .remove = __devexit_p(wm831x_spi_remove), 192 - .suspend = wm831x_spi_suspend, 193 187 }; 194 188 195 189 static struct spi_driver wm8326_spi_driver = { ··· 197 191 .name = "wm8326", 198 192 .bus = &spi_bus_type, 199 193 .owner = THIS_MODULE, 194 + .pm = &wm831x_spi_pm, 200 195 }, 201 196 .probe = wm831x_spi_probe, 202 197 .remove = __devexit_p(wm831x_spi_remove), 203 - .suspend = wm831x_spi_suspend, 204 198 }; 205 199 206 200 static int __init wm831x_spi_init(void)
+1 -1
drivers/mfd/wm8400-core.c
··· 245 245 { 246 246 struct mfd_cell cell = { 247 247 .name = "wm8400-codec", 248 - .driver_data = wm8400, 248 + .mfd_data = wm8400, 249 249 }; 250 250 251 251 return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
+56 -21
drivers/mfd/wm8994-core.c
··· 40 40 return ret; 41 41 42 42 for (i = 0; i < bytes / 2; i++) { 43 - buf[i] = be16_to_cpu(buf[i]); 44 - 45 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 47 return 0; ··· 67 69 if (ret < 0) 68 70 return ret; 69 71 else 70 - return val; 72 + return be16_to_cpu(val); 71 73 } 72 74 EXPORT_SYMBOL_GPL(wm8994_reg_read); 73 75 ··· 77 79 * @wm8994: Device to read from 78 80 * @reg: First register 79 81 * @count: Number of registers 80 - * @buf: Buffer to fill. 82 + * @buf: Buffer to fill. The data will be returned big endian. 81 83 */ 82 84 int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 83 85 int count, u16 *buf) ··· 95 97 EXPORT_SYMBOL_GPL(wm8994_bulk_read); 96 98 97 99 static int wm8994_write(struct wm8994 *wm8994, unsigned short reg, 98 - int bytes, void *src) 100 + int bytes, const void *src) 99 101 { 100 - u16 *buf = src; 102 + const u16 *buf = src; 101 103 int i; 102 104 103 105 BUG_ON(bytes % 2); ··· 105 107 106 108 for (i = 0; i < bytes / 2; i++) { 107 109 dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n", 108 - buf[i], reg + i, reg + i); 109 - 110 - buf[i] = cpu_to_be16(buf[i]); 110 + be16_to_cpu(buf[i]), reg + i, reg + i); 111 111 } 112 112 113 113 return wm8994->write_dev(wm8994, reg, bytes, src); ··· 123 127 { 124 128 int ret; 125 129 130 + val = cpu_to_be16(val); 131 + 126 132 mutex_lock(&wm8994->io_lock); 127 133 128 134 ret = wm8994_write(wm8994, reg, 2, &val); ··· 134 136 return ret; 135 137 } 136 138 EXPORT_SYMBOL_GPL(wm8994_reg_write); 139 + 140 + /** 141 + * wm8994_bulk_write: Write multiple WM8994 registers 142 + * 143 + * @wm8994: Device to write to 144 + * @reg: First register 145 + * @count: Number of registers 146 + * @buf: Buffer to write from. Data must be big-endian formatted. 147 + */ 148 + int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, 149 + int count, const u16 *buf) 150 + { 151 + int ret; 152 + 153 + mutex_lock(&wm8994->io_lock); 154 + 155 + ret = wm8994_write(wm8994, reg, count * 2, buf); 156 + 157 + mutex_unlock(&wm8994->io_lock); 158 + 159 + return ret; 160 + } 161 + EXPORT_SYMBOL_GPL(wm8994_bulk_write); 137 162 138 163 /** 139 164 * wm8994_set_bits: Set the value of a bitfield in a WM8994 register ··· 178 157 if (ret < 0) 179 158 goto out; 180 159 160 + r = be16_to_cpu(r); 161 + 181 162 r &= ~mask; 182 163 r |= val; 164 + 165 + r = cpu_to_be16(r); 183 166 184 167 ret = wm8994_write(wm8994, reg, 2, &r); 185 168 ··· 295 270 &wm8994->ldo_regs); 296 271 if (ret < 0) 297 272 dev_err(dev, "Failed to save LDO registers: %d\n", ret); 273 + 274 + /* Explicitly put the device into reset in case regulators 275 + * don't get disabled in order to ensure consistent restart. 276 + */ 277 + wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET, 0x8994); 298 278 299 279 wm8994->suspended = true; 300 280 ··· 582 552 return 0; 583 553 } 584 554 585 - /* Currently we allocate the write buffer on the stack; this is OK for 586 - * small writes - if we need to do large writes this will need to be 587 - * revised. 588 - */ 589 555 static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg, 590 - int bytes, void *src) 556 + int bytes, const void *src) 591 557 { 592 558 struct i2c_client *i2c = wm8994->control_data; 593 - unsigned char msg[bytes + 2]; 559 + struct i2c_msg xfer[2]; 594 560 int ret; 595 561 596 562 reg = cpu_to_be16(reg); 597 - memcpy(&msg[0], &reg, 2); 598 - memcpy(&msg[2], src, bytes); 599 563 600 - ret = i2c_master_send(i2c, msg, bytes + 2); 564 + xfer[0].addr = i2c->addr; 565 + xfer[0].flags = 0; 566 + xfer[0].len = 2; 567 + xfer[0].buf = (char *)&reg; 568 + 569 + xfer[1].addr = i2c->addr; 570 + xfer[1].flags = I2C_M_NOSTART; 571 + xfer[1].len = bytes; 572 + xfer[1].buf = (char *)src; 573 + 574 + ret = i2c_transfer(i2c->adapter, xfer, 2); 601 575 if (ret < 0) 602 576 return ret; 603 - if (ret < bytes + 2) 577 + if (ret != 2) 604 578 return -EIO; 605 579 606 580 return 0; ··· 646 612 }; 647 613 MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); 648 614 649 - UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, NULL); 615 + static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume, 616 + NULL); 650 617 651 618 static struct i2c_driver wm8994_i2c_driver = { 652 619 .driver = {
+8 -6
drivers/mfd/wm8994-irq.c
··· 182 182 mutex_unlock(&wm8994->irq_lock); 183 183 } 184 184 185 - static void wm8994_irq_unmask(struct irq_data *data) 185 + static void wm8994_irq_enable(struct irq_data *data) 186 186 { 187 187 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); 188 188 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, ··· 191 191 wm8994->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; 192 192 } 193 193 194 - static void wm8994_irq_mask(struct irq_data *data) 194 + static void wm8994_irq_disable(struct irq_data *data) 195 195 { 196 196 struct wm8994 *wm8994 = irq_data_get_irq_chip_data(data); 197 197 struct wm8994_irq_data *irq_data = irq_to_wm8994_irq(wm8994, ··· 204 204 .name = "wm8994", 205 205 .irq_bus_lock = wm8994_irq_lock, 206 206 .irq_bus_sync_unlock = wm8994_irq_sync_unlock, 207 - .irq_mask = wm8994_irq_mask, 208 - .irq_unmask = wm8994_irq_unmask, 207 + .irq_disable = wm8994_irq_disable, 208 + .irq_enable = wm8994_irq_enable, 209 209 }; 210 210 211 211 /* The processing of the primary interrupt occurs in a thread so that ··· 225 225 return IRQ_NONE; 226 226 } 227 227 228 - /* Apply masking */ 229 - for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) 228 + /* Bit swap and apply masking */ 229 + for (i = 0; i < WM8994_NUM_IRQ_REGS; i++) { 230 + status[i] = be16_to_cpu(status[i]); 230 231 status[i] &= ~wm8994->irq_masks_cur[i]; 232 + } 231 233 232 234 /* Report */ 233 235 for (i = 0; i < ARRAY_SIZE(wm8994_irqs); i++) {
+13 -21
drivers/mmc/host/tmio_mmc.c
··· 303 303 304 304 static void tmio_mmc_clk_stop(struct tmio_mmc_host *host) 305 305 { 306 - struct mfd_cell *cell = host->pdev->dev.platform_data; 307 - struct tmio_mmc_data *pdata = cell->driver_data; 306 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 308 307 309 308 /* 310 309 * Testing on sh-mobile showed that SDIO IRQs are unmasked when ··· 326 327 327 328 static void tmio_mmc_clk_start(struct tmio_mmc_host *host) 328 329 { 329 - struct mfd_cell *cell = host->pdev->dev.platform_data; 330 - struct tmio_mmc_data *pdata = cell->driver_data; 330 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 331 331 332 332 sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 | 333 333 sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL)); ··· 667 669 static irqreturn_t tmio_mmc_irq(int irq, void *devid) 668 670 { 669 671 struct tmio_mmc_host *host = devid; 670 - struct mfd_cell *cell = host->pdev->dev.platform_data; 671 - struct tmio_mmc_data *pdata = cell->driver_data; 672 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 672 673 unsigned int ireg, irq_mask, status; 673 674 unsigned int sdio_ireg, sdio_irq_mask, sdio_status; 674 675 ··· 796 799 struct scatterlist *sg = host->sg_ptr, *sg_tmp; 797 800 struct dma_async_tx_descriptor *desc = NULL; 798 801 struct dma_chan *chan = host->chan_rx; 799 - struct mfd_cell *cell = host->pdev->dev.platform_data; 800 - struct tmio_mmc_data *pdata = cell->driver_data; 802 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 801 803 dma_cookie_t cookie; 802 804 int ret, i; 803 805 bool aligned = true, multiple = true; ··· 865 869 struct scatterlist *sg = host->sg_ptr, *sg_tmp; 866 870 struct dma_async_tx_descriptor *desc = NULL; 867 871 struct dma_chan *chan = host->chan_tx; 868 - struct mfd_cell *cell = host->pdev->dev.platform_data; 869 - struct tmio_mmc_data *pdata = cell->driver_data; 872 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 870 873 dma_cookie_t cookie; 871 874 int ret, i; 872 875 bool aligned = true, multiple = true; ··· 1058 1063 static int tmio_mmc_start_data(struct tmio_mmc_host *host, 1059 1064 struct mmc_data *data) 1060 1065 { 1061 - struct mfd_cell *cell = host->pdev->dev.platform_data; 1062 - struct tmio_mmc_data *pdata = cell->driver_data; 1066 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 1063 1067 1064 1068 pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n", 1065 1069 data->blksz, data->blocks); ··· 1163 1169 static int tmio_mmc_get_ro(struct mmc_host *mmc) 1164 1170 { 1165 1171 struct tmio_mmc_host *host = mmc_priv(mmc); 1166 - struct mfd_cell *cell = host->pdev->dev.platform_data; 1167 - struct tmio_mmc_data *pdata = cell->driver_data; 1172 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 1168 1173 1169 1174 return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) || 1170 1175 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1; ··· 1172 1179 static int tmio_mmc_get_cd(struct mmc_host *mmc) 1173 1180 { 1174 1181 struct tmio_mmc_host *host = mmc_priv(mmc); 1175 - struct mfd_cell *cell = host->pdev->dev.platform_data; 1176 - struct tmio_mmc_data *pdata = cell->driver_data; 1182 + struct tmio_mmc_data *pdata = mfd_get_data(host->pdev); 1177 1183 1178 1184 if (!pdata->get_cd) 1179 1185 return -ENOSYS; ··· 1191 1199 #ifdef CONFIG_PM 1192 1200 static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state) 1193 1201 { 1194 - struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1202 + const struct mfd_cell *cell = mfd_get_cell(dev); 1195 1203 struct mmc_host *mmc = platform_get_drvdata(dev); 1196 1204 int ret; 1197 1205 ··· 1206 1214 1207 1215 static int tmio_mmc_resume(struct platform_device *dev) 1208 1216 { 1209 - struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1217 + const struct mfd_cell *cell = mfd_get_cell(dev); 1210 1218 struct mmc_host *mmc = platform_get_drvdata(dev); 1211 1219 int ret = 0; 1212 1220 ··· 1229 1237 1230 1238 static int __devinit tmio_mmc_probe(struct platform_device *dev) 1231 1239 { 1232 - struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1240 + const struct mfd_cell *cell = mfd_get_cell(dev); 1233 1241 struct tmio_mmc_data *pdata; 1234 1242 struct resource *res_ctl; 1235 1243 struct tmio_mmc_host *host; ··· 1244 1252 if (!res_ctl) 1245 1253 goto out; 1246 1254 1247 - pdata = cell->driver_data; 1255 + pdata = mfd_get_data(dev); 1248 1256 if (!pdata || !pdata->hclk) 1249 1257 goto out; 1250 1258 ··· 1344 1352 1345 1353 static int __devexit tmio_mmc_remove(struct platform_device *dev) 1346 1354 { 1347 - struct mfd_cell *cell = (struct mfd_cell *)dev->dev.platform_data; 1355 + const struct mfd_cell *cell = mfd_get_cell(dev); 1348 1356 struct mmc_host *mmc = platform_get_drvdata(dev); 1349 1357 1350 1358 platform_set_drvdata(dev, NULL);
+5 -6
drivers/mtd/nand/tmio_nand.c
··· 319 319 320 320 static 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 323 int ret; 324 324 325 325 if (cell->enable) { ··· 363 363 364 364 static 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 368 tmio_iowrite8(FCR_MODE_POWER_OFF, tmio->fcr + FCR_MODE); 369 369 if (cell->disable) ··· 372 372 373 373 static int tmio_probe(struct platform_device *dev) 374 374 { 375 - struct mfd_cell *cell = dev_get_platdata(&dev->dev); 376 - struct tmio_nand_data *data = cell->driver_data; 375 + struct tmio_nand_data *data = mfd_get_data(dev); 377 376 struct resource *fcr = platform_get_resource(dev, 378 377 IORESOURCE_MEM, 0); 379 378 struct resource *ccr = platform_get_resource(dev, ··· 515 516 #ifdef CONFIG_PM 516 517 static int tmio_suspend(struct platform_device *dev, pm_message_t state) 517 518 { 518 - struct mfd_cell *cell = dev_get_platdata(&dev->dev); 519 + const struct mfd_cell *cell = mfd_get_cell(dev); 519 520 520 521 if (cell->suspend) 521 522 cell->suspend(dev); ··· 526 527 527 528 static int tmio_resume(struct platform_device *dev) 528 529 { 529 - struct mfd_cell *cell = dev_get_platdata(&dev->dev); 530 + const struct mfd_cell *cell = mfd_get_cell(dev); 530 531 531 532 /* FIXME - is this required or merely another attack of the broken 532 533 * SHARP platform? Looks suspicious.
+2 -1
drivers/net/can/janz-ican3.c
··· 15 15 #include <linux/interrupt.h> 16 16 #include <linux/delay.h> 17 17 #include <linux/platform_device.h> 18 + #include <linux/mfd/core.h> 18 19 19 20 #include <linux/netdevice.h> 20 21 #include <linux/can.h> ··· 1644 1643 struct device *dev; 1645 1644 int ret; 1646 1645 1647 - pdata = pdev->dev.platform_data; 1646 + pdata = mfd_get_data(pdev); 1648 1647 if (!pdata) 1649 1648 return -ENXIO; 1650 1649
+2 -1
drivers/net/ks8842.c
··· 26 26 #include <linux/kernel.h> 27 27 #include <linux/module.h> 28 28 #include <linux/platform_device.h> 29 + #include <linux/mfd/core.h> 29 30 #include <linux/netdevice.h> 30 31 #include <linux/etherdevice.h> 31 32 #include <linux/ethtool.h> ··· 1146 1145 struct resource *iomem; 1147 1146 struct net_device *netdev; 1148 1147 struct ks8842_adapter *adapter; 1149 - struct ks8842_platform_data *pdata = pdev->dev.platform_data; 1148 + struct ks8842_platform_data *pdata = mfd_get_data(pdev); 1150 1149 u16 id; 1151 1150 unsigned i; 1152 1151
+2 -2
drivers/power/jz4740-battery.c
··· 39 39 int irq; 40 40 int charge_irq; 41 41 42 - struct mfd_cell *cell; 42 + const struct mfd_cell *cell; 43 43 44 44 int status; 45 45 long voltage; ··· 258 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 263 jz_battery->irq = platform_get_irq(pdev, 0); 264 264 if (jz_battery->irq < 0) {
+25 -23
drivers/regulator/88pm8607.c
··· 15 15 #include <linux/platform_device.h> 16 16 #include <linux/regulator/driver.h> 17 17 #include <linux/regulator/machine.h> 18 + #include <linux/mfd/core.h> 18 19 #include <linux/mfd/88pm860x.h> 19 20 20 21 struct pm8607_regulator_info { ··· 395 394 PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), 396 395 }; 397 396 398 - static inline struct pm8607_regulator_info *find_regulator_info(int id) 399 - { 400 - struct pm8607_regulator_info *info; 401 - int i; 402 - 403 - for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { 404 - info = &pm8607_regulator_info[i]; 405 - if (info->desc.id == id) 406 - return info; 407 - } 408 - return NULL; 409 - } 410 - 411 397 static int __devinit pm8607_regulator_probe(struct platform_device *pdev) 412 398 { 413 399 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 414 - struct pm860x_platform_data *pdata = chip->dev->platform_data; 415 400 struct pm8607_regulator_info *info = NULL; 401 + struct regulator_init_data *pdata; 402 + struct mfd_cell *cell; 403 + int i; 416 404 417 - info = find_regulator_info(pdev->id); 418 - if (info == NULL) { 419 - dev_err(&pdev->dev, "invalid regulator ID specified\n"); 405 + cell = pdev->dev.platform_data; 406 + if (cell == NULL) 407 + return -ENODEV; 408 + pdata = cell->mfd_data; 409 + if (pdata == NULL) 410 + return -EINVAL; 411 + 412 + for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) { 413 + info = &pm8607_regulator_info[i]; 414 + if (!strcmp(info->desc.name, pdata->constraints.name)) 415 + break; 416 + } 417 + if (i > ARRAY_SIZE(pm8607_regulator_info)) { 418 + dev_err(&pdev->dev, "Failed to find regulator %s\n", 419 + pdata->constraints.name); 420 420 return -EINVAL; 421 421 } 422 422 423 423 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion; 424 424 info->chip = chip; 425 425 426 + /* check DVC ramp slope double */ 427 + if (!strcmp(info->desc.name, "BUCK3")) 428 + if (info->chip->buck3_double) 429 + info->slope_double = 1; 430 + 426 431 info->regulator = regulator_register(&info->desc, &pdev->dev, 427 - pdata->regulator[pdev->id], info); 432 + pdata, info); 428 433 if (IS_ERR(info->regulator)) { 429 434 dev_err(&pdev->dev, "failed to register regulator %s\n", 430 435 info->desc.name); 431 436 return PTR_ERR(info->regulator); 432 437 } 433 - 434 - /* check DVC ramp slope double */ 435 - if (info->desc.id == PM8607_ID_BUCK3) 436 - if (info->chip->buck3_double) 437 - info->slope_double = 1; 438 438 439 439 platform_set_drvdata(pdev, info); 440 440 return 0;
+18
drivers/regulator/Kconfig
··· 108 108 via I2C bus. Maxim 8952 has one voltage output and supports 4 DVS 109 109 modes ranging from 0.77V to 1.40V by 0.01V steps. 110 110 111 + config 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 + 111 120 config REGULATOR_MAX8998 112 121 tristate "Maxim 8998 voltage regulator" 113 122 depends on MFD_MAX8998 ··· 222 213 These regulators correspond to functionality in the 223 214 AB3100 analog baseband dealing with power regulators 224 215 for the system. 216 + 217 + config REGULATOR_TPS6105X 218 + tristate "TI TPS6105X Power regulators" 219 + depends on TPS6105X 220 + default y if TPS6105X 221 + help 222 + This driver supports TPS61050/TPS61052 voltage regulator chips. 223 + It is a single boost converter primarily for white LEDs and 224 + audio amplifiers. 225 225 226 226 config REGULATOR_TPS65023 227 227 tristate "TI TPS65023 Power regulators"
+2 -1
drivers/regulator/Makefile
··· 18 18 obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 19 19 obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o 20 20 obj-$(CONFIG_REGULATOR_MAX8952) += max8952.o 21 + obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o 21 22 obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o 22 23 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 23 24 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o ··· 34 33 obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o 35 34 obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o 36 35 obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o 37 - 36 + obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o 38 37 obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o 39 38 obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o 40 39 obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o
+2 -1
drivers/regulator/ab3100.c
··· 17 17 #include <linux/platform_device.h> 18 18 #include <linux/regulator/driver.h> 19 19 #include <linux/mfd/abx500.h> 20 + #include <linux/mfd/core.h> 20 21 21 22 /* LDO registers and some handy masking definitions for AB3100 */ 22 23 #define AB3100_LDO_A 0x40 ··· 577 576 578 577 static int __devinit ab3100_regulators_probe(struct platform_device *pdev) 579 578 { 580 - struct ab3100_platform_data *plfdata = pdev->dev.platform_data; 579 + struct ab3100_platform_data *plfdata = mfd_get_data(pdev); 581 580 int err = 0; 582 581 u8 data; 583 582 int i;
+1213
drivers/regulator/max8997.c
··· 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 + 35 + struct 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 + 50 + static 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 + 63 + struct voltage_map_desc { 64 + int min; 65 + int max; 66 + int step; 67 + unsigned int n_bits; 68 + }; 69 + 70 + /* Voltage maps in mV */ 71 + static 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 + 75 + static 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 + 79 + static 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 */ 84 + static const struct voltage_map_desc charger_current_map_desc = { 85 + .min = 200, .max = 950, .step = 50, .n_bits = 4, 86 + }; 87 + 88 + static const struct voltage_map_desc topoff_current_map_desc = { 89 + .min = 50, .max = 200, .step = 10, .n_bits = 4, 90 + }; 91 + 92 + static 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 + 129 + static inline int max8997_get_rid(struct regulator_dev *rdev) 130 + { 131 + return rdev_get_id(rdev); 132 + } 133 + 134 + static 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 + 157 + static 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 + } 175 + err: 176 + return -EINVAL; 177 + } 178 + 179 + static 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 + 201 + static 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 + 276 + static 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 + 296 + static 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 + 309 + static 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 + 322 + static 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 + 381 + static 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 + 418 + static 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 + 443 + static 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 + */ 498 + static 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 + */ 561 + static 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 + */ 640 + static 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 + 705 + out: 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 + 716 + static const int safeoutvolt[] = { 717 + 3300000, 718 + 4850000, 719 + 4900000, 720 + 4950000, 721 + }; 722 + 723 + /* For SAFEOUT1 and SAFEOUT2 */ 724 + static 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 + 761 + static int max8997_reg_enable_suspend(struct regulator_dev *rdev) 762 + { 763 + return 0; 764 + } 765 + 766 + static 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 + 793 + static 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 + 804 + static 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 + 815 + static 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 + 824 + static 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 + 835 + static 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 + 841 + static 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 + 850 + static 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 + 858 + static 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 + 879 + static 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 + 963 + static __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; 1157 + err: 1158 + for (i = 0; i < max8997->num_regulators; i++) 1159 + if (rdev[i]) 1160 + regulator_unregister(rdev[i]); 1161 + err_alloc: 1162 + kfree(max8997->rdev); 1163 + kfree(max8997); 1164 + 1165 + return ret; 1166 + } 1167 + 1168 + static 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 + 1184 + static const struct platform_device_id max8997_pmic_id[] = { 1185 + { "max8997-pmic", 0}, 1186 + { }, 1187 + }; 1188 + 1189 + static 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 + 1199 + static int __init max8997_pmic_init(void) 1200 + { 1201 + return platform_driver_register(&max8997_pmic_driver); 1202 + } 1203 + subsys_initcall(max8997_pmic_init); 1204 + 1205 + static void __exit max8997_pmic_cleanup(void) 1206 + { 1207 + platform_driver_unregister(&max8997_pmic_driver); 1208 + } 1209 + module_exit(max8997_pmic_cleanup); 1210 + 1211 + MODULE_DESCRIPTION("MAXIM 8997/8966 Regulator Driver"); 1212 + MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>"); 1213 + MODULE_LICENSE("GPL");
+3 -4
drivers/regulator/mc13783-regulator.c
··· 15 15 #include <linux/regulator/driver.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/kernel.h> 18 + #include <linux/mfd/core.h> 18 19 #include <linux/slab.h> 19 20 #include <linux/init.h> 20 21 #include <linux/err.h> ··· 337 336 { 338 337 struct mc13xxx_regulator_priv *priv; 339 338 struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent); 340 - struct mc13783_regulator_platform_data *pdata = 341 - dev_get_platdata(&pdev->dev); 339 + struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev); 342 340 struct mc13783_regulator_init_data *init_data; 343 341 int i, ret; 344 342 ··· 381 381 static int __devexit mc13783_regulator_remove(struct platform_device *pdev) 382 382 { 383 383 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 384 - struct mc13783_regulator_platform_data *pdata = 385 - dev_get_platdata(&pdev->dev); 384 + struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev); 386 385 int i; 387 386 388 387 platform_set_drvdata(pdev, NULL);
+3 -4
drivers/regulator/mc13892-regulator.c
··· 15 15 #include <linux/regulator/driver.h> 16 16 #include <linux/platform_device.h> 17 17 #include <linux/kernel.h> 18 + #include <linux/mfd/core.h> 18 19 #include <linux/slab.h> 19 20 #include <linux/init.h> 20 21 #include <linux/err.h> ··· 521 520 { 522 521 struct mc13xxx_regulator_priv *priv; 523 522 struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent); 524 - struct mc13xxx_regulator_platform_data *pdata = 525 - dev_get_platdata(&pdev->dev); 523 + struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev); 526 524 struct mc13xxx_regulator_init_data *init_data; 527 525 int i, ret; 528 526 u32 val; ··· 595 595 static int __devexit mc13892_regulator_remove(struct platform_device *pdev) 596 596 { 597 597 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 598 - struct mc13xxx_regulator_platform_data *pdata = 599 - dev_get_platdata(&pdev->dev); 598 + struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev); 600 599 int i; 601 600 602 601 platform_set_drvdata(pdev, NULL);
+196
drivers/regulator/tps6105x-regulator.c
··· 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 + 23 + static const int tps6105x_voltages[] = { 24 + 4500000, 25 + 5000000, 26 + 5250000, 27 + 5000000, /* There is an additional 5V */ 28 + }; 29 + 30 + static 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 + 45 + static 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 + 60 + static 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 + 78 + static 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 + 93 + static 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 + 108 + static 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 + 117 + static 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 + 126 + static 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 + */ 138 + static 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 + 165 + static 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 + 172 + static 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 + 181 + static __init int tps6105x_regulator_init(void) 182 + { 183 + return platform_driver_register(&tps6105x_regulator_driver); 184 + } 185 + subsys_initcall(tps6105x_regulator_init); 186 + 187 + static __exit void tps6105x_regulator_exit(void) 188 + { 189 + platform_driver_unregister(&tps6105x_regulator_driver); 190 + } 191 + module_exit(tps6105x_regulator_exit); 192 + 193 + MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); 194 + MODULE_DESCRIPTION("TPS6105x regulator driver"); 195 + MODULE_LICENSE("GPL v2"); 196 + MODULE_ALIAS("platform:tps6105x-regulator");
+23 -1
drivers/regulator/twl-regulator.c
··· 475 475 .get_status = twlreg_get_status, 476 476 }; 477 477 478 + static 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 487 #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ ··· 545 538 }, \ 546 539 } 547 540 541 + #define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay, remap_conf) { \ 542 + .base = offset, \ 543 + .id = num, \ 544 + .delay = turnon_delay, \ 545 + .remap = remap_conf, \ 546 + .desc = { \ 547 + .name = #label, \ 548 + .id = TWL6030_REG_##label, \ 549 + .ops = &twl6030_fixed_resource, \ 550 + .type = REGULATOR_VOLTAGE, \ 551 + .owner = THIS_MODULE, \ 552 + }, \ 553 + } 554 + 548 555 /* 549 556 * We list regulators here if systems need some level of 550 557 * software control over them after boot. ··· 598 577 TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), 599 578 TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), 600 579 TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), 601 - TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21) 580 + TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21), 581 + TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21), 602 582 }; 603 583 604 584 static int __devinit twlreg_probe(struct platform_device *pdev)
+2 -1
drivers/spi/xilinx_spi.c
··· 18 18 #include <linux/interrupt.h> 19 19 #include <linux/of.h> 20 20 #include <linux/platform_device.h> 21 + #include <linux/mfd/core.h> 21 22 #include <linux/spi/spi.h> 22 23 #include <linux/spi/spi_bitbang.h> 23 24 #include <linux/spi/xilinx_spi.h> ··· 471 470 struct spi_master *master; 472 471 u8 i; 473 472 474 - pdata = dev->dev.platform_data; 473 + pdata = mfd_get_data(dev); 475 474 if (pdata) { 476 475 num_cs = pdata->num_chipselect; 477 476 little_endian = pdata->little_endian;
+4 -4
drivers/usb/host/ohci-tmio.c
··· 185 185 186 186 static 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 189 struct resource *regs = platform_get_resource(dev, IORESOURCE_MEM, 0); 190 190 struct resource *config = platform_get_resource(dev, IORESOURCE_MEM, 1); 191 191 struct resource *sram = platform_get_resource(dev, IORESOURCE_MEM, 2); ··· 274 274 { 275 275 struct usb_hcd *hcd = platform_get_drvdata(dev); 276 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 279 usb_remove_hcd(hcd); 280 280 tmio_stop_hc(dev); ··· 293 293 #ifdef CONFIG_PM 294 294 static 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 297 struct usb_hcd *hcd = platform_get_drvdata(dev); 298 298 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 299 299 struct tmio_hcd *tmio = hcd_to_tmio(hcd); ··· 326 326 327 327 static 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 330 struct usb_hcd *hcd = platform_get_drvdata(dev); 331 331 struct ohci_hcd *ohci = hcd_to_ohci(hcd); 332 332 struct tmio_hcd *tmio = hcd_to_tmio(hcd);
+8 -26
drivers/video/backlight/88pm860x_bl.c
··· 12 12 #include <linux/init.h> 13 13 #include <linux/kernel.h> 14 14 #include <linux/platform_device.h> 15 + #include <linux/slab.h> 15 16 #include <linux/fb.h> 16 17 #include <linux/i2c.h> 17 18 #include <linux/backlight.h> 19 + #include <linux/mfd/core.h> 18 20 #include <linux/mfd/88pm860x.h> 19 - #include <linux/slab.h> 20 21 21 22 #define MAX_BRIGHTNESS (0xFF) 22 23 #define MIN_BRIGHTNESS (0) ··· 162 161 .get_brightness = pm860x_backlight_get_brightness, 163 162 }; 164 163 165 - static int __check_device(struct pm860x_backlight_pdata *pdata, char *name) 166 - { 167 - struct pm860x_backlight_pdata *p = pdata; 168 - int ret = -EINVAL; 169 - 170 - while (p && p->id) { 171 - if ((p->id != PM8606_ID_BACKLIGHT) || (p->flags < 0)) 172 - break; 173 - 174 - if (!strncmp(name, pm860x_backlight_name[p->flags], 175 - MFD_NAME_SIZE)) { 176 - ret = (int)p->flags; 177 - break; 178 - } 179 - p++; 180 - } 181 - return ret; 182 - } 183 - 184 164 static int pm860x_backlight_probe(struct platform_device *pdev) 185 165 { 186 166 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 187 - struct pm860x_platform_data *pm860x_pdata; 188 167 struct pm860x_backlight_pdata *pdata = NULL; 189 168 struct pm860x_backlight_data *data; 190 169 struct backlight_device *bl; 170 + struct mfd_cell *cell; 191 171 struct resource *res; 192 172 struct backlight_properties props; 193 173 unsigned char value; ··· 181 199 return -EINVAL; 182 200 } 183 201 184 - if (pdev->dev.parent->platform_data) { 185 - pm860x_pdata = pdev->dev.parent->platform_data; 186 - pdata = pm860x_pdata->backlight; 187 - } 202 + cell = pdev->dev.platform_data; 203 + if (cell == NULL) 204 + return -ENODEV; 205 + pdata = cell->mfd_data; 188 206 if (pdata == NULL) { 189 207 dev_err(&pdev->dev, "platform data isn't assigned to " 190 208 "backlight\n"); ··· 201 219 data->current_brightness = MAX_BRIGHTNESS; 202 220 data->pwm = pdata->pwm; 203 221 data->iset = pdata->iset; 204 - data->port = __check_device(pdata, name); 222 + data->port = pdata->flags; 205 223 if (data->port < 0) { 206 224 dev_err(&pdev->dev, "wrong platform data is assigned"); 207 225 kfree(data);
+12 -16
drivers/video/tmiofb.c
··· 250 250 */ 251 251 static int tmiofb_hw_stop(struct platform_device *dev) 252 252 { 253 - struct mfd_cell *cell = dev->dev.platform_data; 254 - struct tmio_fb_data *data = cell->driver_data; 253 + struct tmio_fb_data *data = mfd_get_data(dev); 255 254 struct fb_info *info = platform_get_drvdata(dev); 256 255 struct tmiofb_par *par = info->par; 257 256 ··· 267 268 */ 268 269 static int tmiofb_hw_init(struct platform_device *dev) 269 270 { 270 - struct mfd_cell *cell = dev->dev.platform_data; 271 + const struct mfd_cell *cell = mfd_get_cell(dev); 271 272 struct fb_info *info = platform_get_drvdata(dev); 272 273 struct tmiofb_par *par = info->par; 273 274 const struct resource *nlcr = &cell->resources[0]; ··· 311 312 */ 312 313 static void tmiofb_hw_mode(struct platform_device *dev) 313 314 { 314 - struct mfd_cell *cell = dev->dev.platform_data; 315 - struct tmio_fb_data *data = cell->driver_data; 315 + struct tmio_fb_data *data = mfd_get_data(dev); 316 316 struct fb_info *info = platform_get_drvdata(dev); 317 317 struct fb_videomode *mode = info->mode; 318 318 struct tmiofb_par *par = info->par; ··· 557 559 static struct fb_videomode * 558 560 tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var) 559 561 { 560 - struct mfd_cell *cell = 561 - info->device->platform_data; 562 - struct tmio_fb_data *data = cell->driver_data; 562 + struct tmio_fb_data *data = 563 + mfd_get_data(to_platform_device(info->device)); 563 564 struct fb_videomode *best = NULL; 564 565 int i; 565 566 ··· 578 581 { 579 582 580 583 struct fb_videomode *mode; 581 - struct mfd_cell *cell = 582 - info->device->platform_data; 583 - struct tmio_fb_data *data = cell->driver_data; 584 + struct tmio_fb_data *data = 585 + mfd_get_data(to_platform_device(info->device)); 584 586 585 587 mode = tmiofb_find_mode(info, var); 586 588 if (!mode || var->bits_per_pixel > 16) ··· 679 683 680 684 static int __devinit tmiofb_probe(struct platform_device *dev) 681 685 { 682 - struct mfd_cell *cell = dev->dev.platform_data; 683 - struct tmio_fb_data *data = cell->driver_data; 686 + const struct mfd_cell *cell = mfd_get_cell(dev); 687 + struct tmio_fb_data *data = mfd_get_data(dev); 684 688 struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1); 685 689 struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0); 686 690 struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); ··· 807 811 808 812 static int __devexit tmiofb_remove(struct platform_device *dev) 809 813 { 810 - struct mfd_cell *cell = dev->dev.platform_data; 814 + const struct mfd_cell *cell = mfd_get_cell(dev); 811 815 struct fb_info *info = platform_get_drvdata(dev); 812 816 int irq = platform_get_irq(dev, 0); 813 817 struct tmiofb_par *par; ··· 937 941 #ifdef CONFIG_FB_TMIO_ACCELL 938 942 struct tmiofb_par *par = info->par; 939 943 #endif 940 - struct mfd_cell *cell = dev->dev.platform_data; 944 + const struct mfd_cell *cell = mfd_get_cell(dev); 941 945 int retval = 0; 942 946 943 947 console_lock(); ··· 969 973 static int tmiofb_resume(struct platform_device *dev) 970 974 { 971 975 struct fb_info *info = platform_get_drvdata(dev); 972 - struct mfd_cell *cell = dev->dev.platform_data; 976 + const struct mfd_cell *cell = mfd_get_cell(dev); 973 977 int retval = 0; 974 978 975 979 console_lock();
+4 -9
drivers/w1/masters/ds1wm.c
··· 90 90 void __iomem *map; 91 91 int bus_shift; /* # of shifts to calc register offsets */ 92 92 struct platform_device *pdev; 93 - struct mfd_cell *cell; 93 + const struct mfd_cell *cell; 94 94 int irq; 95 95 int active_high; 96 96 int slave_present; ··· 216 216 static void ds1wm_up(struct ds1wm_data *ds1wm_data) 217 217 { 218 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 221 if (ds1wm_data->cell->enable) 222 222 ds1wm_data->cell->enable(ds1wm_data->pdev); ··· 330 330 struct ds1wm_data *ds1wm_data; 331 331 struct ds1wm_driver_data *plat; 332 332 struct resource *res; 333 - struct mfd_cell *cell; 334 333 int ret; 335 334 336 335 if (!pdev) 337 - return -ENODEV; 338 - 339 - cell = pdev->dev.platform_data; 340 - if (!cell) 341 336 return -ENODEV; 342 337 343 338 ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL); ··· 351 356 ret = -ENOMEM; 352 357 goto err0; 353 358 } 354 - plat = cell->driver_data; 359 + plat = mfd_get_data(pdev); 355 360 356 361 /* calculate bus shift from mem resource */ 357 362 ds1wm_data->bus_shift = resource_size(res) >> 3; 358 363 359 364 ds1wm_data->pdev = pdev; 360 - ds1wm_data->cell = cell; 365 + ds1wm_data->cell = mfd_get_cell(pdev); 361 366 362 367 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 363 368 if (!res) {
+2 -1
drivers/watchdog/rdc321x_wdt.c
··· 37 37 #include <linux/io.h> 38 38 #include <linux/uaccess.h> 39 39 #include <linux/mfd/rdc321x.h> 40 + #include <linux/mfd/core.h> 40 41 41 42 #define RDC_WDT_MASK 0x80000000 /* Mask */ 42 43 #define RDC_WDT_EN 0x00800000 /* Enable bit */ ··· 232 231 struct resource *r; 233 232 struct rdc321x_wdt_pdata *pdata; 234 233 235 - pdata = platform_get_drvdata(pdev); 234 + pdata = mfd_get_data(pdev); 236 235 if (!pdata) { 237 236 dev_err(&pdev->dev, "no platform data supplied\n"); 238 237 return -ENODEV;
+2
include/linux/i2c/twl.h
··· 698 698 struct regulator_init_data *vana; 699 699 struct regulator_init_data *vcxio; 700 700 struct regulator_init_data *vusb; 701 + struct regulator_init_data *clk32kg; 701 702 }; 702 703 703 704 /*----------------------------------------------------------------------*/ ··· 778 777 779 778 /* INTERNAL LDOs */ 780 779 #define TWL6030_REG_VRTC 47 780 + #define TWL6030_REG_CLK32KG 48 781 781 782 782 #endif /* End of __TWL4030_H */
+141
include/linux/i2c/twl4030-madc.h
··· 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 + 26 + struct 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 + 44 + struct 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 + 55 + enum conversion_methods { 56 + TWL4030_MADC_RT, 57 + TWL4030_MADC_SW1, 58 + TWL4030_MADC_SW2, 59 + TWL4030_MADC_NUM_METHODS 60 + }; 61 + 62 + enum 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 + 132 + struct twl4030_madc_user_parms { 133 + int channel; 134 + int average; 135 + int status; 136 + u16 result; 137 + }; 138 + 139 + int twl4030_madc_conversion(struct twl4030_madc_request *conv); 140 + int twl4030_get_madc_conversion(int channel_no); 141 + #endif
+14 -6
include/linux/mfd/88pm860x.h
··· 131 131 PM8607_ID_LDO8, 132 132 PM8607_ID_LDO9, 133 133 PM8607_ID_LDO10, 134 + PM8607_ID_LDO11, 134 135 PM8607_ID_LDO12, 135 136 PM8607_ID_LDO13, 136 137 PM8607_ID_LDO14, 138 + PM8607_ID_LDO15, 137 139 138 140 PM8607_ID_RG_MAX, 139 141 }; ··· 312 310 313 311 }; 314 312 315 - #define PM8607_MAX_REGULATOR PM8607_ID_RG_MAX /* 3 Bucks, 13 LDOs */ 316 - 317 313 enum { 318 314 GI2C_PORT = 0, 319 315 PI2C_PORT, ··· 351 351 struct pm860x_led_pdata *led; 352 352 struct pm860x_touch_pdata *touch; 353 353 struct pm860x_power_pdata *power; 354 + struct regulator_init_data *regulator; 354 355 355 356 unsigned short companion_addr; /* I2C address of companion chip */ 356 357 int i2c_port; /* Controlled by GI2C or PI2C */ 357 358 int irq_mode; /* Clear interrupt by read/write(0/1) */ 358 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 - 362 - extern char pm860x_backlight_name[][MFD_NAME_SIZE]; 363 - extern char pm860x_led_name[][MFD_NAME_SIZE]; 364 364 365 365 extern int pm860x_reg_read(struct i2c_client *, int); 366 366 extern int pm860x_reg_write(struct i2c_client *, int, unsigned char); ··· 368 368 extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *); 369 369 extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, 370 370 unsigned char); 371 + extern int pm860x_page_reg_read(struct i2c_client *, int); 372 + extern int pm860x_page_reg_write(struct i2c_client *, int, unsigned char); 373 + extern int pm860x_page_bulk_read(struct i2c_client *, int, int, 374 + unsigned char *); 375 + extern int pm860x_page_bulk_write(struct i2c_client *, int, int, 376 + unsigned char *); 377 + extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char, 378 + unsigned char); 371 379 372 380 extern int pm860x_device_init(struct pm860x_chip *chip, 373 381 struct pm860x_platform_data *pdata) __devinit ;
+2 -2
include/linux/mfd/ab8500.h
··· 111 111 * @dev: parent device 112 112 * @lock: read/write operations lock 113 113 * @irq_lock: genirq bus lock 114 - * @revision: chip revision 115 114 * @irq: irq line 115 + * @chip_id: chip revision id 116 116 * @write: register write 117 117 * @read: register read 118 118 * @rx_buf: rx buf for SPI ··· 124 124 struct device *dev; 125 125 struct mutex lock; 126 126 struct mutex irq_lock; 127 - int revision; 127 + 128 128 int irq_base; 129 129 int irq; 130 130 u8 chip_id;
+32
include/linux/mfd/ab8500/gpadc.h
··· 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 + 27 + struct ab8500_gpadc; 28 + 29 + struct ab8500_gpadc *ab8500_gpadc_get(char *name); 30 + int ab8500_gpadc_convert(struct ab8500_gpadc *gpadc, u8 input); 31 + 32 + #endif /* _AB8500_GPADC_H */
+254
include/linux/mfd/ab8500/sysctrl.h
··· 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 + 13 + int ab8500_sysctrl_read(u16 reg, u8 *value); 14 + int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value); 15 + 16 + #else 17 + 18 + static inline int ab8500_sysctrl_read(u16 reg, u8 *value) 19 + { 20 + return 0; 21 + } 22 + 23 + static inline int ab8500_sysctrl_write(u16 reg, u8 mask, u8 value) 24 + { 25 + return 0; 26 + } 27 + 28 + #endif /* CONFIG_AB8500_CORE */ 29 + 30 + static inline int ab8500_sysctrl_set(u16 reg, u8 bits) 31 + { 32 + return ab8500_sysctrl_write(reg, bits, bits); 33 + } 34 + 35 + static 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 */
-1
include/linux/mfd/abx500.h
··· 186 186 struct ab3550_platform_data { 187 187 struct {unsigned int base; unsigned int count; } irq; 188 188 void *dev_data[AB3550_NUM_DEVICES]; 189 - size_t dev_data_sz[AB3550_NUM_DEVICES]; 190 189 struct abx500_init_settings *init_settings; 191 190 unsigned int init_settings_sz; 192 191 };
+44 -10
include/linux/mfd/core.h
··· 25 25 const char *name; 26 26 int id; 27 27 28 + /* refcounting for multiple drivers to use a single cell */ 29 + atomic_t *usage_count; 28 30 int (*enable)(struct platform_device *dev); 29 31 int (*disable)(struct platform_device *dev); 32 + 30 33 int (*suspend)(struct platform_device *dev); 31 34 int (*resume)(struct platform_device *dev); 32 35 33 - /* driver-specific data for MFD-aware "cell" drivers */ 34 - void *driver_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; 36 + /* mfd_data can be used to pass data to client drivers */ 37 + void *mfd_data; 40 38 41 39 /* 42 - * This resources can be specified relatively to the parent device. 43 - * For accessing device you should use resources from device 40 + * These resources can be specified relative to the parent device. 41 + * For accessing hardware you should use resources from the platform dev 44 42 */ 45 43 int num_resources; 46 44 const struct resource *resources; ··· 53 55 bool pm_runtime_no_callbacks; 54 56 }; 55 57 58 + /* 59 + * Convenience functions for clients using shared cells. Refcounting 60 + * happens automatically, with the cell's enable/disable callbacks 61 + * being called only when a device is first being enabled or no other 62 + * clients are making use of it. 63 + */ 64 + extern int mfd_cell_enable(struct platform_device *pdev); 65 + extern int mfd_cell_disable(struct platform_device *pdev); 66 + 67 + /* 68 + * Given a platform device that's been created by mfd_add_devices(), fetch 69 + * the mfd_cell that created it. 70 + */ 71 + static inline const struct mfd_cell *mfd_get_cell(struct platform_device *pdev) 72 + { 73 + return pdev->dev.platform_data; 74 + } 75 + 76 + /* 77 + * Given a platform device that's been created by mfd_add_devices(), fetch 78 + * the .mfd_data entry from the mfd_cell that created it. 79 + */ 80 + static inline void *mfd_get_data(struct platform_device *pdev) 81 + { 82 + return mfd_get_cell(pdev)->mfd_data; 83 + } 84 + 56 85 extern int mfd_add_devices(struct device *parent, int id, 57 - const struct mfd_cell *cells, int n_devs, 86 + struct mfd_cell *cells, int n_devs, 58 87 struct resource *mem_base, 59 88 int irq_base); 60 89 61 90 extern void mfd_remove_devices(struct device *parent); 91 + 92 + /* 93 + * For MFD drivers with clients sharing access to resources, these create 94 + * multiple platform devices per cell. Contention handling must still be 95 + * handled via drivers (ie, with enable/disable hooks). 96 + */ 97 + extern int mfd_shared_platform_driver_register(struct platform_driver *drv, 98 + const char *cellname); 99 + extern void mfd_shared_platform_driver_unregister(struct platform_driver *drv); 62 100 63 101 #endif
+347
include/linux/mfd/max8997-private.h
··· 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 + 27 + enum 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 + 173 + enum 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 + 193 + enum 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 */ 216 + enum 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 + 246 + enum 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 + 266 + enum 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 + 316 + struct 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 + 334 + enum max8997_types { 335 + TYPE_MAX8997, 336 + TYPE_MAX8966, 337 + }; 338 + 339 + extern int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest); 340 + extern int max8997_bulk_read(struct i2c_client *i2c, u8 reg, int count, 341 + u8 *buf); 342 + extern int max8997_write_reg(struct i2c_client *i2c, u8 reg, u8 value); 343 + extern int max8997_bulk_write(struct i2c_client *i2c, u8 reg, int count, 344 + u8 *buf); 345 + extern int max8997_update_reg(struct i2c_client *i2c, u8 reg, u8 val, u8 mask); 346 + 347 + #endif /* __LINUX_MFD_MAX8997_PRIV_H */
+114
include/linux/mfd/max8997.h
··· 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 */ 36 + enum 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 + 75 + struct max8997_regulator_data { 76 + int id; 77 + struct regulator_init_data *initdata; 78 + }; 79 + 80 + struct 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 */
+1 -2
include/linux/mfd/mc13xxx.h
··· 146 146 #define MC13XXX_USE_LED (1 << 5) 147 147 unsigned int flags; 148 148 149 - int num_regulators; 150 - struct mc13xxx_regulator_init_data *regulators; 149 + struct mc13xxx_regulator_platform_data regulators; 151 150 struct mc13xxx_leds_platform_data *leds; 152 151 }; 153 152
+101
include/linux/mfd/tps6105x.h
··· 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 + */ 64 + enum 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 + */ 78 + struct 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 + */ 89 + struct tps6105x { 90 + struct tps6105x_platform_data *pdata; 91 + struct mutex lock; 92 + struct i2c_client *client; 93 + struct regulator_dev *regulator; 94 + }; 95 + 96 + extern int tps6105x_set(struct tps6105x *tps6105x, u8 reg, u8 value); 97 + extern int tps6105x_get(struct tps6105x *tps6105x, u8 reg, u8 *buf); 98 + extern int tps6105x_mask_and_set(struct tps6105x *tps6105x, u8 reg, 99 + u8 bitmask, u8 bitvalues); 100 + 101 + #endif
+6
include/linux/mfd/wm831x/pdata.h
··· 104 104 #define WM831X_MAX_ISINK 2 105 105 106 106 struct wm831x_pdata { 107 + /** Used to distinguish multiple WM831x chips */ 108 + int wm831x_num; 109 + 107 110 /** Called before subdevices are set up */ 108 111 int (*pre_init)(struct wm831x *wm831x); 109 112 /** Called after subdevices are set up */ 110 113 int (*post_init)(struct wm831x *wm831x); 114 + 115 + /** Put the /IRQ line into CMOS mode */ 116 + bool irq_cmos; 111 117 112 118 int irq_base; 113 119 int gpio_base;
+3 -1
include/linux/mfd/wm8994/core.h
··· 59 59 int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, 60 60 int bytes, void *dest); 61 61 int (*write_dev)(struct wm8994 *wm8994, unsigned short reg, 62 - int bytes, void *src); 62 + int bytes, const void *src); 63 63 64 64 void *control_data; 65 65 ··· 88 88 unsigned short mask, unsigned short val); 89 89 int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg, 90 90 int count, u16 *buf); 91 + int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg, 92 + int count, const u16 *buf); 91 93 92 94 93 95 /* Helper to save on boilerplate */
+1
include/linux/pci_ids.h
··· 2737 2737 #define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 2738 2738 #define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119 2739 2739 #define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a 2740 + #define PCI_DEVICE_ID_INTEL_ITC_LPC 0x8186 2740 2741 #define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 2741 2742 #define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 2742 2743 #define PCI_DEVICE_ID_INTEL_82451NX 0x84ca
+2 -1
sound/soc/codecs/cq93vc.c
··· 153 153 154 154 static 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 159 davinci_vc->cq93vc.codec = codec; 159 160 codec->control_data = davinci_vc;
+4 -2
sound/soc/codecs/twl4030.c
··· 26 26 #include <linux/pm.h> 27 27 #include <linux/i2c.h> 28 28 #include <linux/platform_device.h> 29 + #include <linux/mfd/core.h> 29 30 #include <linux/i2c/twl.h> 30 31 #include <linux/slab.h> 31 32 #include <sound/core.h> ··· 733 732 734 733 static void headset_ramp(struct snd_soc_codec *codec, int ramp) 735 734 { 736 - struct twl4030_codec_audio_data *pdata = codec->dev->platform_data; 735 + struct twl4030_codec_audio_data *pdata = 736 + mfd_get_data(to_platform_device(codec->dev)); 737 737 unsigned char hs_gain, hs_pop; 738 738 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 739 739 /* Base values for ramp delay calculation: 2^19 - 2^26 */ ··· 2299 2297 2300 2298 static int __devinit twl4030_codec_probe(struct platform_device *pdev) 2301 2299 { 2302 - struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; 2300 + struct twl4030_codec_audio_data *pdata = mfd_get_data(pdev); 2303 2301 2304 2302 if (!pdata) { 2305 2303 dev_err(&pdev->dev, "platform_data is missing\n");
+2 -1
sound/soc/codecs/wl1273.c
··· 436 436 437 437 static 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 441 struct wl1273_priv *wl1273; 441 442 int r; 442 443
+2 -1
sound/soc/codecs/wm8400.c
··· 22 22 #include <linux/regulator/consumer.h> 23 23 #include <linux/mfd/wm8400-audio.h> 24 24 #include <linux/mfd/wm8400-private.h> 25 + #include <linux/mfd/core.h> 25 26 #include <sound/core.h> 26 27 #include <sound/pcm.h> 27 28 #include <sound/pcm_params.h> ··· 1378 1377 1379 1378 static int wm8400_codec_probe(struct snd_soc_codec *codec) 1380 1379 { 1381 - struct wm8400 *wm8400 = dev_get_platdata(codec->dev); 1380 + struct wm8400 *wm8400 = mfd_get_data(to_platform_device(codec->dev)); 1382 1381 struct wm8400_priv *priv; 1383 1382 int ret; 1384 1383 u16 reg;
+1 -1
sound/soc/davinci/davinci-vcif.c
··· 205 205 206 206 static 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 209 struct davinci_vcif_dev *davinci_vcif_dev; 210 210 int ret; 211 211