]> git.baikalelectronics.ru Git - kernel.git/commitdiff
mfd: Rename twl4030* driver files to enable re-use
authorSantosh Shilimkar <santosh.shilimkar@ti.com>
Sun, 13 Dec 2009 19:05:51 +0000 (20:05 +0100)
committerSamuel Ortiz <sameo@linux.intel.com>
Sun, 13 Dec 2009 19:05:51 +0000 (20:05 +0100)
The upcoming TWL6030 is companion chip for OMAP4 like the current TWL4030
for OMAP3. The common modules like RTC, Regulator creates opportunity
to re-use the most of the code from twl4030.

This patch renames few common drivers twl4030* files to twl* to enable
the code re-use.

Signed-off-by: Rajendra Nayak <rnayak@ti.com>
Signed-off-by: Balaji T K <balajitk@ti.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Acked-by: Kevin Hilman <khilman@deeprootsystems.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
26 files changed:
arch/arm/mach-omap2/board-2430sdp.c
arch/arm/mach-omap2/board-3430sdp.c
arch/arm/mach-omap2/board-ldp.c
arch/arm/mach-omap2/board-omap3beagle.c
arch/arm/mach-omap2/board-omap3pandora.c
arch/arm/mach-omap2/board-overo.c
drivers/gpio/twl4030-gpio.c
drivers/input/keyboard/twl4030_keypad.c
drivers/input/misc/twl4030-pwrbutton.c
drivers/mfd/Makefile
drivers/mfd/twl-core.c [new file with mode: 0644]
drivers/mfd/twl4030-core.c [deleted file]
drivers/mfd/twl4030-irq.c
drivers/mfd/twl4030-power.c
drivers/regulator/Makefile
drivers/regulator/twl-regulator.c [new file with mode: 0644]
drivers/regulator/twl4030-regulator.c [deleted file]
drivers/rtc/Makefile
drivers/rtc/rtc-twl.c [new file with mode: 0644]
drivers/rtc/rtc-twl4030.c [deleted file]
drivers/usb/otg/twl4030-usb.c
drivers/video/omap/lcd_2430sdp.c
drivers/watchdog/twl4030_wdt.c
include/linux/i2c/twl.h [new file with mode: 0644]
include/linux/i2c/twl4030.h [deleted file]
sound/soc/codecs/twl4030.c

index db9374bc528b588f8b51545dd8e686d4c10bef00..e508904fb67e3addfe4066f44860e6ecd737afd8 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/delay.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
index 4cfb7b68dfadc574181e4884dfb493b923abd263..c90b0d0b1927e58911dad6d7bfe593b712323557 100644 (file)
@@ -20,7 +20,7 @@
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
index 37431738f1c2a40632b024f70e4b3cbd70cc133b..995d4a2b2dfd5fa61c7337ee350d1e0e60b5f000 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/io.h>
 #include <linux/smsc911x.h>
 
index 6ada8029f9a8bb605e797295f5e0e6091bfb4a86..231cb4ec1847cfd51c038e2d533c7f40ae9d1295 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/mtd/nand.h>
 
 #include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
index 6f6c601eeab7c1ecbdd12dc88c77ec853248f372..ef17cf1ab6d7cc37b132a30d3b443ea4e93f9bf0 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/ads7846.h>
 #include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/leds.h>
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
index 5b78a87217e056754ccd08a0f3c7bd7280cf9448..d192dd98a591779ac126fdf3c3ab0fbb2b489f51 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 
 #include <linux/mtd/mtd.h>
index 49384a7c54920399e2d629d3e87b6986b3a964eb..a320d7bfe67cee75414f487ded98fd173e052269 100644 (file)
@@ -34,7 +34,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 
 /*
index 9a2977c216967d3c7a23daca744e8f136663c213..1d1536a2fe46172170cb4ccbd4a11ba266ab8a05 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/interrupt.h>
 #include <linux/input.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 
 /*
index f5fc9974a111842cd18af2bfd21ef9f762cd3c05..a73b889fff794e1eee0d7dc35b650957e0b282ec 100644 (file)
@@ -27,7 +27,7 @@
 #include <linux/input.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 #define PWR_PWRON_IRQ (1 << 0)
 
index 75638ca8288b442969579ae536bed3201f98c2f9..f4d14b7589bf49aafd4e4f51f7ec021aa8df50a1 100644 (file)
@@ -26,7 +26,7 @@ obj-$(CONFIG_MFD_WM8350_I2C)  += wm8350-i2c.o
 obj-$(CONFIG_TPS65010)         += tps65010.o
 obj-$(CONFIG_MENELAUS)         += menelaus.o
 
-obj-$(CONFIG_TWL4030_CORE)     += twl4030-core.o twl4030-irq.o
+obj-$(CONFIG_TWL4030_CORE)     += twl-core.o twl4030-irq.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
 obj-$(CONFIG_TWL4030_CODEC)    += twl4030-codec.o
 
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
new file mode 100644 (file)
index 0000000..44714f5
--- /dev/null
@@ -0,0 +1,929 @@
+/*
+ * twl4030_core.c - driver for TWL4030/TPS659x0 PM and audio CODEC devices
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * Modifications to defer interrupt handling to a kernel thread:
+ * Copyright (C) 2006 MontaVista Software, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * Code cleanup and modifications to IRQ handler.
+ * by syed khasim <x0khasim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <linux/regulator/machine.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+#include <plat/cpu.h>
+#endif
+
+/*
+ * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
+ * Management and System Companion Device" chips originally designed for
+ * use in OMAP2 and OMAP 3 based systems.  Its control interfaces use I2C,
+ * often at around 3 Mbit/sec, including for interrupt handling.
+ *
+ * This driver core provides genirq support for the interrupts emitted,
+ * by the various modules, and exports register access primitives.
+ *
+ * FIXME this driver currently requires use of the first interrupt line
+ * (and associated registers).
+ */
+
+#define DRIVER_NAME                    "twl4030"
+
+#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
+       defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
+#define twl_has_bci()          true
+#else
+#define twl_has_bci()          false
+#endif
+
+#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
+#define twl_has_keypad()       true
+#else
+#define twl_has_keypad()       false
+#endif
+
+#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
+#define twl_has_gpio() true
+#else
+#define twl_has_gpio() false
+#endif
+
+#if defined(CONFIG_REGULATOR_TWL4030) \
+       || defined(CONFIG_REGULATOR_TWL4030_MODULE)
+#define twl_has_regulator()    true
+#else
+#define twl_has_regulator()    false
+#endif
+
+#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
+#define twl_has_madc() true
+#else
+#define twl_has_madc() false
+#endif
+
+#ifdef CONFIG_TWL4030_POWER
+#define twl_has_power()        true
+#else
+#define twl_has_power()        false
+#endif
+
+#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
+#define twl_has_rtc()  true
+#else
+#define twl_has_rtc()  false
+#endif
+
+#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE)
+#define twl_has_usb()  true
+#else
+#define twl_has_usb()  false
+#endif
+
+#if defined(CONFIG_TWL4030_WATCHDOG) || \
+       defined(CONFIG_TWL4030_WATCHDOG_MODULE)
+#define twl_has_watchdog()        true
+#else
+#define twl_has_watchdog()        false
+#endif
+
+#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE)
+#define twl_has_codec()        true
+#else
+#define twl_has_codec()        false
+#endif
+
+/* Triton Core internal information (BEGIN) */
+
+/* Last - for index max*/
+#define TWL4030_MODULE_LAST            TWL4030_MODULE_SECURED_REG
+
+#define TWL4030_NUM_SLAVES             4
+
+#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
+       || defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
+#define twl_has_pwrbutton()    true
+#else
+#define twl_has_pwrbutton()    false
+#endif
+
+/* Base Address defns for twl4030_map[] */
+
+/* subchip/slave 0 - USB ID */
+#define TWL4030_BASEADD_USB            0x0000
+
+/* subchip/slave 1 - AUD ID */
+#define TWL4030_BASEADD_AUDIO_VOICE    0x0000
+#define TWL4030_BASEADD_GPIO           0x0098
+#define TWL4030_BASEADD_INTBR          0x0085
+#define TWL4030_BASEADD_PIH            0x0080
+#define TWL4030_BASEADD_TEST           0x004C
+
+/* subchip/slave 2 - AUX ID */
+#define TWL4030_BASEADD_INTERRUPTS     0x00B9
+#define TWL4030_BASEADD_LED            0x00EE
+#define TWL4030_BASEADD_MADC           0x0000
+#define TWL4030_BASEADD_MAIN_CHARGE    0x0074
+#define TWL4030_BASEADD_PRECHARGE      0x00AA
+#define TWL4030_BASEADD_PWM0           0x00F8
+#define TWL4030_BASEADD_PWM1           0x00FB
+#define TWL4030_BASEADD_PWMA           0x00EF
+#define TWL4030_BASEADD_PWMB           0x00F1
+#define TWL4030_BASEADD_KEYPAD         0x00D2
+
+#define TWL5031_BASEADD_ACCESSORY      0x0074 /* Replaces Main Charge */
+#define TWL5031_BASEADD_INTERRUPTS     0x00B9 /* Different than TWL4030's
+                                                 one */
+
+/* subchip/slave 3 - POWER ID */
+#define TWL4030_BASEADD_BACKUP         0x0014
+#define TWL4030_BASEADD_INT            0x002E
+#define TWL4030_BASEADD_PM_MASTER      0x0036
+#define TWL4030_BASEADD_PM_RECEIVER    0x005B
+#define TWL4030_BASEADD_RTC            0x001C
+#define TWL4030_BASEADD_SECURED_REG    0x0000
+
+/* Triton Core internal information (END) */
+
+
+/* Few power values */
+#define R_CFG_BOOT                     0x05
+#define R_PROTECT_KEY                  0x0E
+
+/* access control values for R_PROTECT_KEY */
+#define KEY_UNLOCK1                    0xce
+#define KEY_UNLOCK2                    0xec
+#define KEY_LOCK                       0x00
+
+/* some fields in R_CFG_BOOT */
+#define HFCLK_FREQ_19p2_MHZ            (1 << 0)
+#define HFCLK_FREQ_26_MHZ              (2 << 0)
+#define HFCLK_FREQ_38p4_MHZ            (3 << 0)
+#define HIGH_PERF_SQ                   (1 << 3)
+#define CK32K_LOWPWR_EN                        (1 << 7)
+
+
+/* chip-specific feature flags, for i2c_device_id.driver_data */
+#define TWL4030_VAUX2          BIT(0)  /* pre-5030 voltage ranges */
+#define TPS_SUBSET             BIT(1)  /* tps659[23]0 have fewer LDOs */
+#define TWL5031                        BIT(2)  /* twl5031 has different registers */
+
+/*----------------------------------------------------------------------*/
+
+/* is driver active, bound to a chip? */
+static bool inuse;
+
+/* Structure for each TWL4030 Slave */
+struct twl4030_client {
+       struct i2c_client *client;
+       u8 address;
+
+       /* max numb of i2c_msg required is for read =2 */
+       struct i2c_msg xfer_msg[2];
+
+       /* To lock access to xfer_msg */
+       struct mutex xfer_lock;
+};
+
+static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES];
+
+
+/* mapping the module id to slave id and base address */
+struct twl4030mapping {
+       unsigned char sid;      /* Slave ID */
+       unsigned char base;     /* base address */
+};
+
+static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
+       /*
+        * NOTE:  don't change this table without updating the
+        * <linux/i2c/twl4030.h> defines for TWL4030_MODULE_*
+        * so they continue to match the order in this table.
+        */
+
+       { 0, TWL4030_BASEADD_USB },
+
+       { 1, TWL4030_BASEADD_AUDIO_VOICE },
+       { 1, TWL4030_BASEADD_GPIO },
+       { 1, TWL4030_BASEADD_INTBR },
+       { 1, TWL4030_BASEADD_PIH },
+       { 1, TWL4030_BASEADD_TEST },
+
+       { 2, TWL4030_BASEADD_KEYPAD },
+       { 2, TWL4030_BASEADD_MADC },
+       { 2, TWL4030_BASEADD_INTERRUPTS },
+       { 2, TWL4030_BASEADD_LED },
+       { 2, TWL4030_BASEADD_MAIN_CHARGE },
+       { 2, TWL4030_BASEADD_PRECHARGE },
+       { 2, TWL4030_BASEADD_PWM0 },
+       { 2, TWL4030_BASEADD_PWM1 },
+       { 2, TWL4030_BASEADD_PWMA },
+       { 2, TWL4030_BASEADD_PWMB },
+       { 2, TWL5031_BASEADD_ACCESSORY },
+       { 2, TWL5031_BASEADD_INTERRUPTS },
+
+       { 3, TWL4030_BASEADD_BACKUP },
+       { 3, TWL4030_BASEADD_INT },
+       { 3, TWL4030_BASEADD_PM_MASTER },
+       { 3, TWL4030_BASEADD_PM_RECEIVER },
+       { 3, TWL4030_BASEADD_RTC },
+       { 3, TWL4030_BASEADD_SECURED_REG },
+};
+
+/*----------------------------------------------------------------------*/
+
+/* Exported Functions */
+
+/**
+ * twl4030_i2c_write - Writes a n bit register in TWL4030
+ * @mod_no: module number
+ * @value: an array of num_bytes+1 containing data to write
+ * @reg: register address (just offset will do)
+ * @num_bytes: number of bytes to transfer
+ *
+ * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and
+ * valid data starts at Offset 1.
+ *
+ * Returns the result of operation - 0 is success
+ */
+int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
+{
+       int ret;
+       int sid;
+       struct twl4030_client *twl;
+       struct i2c_msg *msg;
+
+       if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
+               pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
+               return -EPERM;
+       }
+       sid = twl4030_map[mod_no].sid;
+       twl = &twl4030_modules[sid];
+
+       if (unlikely(!inuse)) {
+               pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+               return -EPERM;
+       }
+       mutex_lock(&twl->xfer_lock);
+       /*
+        * [MSG1]: fill the register address data
+        * fill the data Tx buffer
+        */
+       msg = &twl->xfer_msg[0];
+       msg->addr = twl->address;
+       msg->len = num_bytes + 1;
+       msg->flags = 0;
+       msg->buf = value;
+       /* over write the first byte of buffer with the register address */
+       *value = twl4030_map[mod_no].base + reg;
+       ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1);
+       mutex_unlock(&twl->xfer_lock);
+
+       /* i2c_transfer returns number of messages transferred */
+       if (ret != 1) {
+               pr_err("%s: i2c_write failed to transfer all messages\n",
+                       DRIVER_NAME);
+               if (ret < 0)
+                       return ret;
+               else
+                       return -EIO;
+       } else {
+               return 0;
+       }
+}
+EXPORT_SYMBOL(twl4030_i2c_write);
+
+/**
+ * twl4030_i2c_read - Reads a n bit register in TWL4030
+ * @mod_no: module number
+ * @value: an array of num_bytes containing data to be read
+ * @reg: register address (just offset will do)
+ * @num_bytes: number of bytes to transfer
+ *
+ * Returns result of operation - num_bytes is success else failure.
+ */
+int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
+{
+       int ret;
+       u8 val;
+       int sid;
+       struct twl4030_client *twl;
+       struct i2c_msg *msg;
+
+       if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
+               pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
+               return -EPERM;
+       }
+       sid = twl4030_map[mod_no].sid;
+       twl = &twl4030_modules[sid];
+
+       if (unlikely(!inuse)) {
+               pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
+               return -EPERM;
+       }
+       mutex_lock(&twl->xfer_lock);
+       /* [MSG1] fill the register address data */
+       msg = &twl->xfer_msg[0];
+       msg->addr = twl->address;
+       msg->len = 1;
+       msg->flags = 0; /* Read the register value */
+       val = twl4030_map[mod_no].base + reg;
+       msg->buf = &val;
+       /* [MSG2] fill the data rx buffer */
+       msg = &twl->xfer_msg[1];
+       msg->addr = twl->address;
+       msg->flags = I2C_M_RD;  /* Read the register value */
+       msg->len = num_bytes;   /* only n bytes */
+       msg->buf = value;
+       ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2);
+       mutex_unlock(&twl->xfer_lock);
+
+       /* i2c_transfer returns number of messages transferred */
+       if (ret != 2) {
+               pr_err("%s: i2c_read failed to transfer all messages\n",
+                       DRIVER_NAME);
+               if (ret < 0)
+                       return ret;
+               else
+                       return -EIO;
+       } else {
+               return 0;
+       }
+}
+EXPORT_SYMBOL(twl4030_i2c_read);
+
+/**
+ * twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030
+ * @mod_no: module number
+ * @value: the value to be written 8 bit
+ * @reg: register address (just offset will do)
+ *
+ * Returns result of operation - 0 is success
+ */
+int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
+{
+
+       /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
+       u8 temp_buffer[2] = { 0 };
+       /* offset 1 contains the data */
+       temp_buffer[1] = value;
+       return twl4030_i2c_write(mod_no, temp_buffer, reg, 1);
+}
+EXPORT_SYMBOL(twl4030_i2c_write_u8);
+
+/**
+ * twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030
+ * @mod_no: module number
+ * @value: the value read 8 bit
+ * @reg: register address (just offset will do)
+ *
+ * Returns result of operation - 0 is success
+ */
+int twl4030_i2c_read_u8(u8 mod_no, u8 *value, u8 reg)
+{
+       return twl4030_i2c_read(mod_no, value, reg, 1);
+}
+EXPORT_SYMBOL(twl4030_i2c_read_u8);
+
+/*----------------------------------------------------------------------*/
+
+static struct device *
+add_numbered_child(unsigned chip, const char *name, int num,
+               void *pdata, unsigned pdata_len,
+               bool can_wakeup, int irq0, int irq1)
+{
+       struct platform_device  *pdev;
+       struct twl4030_client   *twl = &twl4030_modules[chip];
+       int                     status;
+
+       pdev = platform_device_alloc(name, num);
+       if (!pdev) {
+               dev_dbg(&twl->client->dev, "can't alloc dev\n");
+               status = -ENOMEM;
+               goto err;
+       }
+
+       device_init_wakeup(&pdev->dev, can_wakeup);
+       pdev->dev.parent = &twl->client->dev;
+
+       if (pdata) {
+               status = platform_device_add_data(pdev, pdata, pdata_len);
+               if (status < 0) {
+                       dev_dbg(&pdev->dev, "can't add platform_data\n");
+                       goto err;
+               }
+       }
+
+       if (irq0) {
+               struct resource r[2] = {
+                       { .start = irq0, .flags = IORESOURCE_IRQ, },
+                       { .start = irq1, .flags = IORESOURCE_IRQ, },
+               };
+
+               status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
+               if (status < 0) {
+                       dev_dbg(&pdev->dev, "can't add irqs\n");
+                       goto err;
+               }
+       }
+
+       status = platform_device_add(pdev);
+
+err:
+       if (status < 0) {
+               platform_device_put(pdev);
+               dev_err(&twl->client->dev, "can't add %s dev\n", name);
+               return ERR_PTR(status);
+       }
+       return &pdev->dev;
+}
+
+static inline struct device *add_child(unsigned chip, const char *name,
+               void *pdata, unsigned pdata_len,
+               bool can_wakeup, int irq0, int irq1)
+{
+       return add_numbered_child(chip, name, -1, pdata, pdata_len,
+               can_wakeup, irq0, irq1);
+}
+
+static struct device *
+add_regulator_linked(int num, struct regulator_init_data *pdata,
+               struct regulator_consumer_supply *consumers,
+               unsigned num_consumers)
+{
+       /* regulator framework demands init_data ... */
+       if (!pdata)
+               return NULL;
+
+       if (consumers) {
+               pdata->consumer_supplies = consumers;
+               pdata->num_consumer_supplies = num_consumers;
+       }
+
+       /* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
+       return add_numbered_child(3, "twl4030_reg", num,
+               pdata, sizeof(*pdata), false, 0, 0);
+}
+
+static struct device *
+add_regulator(int num, struct regulator_init_data *pdata)
+{
+       return add_regulator_linked(num, pdata, NULL, 0);
+}
+
+/*
+ * NOTE:  We know the first 8 IRQs after pdata->base_irq are
+ * for the PIH, and the next are for the PWR_INT SIH, since
+ * that's how twl_init_irq() sets things up.
+ */
+
+static int
+add_children(struct twl4030_platform_data *pdata, unsigned long features)
+{
+       struct device   *child;
+
+       if (twl_has_bci() && pdata->bci &&
+           !(features & (TPS_SUBSET | TWL5031))) {
+               child = add_child(3, "twl4030_bci",
+                               pdata->bci, sizeof(*pdata->bci),
+                               false,
+                               /* irq0 = CHG_PRES, irq1 = BCI */
+                               pdata->irq_base + 8 + 1, pdata->irq_base + 2);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_gpio() && pdata->gpio) {
+               child = add_child(1, "twl4030_gpio",
+                               pdata->gpio, sizeof(*pdata->gpio),
+                               false, pdata->irq_base + 0, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_keypad() && pdata->keypad) {
+               child = add_child(2, "twl4030_keypad",
+                               pdata->keypad, sizeof(*pdata->keypad),
+                               true, pdata->irq_base + 1, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_madc() && pdata->madc) {
+               child = add_child(2, "twl4030_madc",
+                               pdata->madc, sizeof(*pdata->madc),
+                               true, pdata->irq_base + 3, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_rtc()) {
+               /*
+                * REVISIT platform_data here currently might expose the
+                * "msecure" line ... but for now we just expect board
+                * setup to tell the chip "it's always ok to SET_TIME".
+                * Eventually, Linux might become more aware of such
+                * HW security concerns, and "least privilege".
+                */
+               child = add_child(3, "twl4030_rtc",
+                               NULL, 0,
+                               true, pdata->irq_base + 8 + 3, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_usb() && pdata->usb) {
+
+               static struct regulator_consumer_supply usb1v5 = {
+                       .supply =       "usb1v5",
+               };
+               static struct regulator_consumer_supply usb1v8 = {
+                       .supply =       "usb1v8",
+               };
+               static struct regulator_consumer_supply usb3v1 = {
+                       .supply =       "usb3v1",
+               };
+
+       /* First add the regulators so that they can be used by transceiver */
+               if (twl_has_regulator()) {
+                       /* this is a template that gets copied */
+                       struct regulator_init_data usb_fixed = {
+                               .constraints.valid_modes_mask =
+                                       REGULATOR_MODE_NORMAL
+                                       | REGULATOR_MODE_STANDBY,
+                               .constraints.valid_ops_mask =
+                                       REGULATOR_CHANGE_MODE
+                                       | REGULATOR_CHANGE_STATUS,
+                       };
+
+                       child = add_regulator_linked(TWL4030_REG_VUSB1V5,
+                                                     &usb_fixed, &usb1v5, 1);
+                       if (IS_ERR(child))
+                               return PTR_ERR(child);
+
+                       child = add_regulator_linked(TWL4030_REG_VUSB1V8,
+                                                     &usb_fixed, &usb1v8, 1);
+                       if (IS_ERR(child))
+                               return PTR_ERR(child);
+
+                       child = add_regulator_linked(TWL4030_REG_VUSB3V1,
+                                                     &usb_fixed, &usb3v1, 1);
+                       if (IS_ERR(child))
+                               return PTR_ERR(child);
+
+               }
+
+               child = add_child(0, "twl4030_usb",
+                               pdata->usb, sizeof(*pdata->usb),
+                               true,
+                               /* irq0 = USB_PRES, irq1 = USB */
+                               pdata->irq_base + 8 + 2, pdata->irq_base + 4);
+
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               /* we need to connect regulators to this transceiver */
+               if (twl_has_regulator() && child) {
+                       usb1v5.dev = child;
+                       usb1v8.dev = child;
+                       usb3v1.dev = child;
+               }
+       }
+
+       if (twl_has_watchdog()) {
+               child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_pwrbutton()) {
+               child = add_child(1, "twl4030_pwrbutton",
+                               NULL, 0, true, pdata->irq_base + 8 + 0, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_codec() && pdata->codec) {
+               child = add_child(1, "twl4030_codec",
+                               pdata->codec, sizeof(*pdata->codec),
+                               false, 0, 0);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       if (twl_has_regulator()) {
+               child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VIO, pdata->vio);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VDAC, pdata->vdac);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator((features & TWL4030_VAUX2)
+                                       ? TWL4030_REG_VAUX2_4030
+                                       : TWL4030_REG_VAUX2,
+                               pdata->vaux2);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       /* maybe add LDOs that are omitted on cost-reduced parts */
+       if (twl_has_regulator() && !(features & TPS_SUBSET)) {
+               child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VSIM, pdata->vsim);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+
+               child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4);
+               if (IS_ERR(child))
+                       return PTR_ERR(child);
+       }
+
+       return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * These three functions initialize the on-chip clock framework,
+ * letting it generate the right frequencies for USB, MADC, and
+ * other purposes.
+ */
+static inline int __init protect_pm_master(void)
+{
+       int e = 0;
+
+       e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK,
+                       R_PROTECT_KEY);
+       return e;
+}
+
+static inline int __init unprotect_pm_master(void)
+{
+       int e = 0;
+
+       e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1,
+                       R_PROTECT_KEY);
+       e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2,
+                       R_PROTECT_KEY);
+       return e;
+}
+
+static void clocks_init(struct device *dev,
+                       struct twl4030_clock_init_data *clock)
+{
+       int e = 0;
+       struct clk *osc;
+       u32 rate;
+       u8 ctrl = HFCLK_FREQ_26_MHZ;
+
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+       if (cpu_is_omap2430())
+               osc = clk_get(dev, "osc_ck");
+       else
+               osc = clk_get(dev, "osc_sys_ck");
+
+       if (IS_ERR(osc)) {
+               printk(KERN_WARNING "Skipping twl4030 internal clock init and "
+                               "using bootloader value (unknown osc rate)\n");
+               return;
+       }
+
+       rate = clk_get_rate(osc);
+       clk_put(osc);
+
+#else
+       /* REVISIT for non-OMAP systems, pass the clock rate from
+        * board init code, using platform_data.
+        */
+       osc = ERR_PTR(-EIO);
+
+       printk(KERN_WARNING "Skipping twl4030 internal clock init and "
+              "using bootloader value (unknown osc rate)\n");
+
+       return;
+#endif
+
+       switch (rate) {
+       case 19200000:
+               ctrl = HFCLK_FREQ_19p2_MHZ;
+               break;
+       case 26000000:
+               ctrl = HFCLK_FREQ_26_MHZ;
+               break;
+       case 38400000:
+               ctrl = HFCLK_FREQ_38p4_MHZ;
+               break;
+       }
+
+       ctrl |= HIGH_PERF_SQ;
+       if (clock && clock->ck32k_lowpwr_enable)
+               ctrl |= CK32K_LOWPWR_EN;
+
+       e |= unprotect_pm_master();
+       /* effect->MADC+USB ck en */
+       e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
+       e |= protect_pm_master();
+
+       if (e < 0)
+               pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e);
+}
+
+/*----------------------------------------------------------------------*/
+
+int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
+int twl_exit_irq(void);
+int twl_init_chip_irq(const char *chip);
+
+static int twl4030_remove(struct i2c_client *client)
+{
+       unsigned i;
+       int status;
+
+       status = twl_exit_irq();
+       if (status < 0)
+               return status;
+
+       for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
+               struct twl4030_client   *twl = &twl4030_modules[i];
+
+               if (twl->client && twl->client != client)
+                       i2c_unregister_device(twl->client);
+               twl4030_modules[i].client = NULL;
+       }
+       inuse = false;
+       return 0;
+}
+
+/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
+static int __init
+twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+       int                             status;
+       unsigned                        i;
+       struct twl4030_platform_data    *pdata = client->dev.platform_data;
+
+       if (!pdata) {
+               dev_dbg(&client->dev, "no platform data?\n");
+               return -EINVAL;
+       }
+
+       if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
+               dev_dbg(&client->dev, "can't talk I2C?\n");
+               return -EIO;
+       }
+
+       if (inuse) {
+               dev_dbg(&client->dev, "driver is already in use\n");
+               return -EBUSY;
+       }
+
+       for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
+               struct twl4030_client   *twl = &twl4030_modules[i];
+
+               twl->address = client->addr + i;
+               if (i == 0)
+                       twl->client = client;
+               else {
+                       twl->client = i2c_new_dummy(client->adapter,
+                                       twl->address);
+                       if (!twl->client) {
+                               dev_err(&client->dev,
+                                       "can't attach client %d\n", i);
+                               status = -ENOMEM;
+                               goto fail;
+                       }
+               }
+               mutex_init(&twl->xfer_lock);
+       }
+       inuse = true;
+
+       /* setup clock framework */
+       clocks_init(&client->dev, pdata->clock);
+
+       /* load power event scripts */
+       if (twl_has_power() && pdata->power)
+               twl4030_power_init(pdata->power);
+
+       /* Maybe init the T2 Interrupt subsystem */
+       if (client->irq
+                       && pdata->irq_base
+                       && pdata->irq_end > pdata->irq_base) {
+               twl_init_chip_irq(id->name);
+               status = twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end);
+               if (status < 0)
+                       goto fail;
+       }
+
+       status = add_children(pdata, id->driver_data);
+fail:
+       if (status < 0)
+               twl4030_remove(client);
+       return status;
+}
+
+static const struct i2c_device_id twl4030_ids[] = {
+       { "twl4030", TWL4030_VAUX2 },   /* "Triton 2" */
+       { "twl5030", 0 },               /* T2 updated */
+       { "twl5031", TWL5031 },         /* TWL5030 updated */
+       { "tps65950", 0 },              /* catalog version of twl5030 */
+       { "tps65930", TPS_SUBSET },     /* fewer LDOs and DACs; no charger */
+       { "tps65920", TPS_SUBSET },     /* fewer LDOs; no codec or charger */
+       { /* end of list */ },
+};
+MODULE_DEVICE_TABLE(i2c, twl4030_ids);
+
+/* One Client Driver , 4 Clients */
+static struct i2c_driver twl4030_driver = {
+       .driver.name    = DRIVER_NAME,
+       .id_table       = twl4030_ids,
+       .probe          = twl4030_probe,
+       .remove         = twl4030_remove,
+};
+
+static int __init twl4030_init(void)
+{
+       return i2c_add_driver(&twl4030_driver);
+}
+subsys_initcall(twl4030_init);
+
+static void __exit twl4030_exit(void)
+{
+       i2c_del_driver(&twl4030_driver);
+}
+module_exit(twl4030_exit);
+
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("I2C Core interface for TWL4030");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
deleted file mode 100644 (file)
index 7c2ec0a..0000000
+++ /dev/null
@@ -1,929 +0,0 @@
-/*
- * twl4030_core.c - driver for TWL4030/TPS659x0 PM and audio CODEC devices
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * Modifications to defer interrupt handling to a kernel thread:
- * Copyright (C) 2006 MontaVista Software, Inc.
- *
- * Based on tlv320aic23.c:
- * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
- *
- * Code cleanup and modifications to IRQ handler.
- * by syed khasim <x0khasim@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- */
-
-#include <linux/init.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-
-#include <linux/regulator/machine.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c/twl4030.h>
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-#include <plat/cpu.h>
-#endif
-
-/*
- * The TWL4030 "Triton 2" is one of a family of a multi-function "Power
- * Management and System Companion Device" chips originally designed for
- * use in OMAP2 and OMAP 3 based systems.  Its control interfaces use I2C,
- * often at around 3 Mbit/sec, including for interrupt handling.
- *
- * This driver core provides genirq support for the interrupts emitted,
- * by the various modules, and exports register access primitives.
- *
- * FIXME this driver currently requires use of the first interrupt line
- * (and associated registers).
- */
-
-#define DRIVER_NAME                    "twl4030"
-
-#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
-       defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
-#define twl_has_bci()          true
-#else
-#define twl_has_bci()          false
-#endif
-
-#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
-#define twl_has_keypad()       true
-#else
-#define twl_has_keypad()       false
-#endif
-
-#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
-#define twl_has_gpio() true
-#else
-#define twl_has_gpio() false
-#endif
-
-#if defined(CONFIG_REGULATOR_TWL4030) \
-       || defined(CONFIG_REGULATOR_TWL4030_MODULE)
-#define twl_has_regulator()    true
-#else
-#define twl_has_regulator()    false
-#endif
-
-#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
-#define twl_has_madc() true
-#else
-#define twl_has_madc() false
-#endif
-
-#ifdef CONFIG_TWL4030_POWER
-#define twl_has_power()        true
-#else
-#define twl_has_power()        false
-#endif
-
-#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
-#define twl_has_rtc()  true
-#else
-#define twl_has_rtc()  false
-#endif
-
-#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE)
-#define twl_has_usb()  true
-#else
-#define twl_has_usb()  false
-#endif
-
-#if defined(CONFIG_TWL4030_WATCHDOG) || \
-       defined(CONFIG_TWL4030_WATCHDOG_MODULE)
-#define twl_has_watchdog()        true
-#else
-#define twl_has_watchdog()        false
-#endif
-
-#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE)
-#define twl_has_codec()        true
-#else
-#define twl_has_codec()        false
-#endif
-
-/* Triton Core internal information (BEGIN) */
-
-/* Last - for index max*/
-#define TWL4030_MODULE_LAST            TWL4030_MODULE_SECURED_REG
-
-#define TWL4030_NUM_SLAVES             4
-
-#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
-       || defined(CONFIG_INPUT_TWL4030_PWBUTTON_MODULE)
-#define twl_has_pwrbutton()    true
-#else
-#define twl_has_pwrbutton()    false
-#endif
-
-/* Base Address defns for twl4030_map[] */
-
-/* subchip/slave 0 - USB ID */
-#define TWL4030_BASEADD_USB            0x0000
-
-/* subchip/slave 1 - AUD ID */
-#define TWL4030_BASEADD_AUDIO_VOICE    0x0000
-#define TWL4030_BASEADD_GPIO           0x0098
-#define TWL4030_BASEADD_INTBR          0x0085
-#define TWL4030_BASEADD_PIH            0x0080
-#define TWL4030_BASEADD_TEST           0x004C
-
-/* subchip/slave 2 - AUX ID */
-#define TWL4030_BASEADD_INTERRUPTS     0x00B9
-#define TWL4030_BASEADD_LED            0x00EE
-#define TWL4030_BASEADD_MADC           0x0000
-#define TWL4030_BASEADD_MAIN_CHARGE    0x0074
-#define TWL4030_BASEADD_PRECHARGE      0x00AA
-#define TWL4030_BASEADD_PWM0           0x00F8
-#define TWL4030_BASEADD_PWM1           0x00FB
-#define TWL4030_BASEADD_PWMA           0x00EF
-#define TWL4030_BASEADD_PWMB           0x00F1
-#define TWL4030_BASEADD_KEYPAD         0x00D2
-
-#define TWL5031_BASEADD_ACCESSORY      0x0074 /* Replaces Main Charge */
-#define TWL5031_BASEADD_INTERRUPTS     0x00B9 /* Different than TWL4030's
-                                                 one */
-
-/* subchip/slave 3 - POWER ID */
-#define TWL4030_BASEADD_BACKUP         0x0014
-#define TWL4030_BASEADD_INT            0x002E
-#define TWL4030_BASEADD_PM_MASTER      0x0036
-#define TWL4030_BASEADD_PM_RECEIVER    0x005B
-#define TWL4030_BASEADD_RTC            0x001C
-#define TWL4030_BASEADD_SECURED_REG    0x0000
-
-/* Triton Core internal information (END) */
-
-
-/* Few power values */
-#define R_CFG_BOOT                     0x05
-#define R_PROTECT_KEY                  0x0E
-
-/* access control values for R_PROTECT_KEY */
-#define KEY_UNLOCK1                    0xce
-#define KEY_UNLOCK2                    0xec
-#define KEY_LOCK                       0x00
-
-/* some fields in R_CFG_BOOT */
-#define HFCLK_FREQ_19p2_MHZ            (1 << 0)
-#define HFCLK_FREQ_26_MHZ              (2 << 0)
-#define HFCLK_FREQ_38p4_MHZ            (3 << 0)
-#define HIGH_PERF_SQ                   (1 << 3)
-#define CK32K_LOWPWR_EN                        (1 << 7)
-
-
-/* chip-specific feature flags, for i2c_device_id.driver_data */
-#define TWL4030_VAUX2          BIT(0)  /* pre-5030 voltage ranges */
-#define TPS_SUBSET             BIT(1)  /* tps659[23]0 have fewer LDOs */
-#define TWL5031                        BIT(2)  /* twl5031 has different registers */
-
-/*----------------------------------------------------------------------*/
-
-/* is driver active, bound to a chip? */
-static bool inuse;
-
-/* Structure for each TWL4030 Slave */
-struct twl4030_client {
-       struct i2c_client *client;
-       u8 address;
-
-       /* max numb of i2c_msg required is for read =2 */
-       struct i2c_msg xfer_msg[2];
-
-       /* To lock access to xfer_msg */
-       struct mutex xfer_lock;
-};
-
-static struct twl4030_client twl4030_modules[TWL4030_NUM_SLAVES];
-
-
-/* mapping the module id to slave id and base address */
-struct twl4030mapping {
-       unsigned char sid;      /* Slave ID */
-       unsigned char base;     /* base address */
-};
-
-static struct twl4030mapping twl4030_map[TWL4030_MODULE_LAST + 1] = {
-       /*
-        * NOTE:  don't change this table without updating the
-        * <linux/i2c/twl4030.h> defines for TWL4030_MODULE_*
-        * so they continue to match the order in this table.
-        */
-
-       { 0, TWL4030_BASEADD_USB },
-
-       { 1, TWL4030_BASEADD_AUDIO_VOICE },
-       { 1, TWL4030_BASEADD_GPIO },
-       { 1, TWL4030_BASEADD_INTBR },
-       { 1, TWL4030_BASEADD_PIH },
-       { 1, TWL4030_BASEADD_TEST },
-
-       { 2, TWL4030_BASEADD_KEYPAD },
-       { 2, TWL4030_BASEADD_MADC },
-       { 2, TWL4030_BASEADD_INTERRUPTS },
-       { 2, TWL4030_BASEADD_LED },
-       { 2, TWL4030_BASEADD_MAIN_CHARGE },
-       { 2, TWL4030_BASEADD_PRECHARGE },
-       { 2, TWL4030_BASEADD_PWM0 },
-       { 2, TWL4030_BASEADD_PWM1 },
-       { 2, TWL4030_BASEADD_PWMA },
-       { 2, TWL4030_BASEADD_PWMB },
-       { 2, TWL5031_BASEADD_ACCESSORY },
-       { 2, TWL5031_BASEADD_INTERRUPTS },
-
-       { 3, TWL4030_BASEADD_BACKUP },
-       { 3, TWL4030_BASEADD_INT },
-       { 3, TWL4030_BASEADD_PM_MASTER },
-       { 3, TWL4030_BASEADD_PM_RECEIVER },
-       { 3, TWL4030_BASEADD_RTC },
-       { 3, TWL4030_BASEADD_SECURED_REG },
-};
-
-/*----------------------------------------------------------------------*/
-
-/* Exported Functions */
-
-/**
- * twl4030_i2c_write - Writes a n bit register in TWL4030
- * @mod_no: module number
- * @value: an array of num_bytes+1 containing data to write
- * @reg: register address (just offset will do)
- * @num_bytes: number of bytes to transfer
- *
- * IMPORTANT: for 'value' parameter: Allocate value num_bytes+1 and
- * valid data starts at Offset 1.
- *
- * Returns the result of operation - 0 is success
- */
-int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
-{
-       int ret;
-       int sid;
-       struct twl4030_client *twl;
-       struct i2c_msg *msg;
-
-       if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
-               pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
-               return -EPERM;
-       }
-       sid = twl4030_map[mod_no].sid;
-       twl = &twl4030_modules[sid];
-
-       if (unlikely(!inuse)) {
-               pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
-               return -EPERM;
-       }
-       mutex_lock(&twl->xfer_lock);
-       /*
-        * [MSG1]: fill the register address data
-        * fill the data Tx buffer
-        */
-       msg = &twl->xfer_msg[0];
-       msg->addr = twl->address;
-       msg->len = num_bytes + 1;
-       msg->flags = 0;
-       msg->buf = value;
-       /* over write the first byte of buffer with the register address */
-       *value = twl4030_map[mod_no].base + reg;
-       ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 1);
-       mutex_unlock(&twl->xfer_lock);
-
-       /* i2c_transfer returns number of messages transferred */
-       if (ret != 1) {
-               pr_err("%s: i2c_write failed to transfer all messages\n",
-                       DRIVER_NAME);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EIO;
-       } else {
-               return 0;
-       }
-}
-EXPORT_SYMBOL(twl4030_i2c_write);
-
-/**
- * twl4030_i2c_read - Reads a n bit register in TWL4030
- * @mod_no: module number
- * @value: an array of num_bytes containing data to be read
- * @reg: register address (just offset will do)
- * @num_bytes: number of bytes to transfer
- *
- * Returns result of operation - num_bytes is success else failure.
- */
-int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
-{
-       int ret;
-       u8 val;
-       int sid;
-       struct twl4030_client *twl;
-       struct i2c_msg *msg;
-
-       if (unlikely(mod_no > TWL4030_MODULE_LAST)) {
-               pr_err("%s: invalid module number %d\n", DRIVER_NAME, mod_no);
-               return -EPERM;
-       }
-       sid = twl4030_map[mod_no].sid;
-       twl = &twl4030_modules[sid];
-
-       if (unlikely(!inuse)) {
-               pr_err("%s: client %d is not initialized\n", DRIVER_NAME, sid);
-               return -EPERM;
-       }
-       mutex_lock(&twl->xfer_lock);
-       /* [MSG1] fill the register address data */
-       msg = &twl->xfer_msg[0];
-       msg->addr = twl->address;
-       msg->len = 1;
-       msg->flags = 0; /* Read the register value */
-       val = twl4030_map[mod_no].base + reg;
-       msg->buf = &val;
-       /* [MSG2] fill the data rx buffer */
-       msg = &twl->xfer_msg[1];
-       msg->addr = twl->address;
-       msg->flags = I2C_M_RD;  /* Read the register value */
-       msg->len = num_bytes;   /* only n bytes */
-       msg->buf = value;
-       ret = i2c_transfer(twl->client->adapter, twl->xfer_msg, 2);
-       mutex_unlock(&twl->xfer_lock);
-
-       /* i2c_transfer returns number of messages transferred */
-       if (ret != 2) {
-               pr_err("%s: i2c_read failed to transfer all messages\n",
-                       DRIVER_NAME);
-               if (ret < 0)
-                       return ret;
-               else
-                       return -EIO;
-       } else {
-               return 0;
-       }
-}
-EXPORT_SYMBOL(twl4030_i2c_read);
-
-/**
- * twl4030_i2c_write_u8 - Writes a 8 bit register in TWL4030
- * @mod_no: module number
- * @value: the value to be written 8 bit
- * @reg: register address (just offset will do)
- *
- * Returns result of operation - 0 is success
- */
-int twl4030_i2c_write_u8(u8 mod_no, u8 value, u8 reg)
-{
-
-       /* 2 bytes offset 1 contains the data offset 0 is used by i2c_write */
-       u8 temp_buffer[2] = { 0 };
-       /* offset 1 contains the data */
-       temp_buffer[1] = value;
-       return twl4030_i2c_write(mod_no, temp_buffer, reg, 1);
-}
-EXPORT_SYMBOL(twl4030_i2c_write_u8);
-
-/**
- * twl4030_i2c_read_u8 - Reads a 8 bit register from TWL4030
- * @mod_no: module number
- * @value: the value read 8 bit
- * @reg: register address (just offset will do)
- *
- * Returns result of operation - 0 is success
- */
-int twl4030_i2c_read_u8(u8 mod_no, u8 *value, u8 reg)
-{
-       return twl4030_i2c_read(mod_no, value, reg, 1);
-}
-EXPORT_SYMBOL(twl4030_i2c_read_u8);
-
-/*----------------------------------------------------------------------*/
-
-static struct device *
-add_numbered_child(unsigned chip, const char *name, int num,
-               void *pdata, unsigned pdata_len,
-               bool can_wakeup, int irq0, int irq1)
-{
-       struct platform_device  *pdev;
-       struct twl4030_client   *twl = &twl4030_modules[chip];
-       int                     status;
-
-       pdev = platform_device_alloc(name, num);
-       if (!pdev) {
-               dev_dbg(&twl->client->dev, "can't alloc dev\n");
-               status = -ENOMEM;
-               goto err;
-       }
-
-       device_init_wakeup(&pdev->dev, can_wakeup);
-       pdev->dev.parent = &twl->client->dev;
-
-       if (pdata) {
-               status = platform_device_add_data(pdev, pdata, pdata_len);
-               if (status < 0) {
-                       dev_dbg(&pdev->dev, "can't add platform_data\n");
-                       goto err;
-               }
-       }
-
-       if (irq0) {
-               struct resource r[2] = {
-                       { .start = irq0, .flags = IORESOURCE_IRQ, },
-                       { .start = irq1, .flags = IORESOURCE_IRQ, },
-               };
-
-               status = platform_device_add_resources(pdev, r, irq1 ? 2 : 1);
-               if (status < 0) {
-                       dev_dbg(&pdev->dev, "can't add irqs\n");
-                       goto err;
-               }
-       }
-
-       status = platform_device_add(pdev);
-
-err:
-       if (status < 0) {
-               platform_device_put(pdev);
-               dev_err(&twl->client->dev, "can't add %s dev\n", name);
-               return ERR_PTR(status);
-       }
-       return &pdev->dev;
-}
-
-static inline struct device *add_child(unsigned chip, const char *name,
-               void *pdata, unsigned pdata_len,
-               bool can_wakeup, int irq0, int irq1)
-{
-       return add_numbered_child(chip, name, -1, pdata, pdata_len,
-               can_wakeup, irq0, irq1);
-}
-
-static struct device *
-add_regulator_linked(int num, struct regulator_init_data *pdata,
-               struct regulator_consumer_supply *consumers,
-               unsigned num_consumers)
-{
-       /* regulator framework demands init_data ... */
-       if (!pdata)
-               return NULL;
-
-       if (consumers) {
-               pdata->consumer_supplies = consumers;
-               pdata->num_consumer_supplies = num_consumers;
-       }
-
-       /* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
-       return add_numbered_child(3, "twl4030_reg", num,
-               pdata, sizeof(*pdata), false, 0, 0);
-}
-
-static struct device *
-add_regulator(int num, struct regulator_init_data *pdata)
-{
-       return add_regulator_linked(num, pdata, NULL, 0);
-}
-
-/*
- * NOTE:  We know the first 8 IRQs after pdata->base_irq are
- * for the PIH, and the next are for the PWR_INT SIH, since
- * that's how twl_init_irq() sets things up.
- */
-
-static int
-add_children(struct twl4030_platform_data *pdata, unsigned long features)
-{
-       struct device   *child;
-
-       if (twl_has_bci() && pdata->bci &&
-           !(features & (TPS_SUBSET | TWL5031))) {
-               child = add_child(3, "twl4030_bci",
-                               pdata->bci, sizeof(*pdata->bci),
-                               false,
-                               /* irq0 = CHG_PRES, irq1 = BCI */
-                               pdata->irq_base + 8 + 1, pdata->irq_base + 2);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_gpio() && pdata->gpio) {
-               child = add_child(1, "twl4030_gpio",
-                               pdata->gpio, sizeof(*pdata->gpio),
-                               false, pdata->irq_base + 0, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_keypad() && pdata->keypad) {
-               child = add_child(2, "twl4030_keypad",
-                               pdata->keypad, sizeof(*pdata->keypad),
-                               true, pdata->irq_base + 1, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_madc() && pdata->madc) {
-               child = add_child(2, "twl4030_madc",
-                               pdata->madc, sizeof(*pdata->madc),
-                               true, pdata->irq_base + 3, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_rtc()) {
-               /*
-                * REVISIT platform_data here currently might expose the
-                * "msecure" line ... but for now we just expect board
-                * setup to tell the chip "it's always ok to SET_TIME".
-                * Eventually, Linux might become more aware of such
-                * HW security concerns, and "least privilege".
-                */
-               child = add_child(3, "twl4030_rtc",
-                               NULL, 0,
-                               true, pdata->irq_base + 8 + 3, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_usb() && pdata->usb) {
-
-               static struct regulator_consumer_supply usb1v5 = {
-                       .supply =       "usb1v5",
-               };
-               static struct regulator_consumer_supply usb1v8 = {
-                       .supply =       "usb1v8",
-               };
-               static struct regulator_consumer_supply usb3v1 = {
-                       .supply =       "usb3v1",
-               };
-
-       /* First add the regulators so that they can be used by transceiver */
-               if (twl_has_regulator()) {
-                       /* this is a template that gets copied */
-                       struct regulator_init_data usb_fixed = {
-                               .constraints.valid_modes_mask =
-                                       REGULATOR_MODE_NORMAL
-                                       | REGULATOR_MODE_STANDBY,
-                               .constraints.valid_ops_mask =
-                                       REGULATOR_CHANGE_MODE
-                                       | REGULATOR_CHANGE_STATUS,
-                       };
-
-                       child = add_regulator_linked(TWL4030_REG_VUSB1V5,
-                                                     &usb_fixed, &usb1v5, 1);
-                       if (IS_ERR(child))
-                               return PTR_ERR(child);
-
-                       child = add_regulator_linked(TWL4030_REG_VUSB1V8,
-                                                     &usb_fixed, &usb1v8, 1);
-                       if (IS_ERR(child))
-                               return PTR_ERR(child);
-
-                       child = add_regulator_linked(TWL4030_REG_VUSB3V1,
-                                                     &usb_fixed, &usb3v1, 1);
-                       if (IS_ERR(child))
-                               return PTR_ERR(child);
-
-               }
-
-               child = add_child(0, "twl4030_usb",
-                               pdata->usb, sizeof(*pdata->usb),
-                               true,
-                               /* irq0 = USB_PRES, irq1 = USB */
-                               pdata->irq_base + 8 + 2, pdata->irq_base + 4);
-
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               /* we need to connect regulators to this transceiver */
-               if (twl_has_regulator() && child) {
-                       usb1v5.dev = child;
-                       usb1v8.dev = child;
-                       usb3v1.dev = child;
-               }
-       }
-
-       if (twl_has_watchdog()) {
-               child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_pwrbutton()) {
-               child = add_child(1, "twl4030_pwrbutton",
-                               NULL, 0, true, pdata->irq_base + 8 + 0, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_codec() && pdata->codec) {
-               child = add_child(1, "twl4030_codec",
-                               pdata->codec, sizeof(*pdata->codec),
-                               false, 0, 0);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       if (twl_has_regulator()) {
-               child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VIO, pdata->vio);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VDAC, pdata->vdac);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator((features & TWL4030_VAUX2)
-                                       ? TWL4030_REG_VAUX2_4030
-                                       : TWL4030_REG_VAUX2,
-                               pdata->vaux2);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       /* maybe add LDOs that are omitted on cost-reduced parts */
-       if (twl_has_regulator() && !(features & TPS_SUBSET)) {
-               child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VSIM, pdata->vsim);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-
-               child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4);
-               if (IS_ERR(child))
-                       return PTR_ERR(child);
-       }
-
-       return 0;
-}
-
-/*----------------------------------------------------------------------*/
-
-/*
- * These three functions initialize the on-chip clock framework,
- * letting it generate the right frequencies for USB, MADC, and
- * other purposes.
- */
-static inline int __init protect_pm_master(void)
-{
-       int e = 0;
-
-       e = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_LOCK,
-                       R_PROTECT_KEY);
-       return e;
-}
-
-static inline int __init unprotect_pm_master(void)
-{
-       int e = 0;
-
-       e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK1,
-                       R_PROTECT_KEY);
-       e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, KEY_UNLOCK2,
-                       R_PROTECT_KEY);
-       return e;
-}
-
-static void clocks_init(struct device *dev,
-                       struct twl4030_clock_init_data *clock)
-{
-       int e = 0;
-       struct clk *osc;
-       u32 rate;
-       u8 ctrl = HFCLK_FREQ_26_MHZ;
-
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-       if (cpu_is_omap2430())
-               osc = clk_get(dev, "osc_ck");
-       else
-               osc = clk_get(dev, "osc_sys_ck");
-
-       if (IS_ERR(osc)) {
-               printk(KERN_WARNING "Skipping twl4030 internal clock init and "
-                               "using bootloader value (unknown osc rate)\n");
-               return;
-       }
-
-       rate = clk_get_rate(osc);
-       clk_put(osc);
-
-#else
-       /* REVISIT for non-OMAP systems, pass the clock rate from
-        * board init code, using platform_data.
-        */
-       osc = ERR_PTR(-EIO);
-
-       printk(KERN_WARNING "Skipping twl4030 internal clock init and "
-              "using bootloader value (unknown osc rate)\n");
-
-       return;
-#endif
-
-       switch (rate) {
-       case 19200000:
-               ctrl = HFCLK_FREQ_19p2_MHZ;
-               break;
-       case 26000000:
-               ctrl = HFCLK_FREQ_26_MHZ;
-               break;
-       case 38400000:
-               ctrl = HFCLK_FREQ_38p4_MHZ;
-               break;
-       }
-
-       ctrl |= HIGH_PERF_SQ;
-       if (clock && clock->ck32k_lowpwr_enable)
-               ctrl |= CK32K_LOWPWR_EN;
-
-       e |= unprotect_pm_master();
-       /* effect->MADC+USB ck en */
-       e |= twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, ctrl, R_CFG_BOOT);
-       e |= protect_pm_master();
-
-       if (e < 0)
-               pr_err("%s: clock init err [%d]\n", DRIVER_NAME, e);
-}
-
-/*----------------------------------------------------------------------*/
-
-int twl_init_irq(int irq_num, unsigned irq_base, unsigned irq_end);
-int twl_exit_irq(void);
-int twl_init_chip_irq(const char *chip);
-
-static int twl4030_remove(struct i2c_client *client)
-{
-       unsigned i;
-       int status;
-
-       status = twl_exit_irq();
-       if (status < 0)
-               return status;
-
-       for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
-               struct twl4030_client   *twl = &twl4030_modules[i];
-
-               if (twl->client && twl->client != client)
-                       i2c_unregister_device(twl->client);
-               twl4030_modules[i].client = NULL;
-       }
-       inuse = false;
-       return 0;
-}
-
-/* NOTE:  this driver only handles a single twl4030/tps659x0 chip */
-static int __init
-twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
-       int                             status;
-       unsigned                        i;
-       struct twl4030_platform_data    *pdata = client->dev.platform_data;
-
-       if (!pdata) {
-               dev_dbg(&client->dev, "no platform data?\n");
-               return -EINVAL;
-       }
-
-       if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
-               dev_dbg(&client->dev, "can't talk I2C?\n");
-               return -EIO;
-       }
-
-       if (inuse) {
-               dev_dbg(&client->dev, "driver is already in use\n");
-               return -EBUSY;
-       }
-
-       for (i = 0; i < TWL4030_NUM_SLAVES; i++) {
-               struct twl4030_client   *twl = &twl4030_modules[i];
-
-               twl->address = client->addr + i;
-               if (i == 0)
-                       twl->client = client;
-               else {
-                       twl->client = i2c_new_dummy(client->adapter,
-                                       twl->address);
-                       if (!twl->client) {
-                               dev_err(&client->dev,
-                                       "can't attach client %d\n", i);
-                               status = -ENOMEM;
-                               goto fail;
-                       }
-               }
-               mutex_init(&twl->xfer_lock);
-       }
-       inuse = true;
-
-       /* setup clock framework */
-       clocks_init(&client->dev, pdata->clock);
-
-       /* load power event scripts */
-       if (twl_has_power() && pdata->power)
-               twl4030_power_init(pdata->power);
-
-       /* Maybe init the T2 Interrupt subsystem */
-       if (client->irq
-                       && pdata->irq_base
-                       && pdata->irq_end > pdata->irq_base) {
-               twl_init_chip_irq(id->name);
-               status = twl_init_irq(client->irq, pdata->irq_base, pdata->irq_end);
-               if (status < 0)
-                       goto fail;
-       }
-
-       status = add_children(pdata, id->driver_data);
-fail:
-       if (status < 0)
-               twl4030_remove(client);
-       return status;
-}
-
-static const struct i2c_device_id twl4030_ids[] = {
-       { "twl4030", TWL4030_VAUX2 },   /* "Triton 2" */
-       { "twl5030", 0 },               /* T2 updated */
-       { "twl5031", TWL5031 },         /* TWL5030 updated */
-       { "tps65950", 0 },              /* catalog version of twl5030 */
-       { "tps65930", TPS_SUBSET },     /* fewer LDOs and DACs; no charger */
-       { "tps65920", TPS_SUBSET },     /* fewer LDOs; no codec or charger */
-       { /* end of list */ },
-};
-MODULE_DEVICE_TABLE(i2c, twl4030_ids);
-
-/* One Client Driver , 4 Clients */
-static struct i2c_driver twl4030_driver = {
-       .driver.name    = DRIVER_NAME,
-       .id_table       = twl4030_ids,
-       .probe          = twl4030_probe,
-       .remove         = twl4030_remove,
-};
-
-static int __init twl4030_init(void)
-{
-       return i2c_add_driver(&twl4030_driver);
-}
-subsys_initcall(twl4030_init);
-
-static void __exit twl4030_exit(void)
-{
-       i2c_del_driver(&twl4030_driver);
-}
-module_exit(twl4030_exit);
-
-MODULE_AUTHOR("Texas Instruments, Inc.");
-MODULE_DESCRIPTION("I2C Core interface for TWL4030");
-MODULE_LICENSE("GPL");
index 3f7e93ca05147deabecc389d0085cd18de80c4e8..c4528db549c639d55edd4bdf6fe6c3ff72406caf 100644 (file)
@@ -32,7 +32,7 @@
 #include <linux/irq.h>
 #include <linux/kthread.h>
 
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 
 /*
index 3048f18e0419277facb1da4994a81355399a89a9..424b255d6f92902fadd7a906b32cac7fd6df9a43 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <linux/module.h>
 #include <linux/pm.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/platform_device.h>
 
 #include <asm/mach-types.h>
index 4257a868377803b0359f49af864fb3b4ad014d57..9ae3cc44e668d97dacaecee4489322de94f8d56e 100644 (file)
@@ -11,7 +11,7 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
 obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
 obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
-obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
 obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
new file mode 100644 (file)
index 0000000..c8a6e58
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * twl4030-regulator.c -- support regulators in twl4030 family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl.h>
+
+
+/*
+ * The TWL4030/TW5030/TPS659x0 family chips include power management, a
+ * USB OTG transceiver, an RTC, ADC, PWM, and lots more.  Some versions
+ * include an audio codec, battery charger, and more voltage regulators.
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators.  This is usually augmented with state machine
+ * based control.
+ */
+
+struct twlreg_info {
+       /* start of regulator's PM_RECEIVER control register bank */
+       u8                      base;
+
+       /* twl4030 resource ID, for resource control state machine */
+       u8                      id;
+
+       /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
+       u8                      table_len;
+       const u16               *table;
+
+       /* chip constraints on regulator behavior */
+       u16                     min_mV;
+
+       /* used by regulator core */
+       struct regulator_desc   desc;
+};
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+#define VREG_GRP               0
+#define VREG_TYPE              1
+#define VREG_REMAP             2
+#define VREG_DEDICATED         3       /* LDO control */
+
+
+static inline int
+twl4030reg_read(struct twlreg_info *info, unsigned offset)
+{
+       u8 value;
+       int status;
+
+       status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
+                       &value, info->base + offset);
+       return (status < 0) ? status : value;
+}
+
+static inline int
+twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
+{
+       return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+                       value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* generic power resource operations, which work on all regulators */
+
+static int twl4030reg_grp(struct regulator_dev *rdev)
+{
+       return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
+}
+
+/*
+ * Enable/disable regulators by joining/leaving the P1 (processor) group.
+ * We assume nobody else is updating the DEV_GRP registers.
+ */
+
+#define P3_GRP         BIT(7)          /* "peripherals" */
+#define P2_GRP         BIT(6)          /* secondary processor, modem, etc */
+#define P1_GRP         BIT(5)          /* CPU/Linux */
+
+static int twl4030reg_is_enabled(struct regulator_dev *rdev)
+{
+       int     state = twl4030reg_grp(rdev);
+
+       if (state < 0)
+               return state;
+
+       return (state & P1_GRP) != 0;
+}
+
+static int twl4030reg_enable(struct regulator_dev *rdev)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+       int                     grp;
+
+       grp = twl4030reg_read(info, VREG_GRP);
+       if (grp < 0)
+               return grp;
+
+       grp |= P1_GRP;
+       return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_disable(struct regulator_dev *rdev)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+       int                     grp;
+
+       grp = twl4030reg_read(info, VREG_GRP);
+       if (grp < 0)
+               return grp;
+
+       grp &= ~P1_GRP;
+       return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_get_status(struct regulator_dev *rdev)
+{
+       int     state = twl4030reg_grp(rdev);
+
+       if (state < 0)
+               return state;
+       state &= 0x0f;
+
+       /* assume state != WARM_RESET; we'd not be running...  */
+       if (!state)
+               return REGULATOR_STATUS_OFF;
+       return (state & BIT(3))
+               ? REGULATOR_STATUS_NORMAL
+               : REGULATOR_STATUS_STANDBY;
+}
+
+static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+       unsigned                message;
+       int                     status;
+
+       /* We can only set the mode through state machine commands... */
+       switch (mode) {
+       case REGULATOR_MODE_NORMAL:
+               message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
+               break;
+       case REGULATOR_MODE_STANDBY:
+               message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Ensure the resource is associated with some group */
+       status = twl4030reg_grp(rdev);
+       if (status < 0)
+               return status;
+       if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
+               return -EACCES;
+
+       status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+                       message >> 8, 0x15 /* PB_WORD_MSB */ );
+       if (status >= 0)
+               return status;
+
+       return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+                       message, 0x16 /* PB_WORD_LSB */ );
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
+ * select field in its control register.   We use tables indexed by VSEL
+ * to record voltages in milliVolts.  (Accuracy is about three percent.)
+ *
+ * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
+ * currently handled by listing two slightly different VAUX2 regulators,
+ * only one of which will be configured.
+ *
+ * VSEL values documented as "TI cannot support these values" are flagged
+ * in these tables as UNSUP() values; we normally won't assign them.
+ *
+ * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
+ * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
+ */
+#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#define UNSUP_MASK     0x0000
+#else
+#define UNSUP_MASK     0x8000
+#endif
+
+#define UNSUP(x)       (UNSUP_MASK | (x))
+#define IS_UNSUP(x)    (UNSUP_MASK & (x))
+#define LDO_MV(x)      (~UNSUP_MASK & (x))
+
+
+static const u16 VAUX1_VSEL_table[] = {
+       UNSUP(1500), UNSUP(1800), 2500, 2800,
+       3000, 3000, 3000, 3000,
+};
+static const u16 VAUX2_4030_VSEL_table[] = {
+       UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
+       1500, 1800, UNSUP(1850), 2500,
+       UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+       UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VAUX2_VSEL_table[] = {
+       1700, 1700, 1900, 1300,
+       1500, 1800, 2000, 2500,
+       2100, 2800, 2200, 2300,
+       2400, 2400, 2400, 2400,
+};
+static const u16 VAUX3_VSEL_table[] = {
+       1500, 1800, 2500, 2800,
+       3000, 3000, 3000, 3000,
+};
+static const u16 VAUX4_VSEL_table[] = {
+       700, 1000, 1200, UNSUP(1300),
+       1500, 1800, UNSUP(1850), 2500,
+       UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+       UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VMMC1_VSEL_table[] = {
+       1850, 2850, 3000, 3150,
+};
+static const u16 VMMC2_VSEL_table[] = {
+       UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
+       UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
+       2600, 2800, 2850, 3000,
+       3150, 3150, 3150, 3150,
+};
+static const u16 VPLL1_VSEL_table[] = {
+       1000, 1200, 1300, 1800,
+       UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
+};
+static const u16 VPLL2_VSEL_table[] = {
+       700, 1000, 1200, 1300,
+       UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
+       UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
+       UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VSIM_VSEL_table[] = {
+       UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
+       2800, 3000, 3000, 3000,
+};
+static const u16 VDAC_VSEL_table[] = {
+       1200, 1300, 1800, 1800,
+};
+
+
+static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+       int                     mV = info->table[index];
+
+       return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
+}
+
+static int
+twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+       int                     vsel;
+
+       for (vsel = 0; vsel < info->table_len; vsel++) {
+               int mV = info->table[vsel];
+               int uV;
+
+               if (IS_UNSUP(mV))
+                       continue;
+               uV = LDO_MV(mV) * 1000;
+
+               /* REVISIT for VAUX2, first match may not be best/lowest */
+
+               /* use the first in-range value */
+               if (min_uV <= uV && uV <= max_uV)
+                       return twl4030reg_write(info, VREG_DEDICATED, vsel);
+       }
+
+       return -EDOM;
+}
+
+static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+       int                     vsel = twl4030reg_read(info, VREG_DEDICATED);
+
+       if (vsel < 0)
+               return vsel;
+
+       vsel &= info->table_len - 1;
+       return LDO_MV(info->table[vsel]) * 1000;
+}
+
+static struct regulator_ops twl4030ldo_ops = {
+       .list_voltage   = twl4030ldo_list_voltage,
+
+       .set_voltage    = twl4030ldo_set_voltage,
+       .get_voltage    = twl4030ldo_get_voltage,
+
+       .enable         = twl4030reg_enable,
+       .disable        = twl4030reg_disable,
+       .is_enabled     = twl4030reg_is_enabled,
+
+       .set_mode       = twl4030reg_set_mode,
+
+       .get_status     = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Fixed voltage LDOs don't have a VSEL field to update.
+ */
+static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+
+       return info->min_mV * 1000;
+}
+
+static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
+{
+       struct twlreg_info      *info = rdev_get_drvdata(rdev);
+
+       return info->min_mV * 1000;
+}
+
+static struct regulator_ops twl4030fixed_ops = {
+       .list_voltage   = twl4030fixed_list_voltage,
+
+       .get_voltage    = twl4030fixed_get_voltage,
+
+       .enable         = twl4030reg_enable,
+       .disable        = twl4030reg_disable,
+       .is_enabled     = twl4030reg_is_enabled,
+
+       .set_mode       = twl4030reg_set_mode,
+
+       .get_status     = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
+       .base = offset, \
+       .id = num, \
+       .table_len = ARRAY_SIZE(label##_VSEL_table), \
+       .table = label##_VSEL_table, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL4030_REG_##label, \
+               .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
+               .ops = &twl4030ldo_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
+#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
+       .base = offset, \
+       .id = num, \
+       .min_mV = mVolts, \
+       .desc = { \
+               .name = #label, \
+               .id = TWL4030_REG_##label, \
+               .n_voltages = 1, \
+               .ops = &twl4030fixed_ops, \
+               .type = REGULATOR_VOLTAGE, \
+               .owner = THIS_MODULE, \
+               }, \
+       }
+
+/*
+ * We list regulators here if systems need some level of
+ * software control over them after boot.
+ */
+static struct twlreg_info twl4030_regs[] = {
+       TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
+       TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
+       TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
+       TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
+       TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
+       TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
+       TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
+       /*
+       TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
+       */
+       TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
+       TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
+       TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
+       /*
+       TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
+       TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
+       TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
+       TWL_SMPS(VIO, 0x4b, 14),
+       TWL_SMPS(VDD1, 0x55, 15),
+       TWL_SMPS(VDD2, 0x63, 16),
+        */
+       TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
+       TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
+       TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
+       /* VUSBCP is managed *only* by the USB subchip */
+};
+
+static int twl4030reg_probe(struct platform_device *pdev)
+{
+       int                             i;
+       struct twlreg_info              *info;
+       struct regulator_init_data      *initdata;
+       struct regulation_constraints   *c;
+       struct regulator_dev            *rdev;
+
+       for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
+               if (twl4030_regs[i].desc.id != pdev->id)
+                       continue;
+               info = twl4030_regs + i;
+               break;
+       }
+       if (!info)
+               return -ENODEV;
+
+       initdata = pdev->dev.platform_data;
+       if (!initdata)
+               return -EINVAL;
+
+       /* Constrain board-specific capabilities according to what
+        * this driver and the chip itself can actually do.
+        */
+       c = &initdata->constraints;
+       c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
+       c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
+                               | REGULATOR_CHANGE_MODE
+                               | REGULATOR_CHANGE_STATUS;
+
+       rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+       if (IS_ERR(rdev)) {
+               dev_err(&pdev->dev, "can't register %s, %ld\n",
+                               info->desc.name, PTR_ERR(rdev));
+               return PTR_ERR(rdev);
+       }
+       platform_set_drvdata(pdev, rdev);
+
+       /* NOTE:  many regulators support short-circuit IRQs (presentable
+        * as REGULATOR_OVER_CURRENT notifications?) configured via:
+        *  - SC_CONFIG
+        *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
+        *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
+        *  - IT_CONFIG
+        */
+
+       return 0;
+}
+
+static int __devexit twl4030reg_remove(struct platform_device *pdev)
+{
+       regulator_unregister(platform_get_drvdata(pdev));
+       return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_reg");
+
+static struct platform_driver twl4030reg_driver = {
+       .probe          = twl4030reg_probe,
+       .remove         = __devexit_p(twl4030reg_remove),
+       /* NOTE: short name, to work around driver model truncation of
+        * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
+        */
+       .driver.name    = "twl4030_reg",
+       .driver.owner   = THIS_MODULE,
+};
+
+static int __init twl4030reg_init(void)
+{
+       return platform_driver_register(&twl4030reg_driver);
+}
+subsys_initcall(twl4030reg_init);
+
+static void __exit twl4030reg_exit(void)
+{
+       platform_driver_unregister(&twl4030reg_driver);
+}
+module_exit(twl4030reg_exit)
+
+MODULE_DESCRIPTION("TWL4030 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl4030-regulator.c
deleted file mode 100644 (file)
index e2032fb..0000000
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * twl4030-regulator.c -- support regulators in twl4030 family chips
- *
- * Copyright (C) 2008 David Brownell
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/machine.h>
-#include <linux/i2c/twl4030.h>
-
-
-/*
- * The TWL4030/TW5030/TPS659x0 family chips include power management, a
- * USB OTG transceiver, an RTC, ADC, PWM, and lots more.  Some versions
- * include an audio codec, battery charger, and more voltage regulators.
- * These chips are often used in OMAP-based systems.
- *
- * This driver implements software-based resource control for various
- * voltage regulators.  This is usually augmented with state machine
- * based control.
- */
-
-struct twlreg_info {
-       /* start of regulator's PM_RECEIVER control register bank */
-       u8                      base;
-
-       /* twl4030 resource ID, for resource control state machine */
-       u8                      id;
-
-       /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
-       u8                      table_len;
-       const u16               *table;
-
-       /* chip constraints on regulator behavior */
-       u16                     min_mV;
-
-       /* used by regulator core */
-       struct regulator_desc   desc;
-};
-
-
-/* LDO control registers ... offset is from the base of its register bank.
- * The first three registers of all power resource banks help hardware to
- * manage the various resource groups.
- */
-#define VREG_GRP               0
-#define VREG_TYPE              1
-#define VREG_REMAP             2
-#define VREG_DEDICATED         3       /* LDO control */
-
-
-static inline int
-twl4030reg_read(struct twlreg_info *info, unsigned offset)
-{
-       u8 value;
-       int status;
-
-       status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
-                       &value, info->base + offset);
-       return (status < 0) ? status : value;
-}
-
-static inline int
-twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
-{
-       return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
-                       value, info->base + offset);
-}
-
-/*----------------------------------------------------------------------*/
-
-/* generic power resource operations, which work on all regulators */
-
-static int twl4030reg_grp(struct regulator_dev *rdev)
-{
-       return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
-}
-
-/*
- * Enable/disable regulators by joining/leaving the P1 (processor) group.
- * We assume nobody else is updating the DEV_GRP registers.
- */
-
-#define P3_GRP         BIT(7)          /* "peripherals" */
-#define P2_GRP         BIT(6)          /* secondary processor, modem, etc */
-#define P1_GRP         BIT(5)          /* CPU/Linux */
-
-static int twl4030reg_is_enabled(struct regulator_dev *rdev)
-{
-       int     state = twl4030reg_grp(rdev);
-
-       if (state < 0)
-               return state;
-
-       return (state & P1_GRP) != 0;
-}
-
-static int twl4030reg_enable(struct regulator_dev *rdev)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int                     grp;
-
-       grp = twl4030reg_read(info, VREG_GRP);
-       if (grp < 0)
-               return grp;
-
-       grp |= P1_GRP;
-       return twl4030reg_write(info, VREG_GRP, grp);
-}
-
-static int twl4030reg_disable(struct regulator_dev *rdev)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int                     grp;
-
-       grp = twl4030reg_read(info, VREG_GRP);
-       if (grp < 0)
-               return grp;
-
-       grp &= ~P1_GRP;
-       return twl4030reg_write(info, VREG_GRP, grp);
-}
-
-static int twl4030reg_get_status(struct regulator_dev *rdev)
-{
-       int     state = twl4030reg_grp(rdev);
-
-       if (state < 0)
-               return state;
-       state &= 0x0f;
-
-       /* assume state != WARM_RESET; we'd not be running...  */
-       if (!state)
-               return REGULATOR_STATUS_OFF;
-       return (state & BIT(3))
-               ? REGULATOR_STATUS_NORMAL
-               : REGULATOR_STATUS_STANDBY;
-}
-
-static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       unsigned                message;
-       int                     status;
-
-       /* We can only set the mode through state machine commands... */
-       switch (mode) {
-       case REGULATOR_MODE_NORMAL:
-               message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
-               break;
-       case REGULATOR_MODE_STANDBY:
-               message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Ensure the resource is associated with some group */
-       status = twl4030reg_grp(rdev);
-       if (status < 0)
-               return status;
-       if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
-               return -EACCES;
-
-       status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       message >> 8, 0x15 /* PB_WORD_MSB */ );
-       if (status >= 0)
-               return status;
-
-       return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
-                       message, 0x16 /* PB_WORD_LSB */ );
-}
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
- * select field in its control register.   We use tables indexed by VSEL
- * to record voltages in milliVolts.  (Accuracy is about three percent.)
- *
- * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
- * currently handled by listing two slightly different VAUX2 regulators,
- * only one of which will be configured.
- *
- * VSEL values documented as "TI cannot support these values" are flagged
- * in these tables as UNSUP() values; we normally won't assign them.
- *
- * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
- * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
- */
-#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
-#define UNSUP_MASK     0x0000
-#else
-#define UNSUP_MASK     0x8000
-#endif
-
-#define UNSUP(x)       (UNSUP_MASK | (x))
-#define IS_UNSUP(x)    (UNSUP_MASK & (x))
-#define LDO_MV(x)      (~UNSUP_MASK & (x))
-
-
-static const u16 VAUX1_VSEL_table[] = {
-       UNSUP(1500), UNSUP(1800), 2500, 2800,
-       3000, 3000, 3000, 3000,
-};
-static const u16 VAUX2_4030_VSEL_table[] = {
-       UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
-       1500, 1800, UNSUP(1850), 2500,
-       UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
-       UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
-};
-static const u16 VAUX2_VSEL_table[] = {
-       1700, 1700, 1900, 1300,
-       1500, 1800, 2000, 2500,
-       2100, 2800, 2200, 2300,
-       2400, 2400, 2400, 2400,
-};
-static const u16 VAUX3_VSEL_table[] = {
-       1500, 1800, 2500, 2800,
-       3000, 3000, 3000, 3000,
-};
-static const u16 VAUX4_VSEL_table[] = {
-       700, 1000, 1200, UNSUP(1300),
-       1500, 1800, UNSUP(1850), 2500,
-       UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
-       UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
-};
-static const u16 VMMC1_VSEL_table[] = {
-       1850, 2850, 3000, 3150,
-};
-static const u16 VMMC2_VSEL_table[] = {
-       UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
-       UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
-       2600, 2800, 2850, 3000,
-       3150, 3150, 3150, 3150,
-};
-static const u16 VPLL1_VSEL_table[] = {
-       1000, 1200, 1300, 1800,
-       UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
-};
-static const u16 VPLL2_VSEL_table[] = {
-       700, 1000, 1200, 1300,
-       UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
-       UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
-       UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
-};
-static const u16 VSIM_VSEL_table[] = {
-       UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
-       2800, 3000, 3000, 3000,
-};
-static const u16 VDAC_VSEL_table[] = {
-       1200, 1300, 1800, 1800,
-};
-
-
-static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int                     mV = info->table[index];
-
-       return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
-}
-
-static int
-twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int                     vsel;
-
-       for (vsel = 0; vsel < info->table_len; vsel++) {
-               int mV = info->table[vsel];
-               int uV;
-
-               if (IS_UNSUP(mV))
-                       continue;
-               uV = LDO_MV(mV) * 1000;
-
-               /* REVISIT for VAUX2, first match may not be best/lowest */
-
-               /* use the first in-range value */
-               if (min_uV <= uV && uV <= max_uV)
-                       return twl4030reg_write(info, VREG_DEDICATED, vsel);
-       }
-
-       return -EDOM;
-}
-
-static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-       int                     vsel = twl4030reg_read(info, VREG_DEDICATED);
-
-       if (vsel < 0)
-               return vsel;
-
-       vsel &= info->table_len - 1;
-       return LDO_MV(info->table[vsel]) * 1000;
-}
-
-static struct regulator_ops twl4030ldo_ops = {
-       .list_voltage   = twl4030ldo_list_voltage,
-
-       .set_voltage    = twl4030ldo_set_voltage,
-       .get_voltage    = twl4030ldo_get_voltage,
-
-       .enable         = twl4030reg_enable,
-       .disable        = twl4030reg_disable,
-       .is_enabled     = twl4030reg_is_enabled,
-
-       .set_mode       = twl4030reg_set_mode,
-
-       .get_status     = twl4030reg_get_status,
-};
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Fixed voltage LDOs don't have a VSEL field to update.
- */
-static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-
-       return info->min_mV * 1000;
-}
-
-static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
-{
-       struct twlreg_info      *info = rdev_get_drvdata(rdev);
-
-       return info->min_mV * 1000;
-}
-
-static struct regulator_ops twl4030fixed_ops = {
-       .list_voltage   = twl4030fixed_list_voltage,
-
-       .get_voltage    = twl4030fixed_get_voltage,
-
-       .enable         = twl4030reg_enable,
-       .disable        = twl4030reg_disable,
-       .is_enabled     = twl4030reg_is_enabled,
-
-       .set_mode       = twl4030reg_set_mode,
-
-       .get_status     = twl4030reg_get_status,
-};
-
-/*----------------------------------------------------------------------*/
-
-#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
-       .base = offset, \
-       .id = num, \
-       .table_len = ARRAY_SIZE(label##_VSEL_table), \
-       .table = label##_VSEL_table, \
-       .desc = { \
-               .name = #label, \
-               .id = TWL4030_REG_##label, \
-               .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
-               .ops = &twl4030ldo_ops, \
-               .type = REGULATOR_VOLTAGE, \
-               .owner = THIS_MODULE, \
-               }, \
-       }
-
-#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
-       .base = offset, \
-       .id = num, \
-       .min_mV = mVolts, \
-       .desc = { \
-               .name = #label, \
-               .id = TWL4030_REG_##label, \
-               .n_voltages = 1, \
-               .ops = &twl4030fixed_ops, \
-               .type = REGULATOR_VOLTAGE, \
-               .owner = THIS_MODULE, \
-               }, \
-       }
-
-/*
- * We list regulators here if systems need some level of
- * software control over them after boot.
- */
-static struct twlreg_info twl4030_regs[] = {
-       TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
-       TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
-       TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
-       TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
-       TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
-       TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
-       TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
-       /*
-       TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
-       */
-       TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
-       TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
-       TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
-       /*
-       TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
-       TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
-       TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
-       TWL_SMPS(VIO, 0x4b, 14),
-       TWL_SMPS(VDD1, 0x55, 15),
-       TWL_SMPS(VDD2, 0x63, 16),
-        */
-       TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
-       TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
-       TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
-       /* VUSBCP is managed *only* by the USB subchip */
-};
-
-static int twl4030reg_probe(struct platform_device *pdev)
-{
-       int                             i;
-       struct twlreg_info              *info;
-       struct regulator_init_data      *initdata;
-       struct regulation_constraints   *c;
-       struct regulator_dev            *rdev;
-
-       for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
-               if (twl4030_regs[i].desc.id != pdev->id)
-                       continue;
-               info = twl4030_regs + i;
-               break;
-       }
-       if (!info)
-               return -ENODEV;
-
-       initdata = pdev->dev.platform_data;
-       if (!initdata)
-               return -EINVAL;
-
-       /* Constrain board-specific capabilities according to what
-        * this driver and the chip itself can actually do.
-        */
-       c = &initdata->constraints;
-       c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
-       c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
-                               | REGULATOR_CHANGE_MODE
-                               | REGULATOR_CHANGE_STATUS;
-
-       rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
-       if (IS_ERR(rdev)) {
-               dev_err(&pdev->dev, "can't register %s, %ld\n",
-                               info->desc.name, PTR_ERR(rdev));
-               return PTR_ERR(rdev);
-       }
-       platform_set_drvdata(pdev, rdev);
-
-       /* NOTE:  many regulators support short-circuit IRQs (presentable
-        * as REGULATOR_OVER_CURRENT notifications?) configured via:
-        *  - SC_CONFIG
-        *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
-        *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
-        *  - IT_CONFIG
-        */
-
-       return 0;
-}
-
-static int __devexit twl4030reg_remove(struct platform_device *pdev)
-{
-       regulator_unregister(platform_get_drvdata(pdev));
-       return 0;
-}
-
-MODULE_ALIAS("platform:twl4030_reg");
-
-static struct platform_driver twl4030reg_driver = {
-       .probe          = twl4030reg_probe,
-       .remove         = __devexit_p(twl4030reg_remove),
-       /* NOTE: short name, to work around driver model truncation of
-        * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
-        */
-       .driver.name    = "twl4030_reg",
-       .driver.owner   = THIS_MODULE,
-};
-
-static int __init twl4030reg_init(void)
-{
-       return platform_driver_register(&twl4030reg_driver);
-}
-subsys_initcall(twl4030reg_init);
-
-static void __exit twl4030reg_exit(void)
-{
-       platform_driver_unregister(&twl4030reg_driver);
-}
-module_exit(twl4030reg_exit)
-
-MODULE_DESCRIPTION("TWL4030 regulator driver");
-MODULE_LICENSE("GPL");
index af1ba7ae285716667172ed663df8b85ecda301e5..7da6efb3e953407d9be5723797dd7a9c4ece1e30 100644 (file)
@@ -80,7 +80,7 @@ obj-$(CONFIG_RTC_DRV_STK17TA8)        += rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_STMP)     += rtc-stmp3xxx.o
 obj-$(CONFIG_RTC_DRV_SUN4V)    += rtc-sun4v.o
 obj-$(CONFIG_RTC_DRV_TEST)     += rtc-test.o
-obj-$(CONFIG_RTC_DRV_TWL4030)  += rtc-twl4030.o
+obj-$(CONFIG_RTC_DRV_TWL4030)  += rtc-twl.o
 obj-$(CONFIG_RTC_DRV_TX4939)   += rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)    += rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)   += rtc-vr41xx.o
diff --git a/drivers/rtc/rtc-twl.c b/drivers/rtc/rtc-twl.c
new file mode 100644 (file)
index 0000000..93565be
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+ * rtc-twl4030.c -- TWL4030 Real Time Clock interface
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc
+ * Author: Alexandre Rusev <source@mvista.com>
+ *
+ * Based on original TI driver twl4030-rtc.c
+ *   Copyright (C) 2006 Texas Instruments, Inc.
+ *
+ * Based on rtc-omap.c
+ *   Copyright (C) 2003 MontaVista Software, Inc.
+ *   Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
+ *   Copyright (C) 2006 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+
+#include <linux/i2c/twl.h>
+
+
+/*
+ * RTC block register offsets (use TWL_MODULE_RTC)
+ */
+#define REG_SECONDS_REG                          0x00
+#define REG_MINUTES_REG                          0x01
+#define REG_HOURS_REG                            0x02
+#define REG_DAYS_REG                             0x03
+#define REG_MONTHS_REG                           0x04
+#define REG_YEARS_REG                            0x05
+#define REG_WEEKS_REG                            0x06
+
+#define REG_ALARM_SECONDS_REG                    0x07
+#define REG_ALARM_MINUTES_REG                    0x08
+#define REG_ALARM_HOURS_REG                      0x09
+#define REG_ALARM_DAYS_REG                       0x0A
+#define REG_ALARM_MONTHS_REG                     0x0B
+#define REG_ALARM_YEARS_REG                      0x0C
+
+#define REG_RTC_CTRL_REG                         0x0D
+#define REG_RTC_STATUS_REG                       0x0E
+#define REG_RTC_INTERRUPTS_REG                   0x0F
+
+#define REG_RTC_COMP_LSB_REG                     0x10
+#define REG_RTC_COMP_MSB_REG                     0x11
+
+/* RTC_CTRL_REG bitfields */
+#define BIT_RTC_CTRL_REG_STOP_RTC_M              0x01
+#define BIT_RTC_CTRL_REG_ROUND_30S_M             0x02
+#define BIT_RTC_CTRL_REG_AUTO_COMP_M             0x04
+#define BIT_RTC_CTRL_REG_MODE_12_24_M            0x08
+#define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
+#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
+#define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
+
+/* RTC_STATUS_REG bitfields */
+#define BIT_RTC_STATUS_REG_RUN_M                 0x02
+#define BIT_RTC_STATUS_REG_1S_EVENT_M            0x04
+#define BIT_RTC_STATUS_REG_1M_EVENT_M            0x08
+#define BIT_RTC_STATUS_REG_1H_EVENT_M            0x10
+#define BIT_RTC_STATUS_REG_1D_EVENT_M            0x20
+#define BIT_RTC_STATUS_REG_ALARM_M               0x40
+#define BIT_RTC_STATUS_REG_POWER_UP_M            0x80
+
+/* RTC_INTERRUPTS_REG bitfields */
+#define BIT_RTC_INTERRUPTS_REG_EVERY_M           0x03
+#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M        0x04
+#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M        0x08
+
+
+/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
+#define ALL_TIME_REGS          6
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Supports 1 byte read from TWL4030 RTC register.
+ */
+static int twl4030_rtc_read_u8(u8 *data, u8 reg)
+{
+       int ret;
+
+       ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg);
+       if (ret < 0)
+               pr_err("twl4030_rtc: Could not read TWL4030"
+                      "register %X - error %d\n", reg, ret);
+       return ret;
+}
+
+/*
+ * Supports 1 byte write to TWL4030 RTC registers.
+ */
+static int twl4030_rtc_write_u8(u8 data, u8 reg)
+{
+       int ret;
+
+       ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg);
+       if (ret < 0)
+               pr_err("twl4030_rtc: Could not write TWL4030"
+                      "register %X - error %d\n", reg, ret);
+       return ret;
+}
+
+/*
+ * Cache the value for timer/alarm interrupts register; this is
+ * only changed by callers holding rtc ops lock (or resume).
+ */
+static unsigned char rtc_irq_bits;
+
+/*
+ * Enable 1/second update and/or alarm interrupts.
+ */
+static int set_rtc_irq_bit(unsigned char bit)
+{
+       unsigned char val;
+       int ret;
+
+       val = rtc_irq_bits | bit;
+       val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
+       ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+       if (ret == 0)
+               rtc_irq_bits = val;
+
+       return ret;
+}
+
+/*
+ * Disable update and/or alarm interrupts.
+ */
+static int mask_rtc_irq_bit(unsigned char bit)
+{
+       unsigned char val;
+       int ret;
+
+       val = rtc_irq_bits & ~bit;
+       ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
+       if (ret == 0)
+               rtc_irq_bits = val;
+
+       return ret;
+}
+
+static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
+{
+       int ret;
+
+       if (enabled)
+               ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+       else
+               ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+
+       return ret;
+}
+
+static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled)
+{
+       int ret;
+
+       if (enabled)
+               ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+       else
+               ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+
+       return ret;
+}
+
+/*
+ * Gets current TWL4030 RTC time and date parameters.
+ *
+ * The RTC's time/alarm representation is not what gmtime(3) requires
+ * Linux to use:
+ *
+ *  - Months are 1..12 vs Linux 0-11
+ *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
+ */
+static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       int ret;
+       u8 save_control;
+
+       ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               return ret;
+
+       save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
+
+       ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               return ret;
+
+       ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
+                              REG_SECONDS_REG, ALL_TIME_REGS);
+
+       if (ret < 0) {
+               dev_err(dev, "rtc_read_time error %d\n", ret);
+               return ret;
+       }
+
+       tm->tm_sec = bcd2bin(rtc_data[0]);
+       tm->tm_min = bcd2bin(rtc_data[1]);
+       tm->tm_hour = bcd2bin(rtc_data[2]);
+       tm->tm_mday = bcd2bin(rtc_data[3]);
+       tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
+       tm->tm_year = bcd2bin(rtc_data[5]) + 100;
+
+       return ret;
+}
+
+static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+       unsigned char save_control;
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       int ret;
+
+       rtc_data[1] = bin2bcd(tm->tm_sec);
+       rtc_data[2] = bin2bcd(tm->tm_min);
+       rtc_data[3] = bin2bcd(tm->tm_hour);
+       rtc_data[4] = bin2bcd(tm->tm_mday);
+       rtc_data[5] = bin2bcd(tm->tm_mon + 1);
+       rtc_data[6] = bin2bcd(tm->tm_year - 100);
+
+       /* Stop RTC while updating the TC registers */
+       ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               goto out;
+
+       save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
+       twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               goto out;
+
+       /* update all the time registers in one shot */
+       ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
+                       REG_SECONDS_REG, ALL_TIME_REGS);
+       if (ret < 0) {
+               dev_err(dev, "rtc_set_time error %d\n", ret);
+               goto out;
+       }
+
+       /* Start back RTC */
+       save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
+       ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
+
+out:
+       return ret;
+}
+
+/*
+ * Gets current TWL4030 RTC alarm time.
+ */
+static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       unsigned char rtc_data[ALL_TIME_REGS + 1];
+       int ret;
+
+       ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
+                              REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
+       if (ret < 0) {
+               dev_err(dev, "rtc_read_alarm error %d\n", ret);
+               return ret;
+       }
+
+       /* some of these fields may be wildcard/"match all" */
+       alm->time.tm_sec = bcd2bin(rtc_data[0]);
+       alm->time.tm_min = bcd2bin(rtc_data[1]);
+       alm->time.tm_hour = bcd2bin(rtc_data[2]);
+       alm->time.tm_mday = bcd2bin(rtc_data[3]);
+       alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
+       alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
+
+       /* report cached alarm enable state */
+       if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
+               alm->enabled = 1;
+
+       return ret;
+}
+
+static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+       unsigned char alarm_data[ALL_TIME_REGS + 1];
+       int ret;
+
+       ret = twl4030_rtc_alarm_irq_enable(dev, 0);
+       if (ret)
+               goto out;
+
+       alarm_data[1] = bin2bcd(alm->time.tm_sec);
+       alarm_data[2] = bin2bcd(alm->time.tm_min);
+       alarm_data[3] = bin2bcd(alm->time.tm_hour);
+       alarm_data[4] = bin2bcd(alm->time.tm_mday);
+       alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
+       alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
+
+       /* update all the alarm registers in one shot */
+       ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data,
+                       REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
+       if (ret) {
+               dev_err(dev, "rtc_set_alarm error %d\n", ret);
+               goto out;
+       }
+
+       if (alm->enabled)
+               ret = twl4030_rtc_alarm_irq_enable(dev, 1);
+out:
+       return ret;
+}
+
+static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
+{
+       unsigned long events = 0;
+       int ret = IRQ_NONE;
+       int res;
+       u8 rd_reg;
+
+#ifdef CONFIG_LOCKDEP
+       /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
+        * we don't want and can't tolerate.  Although it might be
+        * friendlier not to borrow this thread context...
+        */
+       local_irq_enable();
+#endif
+
+       res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+       if (res)
+               goto out;
+       /*
+        * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
+        * only one (ALARM or RTC) interrupt source may be enabled
+        * at time, we also could check our results
+        * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
+        */
+       if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
+               events |= RTC_IRQF | RTC_AF;
+       else
+               events |= RTC_IRQF | RTC_UF;
+
+       res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
+                                  REG_RTC_STATUS_REG);
+       if (res)
+               goto out;
+
+       /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
+        * needs 2 reads to clear the interrupt. One read is done in
+        * do_twl4030_pwrirq(). Doing the second read, to clear
+        * the bit.
+        *
+        * FIXME the reason PWR_ISR1 needs an extra read is that
+        * RTC_IF retriggered until we cleared REG_ALARM_M above.
+        * But re-reading like this is a bad hack; by doing so we
+        * risk wrongly clearing status for some other IRQ (losing
+        * the interrupt).  Be smarter about handling RTC_UF ...
+        */
+       res = twl4030_i2c_read_u8(TWL4030_MODULE_INT,
+                       &rd_reg, TWL4030_INT_PWR_ISR1);
+       if (res)
+               goto out;
+
+       /* Notify RTC core on event */
+       rtc_update_irq(rtc, 1, events);
+
+       ret = IRQ_HANDLED;
+out:
+       return ret;
+}
+
+static struct rtc_class_ops twl4030_rtc_ops = {
+       .read_time      = twl4030_rtc_read_time,
+       .set_time       = twl4030_rtc_set_time,
+       .read_alarm     = twl4030_rtc_read_alarm,
+       .set_alarm      = twl4030_rtc_set_alarm,
+       .alarm_irq_enable = twl4030_rtc_alarm_irq_enable,
+       .update_irq_enable = twl4030_rtc_update_irq_enable,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
+{
+       struct rtc_device *rtc;
+       int ret = 0;
+       int irq = platform_get_irq(pdev, 0);
+       u8 rd_reg;
+
+       if (irq <= 0)
+               return -EINVAL;
+
+       rtc = rtc_device_register(pdev->name,
+                                 &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
+       if (IS_ERR(rtc)) {
+               ret = PTR_ERR(rtc);
+               dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+                       PTR_ERR(rtc));
+               goto out0;
+
+       }
+
+       platform_set_drvdata(pdev, rtc);
+
+       ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
+       if (ret < 0)
+               goto out1;
+
+       if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
+               dev_warn(&pdev->dev, "Power up reset detected.\n");
+
+       if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
+               dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
+
+       /* Clear RTC Power up reset and pending alarm interrupts */
+       ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
+       if (ret < 0)
+               goto out1;
+
+       ret = request_irq(irq, twl4030_rtc_interrupt,
+                               IRQF_TRIGGER_RISING,
+                               dev_name(&rtc->dev), rtc);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "IRQ is not free.\n");
+               goto out1;
+       }
+
+       /* Check RTC module status, Enable if it is off */
+       ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
+       if (ret < 0)
+               goto out2;
+
+       if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
+               dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
+               rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
+               ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
+               if (ret < 0)
+                       goto out2;
+       }
+
+       /* init cached IRQ enable bits */
+       ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
+       if (ret < 0)
+               goto out2;
+
+       return ret;
+
+out2:
+       free_irq(irq, rtc);
+out1:
+       rtc_device_unregister(rtc);
+out0:
+       return ret;
+}
+
+/*
+ * Disable all TWL4030 RTC module interrupts.
+ * Sets status flag to free.
+ */
+static int __devexit twl4030_rtc_remove(struct platform_device *pdev)
+{
+       /* leave rtc running, but disable irqs */
+       struct rtc_device *rtc = platform_get_drvdata(pdev);
+       int irq = platform_get_irq(pdev, 0);
+
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+
+       free_irq(irq, rtc);
+
+       rtc_device_unregister(rtc);
+       platform_set_drvdata(pdev, NULL);
+       return 0;
+}
+
+static void twl4030_rtc_shutdown(struct platform_device *pdev)
+{
+       /* mask timer interrupts, but leave alarm interrupts on to enable
+          power-on when alarm is triggered */
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+}
+
+#ifdef CONFIG_PM
+
+static unsigned char irqstat;
+
+static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       irqstat = rtc_irq_bits;
+
+       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
+       return 0;
+}
+
+static int twl4030_rtc_resume(struct platform_device *pdev)
+{
+       set_rtc_irq_bit(irqstat);
+       return 0;
+}
+
+#else
+#define twl4030_rtc_suspend NULL
+#define twl4030_rtc_resume  NULL
+#endif
+
+MODULE_ALIAS("platform:twl4030_rtc");
+
+static struct platform_driver twl4030rtc_driver = {
+       .probe          = twl4030_rtc_probe,
+       .remove         = __devexit_p(twl4030_rtc_remove),
+       .shutdown       = twl4030_rtc_shutdown,
+       .suspend        = twl4030_rtc_suspend,
+       .resume         = twl4030_rtc_resume,
+       .driver         = {
+               .owner  = THIS_MODULE,
+               .name   = "twl4030_rtc",
+       },
+};
+
+static int __init twl4030_rtc_init(void)
+{
+       return platform_driver_register(&twl4030rtc_driver);
+}
+module_init(twl4030_rtc_init);
+
+static void __exit twl4030_rtc_exit(void)
+{
+       platform_driver_unregister(&twl4030rtc_driver);
+}
+module_exit(twl4030_rtc_exit);
+
+MODULE_AUTHOR("Texas Instruments, MontaVista Software");
+MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-twl4030.c b/drivers/rtc/rtc-twl4030.c
deleted file mode 100644 (file)
index 9c8c70c..0000000
+++ /dev/null
@@ -1,540 +0,0 @@
-/*
- * rtc-twl4030.c -- TWL4030 Real Time Clock interface
- *
- * Copyright (C) 2007 MontaVista Software, Inc
- * Author: Alexandre Rusev <source@mvista.com>
- *
- * Based on original TI driver twl4030-rtc.c
- *   Copyright (C) 2006 Texas Instruments, Inc.
- *
- * Based on rtc-omap.c
- *   Copyright (C) 2003 MontaVista Software, Inc.
- *   Author: George G. Davis <gdavis@mvista.com> or <source@mvista.com>
- *   Copyright (C) 2006 David Brownell
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-
-#include <linux/i2c/twl4030.h>
-
-
-/*
- * RTC block register offsets (use TWL_MODULE_RTC)
- */
-#define REG_SECONDS_REG                          0x00
-#define REG_MINUTES_REG                          0x01
-#define REG_HOURS_REG                            0x02
-#define REG_DAYS_REG                             0x03
-#define REG_MONTHS_REG                           0x04
-#define REG_YEARS_REG                            0x05
-#define REG_WEEKS_REG                            0x06
-
-#define REG_ALARM_SECONDS_REG                    0x07
-#define REG_ALARM_MINUTES_REG                    0x08
-#define REG_ALARM_HOURS_REG                      0x09
-#define REG_ALARM_DAYS_REG                       0x0A
-#define REG_ALARM_MONTHS_REG                     0x0B
-#define REG_ALARM_YEARS_REG                      0x0C
-
-#define REG_RTC_CTRL_REG                         0x0D
-#define REG_RTC_STATUS_REG                       0x0E
-#define REG_RTC_INTERRUPTS_REG                   0x0F
-
-#define REG_RTC_COMP_LSB_REG                     0x10
-#define REG_RTC_COMP_MSB_REG                     0x11
-
-/* RTC_CTRL_REG bitfields */
-#define BIT_RTC_CTRL_REG_STOP_RTC_M              0x01
-#define BIT_RTC_CTRL_REG_ROUND_30S_M             0x02
-#define BIT_RTC_CTRL_REG_AUTO_COMP_M             0x04
-#define BIT_RTC_CTRL_REG_MODE_12_24_M            0x08
-#define BIT_RTC_CTRL_REG_TEST_MODE_M             0x10
-#define BIT_RTC_CTRL_REG_SET_32_COUNTER_M        0x20
-#define BIT_RTC_CTRL_REG_GET_TIME_M              0x40
-
-/* RTC_STATUS_REG bitfields */
-#define BIT_RTC_STATUS_REG_RUN_M                 0x02
-#define BIT_RTC_STATUS_REG_1S_EVENT_M            0x04
-#define BIT_RTC_STATUS_REG_1M_EVENT_M            0x08
-#define BIT_RTC_STATUS_REG_1H_EVENT_M            0x10
-#define BIT_RTC_STATUS_REG_1D_EVENT_M            0x20
-#define BIT_RTC_STATUS_REG_ALARM_M               0x40
-#define BIT_RTC_STATUS_REG_POWER_UP_M            0x80
-
-/* RTC_INTERRUPTS_REG bitfields */
-#define BIT_RTC_INTERRUPTS_REG_EVERY_M           0x03
-#define BIT_RTC_INTERRUPTS_REG_IT_TIMER_M        0x04
-#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M        0x08
-
-
-/* REG_SECONDS_REG through REG_YEARS_REG is how many registers? */
-#define ALL_TIME_REGS          6
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Supports 1 byte read from TWL4030 RTC register.
- */
-static int twl4030_rtc_read_u8(u8 *data, u8 reg)
-{
-       int ret;
-
-       ret = twl4030_i2c_read_u8(TWL4030_MODULE_RTC, data, reg);
-       if (ret < 0)
-               pr_err("twl4030_rtc: Could not read TWL4030"
-                      "register %X - error %d\n", reg, ret);
-       return ret;
-}
-
-/*
- * Supports 1 byte write to TWL4030 RTC registers.
- */
-static int twl4030_rtc_write_u8(u8 data, u8 reg)
-{
-       int ret;
-
-       ret = twl4030_i2c_write_u8(TWL4030_MODULE_RTC, data, reg);
-       if (ret < 0)
-               pr_err("twl4030_rtc: Could not write TWL4030"
-                      "register %X - error %d\n", reg, ret);
-       return ret;
-}
-
-/*
- * Cache the value for timer/alarm interrupts register; this is
- * only changed by callers holding rtc ops lock (or resume).
- */
-static unsigned char rtc_irq_bits;
-
-/*
- * Enable 1/second update and/or alarm interrupts.
- */
-static int set_rtc_irq_bit(unsigned char bit)
-{
-       unsigned char val;
-       int ret;
-
-       val = rtc_irq_bits | bit;
-       val &= ~BIT_RTC_INTERRUPTS_REG_EVERY_M;
-       ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
-       if (ret == 0)
-               rtc_irq_bits = val;
-
-       return ret;
-}
-
-/*
- * Disable update and/or alarm interrupts.
- */
-static int mask_rtc_irq_bit(unsigned char bit)
-{
-       unsigned char val;
-       int ret;
-
-       val = rtc_irq_bits & ~bit;
-       ret = twl4030_rtc_write_u8(val, REG_RTC_INTERRUPTS_REG);
-       if (ret == 0)
-               rtc_irq_bits = val;
-
-       return ret;
-}
-
-static int twl4030_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
-{
-       int ret;
-
-       if (enabled)
-               ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-       else
-               ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-
-       return ret;
-}
-
-static int twl4030_rtc_update_irq_enable(struct device *dev, unsigned enabled)
-{
-       int ret;
-
-       if (enabled)
-               ret = set_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-       else
-               ret = mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-
-       return ret;
-}
-
-/*
- * Gets current TWL4030 RTC time and date parameters.
- *
- * The RTC's time/alarm representation is not what gmtime(3) requires
- * Linux to use:
- *
- *  - Months are 1..12 vs Linux 0-11
- *  - Years are 0..99 vs Linux 1900..N (we assume 21st century)
- */
-static int twl4030_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
-       unsigned char rtc_data[ALL_TIME_REGS + 1];
-       int ret;
-       u8 save_control;
-
-       ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
-       if (ret < 0)
-               return ret;
-
-       save_control |= BIT_RTC_CTRL_REG_GET_TIME_M;
-
-       ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-       if (ret < 0)
-               return ret;
-
-       ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
-                              REG_SECONDS_REG, ALL_TIME_REGS);
-
-       if (ret < 0) {
-               dev_err(dev, "rtc_read_time error %d\n", ret);
-               return ret;
-       }
-
-       tm->tm_sec = bcd2bin(rtc_data[0]);
-       tm->tm_min = bcd2bin(rtc_data[1]);
-       tm->tm_hour = bcd2bin(rtc_data[2]);
-       tm->tm_mday = bcd2bin(rtc_data[3]);
-       tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
-       tm->tm_year = bcd2bin(rtc_data[5]) + 100;
-
-       return ret;
-}
-
-static int twl4030_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
-       unsigned char save_control;
-       unsigned char rtc_data[ALL_TIME_REGS + 1];
-       int ret;
-
-       rtc_data[1] = bin2bcd(tm->tm_sec);
-       rtc_data[2] = bin2bcd(tm->tm_min);
-       rtc_data[3] = bin2bcd(tm->tm_hour);
-       rtc_data[4] = bin2bcd(tm->tm_mday);
-       rtc_data[5] = bin2bcd(tm->tm_mon + 1);
-       rtc_data[6] = bin2bcd(tm->tm_year - 100);
-
-       /* Stop RTC while updating the TC registers */
-       ret = twl4030_rtc_read_u8(&save_control, REG_RTC_CTRL_REG);
-       if (ret < 0)
-               goto out;
-
-       save_control &= ~BIT_RTC_CTRL_REG_STOP_RTC_M;
-       twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-       if (ret < 0)
-               goto out;
-
-       /* update all the time registers in one shot */
-       ret = twl4030_i2c_write(TWL4030_MODULE_RTC, rtc_data,
-                       REG_SECONDS_REG, ALL_TIME_REGS);
-       if (ret < 0) {
-               dev_err(dev, "rtc_set_time error %d\n", ret);
-               goto out;
-       }
-
-       /* Start back RTC */
-       save_control |= BIT_RTC_CTRL_REG_STOP_RTC_M;
-       ret = twl4030_rtc_write_u8(save_control, REG_RTC_CTRL_REG);
-
-out:
-       return ret;
-}
-
-/*
- * Gets current TWL4030 RTC alarm time.
- */
-static int twl4030_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
-       unsigned char rtc_data[ALL_TIME_REGS + 1];
-       int ret;
-
-       ret = twl4030_i2c_read(TWL4030_MODULE_RTC, rtc_data,
-                              REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
-       if (ret < 0) {
-               dev_err(dev, "rtc_read_alarm error %d\n", ret);
-               return ret;
-       }
-
-       /* some of these fields may be wildcard/"match all" */
-       alm->time.tm_sec = bcd2bin(rtc_data[0]);
-       alm->time.tm_min = bcd2bin(rtc_data[1]);
-       alm->time.tm_hour = bcd2bin(rtc_data[2]);
-       alm->time.tm_mday = bcd2bin(rtc_data[3]);
-       alm->time.tm_mon = bcd2bin(rtc_data[4]) - 1;
-       alm->time.tm_year = bcd2bin(rtc_data[5]) + 100;
-
-       /* report cached alarm enable state */
-       if (rtc_irq_bits & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M)
-               alm->enabled = 1;
-
-       return ret;
-}
-
-static int twl4030_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
-{
-       unsigned char alarm_data[ALL_TIME_REGS + 1];
-       int ret;
-
-       ret = twl4030_rtc_alarm_irq_enable(dev, 0);
-       if (ret)
-               goto out;
-
-       alarm_data[1] = bin2bcd(alm->time.tm_sec);
-       alarm_data[2] = bin2bcd(alm->time.tm_min);
-       alarm_data[3] = bin2bcd(alm->time.tm_hour);
-       alarm_data[4] = bin2bcd(alm->time.tm_mday);
-       alarm_data[5] = bin2bcd(alm->time.tm_mon + 1);
-       alarm_data[6] = bin2bcd(alm->time.tm_year - 100);
-
-       /* update all the alarm registers in one shot */
-       ret = twl4030_i2c_write(TWL4030_MODULE_RTC, alarm_data,
-                       REG_ALARM_SECONDS_REG, ALL_TIME_REGS);
-       if (ret) {
-               dev_err(dev, "rtc_set_alarm error %d\n", ret);
-               goto out;
-       }
-
-       if (alm->enabled)
-               ret = twl4030_rtc_alarm_irq_enable(dev, 1);
-out:
-       return ret;
-}
-
-static irqreturn_t twl4030_rtc_interrupt(int irq, void *rtc)
-{
-       unsigned long events = 0;
-       int ret = IRQ_NONE;
-       int res;
-       u8 rd_reg;
-
-#ifdef CONFIG_LOCKDEP
-       /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which
-        * we don't want and can't tolerate.  Although it might be
-        * friendlier not to borrow this thread context...
-        */
-       local_irq_enable();
-#endif
-
-       res = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
-       if (res)
-               goto out;
-       /*
-        * Figure out source of interrupt: ALARM or TIMER in RTC_STATUS_REG.
-        * only one (ALARM or RTC) interrupt source may be enabled
-        * at time, we also could check our results
-        * by reading RTS_INTERRUPTS_REGISTER[IT_TIMER,IT_ALARM]
-        */
-       if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
-               events |= RTC_IRQF | RTC_AF;
-       else
-               events |= RTC_IRQF | RTC_UF;
-
-       res = twl4030_rtc_write_u8(rd_reg | BIT_RTC_STATUS_REG_ALARM_M,
-                                  REG_RTC_STATUS_REG);
-       if (res)
-               goto out;
-
-       /* Clear on Read enabled. RTC_IT bit of TWL4030_INT_PWR_ISR1
-        * needs 2 reads to clear the interrupt. One read is done in
-        * do_twl4030_pwrirq(). Doing the second read, to clear
-        * the bit.
-        *
-        * FIXME the reason PWR_ISR1 needs an extra read is that
-        * RTC_IF retriggered until we cleared REG_ALARM_M above.
-        * But re-reading like this is a bad hack; by doing so we
-        * risk wrongly clearing status for some other IRQ (losing
-        * the interrupt).  Be smarter about handling RTC_UF ...
-        */
-       res = twl4030_i2c_read_u8(TWL4030_MODULE_INT,
-                       &rd_reg, TWL4030_INT_PWR_ISR1);
-       if (res)
-               goto out;
-
-       /* Notify RTC core on event */
-       rtc_update_irq(rtc, 1, events);
-
-       ret = IRQ_HANDLED;
-out:
-       return ret;
-}
-
-static struct rtc_class_ops twl4030_rtc_ops = {
-       .read_time      = twl4030_rtc_read_time,
-       .set_time       = twl4030_rtc_set_time,
-       .read_alarm     = twl4030_rtc_read_alarm,
-       .set_alarm      = twl4030_rtc_set_alarm,
-       .alarm_irq_enable = twl4030_rtc_alarm_irq_enable,
-       .update_irq_enable = twl4030_rtc_update_irq_enable,
-};
-
-/*----------------------------------------------------------------------*/
-
-static int __devinit twl4030_rtc_probe(struct platform_device *pdev)
-{
-       struct rtc_device *rtc;
-       int ret = 0;
-       int irq = platform_get_irq(pdev, 0);
-       u8 rd_reg;
-
-       if (irq <= 0)
-               return -EINVAL;
-
-       rtc = rtc_device_register(pdev->name,
-                                 &pdev->dev, &twl4030_rtc_ops, THIS_MODULE);
-       if (IS_ERR(rtc)) {
-               ret = PTR_ERR(rtc);
-               dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
-                       PTR_ERR(rtc));
-               goto out0;
-
-       }
-
-       platform_set_drvdata(pdev, rtc);
-
-       ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_STATUS_REG);
-       if (ret < 0)
-               goto out1;
-
-       if (rd_reg & BIT_RTC_STATUS_REG_POWER_UP_M)
-               dev_warn(&pdev->dev, "Power up reset detected.\n");
-
-       if (rd_reg & BIT_RTC_STATUS_REG_ALARM_M)
-               dev_warn(&pdev->dev, "Pending Alarm interrupt detected.\n");
-
-       /* Clear RTC Power up reset and pending alarm interrupts */
-       ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_STATUS_REG);
-       if (ret < 0)
-               goto out1;
-
-       ret = request_irq(irq, twl4030_rtc_interrupt,
-                               IRQF_TRIGGER_RISING,
-                               dev_name(&rtc->dev), rtc);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "IRQ is not free.\n");
-               goto out1;
-       }
-
-       /* Check RTC module status, Enable if it is off */
-       ret = twl4030_rtc_read_u8(&rd_reg, REG_RTC_CTRL_REG);
-       if (ret < 0)
-               goto out2;
-
-       if (!(rd_reg & BIT_RTC_CTRL_REG_STOP_RTC_M)) {
-               dev_info(&pdev->dev, "Enabling TWL4030-RTC.\n");
-               rd_reg = BIT_RTC_CTRL_REG_STOP_RTC_M;
-               ret = twl4030_rtc_write_u8(rd_reg, REG_RTC_CTRL_REG);
-               if (ret < 0)
-                       goto out2;
-       }
-
-       /* init cached IRQ enable bits */
-       ret = twl4030_rtc_read_u8(&rtc_irq_bits, REG_RTC_INTERRUPTS_REG);
-       if (ret < 0)
-               goto out2;
-
-       return ret;
-
-out2:
-       free_irq(irq, rtc);
-out1:
-       rtc_device_unregister(rtc);
-out0:
-       return ret;
-}
-
-/*
- * Disable all TWL4030 RTC module interrupts.
- * Sets status flag to free.
- */
-static int __devexit twl4030_rtc_remove(struct platform_device *pdev)
-{
-       /* leave rtc running, but disable irqs */
-       struct rtc_device *rtc = platform_get_drvdata(pdev);
-       int irq = platform_get_irq(pdev, 0);
-
-       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
-       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-
-       free_irq(irq, rtc);
-
-       rtc_device_unregister(rtc);
-       platform_set_drvdata(pdev, NULL);
-       return 0;
-}
-
-static void twl4030_rtc_shutdown(struct platform_device *pdev)
-{
-       /* mask timer interrupts, but leave alarm interrupts on to enable
-          power-on when alarm is triggered */
-       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-}
-
-#ifdef CONFIG_PM
-
-static unsigned char irqstat;
-
-static int twl4030_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       irqstat = rtc_irq_bits;
-
-       mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
-       return 0;
-}
-
-static int twl4030_rtc_resume(struct platform_device *pdev)
-{
-       set_rtc_irq_bit(irqstat);
-       return 0;
-}
-
-#else
-#define twl4030_rtc_suspend NULL
-#define twl4030_rtc_resume  NULL
-#endif
-
-MODULE_ALIAS("platform:twl4030_rtc");
-
-static struct platform_driver twl4030rtc_driver = {
-       .probe          = twl4030_rtc_probe,
-       .remove         = __devexit_p(twl4030_rtc_remove),
-       .shutdown       = twl4030_rtc_shutdown,
-       .suspend        = twl4030_rtc_suspend,
-       .resume         = twl4030_rtc_resume,
-       .driver         = {
-               .owner  = THIS_MODULE,
-               .name   = "twl4030_rtc",
-       },
-};
-
-static int __init twl4030_rtc_init(void)
-{
-       return platform_driver_register(&twl4030rtc_driver);
-}
-module_init(twl4030_rtc_init);
-
-static void __exit twl4030_rtc_exit(void)
-{
-       platform_driver_unregister(&twl4030rtc_driver);
-}
-module_exit(twl4030_rtc_exit);
-
-MODULE_AUTHOR("Texas Instruments, MontaVista Software");
-MODULE_LICENSE("GPL");
index bd9883f41e63b2279940ab239edf8bb947d57c6f..3acbdb82bcf9fb78feca39b11ccfc197fc0d8ec7 100644 (file)
@@ -33,7 +33,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/usb/otg.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
 
index 760645d9dbb6ca0a3cb0c0c83cee785be3592ed8..3764a36d914286b5aa7545a9f3bb27a06e028340 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 #include <plat/mux.h>
 #include <asm/mach-types.h>
index cb46556f2973fb43900050ad9fa97e476b68a576..20968b2aadef816f8af235bcf215a4cc10c076a2 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/platform_device.h>
 #include <linux/miscdevice.h>
 #include <linux/uaccess.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 
 #define TWL4030_WATCHDOG_CFG_REG_OFFS  0x3
 
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
new file mode 100644 (file)
index 0000000..a50bcf8
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * twl4030.h - header for TWL4030 PM and audio CODEC device
+ *
+ * Copyright (C) 2005-2006 Texas Instruments, Inc.
+ *
+ * Based on tlv320aic23.c:
+ * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+#ifndef __TWL4030_H_
+#define __TWL4030_H_
+
+#include <linux/types.h>
+#include <linux/input/matrix_keypad.h>
+
+/*
+ * Using the twl4030 core we address registers using a pair
+ *     { module id, relative register offset }
+ * which that core then maps to the relevant
+ *     { i2c slave, absolute register address }
+ *
+ * The module IDs are meaningful only to the twl4030 core code,
+ * which uses them as array indices to look up the first register
+ * address each module uses within a given i2c slave.
+ */
+
+/* Slave 0 (i2c address 0x48) */
+#define TWL4030_MODULE_USB             0x00
+
+/* Slave 1 (i2c address 0x49) */
+#define TWL4030_MODULE_AUDIO_VOICE     0x01
+#define TWL4030_MODULE_GPIO            0x02
+#define TWL4030_MODULE_INTBR           0x03
+#define TWL4030_MODULE_PIH             0x04
+#define TWL4030_MODULE_TEST            0x05
+
+/* Slave 2 (i2c address 0x4a) */
+#define TWL4030_MODULE_KEYPAD          0x06
+#define TWL4030_MODULE_MADC            0x07
+#define TWL4030_MODULE_INTERRUPTS      0x08
+#define TWL4030_MODULE_LED             0x09
+#define TWL4030_MODULE_MAIN_CHARGE     0x0A
+#define TWL4030_MODULE_PRECHARGE       0x0B
+#define TWL4030_MODULE_PWM0            0x0C
+#define TWL4030_MODULE_PWM1            0x0D
+#define TWL4030_MODULE_PWMA            0x0E
+#define TWL4030_MODULE_PWMB            0x0F
+
+#define TWL5031_MODULE_ACCESSORY       0x10
+#define TWL5031_MODULE_INTERRUPTS      0x11
+
+/* Slave 3 (i2c address 0x4b) */
+#define TWL4030_MODULE_BACKUP          0x12
+#define TWL4030_MODULE_INT             0x13
+#define TWL4030_MODULE_PM_MASTER       0x14
+#define TWL4030_MODULE_PM_RECEIVER     0x15
+#define TWL4030_MODULE_RTC             0x16
+#define TWL4030_MODULE_SECURED_REG     0x17
+
+/*
+ * Read and write single 8-bit registers
+ */
+int twl4030_i2c_write_u8(u8 mod_no, u8 val, u8 reg);
+int twl4030_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
+
+/*
+ * Read and write several 8-bit registers at once.
+ *
+ * IMPORTANT:  For twl4030_i2c_write(), allocate num_bytes + 1
+ * for the value, and populate your data starting at offset 1.
+ */
+int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
+int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE:  at up to 1024 registers, this is a big chip.
+ *
+ * Avoid putting register declarations in this file, instead of into
+ * a driver-private file, unless some of the registers in a block
+ * need to be shared with other drivers.  One example is blocks that
+ * have Secondary IRQ Handler (SIH) registers.
+ */
+
+#define TWL4030_SIH_CTRL_EXCLEN_MASK   BIT(0)
+#define TWL4030_SIH_CTRL_PENDDIS_MASK  BIT(1)
+#define TWL4030_SIH_CTRL_COR_MASK      BIT(2)
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * GPIO Block Register offsets (use TWL4030_MODULE_GPIO)
+ */
+
+#define REG_GPIODATAIN1                        0x0
+#define REG_GPIODATAIN2                        0x1
+#define REG_GPIODATAIN3                        0x2
+#define REG_GPIODATADIR1               0x3
+#define REG_GPIODATADIR2               0x4
+#define REG_GPIODATADIR3               0x5
+#define REG_GPIODATAOUT1               0x6
+#define REG_GPIODATAOUT2               0x7
+#define REG_GPIODATAOUT3               0x8
+#define REG_CLEARGPIODATAOUT1          0x9
+#define REG_CLEARGPIODATAOUT2          0xA
+#define REG_CLEARGPIODATAOUT3          0xB
+#define REG_SETGPIODATAOUT1            0xC
+#define REG_SETGPIODATAOUT2            0xD
+#define REG_SETGPIODATAOUT3            0xE
+#define REG_GPIO_DEBEN1                        0xF
+#define REG_GPIO_DEBEN2                        0x10
+#define REG_GPIO_DEBEN3                        0x11
+#define REG_GPIO_CTRL                  0x12
+#define REG_GPIOPUPDCTR1               0x13
+#define REG_GPIOPUPDCTR2               0x14
+#define REG_GPIOPUPDCTR3               0x15
+#define REG_GPIOPUPDCTR4               0x16
+#define REG_GPIOPUPDCTR5               0x17
+#define REG_GPIO_ISR1A                 0x19
+#define REG_GPIO_ISR2A                 0x1A
+#define REG_GPIO_ISR3A                 0x1B
+#define REG_GPIO_IMR1A                 0x1C
+#define REG_GPIO_IMR2A                 0x1D
+#define REG_GPIO_IMR3A                 0x1E
+#define REG_GPIO_ISR1B                 0x1F
+#define REG_GPIO_ISR2B                 0x20
+#define REG_GPIO_ISR3B                 0x21
+#define REG_GPIO_IMR1B                 0x22
+#define REG_GPIO_IMR2B                 0x23
+#define REG_GPIO_IMR3B                 0x24
+#define REG_GPIO_EDR1                  0x28
+#define REG_GPIO_EDR2                  0x29
+#define REG_GPIO_EDR3                  0x2A
+#define REG_GPIO_EDR4                  0x2B
+#define REG_GPIO_EDR5                  0x2C
+#define REG_GPIO_SIH_CTRL              0x2D
+
+/* Up to 18 signals are available as GPIOs, when their
+ * pins are not assigned to another use (such as ULPI/USB).
+ */
+#define TWL4030_GPIO_MAX               18
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Keypad register offsets (use TWL4030_MODULE_KEYPAD)
+ * ... SIH/interrupt only
+ */
+
+#define TWL4030_KEYPAD_KEYP_ISR1       0x11
+#define TWL4030_KEYPAD_KEYP_IMR1       0x12
+#define TWL4030_KEYPAD_KEYP_ISR2       0x13
+#define TWL4030_KEYPAD_KEYP_IMR2       0x14
+#define TWL4030_KEYPAD_KEYP_SIR                0x15    /* test register */
+#define TWL4030_KEYPAD_KEYP_EDR                0x16
+#define TWL4030_KEYPAD_KEYP_SIH_CTRL   0x17
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Multichannel ADC register offsets (use TWL4030_MODULE_MADC)
+ * ... SIH/interrupt only
+ */
+
+#define TWL4030_MADC_ISR1              0x61
+#define TWL4030_MADC_IMR1              0x62
+#define TWL4030_MADC_ISR2              0x63
+#define TWL4030_MADC_IMR2              0x64
+#define TWL4030_MADC_SIR               0x65    /* test register */
+#define TWL4030_MADC_EDR               0x66
+#define TWL4030_MADC_SIH_CTRL          0x67
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Battery charger register offsets (use TWL4030_MODULE_INTERRUPTS)
+ */
+
+#define TWL4030_INTERRUPTS_BCIISR1A    0x0
+#define TWL4030_INTERRUPTS_BCIISR2A    0x1
+#define TWL4030_INTERRUPTS_BCIIMR1A    0x2
+#define TWL4030_INTERRUPTS_BCIIMR2A    0x3
+#define TWL4030_INTERRUPTS_BCIISR1B    0x4
+#define TWL4030_INTERRUPTS_BCIISR2B    0x5
+#define TWL4030_INTERRUPTS_BCIIMR1B    0x6
+#define TWL4030_INTERRUPTS_BCIIMR2B    0x7
+#define TWL4030_INTERRUPTS_BCISIR1     0x8     /* test register */
+#define TWL4030_INTERRUPTS_BCISIR2     0x9     /* test register */
+#define TWL4030_INTERRUPTS_BCIEDR1     0xa
+#define TWL4030_INTERRUPTS_BCIEDR2     0xb
+#define TWL4030_INTERRUPTS_BCIEDR3     0xc
+#define TWL4030_INTERRUPTS_BCISIHCTRL  0xd
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Power Interrupt block register offsets (use TWL4030_MODULE_INT)
+ */
+
+#define TWL4030_INT_PWR_ISR1           0x0
+#define TWL4030_INT_PWR_IMR1           0x1
+#define TWL4030_INT_PWR_ISR2           0x2
+#define TWL4030_INT_PWR_IMR2           0x3
+#define TWL4030_INT_PWR_SIR            0x4     /* test register */
+#define TWL4030_INT_PWR_EDR1           0x5
+#define TWL4030_INT_PWR_EDR2           0x6
+#define TWL4030_INT_PWR_SIH_CTRL       0x7
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Accessory Interrupts
+ */
+#define TWL5031_ACIIMR_LSB             0x05
+#define TWL5031_ACIIMR_MSB             0x06
+#define TWL5031_ACIIDR_LSB             0x07
+#define TWL5031_ACIIDR_MSB             0x08
+#define TWL5031_ACCISR1                        0x0F
+#define TWL5031_ACCIMR1                        0x10
+#define TWL5031_ACCISR2                        0x11
+#define TWL5031_ACCIMR2                        0x12
+#define TWL5031_ACCSIR                 0x13
+#define TWL5031_ACCEDR1                        0x14
+#define TWL5031_ACCSIHCTRL             0x15
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Battery Charger Controller
+ */
+
+#define TWL5031_INTERRUPTS_BCIISR1     0x0
+#define TWL5031_INTERRUPTS_BCIIMR1     0x1
+#define TWL5031_INTERRUPTS_BCIISR2     0x2
+#define TWL5031_INTERRUPTS_BCIIMR2     0x3
+#define TWL5031_INTERRUPTS_BCISIR      0x4
+#define TWL5031_INTERRUPTS_BCIEDR1     0x5
+#define TWL5031_INTERRUPTS_BCIEDR2     0x6
+#define TWL5031_INTERRUPTS_BCISIHCTRL  0x7
+
+/*----------------------------------------------------------------------*/
+
+/* Power bus message definitions */
+
+/* The TWL4030/5030 splits its power-management resources (the various
+ * regulators, clock and reset lines) into 3 processor groups - P1, P2 and
+ * P3. These groups can then be configured to transition between sleep, wait-on
+ * and active states by sending messages to the power bus.  See Section 5.4.2
+ * Power Resources of TWL4030 TRM
+ */
+
+/* Processor groups */
+#define DEV_GRP_NULL           0x0
+#define DEV_GRP_P1             0x1     /* P1: all OMAP devices */
+#define DEV_GRP_P2             0x2     /* P2: all Modem devices */
+#define DEV_GRP_P3             0x4     /* P3: all peripheral devices */
+
+/* Resource groups */
+#define RES_GRP_RES            0x0     /* Reserved */
+#define RES_GRP_PP             0x1     /* Power providers */
+#define RES_GRP_RC             0x2     /* Reset and control */
+#define RES_GRP_PP_RC          0x3
+#define RES_GRP_PR             0x4     /* Power references */
+#define RES_GRP_PP_PR          0x5
+#define RES_GRP_RC_PR          0x6
+#define RES_GRP_ALL            0x7     /* All resource groups */
+
+#define RES_TYPE2_R0           0x0
+
+#define RES_TYPE_ALL           0x7
+
+/* Resource states */
+#define RES_STATE_WRST         0xF
+#define RES_STATE_ACTIVE       0xE
+#define RES_STATE_SLEEP                0x8
+#define RES_STATE_OFF          0x0
+
+/* Power resources */
+
+/* Power providers */
+#define RES_VAUX1               1
+#define RES_VAUX2               2
+#define RES_VAUX3               3
+#define RES_VAUX4               4
+#define RES_VMMC1               5
+#define RES_VMMC2               6
+#define RES_VPLL1               7
+#define RES_VPLL2               8
+#define RES_VSIM                9
+#define RES_VDAC                10
+#define RES_VINTANA1            11
+#define RES_VINTANA2            12
+#define RES_VINTDIG             13
+#define RES_VIO                 14
+#define RES_VDD1                15
+#define RES_VDD2                16
+#define RES_VUSB_1V5            17
+#define RES_VUSB_1V8            18
+#define RES_VUSB_3V1            19
+#define RES_VUSBCP              20
+#define RES_REGEN               21
+/* Reset and control */
+#define RES_NRES_PWRON          22
+#define RES_CLKEN               23
+#define RES_SYSEN               24
+#define RES_HFCLKOUT            25
+#define RES_32KCLKOUT           26
+#define RES_RESET               27
+/* Power Reference */
+#define RES_Main_Ref            28
+
+#define TOTAL_RESOURCES                28
+/*
+ * Power Bus Message Format ... these can be sent individually by Linux,
+ * but are usually part of downloaded scripts that are run when various
+ * power events are triggered.
+ *
+ *  Broadcast Message (16 Bits):
+ *    DEV_GRP[15:13] MT[12]  RES_GRP[11:9]  RES_TYPE2[8:7] RES_TYPE[6:4]
+ *    RES_STATE[3:0]
+ *
+ *  Singular Message (16 Bits):
+ *    DEV_GRP[15:13] MT[12]  RES_ID[11:4]  RES_STATE[3:0]
+ */
+
+#define MSG_BROADCAST(devgrp, grp, type, type2, state) \
+       ( (devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \
+       | (type) << 4 | (state))
+
+#define MSG_SINGULAR(devgrp, id, state) \
+       ((devgrp) << 13 | 0 << 12 | (id) << 4 | (state))
+
+/*----------------------------------------------------------------------*/
+
+struct twl4030_clock_init_data {
+       bool ck32k_lowpwr_enable;
+};
+
+struct twl4030_bci_platform_data {
+       int *battery_tmp_tbl;
+       unsigned int tblsize;
+};
+
+/* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */
+struct twl4030_gpio_platform_data {
+       int             gpio_base;
+       unsigned        irq_base, irq_end;
+
+       /* package the two LED signals as output-only GPIOs? */
+       bool            use_leds;
+
+       /* gpio-n should control VMMC(n+1) if BIT(n) in mmc_cd is set */
+       u8              mmc_cd;
+
+       /* if BIT(N) is set, or VMMC(n+1) is linked, debounce GPIO-N */
+       u32             debounce;
+
+       /* For gpio-N, bit (1 << N) in "pullups" is set if that pullup
+        * should be enabled.  Else, if that bit is set in "pulldowns",
+        * that pulldown is enabled.  Don't waste power by letting any
+        * digital inputs float...
+        */
+       u32             pullups;
+       u32             pulldowns;
+
+       int             (*setup)(struct device *dev,
+                               unsigned gpio, unsigned ngpio);
+       int             (*teardown)(struct device *dev,
+                               unsigned gpio, unsigned ngpio);
+};
+
+struct twl4030_madc_platform_data {
+       int             irq_line;
+};
+
+/* Boards have uniqe mappings of {row, col} --> keycode.
+ * Column and row are 8 bits each, but range only from 0..7.
+ * a PERSISTENT_KEY is "always on" and never reported.
+ */
+#define PERSISTENT_KEY(r, c)   KEY((r), (c), KEY_RESERVED)
+
+struct twl4030_keypad_data {
+       const struct matrix_keymap_data *keymap_data;
+       unsigned rows;
+       unsigned cols;
+       bool rep;
+};
+
+enum twl4030_usb_mode {
+       T2_USB_MODE_ULPI = 1,
+       T2_USB_MODE_CEA2011_3PIN = 2,
+};
+
+struct twl4030_usb_data {
+       enum twl4030_usb_mode   usb_mode;
+};
+
+struct twl4030_ins {
+       u16 pmb_message;
+       u8 delay;
+};
+
+struct twl4030_script {
+       struct twl4030_ins *script;
+       unsigned size;
+       u8 flags;
+#define TWL4030_WRST_SCRIPT    (1<<0)
+#define TWL4030_WAKEUP12_SCRIPT        (1<<1)
+#define TWL4030_WAKEUP3_SCRIPT (1<<2)
+#define TWL4030_SLEEP_SCRIPT   (1<<3)
+};
+
+struct twl4030_resconfig {
+       u8 resource;
+       u8 devgroup;    /* Processor group that Power resource belongs to */
+       u8 type;        /* Power resource addressed, 6 / broadcast message */
+       u8 type2;       /* Power resource addressed, 3 / broadcast message */
+       u8 remap_off;   /* off state remapping */
+       u8 remap_sleep; /* sleep state remapping */
+};
+
+struct twl4030_power_data {
+       struct twl4030_script **scripts;
+       unsigned num;
+       struct twl4030_resconfig *resource_config;
+#define TWL4030_RESCONFIG_UNDEF        ((u8)-1)
+};
+
+extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
+
+struct twl4030_codec_audio_data {
+       unsigned int    audio_mclk;
+       unsigned int ramp_delay_value;
+       unsigned int hs_extmute:1;
+       void (*set_hs_extmute)(int mute);
+};
+
+struct twl4030_codec_vibra_data {
+       unsigned int    audio_mclk;
+       unsigned int    coexist;
+};
+
+struct twl4030_codec_data {
+       unsigned int    audio_mclk;
+       struct twl4030_codec_audio_data         *audio;
+       struct twl4030_codec_vibra_data         *vibra;
+};
+
+struct twl4030_platform_data {
+       unsigned                                irq_base, irq_end;
+       struct twl4030_clock_init_data          *clock;
+       struct twl4030_bci_platform_data        *bci;
+       struct twl4030_gpio_platform_data       *gpio;
+       struct twl4030_madc_platform_data       *madc;
+       struct twl4030_keypad_data              *keypad;
+       struct twl4030_usb_data                 *usb;
+       struct twl4030_power_data               *power;
+       struct twl4030_codec_data               *codec;
+
+       /* LDO regulators */
+       struct regulator_init_data              *vdac;
+       struct regulator_init_data              *vpll1;
+       struct regulator_init_data              *vpll2;
+       struct regulator_init_data              *vmmc1;
+       struct regulator_init_data              *vmmc2;
+       struct regulator_init_data              *vsim;
+       struct regulator_init_data              *vaux1;
+       struct regulator_init_data              *vaux2;
+       struct regulator_init_data              *vaux3;
+       struct regulator_init_data              *vaux4;
+       struct regulator_init_data              *vio;
+       struct regulator_init_data              *vdd1;
+       struct regulator_init_data              *vdd2;
+       struct regulator_init_data              *vintana1;
+       struct regulator_init_data              *vintana2;
+       struct regulator_init_data              *vintdig;
+};
+
+/*----------------------------------------------------------------------*/
+
+int twl4030_sih_setup(int module);
+
+/* Offsets to Power Registers */
+#define TWL4030_VDAC_DEV_GRP           0x3B
+#define TWL4030_VDAC_DEDICATED         0x3E
+#define TWL4030_VAUX1_DEV_GRP          0x17
+#define TWL4030_VAUX1_DEDICATED                0x1A
+#define TWL4030_VAUX2_DEV_GRP          0x1B
+#define TWL4030_VAUX2_DEDICATED                0x1E
+#define TWL4030_VAUX3_DEV_GRP          0x1F
+#define TWL4030_VAUX3_DEDICATED                0x22
+
+#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
+       defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
+       extern int twl4030charger_usb_en(int enable);
+#else
+       static inline int twl4030charger_usb_en(int enable) { return 0; }
+#endif
+
+/*----------------------------------------------------------------------*/
+
+/* Linux-specific regulator identifiers ... for now, we only support
+ * the LDOs, and leave the three buck converters alone.  VDD1 and VDD2
+ * need to tie into hardware based voltage scaling (cpufreq etc), while
+ * VIO is generally fixed.
+ */
+
+/* EXTERNAL dc-to-dc buck converters */
+#define TWL4030_REG_VDD1       0
+#define TWL4030_REG_VDD2       1
+#define TWL4030_REG_VIO                2
+
+/* EXTERNAL LDOs */
+#define TWL4030_REG_VDAC       3
+#define TWL4030_REG_VPLL1      4
+#define TWL4030_REG_VPLL2      5       /* not on all chips */
+#define TWL4030_REG_VMMC1      6
+#define TWL4030_REG_VMMC2      7       /* not on all chips */
+#define TWL4030_REG_VSIM       8       /* not on all chips */
+#define TWL4030_REG_VAUX1      9       /* not on all chips */
+#define TWL4030_REG_VAUX2_4030 10      /* (twl4030-specific) */
+#define TWL4030_REG_VAUX2      11      /* (twl5030 and newer) */
+#define TWL4030_REG_VAUX3      12      /* not on all chips */
+#define TWL4030_REG_VAUX4      13      /* not on all chips */
+
+/* INTERNAL LDOs */
+#define TWL4030_REG_VINTANA1   14
+#define TWL4030_REG_VINTANA2   15
+#define TWL4030_REG_VINTDIG    16
+#define TWL4030_REG_VUSB1V5    17
+#define TWL4030_REG_VUSB1V8    18
+#define TWL4030_REG_VUSB3V1    19
+
+#endif /* End of __TWL4030_H */
diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h
deleted file mode 100644 (file)
index a50bcf8..0000000
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * twl4030.h - header for TWL4030 PM and audio CODEC device
- *
- * Copyright (C) 2005-2006 Texas Instruments, Inc.
- *
- * Based on tlv320aic23.c:
- * Copyright (c) by Kai Svahn <kai.svahn@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
- *
- */
-
-#ifndef __TWL4030_H_
-#define __TWL4030_H_
-
-#include <linux/types.h>
-#include <linux/input/matrix_keypad.h>
-
-/*
- * Using the twl4030 core we address registers using a pair
- *     { module id, relative register offset }
- * which that core then maps to the relevant
- *     { i2c slave, absolute register address }
- *
- * The module IDs are meaningful only to the twl4030 core code,
- * which uses them as array indices to look up the first register
- * address each module uses within a given i2c slave.
- */
-
-/* Slave 0 (i2c address 0x48) */
-#define TWL4030_MODULE_USB             0x00
-
-/* Slave 1 (i2c address 0x49) */
-#define TWL4030_MODULE_AUDIO_VOICE     0x01
-#define TWL4030_MODULE_GPIO            0x02
-#define TWL4030_MODULE_INTBR           0x03
-#define TWL4030_MODULE_PIH             0x04
-#define TWL4030_MODULE_TEST            0x05
-
-/* Slave 2 (i2c address 0x4a) */
-#define TWL4030_MODULE_KEYPAD          0x06
-#define TWL4030_MODULE_MADC            0x07
-#define TWL4030_MODULE_INTERRUPTS      0x08
-#define TWL4030_MODULE_LED             0x09
-#define TWL4030_MODULE_MAIN_CHARGE     0x0A
-#define TWL4030_MODULE_PRECHARGE       0x0B
-#define TWL4030_MODULE_PWM0            0x0C
-#define TWL4030_MODULE_PWM1            0x0D
-#define TWL4030_MODULE_PWMA            0x0E
-#define TWL4030_MODULE_PWMB            0x0F
-
-#define TWL5031_MODULE_ACCESSORY       0x10
-#define TWL5031_MODULE_INTERRUPTS      0x11
-
-/* Slave 3 (i2c address 0x4b) */
-#define TWL4030_MODULE_BACKUP          0x12
-#define TWL4030_MODULE_INT             0x13
-#define TWL4030_MODULE_PM_MASTER       0x14
-#define TWL4030_MODULE_PM_RECEIVER     0x15
-#define TWL4030_MODULE_RTC             0x16
-#define TWL4030_MODULE_SECURED_REG     0x17
-
-/*
- * Read and write single 8-bit registers
- */
-int twl4030_i2c_write_u8(u8 mod_no, u8 val, u8 reg);
-int twl4030_i2c_read_u8(u8 mod_no, u8 *val, u8 reg);
-
-/*
- * Read and write several 8-bit registers at once.
- *
- * IMPORTANT:  For twl4030_i2c_write(), allocate num_bytes + 1
- * for the value, and populate your data starting at offset 1.
- */
-int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
-int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes);
-
-/*----------------------------------------------------------------------*/
-
-/*
- * NOTE:  at up to 1024 registers, this is a big chip.
- *
- * Avoid putting register declarations in this file, instead of into
- * a driver-private file, unless some of the registers in a block
- * need to be shared with other drivers.  One example is blocks that
- * have Secondary IRQ Handler (SIH) registers.
- */
-
-#define TWL4030_SIH_CTRL_EXCLEN_MASK   BIT(0)
-#define TWL4030_SIH_CTRL_PENDDIS_MASK  BIT(1)
-#define TWL4030_SIH_CTRL_COR_MASK      BIT(2)
-
-/*----------------------------------------------------------------------*/
-
-/*
- * GPIO Block Register offsets (use TWL4030_MODULE_GPIO)
- */
-
-#define REG_GPIODATAIN1                        0x0
-#define REG_GPIODATAIN2                        0x1
-#define REG_GPIODATAIN3                        0x2
-#define REG_GPIODATADIR1               0x3
-#define REG_GPIODATADIR2               0x4
-#define REG_GPIODATADIR3               0x5
-#define REG_GPIODATAOUT1               0x6
-#define REG_GPIODATAOUT2               0x7
-#define REG_GPIODATAOUT3               0x8
-#define REG_CLEARGPIODATAOUT1          0x9
-#define REG_CLEARGPIODATAOUT2          0xA
-#define REG_CLEARGPIODATAOUT3          0xB
-#define REG_SETGPIODATAOUT1            0xC
-#define REG_SETGPIODATAOUT2            0xD
-#define REG_SETGPIODATAOUT3            0xE
-#define REG_GPIO_DEBEN1                        0xF
-#define REG_GPIO_DEBEN2                        0x10
-#define REG_GPIO_DEBEN3                        0x11
-#define REG_GPIO_CTRL                  0x12
-#define REG_GPIOPUPDCTR1               0x13
-#define REG_GPIOPUPDCTR2               0x14
-#define REG_GPIOPUPDCTR3               0x15
-#define REG_GPIOPUPDCTR4               0x16
-#define REG_GPIOPUPDCTR5               0x17
-#define REG_GPIO_ISR1A                 0x19
-#define REG_GPIO_ISR2A                 0x1A
-#define REG_GPIO_ISR3A                 0x1B
-#define REG_GPIO_IMR1A                 0x1C
-#define REG_GPIO_IMR2A                 0x1D
-#define REG_GPIO_IMR3A                 0x1E
-#define REG_GPIO_ISR1B                 0x1F
-#define REG_GPIO_ISR2B                 0x20
-#define REG_GPIO_ISR3B                 0x21
-#define REG_GPIO_IMR1B                 0x22
-#define REG_GPIO_IMR2B                 0x23
-#define REG_GPIO_IMR3B                 0x24
-#define REG_GPIO_EDR1                  0x28
-#define REG_GPIO_EDR2                  0x29
-#define REG_GPIO_EDR3                  0x2A
-#define REG_GPIO_EDR4                  0x2B
-#define REG_GPIO_EDR5                  0x2C
-#define REG_GPIO_SIH_CTRL              0x2D
-
-/* Up to 18 signals are available as GPIOs, when their
- * pins are not assigned to another use (such as ULPI/USB).
- */
-#define TWL4030_GPIO_MAX               18
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Keypad register offsets (use TWL4030_MODULE_KEYPAD)
- * ... SIH/interrupt only
- */
-
-#define TWL4030_KEYPAD_KEYP_ISR1       0x11
-#define TWL4030_KEYPAD_KEYP_IMR1       0x12
-#define TWL4030_KEYPAD_KEYP_ISR2       0x13
-#define TWL4030_KEYPAD_KEYP_IMR2       0x14
-#define TWL4030_KEYPAD_KEYP_SIR                0x15    /* test register */
-#define TWL4030_KEYPAD_KEYP_EDR                0x16
-#define TWL4030_KEYPAD_KEYP_SIH_CTRL   0x17
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Multichannel ADC register offsets (use TWL4030_MODULE_MADC)
- * ... SIH/interrupt only
- */
-
-#define TWL4030_MADC_ISR1              0x61
-#define TWL4030_MADC_IMR1              0x62
-#define TWL4030_MADC_ISR2              0x63
-#define TWL4030_MADC_IMR2              0x64
-#define TWL4030_MADC_SIR               0x65    /* test register */
-#define TWL4030_MADC_EDR               0x66
-#define TWL4030_MADC_SIH_CTRL          0x67
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Battery charger register offsets (use TWL4030_MODULE_INTERRUPTS)
- */
-
-#define TWL4030_INTERRUPTS_BCIISR1A    0x0
-#define TWL4030_INTERRUPTS_BCIISR2A    0x1
-#define TWL4030_INTERRUPTS_BCIIMR1A    0x2
-#define TWL4030_INTERRUPTS_BCIIMR2A    0x3
-#define TWL4030_INTERRUPTS_BCIISR1B    0x4
-#define TWL4030_INTERRUPTS_BCIISR2B    0x5
-#define TWL4030_INTERRUPTS_BCIIMR1B    0x6
-#define TWL4030_INTERRUPTS_BCIIMR2B    0x7
-#define TWL4030_INTERRUPTS_BCISIR1     0x8     /* test register */
-#define TWL4030_INTERRUPTS_BCISIR2     0x9     /* test register */
-#define TWL4030_INTERRUPTS_BCIEDR1     0xa
-#define TWL4030_INTERRUPTS_BCIEDR2     0xb
-#define TWL4030_INTERRUPTS_BCIEDR3     0xc
-#define TWL4030_INTERRUPTS_BCISIHCTRL  0xd
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Power Interrupt block register offsets (use TWL4030_MODULE_INT)
- */
-
-#define TWL4030_INT_PWR_ISR1           0x0
-#define TWL4030_INT_PWR_IMR1           0x1
-#define TWL4030_INT_PWR_ISR2           0x2
-#define TWL4030_INT_PWR_IMR2           0x3
-#define TWL4030_INT_PWR_SIR            0x4     /* test register */
-#define TWL4030_INT_PWR_EDR1           0x5
-#define TWL4030_INT_PWR_EDR2           0x6
-#define TWL4030_INT_PWR_SIH_CTRL       0x7
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Accessory Interrupts
- */
-#define TWL5031_ACIIMR_LSB             0x05
-#define TWL5031_ACIIMR_MSB             0x06
-#define TWL5031_ACIIDR_LSB             0x07
-#define TWL5031_ACIIDR_MSB             0x08
-#define TWL5031_ACCISR1                        0x0F
-#define TWL5031_ACCIMR1                        0x10
-#define TWL5031_ACCISR2                        0x11
-#define TWL5031_ACCIMR2                        0x12
-#define TWL5031_ACCSIR                 0x13
-#define TWL5031_ACCEDR1                        0x14
-#define TWL5031_ACCSIHCTRL             0x15
-
-/*----------------------------------------------------------------------*/
-
-/*
- * Battery Charger Controller
- */
-
-#define TWL5031_INTERRUPTS_BCIISR1     0x0
-#define TWL5031_INTERRUPTS_BCIIMR1     0x1
-#define TWL5031_INTERRUPTS_BCIISR2     0x2
-#define TWL5031_INTERRUPTS_BCIIMR2     0x3
-#define TWL5031_INTERRUPTS_BCISIR      0x4
-#define TWL5031_INTERRUPTS_BCIEDR1     0x5
-#define TWL5031_INTERRUPTS_BCIEDR2     0x6
-#define TWL5031_INTERRUPTS_BCISIHCTRL  0x7
-
-/*----------------------------------------------------------------------*/
-
-/* Power bus message definitions */
-
-/* The TWL4030/5030 splits its power-management resources (the various
- * regulators, clock and reset lines) into 3 processor groups - P1, P2 and
- * P3. These groups can then be configured to transition between sleep, wait-on
- * and active states by sending messages to the power bus.  See Section 5.4.2
- * Power Resources of TWL4030 TRM
- */
-
-/* Processor groups */
-#define DEV_GRP_NULL           0x0
-#define DEV_GRP_P1             0x1     /* P1: all OMAP devices */
-#define DEV_GRP_P2             0x2     /* P2: all Modem devices */
-#define DEV_GRP_P3             0x4     /* P3: all peripheral devices */
-
-/* Resource groups */
-#define RES_GRP_RES            0x0     /* Reserved */
-#define RES_GRP_PP             0x1     /* Power providers */
-#define RES_GRP_RC             0x2     /* Reset and control */
-#define RES_GRP_PP_RC          0x3
-#define RES_GRP_PR             0x4     /* Power references */
-#define RES_GRP_PP_PR          0x5
-#define RES_GRP_RC_PR          0x6
-#define RES_GRP_ALL            0x7     /* All resource groups */
-
-#define RES_TYPE2_R0           0x0
-
-#define RES_TYPE_ALL           0x7
-
-/* Resource states */
-#define RES_STATE_WRST         0xF
-#define RES_STATE_ACTIVE       0xE
-#define RES_STATE_SLEEP                0x8
-#define RES_STATE_OFF          0x0
-
-/* Power resources */
-
-/* Power providers */
-#define RES_VAUX1               1
-#define RES_VAUX2               2
-#define RES_VAUX3               3
-#define RES_VAUX4               4
-#define RES_VMMC1               5
-#define RES_VMMC2               6
-#define RES_VPLL1               7
-#define RES_VPLL2               8
-#define RES_VSIM                9
-#define RES_VDAC                10
-#define RES_VINTANA1            11
-#define RES_VINTANA2            12
-#define RES_VINTDIG             13
-#define RES_VIO                 14
-#define RES_VDD1                15
-#define RES_VDD2                16
-#define RES_VUSB_1V5            17
-#define RES_VUSB_1V8            18
-#define RES_VUSB_3V1            19
-#define RES_VUSBCP              20
-#define RES_REGEN               21
-/* Reset and control */
-#define RES_NRES_PWRON          22
-#define RES_CLKEN               23
-#define RES_SYSEN               24
-#define RES_HFCLKOUT            25
-#define RES_32KCLKOUT           26
-#define RES_RESET               27
-/* Power Reference */
-#define RES_Main_Ref            28
-
-#define TOTAL_RESOURCES                28
-/*
- * Power Bus Message Format ... these can be sent individually by Linux,
- * but are usually part of downloaded scripts that are run when various
- * power events are triggered.
- *
- *  Broadcast Message (16 Bits):
- *    DEV_GRP[15:13] MT[12]  RES_GRP[11:9]  RES_TYPE2[8:7] RES_TYPE[6:4]
- *    RES_STATE[3:0]
- *
- *  Singular Message (16 Bits):
- *    DEV_GRP[15:13] MT[12]  RES_ID[11:4]  RES_STATE[3:0]
- */
-
-#define MSG_BROADCAST(devgrp, grp, type, type2, state) \
-       ( (devgrp) << 13 | 1 << 12 | (grp) << 9 | (type2) << 7 \
-       | (type) << 4 | (state))
-
-#define MSG_SINGULAR(devgrp, id, state) \
-       ((devgrp) << 13 | 0 << 12 | (id) << 4 | (state))
-
-/*----------------------------------------------------------------------*/
-
-struct twl4030_clock_init_data {
-       bool ck32k_lowpwr_enable;
-};
-
-struct twl4030_bci_platform_data {
-       int *battery_tmp_tbl;
-       unsigned int tblsize;
-};
-
-/* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */
-struct twl4030_gpio_platform_data {
-       int             gpio_base;
-       unsigned        irq_base, irq_end;
-
-       /* package the two LED signals as output-only GPIOs? */
-       bool            use_leds;
-
-       /* gpio-n should control VMMC(n+1) if BIT(n) in mmc_cd is set */
-       u8              mmc_cd;
-
-       /* if BIT(N) is set, or VMMC(n+1) is linked, debounce GPIO-N */
-       u32             debounce;
-
-       /* For gpio-N, bit (1 << N) in "pullups" is set if that pullup
-        * should be enabled.  Else, if that bit is set in "pulldowns",
-        * that pulldown is enabled.  Don't waste power by letting any
-        * digital inputs float...
-        */
-       u32             pullups;
-       u32             pulldowns;
-
-       int             (*setup)(struct device *dev,
-                               unsigned gpio, unsigned ngpio);
-       int             (*teardown)(struct device *dev,
-                               unsigned gpio, unsigned ngpio);
-};
-
-struct twl4030_madc_platform_data {
-       int             irq_line;
-};
-
-/* Boards have uniqe mappings of {row, col} --> keycode.
- * Column and row are 8 bits each, but range only from 0..7.
- * a PERSISTENT_KEY is "always on" and never reported.
- */
-#define PERSISTENT_KEY(r, c)   KEY((r), (c), KEY_RESERVED)
-
-struct twl4030_keypad_data {
-       const struct matrix_keymap_data *keymap_data;
-       unsigned rows;
-       unsigned cols;
-       bool rep;
-};
-
-enum twl4030_usb_mode {
-       T2_USB_MODE_ULPI = 1,
-       T2_USB_MODE_CEA2011_3PIN = 2,
-};
-
-struct twl4030_usb_data {
-       enum twl4030_usb_mode   usb_mode;
-};
-
-struct twl4030_ins {
-       u16 pmb_message;
-       u8 delay;
-};
-
-struct twl4030_script {
-       struct twl4030_ins *script;
-       unsigned size;
-       u8 flags;
-#define TWL4030_WRST_SCRIPT    (1<<0)
-#define TWL4030_WAKEUP12_SCRIPT        (1<<1)
-#define TWL4030_WAKEUP3_SCRIPT (1<<2)
-#define TWL4030_SLEEP_SCRIPT   (1<<3)
-};
-
-struct twl4030_resconfig {
-       u8 resource;
-       u8 devgroup;    /* Processor group that Power resource belongs to */
-       u8 type;        /* Power resource addressed, 6 / broadcast message */
-       u8 type2;       /* Power resource addressed, 3 / broadcast message */
-       u8 remap_off;   /* off state remapping */
-       u8 remap_sleep; /* sleep state remapping */
-};
-
-struct twl4030_power_data {
-       struct twl4030_script **scripts;
-       unsigned num;
-       struct twl4030_resconfig *resource_config;
-#define TWL4030_RESCONFIG_UNDEF        ((u8)-1)
-};
-
-extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
-
-struct twl4030_codec_audio_data {
-       unsigned int    audio_mclk;
-       unsigned int ramp_delay_value;
-       unsigned int hs_extmute:1;
-       void (*set_hs_extmute)(int mute);
-};
-
-struct twl4030_codec_vibra_data {
-       unsigned int    audio_mclk;
-       unsigned int    coexist;
-};
-
-struct twl4030_codec_data {
-       unsigned int    audio_mclk;
-       struct twl4030_codec_audio_data         *audio;
-       struct twl4030_codec_vibra_data         *vibra;
-};
-
-struct twl4030_platform_data {
-       unsigned                                irq_base, irq_end;
-       struct twl4030_clock_init_data          *clock;
-       struct twl4030_bci_platform_data        *bci;
-       struct twl4030_gpio_platform_data       *gpio;
-       struct twl4030_madc_platform_data       *madc;
-       struct twl4030_keypad_data              *keypad;
-       struct twl4030_usb_data                 *usb;
-       struct twl4030_power_data               *power;
-       struct twl4030_codec_data               *codec;
-
-       /* LDO regulators */
-       struct regulator_init_data              *vdac;
-       struct regulator_init_data              *vpll1;
-       struct regulator_init_data              *vpll2;
-       struct regulator_init_data              *vmmc1;
-       struct regulator_init_data              *vmmc2;
-       struct regulator_init_data              *vsim;
-       struct regulator_init_data              *vaux1;
-       struct regulator_init_data              *vaux2;
-       struct regulator_init_data              *vaux3;
-       struct regulator_init_data              *vaux4;
-       struct regulator_init_data              *vio;
-       struct regulator_init_data              *vdd1;
-       struct regulator_init_data              *vdd2;
-       struct regulator_init_data              *vintana1;
-       struct regulator_init_data              *vintana2;
-       struct regulator_init_data              *vintdig;
-};
-
-/*----------------------------------------------------------------------*/
-
-int twl4030_sih_setup(int module);
-
-/* Offsets to Power Registers */
-#define TWL4030_VDAC_DEV_GRP           0x3B
-#define TWL4030_VDAC_DEDICATED         0x3E
-#define TWL4030_VAUX1_DEV_GRP          0x17
-#define TWL4030_VAUX1_DEDICATED                0x1A
-#define TWL4030_VAUX2_DEV_GRP          0x1B
-#define TWL4030_VAUX2_DEDICATED                0x1E
-#define TWL4030_VAUX3_DEV_GRP          0x1F
-#define TWL4030_VAUX3_DEDICATED                0x22
-
-#if defined(CONFIG_TWL4030_BCI_BATTERY) || \
-       defined(CONFIG_TWL4030_BCI_BATTERY_MODULE)
-       extern int twl4030charger_usb_en(int enable);
-#else
-       static inline int twl4030charger_usb_en(int enable) { return 0; }
-#endif
-
-/*----------------------------------------------------------------------*/
-
-/* Linux-specific regulator identifiers ... for now, we only support
- * the LDOs, and leave the three buck converters alone.  VDD1 and VDD2
- * need to tie into hardware based voltage scaling (cpufreq etc), while
- * VIO is generally fixed.
- */
-
-/* EXTERNAL dc-to-dc buck converters */
-#define TWL4030_REG_VDD1       0
-#define TWL4030_REG_VDD2       1
-#define TWL4030_REG_VIO                2
-
-/* EXTERNAL LDOs */
-#define TWL4030_REG_VDAC       3
-#define TWL4030_REG_VPLL1      4
-#define TWL4030_REG_VPLL2      5       /* not on all chips */
-#define TWL4030_REG_VMMC1      6
-#define TWL4030_REG_VMMC2      7       /* not on all chips */
-#define TWL4030_REG_VSIM       8       /* not on all chips */
-#define TWL4030_REG_VAUX1      9       /* not on all chips */
-#define TWL4030_REG_VAUX2_4030 10      /* (twl4030-specific) */
-#define TWL4030_REG_VAUX2      11      /* (twl5030 and newer) */
-#define TWL4030_REG_VAUX3      12      /* not on all chips */
-#define TWL4030_REG_VAUX4      13      /* not on all chips */
-
-/* INTERNAL LDOs */
-#define TWL4030_REG_VINTANA1   14
-#define TWL4030_REG_VINTANA2   15
-#define TWL4030_REG_VINTDIG    16
-#define TWL4030_REG_VUSB1V5    17
-#define TWL4030_REG_VUSB1V8    18
-#define TWL4030_REG_VUSB3V1    19
-
-#endif /* End of __TWL4030_H */
index 5f1681f6ca766531d07270e82c1f81494f0d86a4..c3a6ceb542cbfa6b6e67406bfb1da27f11ba49e4 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
-#include <linux/i2c/twl4030.h>
+#include <linux/i2c/twl.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>