summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Denk <wd@denx.de>2009-07-30 00:36:25 +0200
committerWolfgang Denk <wd@denx.de>2009-07-30 00:36:25 +0200
commit108f56b056780f0d23f720d98709304f84a0d6c8 (patch)
tree2a2eb0ab998cfdbf6275dcf282ab282056a14f30
parent4c2e3da82dc2b7f8b39b7f1d57f570e4bc5caa6d (diff)
parentbb4291e62579dbc611e84eaaf973631e0bf129c7 (diff)
Merge branch 'master' of git://git.denx.de/u-boot-i2c
-rw-r--r--Makefile1
-rw-r--r--board/omap3/beagle/beagle.c4
-rw-r--r--board/omap3/common/power.c74
-rw-r--r--board/omap3/overo/overo.c4
-rw-r--r--board/omap3/pandora/pandora.c4
-rw-r--r--board/omap3/zoom1/zoom1.c12
-rw-r--r--board/omap3/zoom2/zoom2.c17
-rw-r--r--board/st/nhk8815/nhk8815.c16
-rw-r--r--cpu/arm926ejs/nomadik/Makefile2
-rw-r--r--cpu/arm926ejs/nomadik/gpio.c99
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/kirkwood_i2c.c484
-rw-r--r--drivers/i2c/omap24xx_i2c.c74
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/twl4030_led.c52
-rw-r--r--drivers/mmc/omap3_mmc.c13
-rw-r--r--drivers/power/Makefile (renamed from board/omap3/common/Makefile)25
-rw-r--r--drivers/power/twl4030.c115
-rw-r--r--include/asm-arm/arch-nomadik/gpio.h42
-rw-r--r--include/asm-arm/arch-omap24xx/i2c.h44
-rw-r--r--include/asm-arm/arch-omap3/i2c.h70
-rw-r--r--include/asm-arm/arch-omap3/omap3.h35
-rw-r--r--include/configs/nhk8815.h18
-rw-r--r--include/configs/omap3_beagle.h6
-rw-r--r--include/configs/omap3_evm.h5
-rw-r--r--include/configs/omap3_overo.h6
-rw-r--r--include/configs/omap3_pandora.h6
-rw-r--r--include/configs/omap3_zoom1.h6
-rw-r--r--include/configs/omap3_zoom2.h6
-rw-r--r--include/twl4030.h401
30 files changed, 1484 insertions, 159 deletions
diff --git a/Makefile b/Makefile
index ac844a7584..8096f91f00 100644
--- a/Makefile
+++ b/Makefile
@@ -221,6 +221,7 @@ LIBS += drivers/net/phy/libphy.a
LIBS += drivers/net/sk98lin/libsk98lin.a
LIBS += drivers/pci/libpci.a
LIBS += drivers/pcmcia/libpcmcia.a
+LIBS += drivers/power/libpower.a
LIBS += drivers/spi/libspi.a
ifeq ($(CPU),mpc83xx)
LIBS += drivers/qe/qe.a
diff --git a/board/omap3/beagle/beagle.c b/board/omap3/beagle/beagle.c
index d268e1870d..5423650df0 100644
--- a/board/omap3/beagle/beagle.c
+++ b/board/omap3/beagle/beagle.c
@@ -30,6 +30,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <twl4030.h>
#include <asm/io.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
@@ -105,7 +106,8 @@ int misc_init_r(void)
gpio_t *gpio5_base = (gpio_t *)OMAP34XX_GPIO5_BASE;
gpio_t *gpio6_base = (gpio_t *)OMAP34XX_GPIO6_BASE;
- power_init_r();
+ twl4030_power_init();
+ twl4030_led_init();
/* Configure GPIOs to output */
writel(~(GPIO23 | GPIO10 | GPIO8 | GPIO2 | GPIO1), &gpio6_base->oe);
diff --git a/board/omap3/common/power.c b/board/omap3/common/power.c
deleted file mode 100644
index 4908e5b9be..0000000000
--- a/board/omap3/common/power.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * (C) Copyright 2004-2008
- * Texas Instruments, <www.ti.com>
- *
- * Author :
- * Sunil Kumar <sunilsaini05@gmail.com>
- * Shashi Ranjan <shashiranjanmca05@gmail.com>
- *
- * Derived from Beagle Board and 3430 SDP code by
- * Richard Woodruff <r-woodruff2@ti.com>
- * Syed Mohammed Khasim <khasim@ti.com>
- *
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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 <common.h>
-#include <asm/arch/sys_proto.h>
-#include <i2c.h>
-
-/******************************************************************************
- * Routine: power_init_r
- * Description: Configure power supply
- *****************************************************************************/
-void power_init_r(void)
-{
- unsigned char byte;
-
-#ifdef CONFIG_DRIVER_OMAP34XX_I2C
- i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
-#endif
-
- /*
- * Configure OMAP3 supply voltages in power management
- * companion chip.
- */
-
- /* set VAUX3 to 2.8V */
- byte = DEV_GRP_P1;
- i2c_write(PWRMGT_ADDR_ID4, VAUX3_DEV_GRP, 1, &byte, 1);
- byte = VAUX3_VSEL_28;
- i2c_write(PWRMGT_ADDR_ID4, VAUX3_DEDICATED, 1, &byte, 1);
-
- /* set VPLL2 to 1.8V */
- byte = DEV_GRP_ALL;
- i2c_write(PWRMGT_ADDR_ID4, VPLL2_DEV_GRP, 1, &byte, 1);
- byte = VPLL2_VSEL_18;
- i2c_write(PWRMGT_ADDR_ID4, VPLL2_DEDICATED, 1, &byte, 1);
-
- /* set VDAC to 1.8V */
- byte = DEV_GRP_P1;
- i2c_write(PWRMGT_ADDR_ID4, VDAC_DEV_GRP, 1, &byte, 1);
- byte = VDAC_VSEL_18;
- i2c_write(PWRMGT_ADDR_ID4, VDAC_DEDICATED, 1, &byte, 1);
-
- /* enable LED */
- byte = LEDBPWM | LEDAPWM | LEDBON | LEDAON;
- i2c_write(PWRMGT_ADDR_ID3, LEDEN, 1, &byte, 1);
-}
diff --git a/board/omap3/overo/overo.c b/board/omap3/overo/overo.c
index 809b77b642..dd6d28622d 100644
--- a/board/omap3/overo/overo.c
+++ b/board/omap3/overo/overo.c
@@ -29,6 +29,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <twl4030.h>
#include <asm/io.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
@@ -58,7 +59,8 @@ int board_init(void)
*/
int misc_init_r(void)
{
- power_init_r();
+ twl4030_power_init();
+ twl4030_led_init();
dieid_num_r();
diff --git a/board/omap3/pandora/pandora.c b/board/omap3/pandora/pandora.c
index c2f98ead6a..1538efbb22 100644
--- a/board/omap3/pandora/pandora.c
+++ b/board/omap3/pandora/pandora.c
@@ -30,6 +30,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <twl4030.h>
#include <asm/io.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
@@ -64,7 +65,8 @@ int misc_init_r(void)
gpio_t *gpio5_base = (gpio_t *)OMAP34XX_GPIO5_BASE;
gpio_t *gpio6_base = (gpio_t *)OMAP34XX_GPIO6_BASE;
- power_init_r();
+ twl4030_power_init();
+ twl4030_led_init();
/* Configure GPIOs to output */
writel(~(GPIO14 | GPIO15 | GPIO16 | GPIO23), &gpio1_base->oe);
diff --git a/board/omap3/zoom1/zoom1.c b/board/omap3/zoom1/zoom1.c
index db4d08709f..f4d3754cac 100644
--- a/board/omap3/zoom1/zoom1.c
+++ b/board/omap3/zoom1/zoom1.c
@@ -31,6 +31,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <twl4030.h>
#include <asm/io.h>
#include <asm/arch/mux.h>
#include <asm/arch/sys_proto.h>
@@ -60,8 +61,17 @@ int board_init(void)
*/
int misc_init_r(void)
{
- power_init_r();
+ twl4030_power_init();
+ twl4030_led_init();
dieid_num_r();
+
+ /*
+ * Board Reset
+ * The board is reset by holding the red button on the
+ * top right front face for eight seconds.
+ */
+ twl4030_power_reset_init();
+
return 0;
}
diff --git a/board/omap3/zoom2/zoom2.c b/board/omap3/zoom2/zoom2.c
index 08fdafb644..94a985dcb3 100644
--- a/board/omap3/zoom2/zoom2.c
+++ b/board/omap3/zoom2/zoom2.c
@@ -32,6 +32,7 @@
#ifdef CONFIG_STATUS_LED
#include <status_led.h>
#endif
+#include <twl4030.h>
#include <asm/io.h>
#include <asm/arch/gpio.h>
#include <asm/arch/mem.h>
@@ -154,8 +155,22 @@ int board_init (void)
int misc_init_r(void)
{
zoom2_identify();
- power_init_r();
+ twl4030_power_init();
+ twl4030_led_init();
dieid_num_r();
+
+ /*
+ * Board Reset
+ * The board is reset by holding the the large button
+ * on the top right side of the main board for
+ * eight seconds.
+ *
+ * There are reported problems of some beta boards
+ * continously resetting. For those boards, disable resetting.
+ */
+ if (ZOOM2_REVISION_PRODUCTION <= zoom2_get_revision())
+ twl4030_power_reset_init();
+
return 0;
}
diff --git a/board/st/nhk8815/nhk8815.c b/board/st/nhk8815/nhk8815.c
index 085a5e0a42..1fa506a889 100644
--- a/board/st/nhk8815/nhk8815.c
+++ b/board/st/nhk8815/nhk8815.c
@@ -27,6 +27,7 @@
#include <common.h>
#include <asm/io.h>
+#include <asm/arch/gpio.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -61,9 +62,20 @@ int board_init(void)
return 0;
}
-int misc_init_r(void)
+int board_late_init(void)
{
- setenv("verify", "n");
+ /* Set the two I2C gpio lines to be gpio high */
+ nmk_gpio_set(__SCL, 1); nmk_gpio_set(__SDA, 1);
+ nmk_gpio_dir(__SCL, 1); nmk_gpio_dir(__SDA, 1);
+ nmk_gpio_af(__SCL, GPIO_GPIO); nmk_gpio_af(__SDA, GPIO_GPIO);
+
+ /* Reset the I2C port expander, on GPIO77 */
+ nmk_gpio_af(77, GPIO_GPIO);
+ nmk_gpio_dir(77, 1);
+ nmk_gpio_set(77, 0);
+ udelay(10);
+ nmk_gpio_set(77, 1);
+
return 0;
}
diff --git a/cpu/arm926ejs/nomadik/Makefile b/cpu/arm926ejs/nomadik/Makefile
index e3bd2eef41..0fc9f2a4c1 100644
--- a/cpu/arm926ejs/nomadik/Makefile
+++ b/cpu/arm926ejs/nomadik/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).a
-COBJS = timer.o
+COBJS = timer.o gpio.o
SOBJS = reset.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/cpu/arm926ejs/nomadik/gpio.c b/cpu/arm926ejs/nomadik/gpio.c
new file mode 100644
index 0000000000..62a375b5b5
--- /dev/null
+++ b/cpu/arm926ejs/nomadik/gpio.c
@@ -0,0 +1,99 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <common.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+
+static unsigned long gpio_base[4] = {
+ NOMADIK_GPIO0_BASE,
+ NOMADIK_GPIO1_BASE,
+ NOMADIK_GPIO2_BASE,
+ NOMADIK_GPIO3_BASE
+};
+
+enum gpio_registers {
+ GPIO_DAT = 0x00, /* data register */
+ GPIO_DATS = 0x04, /* data set */
+ GPIO_DATC = 0x08, /* data clear */
+ GPIO_PDIS = 0x0c, /* pull disable */
+ GPIO_DIR = 0x10, /* direction */
+ GPIO_DIRS = 0x14, /* direction set */
+ GPIO_DIRC = 0x18, /* direction clear */
+ GPIO_AFSLA = 0x20, /* alternate function select A */
+ GPIO_AFSLB = 0x24, /* alternate function select B */
+};
+
+static inline unsigned long gpio_to_base(int gpio)
+{
+ return gpio_base[gpio / 32];
+}
+
+static inline u32 gpio_to_bit(int gpio)
+{
+ return 1 << (gpio & 0x1f);
+}
+
+void nmk_gpio_af(int gpio, int alternate_function)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+ u32 afunc, bfunc;
+
+ /* alternate function is 0..3, with one bit per register */
+ afunc = readl(base + GPIO_AFSLA) & ~bit;
+ bfunc = readl(base + GPIO_AFSLB) & ~bit;
+ if (alternate_function & 1) afunc |= bit;
+ if (alternate_function & 2) bfunc |= bit;
+ writel(afunc, base + GPIO_AFSLA);
+ writel(bfunc, base + GPIO_AFSLB);
+}
+
+void nmk_gpio_dir(int gpio, int dir)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+
+ if (dir)
+ writel(bit, base + GPIO_DIRS);
+ else
+ writel(bit, base + GPIO_DIRC);
+}
+
+void nmk_gpio_set(int gpio, int val)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+
+ if (val)
+ writel(bit, base + GPIO_DATS);
+ else
+ writel(bit, base + GPIO_DATC);
+}
+
+int nmk_gpio_get(int gpio)
+{
+ unsigned long base = gpio_to_base(gpio);
+ u32 bit = gpio_to_bit(gpio);
+
+ return readl(base + GPIO_DAT) & bit;
+}
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index ef32f13377..4a12976e37 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -28,6 +28,7 @@ LIB := $(obj)libi2c.a
COBJS-$(CONFIG_BFIN_TWI_I2C) += bfin-twi_i2c.o
COBJS-$(CONFIG_DRIVER_DAVINCI_I2C) += davinci_i2c.o
COBJS-$(CONFIG_FSL_I2C) += fsl_i2c.o
+COBJS-$(CONFIG_I2C_KIRKWOOD) += kirkwood_i2c.o
COBJS-$(CONFIG_I2C_MXC) += mxc_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP1510_I2C) += omap1510_i2c.o
COBJS-$(CONFIG_DRIVER_OMAP24XX_I2C) += omap24xx_i2c.o
diff --git a/drivers/i2c/kirkwood_i2c.c b/drivers/i2c/kirkwood_i2c.c
new file mode 100644
index 0000000000..dd30499b3a
--- /dev/null
+++ b/drivers/i2c/kirkwood_i2c.c
@@ -0,0 +1,484 @@
+/*
+ * Driver for the i2c controller on the Marvell line of host bridges
+ * (e.g, gt642[46]0, mv643[46]0, mv644[46]0, Orion SoC family),
+ * and Kirkwood family.
+ *
+ * Based on:
+ * Author: Mark A. Greer <mgreer@mvista.com>
+ *
+ * 2005 (c) MontaVista, Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * ported from Linux to u-boot
+ * (C) Copyright 2009
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ */
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/kirkwood.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static unsigned int i2c_bus_num __attribute__ ((section (".data"))) = 0;
+#if defined(CONFIG_I2C_MUX)
+static unsigned int i2c_bus_num_mux __attribute__ ((section ("data"))) = 0;
+#endif
+
+/* Register defines */
+#define KW_I2C_REG_SLAVE_ADDR 0x00
+#define KW_I2C_REG_DATA 0x04
+#define KW_I2C_REG_CONTROL 0x08
+#define KW_I2C_REG_STATUS 0x0c
+#define KW_I2C_REG_BAUD 0x0c
+#define KW_I2C_REG_EXT_SLAVE_ADDR 0x10
+#define KW_I2C_REG_SOFT_RESET 0x1c
+
+#define KW_I2C_REG_CONTROL_ACK 0x00000004
+#define KW_I2C_REG_CONTROL_IFLG 0x00000008
+#define KW_I2C_REG_CONTROL_STOP 0x00000010
+#define KW_I2C_REG_CONTROL_START 0x00000020
+#define KW_I2C_REG_CONTROL_TWSIEN 0x00000040
+#define KW_I2C_REG_CONTROL_INTEN 0x00000080
+
+/* Ctlr status values */
+#define KW_I2C_STATUS_BUS_ERR 0x00
+#define KW_I2C_STATUS_MAST_START 0x08
+#define KW_I2C_STATUS_MAST_REPEAT_START 0x10
+#define KW_I2C_STATUS_MAST_WR_ADDR_ACK 0x18
+#define KW_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20
+#define KW_I2C_STATUS_MAST_WR_ACK 0x28
+#define KW_I2C_STATUS_MAST_WR_NO_ACK 0x30
+#define KW_I2C_STATUS_MAST_LOST_ARB 0x38
+#define KW_I2C_STATUS_MAST_RD_ADDR_ACK 0x40
+#define KW_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48
+#define KW_I2C_STATUS_MAST_RD_DATA_ACK 0x50
+#define KW_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58
+#define KW_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0
+#define KW_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8
+#define KW_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0
+#define KW_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8
+#define KW_I2C_STATUS_NO_STATUS 0xf8
+
+/* Driver states */
+enum {
+ KW_I2C_STATE_INVALID,
+ KW_I2C_STATE_IDLE,
+ KW_I2C_STATE_WAITING_FOR_START_COND,
+ KW_I2C_STATE_WAITING_FOR_ADDR_1_ACK,
+ KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK,
+ KW_I2C_STATE_WAITING_FOR_SLAVE_ACK,
+ KW_I2C_STATE_WAITING_FOR_SLAVE_DATA,
+};
+
+/* Driver actions */
+enum {
+ KW_I2C_ACTION_INVALID,
+ KW_I2C_ACTION_CONTINUE,
+ KW_I2C_ACTION_SEND_START,
+ KW_I2C_ACTION_SEND_ADDR_1,
+ KW_I2C_ACTION_SEND_ADDR_2,
+ KW_I2C_ACTION_SEND_DATA,
+ KW_I2C_ACTION_RCV_DATA,
+ KW_I2C_ACTION_RCV_DATA_STOP,
+ KW_I2C_ACTION_SEND_STOP,
+};
+
+/* defines to get compatible with Linux driver */
+#define IRQ_NONE 0x0
+#define IRQ_HANDLED 0x01
+
+#define I2C_M_TEN 0x01
+#define I2C_M_RD 0x02
+#define I2C_M_REV_DIR_ADDR 0x04;
+
+struct i2c_msg {
+ u32 addr;
+ u32 flags;
+ u8 *buf;
+ u32 len;
+};
+
+struct kirkwood_i2c_data {
+ int irq;
+ u32 state;
+ u32 action;
+ u32 aborting;
+ u32 cntl_bits;
+ void *reg_base;
+ u32 reg_base_p;
+ u32 reg_size;
+ u32 addr1;
+ u32 addr2;
+ u32 bytes_left;
+ u32 byte_posn;
+ u32 block;
+ int rc;
+ u32 freq_m;
+ u32 freq_n;
+ struct i2c_msg *msg;
+};
+
+static struct kirkwood_i2c_data __drv_data __attribute__ ((section (".data")));
+static struct kirkwood_i2c_data *drv_data = &__drv_data;
+static struct i2c_msg __i2c_msg __attribute__ ((section (".data")));
+static struct i2c_msg *kirkwood_i2c_msg = &__i2c_msg;
+
+/*
+ *****************************************************************************
+ *
+ * Finite State Machine & Interrupt Routines
+ *
+ *****************************************************************************
+ */
+
+static inline int abs(int n)
+{
+ if(n >= 0)
+ return n;
+ else
+ return n * -1;
+}
+
+static void kirkwood_calculate_speed(int speed)
+{
+ int calcspeed;
+ int diff;
+ int best_diff = CONFIG_SYS_TCLK;
+ int best_speed = 0;
+ int m, n;
+ int tmp[8] = {2, 4, 8, 16, 32, 64, 128, 256};
+
+ for (n = 0; n < 8; n++) {
+ for (m = 0; m < 16; m++) {
+ calcspeed = CONFIG_SYS_TCLK / (10 * (m + 1) * tmp[n]);
+ diff = abs((speed - calcspeed));
+ if ( diff < best_diff) {
+ best_diff = diff;
+ best_speed = calcspeed;
+ drv_data->freq_m = m;
+ drv_data->freq_n = n;
+ }
+ }
+ }
+}
+
+/* Reset hardware and initialize FSM */
+static void
+kirkwood_i2c_hw_init(int speed, int slaveadd)
+{
+ drv_data->state = KW_I2C_STATE_IDLE;
+
+ kirkwood_calculate_speed(speed);
+ writel(0, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_SOFT_RESET);
+ writel((((drv_data->freq_m & 0xf) << 3) | (drv_data->freq_n & 0x7)),
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_BAUD);
+ writel(slaveadd, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_SLAVE_ADDR);
+ writel(0, CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_EXT_SLAVE_ADDR);
+ writel(KW_I2C_REG_CONTROL_TWSIEN | KW_I2C_REG_CONTROL_STOP,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+}
+
+static void
+kirkwood_i2c_fsm(u32 status)
+{
+ /*
+ * If state is idle, then this is likely the remnants of an old
+ * operation that driver has given up on or the user has killed.
+ * If so, issue the stop condition and go to idle.
+ */
+ if (drv_data->state == KW_I2C_STATE_IDLE) {
+ drv_data->action = KW_I2C_ACTION_SEND_STOP;
+ return;
+ }
+
+ /* The status from the ctlr [mostly] tells us what to do next */
+ switch (status) {
+ /* Start condition interrupt */
+ case KW_I2C_STATUS_MAST_START: /* 0x08 */
+ case KW_I2C_STATUS_MAST_REPEAT_START: /* 0x10 */
+ drv_data->action = KW_I2C_ACTION_SEND_ADDR_1;
+ drv_data->state = KW_I2C_STATE_WAITING_FOR_ADDR_1_ACK;
+ break;
+
+ /* Performing a write */
+ case KW_I2C_STATUS_MAST_WR_ADDR_ACK: /* 0x18 */
+ if (drv_data->msg->flags & I2C_M_TEN) {
+ drv_data->action = KW_I2C_ACTION_SEND_ADDR_2;
+ drv_data->state =
+ KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
+ break;
+ }
+ /* FALLTHRU */
+ case KW_I2C_STATUS_MAST_WR_ADDR_2_ACK: /* 0xd0 */
+ case KW_I2C_STATUS_MAST_WR_ACK: /* 0x28 */
+ if ((drv_data->bytes_left == 0)
+ || (drv_data->aborting
+ && (drv_data->byte_posn != 0))) {
+ drv_data->action = KW_I2C_ACTION_SEND_STOP;
+ drv_data->state = KW_I2C_STATE_IDLE;
+ } else {
+ drv_data->action = KW_I2C_ACTION_SEND_DATA;
+ drv_data->state =
+ KW_I2C_STATE_WAITING_FOR_SLAVE_ACK;
+ drv_data->bytes_left--;
+ }
+ break;
+
+ /* Performing a read */
+ case KW_I2C_STATUS_MAST_RD_ADDR_ACK: /* 40 */
+ if (drv_data->msg->flags & I2C_M_TEN) {
+ drv_data->action = KW_I2C_ACTION_SEND_ADDR_2;
+ drv_data->state =
+ KW_I2C_STATE_WAITING_FOR_ADDR_2_ACK;
+ break;
+ }
+ /* FALLTHRU */
+ case KW_I2C_STATUS_MAST_RD_ADDR_2_ACK: /* 0xe0 */
+ if (drv_data->bytes_left == 0) {
+ drv_data->action = KW_I2C_ACTION_SEND_STOP;
+ drv_data->state = KW_I2C_STATE_IDLE;
+ break;
+ }
+ /* FALLTHRU */
+ case KW_I2C_STATUS_MAST_RD_DATA_ACK: /* 0x50 */
+ if (status != KW_I2C_STATUS_MAST_RD_DATA_ACK)
+ drv_data->action = KW_I2C_ACTION_CONTINUE;
+ else {
+ drv_data->action = KW_I2C_ACTION_RCV_DATA;
+ drv_data->bytes_left--;
+ }
+ drv_data->state = KW_I2C_STATE_WAITING_FOR_SLAVE_DATA;
+
+ if ((drv_data->bytes_left == 1) || drv_data->aborting)
+ drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_ACK;
+ break;
+
+ case KW_I2C_STATUS_MAST_RD_DATA_NO_ACK: /* 0x58 */
+ drv_data->action = KW_I2C_ACTION_RCV_DATA_STOP;
+ drv_data->state = KW_I2C_STATE_IDLE;
+ break;
+
+ case KW_I2C_STATUS_MAST_WR_ADDR_NO_ACK: /* 0x20 */
+ case KW_I2C_STATUS_MAST_WR_NO_ACK: /* 30 */
+ case KW_I2C_STATUS_MAST_RD_ADDR_NO_ACK: /* 48 */
+ /* Doesn't seem to be a device at other end */
+ drv_data->action = KW_I2C_ACTION_SEND_STOP;
+ drv_data->state = KW_I2C_STATE_IDLE;
+ drv_data->rc = -ENODEV;
+ break;
+
+ default:
+ printf("kirkwood_i2c_fsm: Ctlr Error -- state: 0x%x, "
+ "status: 0x%x, addr: 0x%x, flags: 0x%x\n",
+ drv_data->state, status, drv_data->msg->addr,
+ drv_data->msg->flags);
+ drv_data->action = KW_I2C_ACTION_SEND_STOP;
+ kirkwood_i2c_hw_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+ drv_data->rc = -EIO;
+ }
+}
+
+static void
+kirkwood_i2c_do_action(void)
+{
+ switch(drv_data->action) {
+ case KW_I2C_ACTION_CONTINUE:
+ writel(drv_data->cntl_bits,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ break;
+
+ case KW_I2C_ACTION_SEND_START:
+ writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_START,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ break;
+
+ case KW_I2C_ACTION_SEND_ADDR_1:
+ writel(drv_data->addr1,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
+ writel(drv_data->cntl_bits,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ break;
+
+ case KW_I2C_ACTION_SEND_ADDR_2:
+ writel(drv_data->addr2,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
+ writel(drv_data->cntl_bits,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ break;
+
+ case KW_I2C_ACTION_SEND_DATA:
+ writel(drv_data->msg->buf[drv_data->byte_posn++],
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
+ writel(drv_data->cntl_bits,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ break;
+
+ case KW_I2C_ACTION_RCV_DATA:
+ drv_data->msg->buf[drv_data->byte_posn++] =
+ readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
+ writel(drv_data->cntl_bits,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ break;
+
+ case KW_I2C_ACTION_RCV_DATA_STOP:
+ drv_data->msg->buf[drv_data->byte_posn++] =
+ readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_DATA);
+ drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_INTEN;
+ writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_STOP,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ drv_data->block = 0;
+ break;
+
+ case KW_I2C_ACTION_INVALID:
+ default:
+ printf("kirkwood_i2c_do_action: Invalid action: %d\n",
+ drv_data->action);
+ drv_data->rc = -EIO;
+ /* FALLTHRU */
+ case KW_I2C_ACTION_SEND_STOP:
+ drv_data->cntl_bits &= ~KW_I2C_REG_CONTROL_INTEN;
+ writel(drv_data->cntl_bits | KW_I2C_REG_CONTROL_STOP,
+ CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ drv_data->block = 0;
+ break;
+ }
+}
+
+static int
+kirkwood_i2c_intr(void)
+{
+ u32 status;
+ u32 ctrl;
+ int rc = IRQ_NONE;
+
+ ctrl = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ while ((ctrl & KW_I2C_REG_CONTROL_IFLG) &&
+ (drv_data->rc == 0)) {
+ status = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_STATUS);
+ kirkwood_i2c_fsm(status);
+ kirkwood_i2c_do_action();
+ rc = IRQ_HANDLED;
+ ctrl = readl(CONFIG_I2C_KW_REG_BASE + KW_I2C_REG_CONTROL);
+ udelay(1000);
+ }
+ return rc;
+}
+
+static void
+kirkwood_i2c_doio(struct i2c_msg *msg)
+{
+ int ret;
+
+ while ((drv_data->rc == 0) && (drv_data->state != KW_I2C_STATE_IDLE)) {
+ /* poll Status register */
+ ret = kirkwood_i2c_intr();
+ if (ret == IRQ_NONE)
+ udelay(10);
+ }
+}
+
+static void
+kirkwood_i2c_prepare_for_io(struct i2c_msg *msg)
+{
+ u32 dir = 0;
+
+ drv_data->msg = msg;
+ drv_data->byte_posn = 0;
+ drv_data->bytes_left = msg->len;
+ drv_data->aborting = 0;
+ drv_data->rc = 0;
+ /* in u-boot we use no IRQs */
+ drv_data->cntl_bits = KW_I2C_REG_CONTROL_ACK | KW_I2C_REG_CONTROL_TWSIEN;
+
+ if (msg->flags & I2C_M_RD)
+ dir = 1;
+ if (msg->flags & I2C_M_TEN) {
+ drv_data->addr1 = 0xf0 | (((u32)msg->addr & 0x300) >> 7) | dir;
+ drv_data->addr2 = (u32)msg->addr & 0xff;
+ } else {
+ drv_data->addr1 = ((u32)msg->addr & 0x7f) << 1 | dir;
+ drv_data->addr2 = 0;
+ }
+ /* OK, no start it (from kirkwood_i2c_execute_msg())*/
+ drv_data->action = KW_I2C_ACTION_SEND_START;
+ drv_data->state = KW_I2C_STATE_WAITING_FOR_START_COND;
+ drv_data->block = 1;
+ kirkwood_i2c_do_action();
+}
+
+void
+i2c_init(int speed, int slaveadd)
+{
+ kirkwood_i2c_hw_init(speed, slaveadd);
+}
+
+int
+i2c_read(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ kirkwood_i2c_msg->buf = data;
+ kirkwood_i2c_msg->len = length;
+ kirkwood_i2c_msg->addr = dev;
+ kirkwood_i2c_msg->flags = I2C_M_RD;
+
+ kirkwood_i2c_prepare_for_io(kirkwood_i2c_msg);
+ kirkwood_i2c_doio(kirkwood_i2c_msg);
+ return drv_data->rc;
+}
+
+int
+i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)
+{
+ kirkwood_i2c_msg->buf = data;
+ kirkwood_i2c_msg->len = length;
+ kirkwood_i2c_msg->addr = dev;
+ kirkwood_i2c_msg->flags = 0;
+
+ kirkwood_i2c_prepare_for_io(kirkwood_i2c_msg);
+ kirkwood_i2c_doio(kirkwood_i2c_msg);
+ return drv_data->rc;
+}
+
+int
+i2c_probe(uchar chip)
+{
+ return i2c_read(chip, 0, 0, NULL, 0);
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+#if defined(CONFIG_I2C_MUX)
+ if (bus < CONFIG_SYS_MAX_I2C_BUS) {
+ i2c_bus_num = bus;
+ } else {
+ int ret;
+
+ ret = i2x_mux_select_mux(bus);
+ if (ret)
+ return ret;
+ i2c_bus_num = 0;
+ }
+ i2c_bus_num_mux = bus;
+#else
+ if (bus > 0) {
+ return -1;
+ }
+
+ i2c_bus_num = bus;
+#endif
+ return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+#if defined(CONFIG_I2C_MUX)
+ return i2c_bus_num_mux;
+#else
+ return i2c_bus_num;
+#endif
+}
+
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index 678460325d..1a4c8c9ad2 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -31,7 +31,69 @@ static void flush_fifo(void);
void i2c_init (int speed, int slaveadd)
{
- u16 scl;
+ int psc, fsscll, fssclh;
+ int hsscll = 0, hssclh = 0;
+ u32 scll, sclh;
+
+ /* Only handle standard, fast and high speeds */
+ if ((speed != OMAP_I2C_STANDARD) &&
+ (speed != OMAP_I2C_FAST_MODE) &&
+ (speed != OMAP_I2C_HIGH_SPEED)) {
+ printf("Error : I2C unsupported speed %d\n", speed);
+ return;
+ }
+
+ psc = I2C_IP_CLK / I2C_INTERNAL_SAMPLING_CLK;
+ psc -= 1;
+ if (psc < I2C_PSC_MIN) {
+ printf("Error : I2C unsupported prescalar %d\n", psc);
+ return;
+ }
+
+ if (speed == OMAP_I2C_HIGH_SPEED) {
+ /* High speed */
+
+ /* For first phase of HS mode */
+ fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK /
+ (2 * OMAP_I2C_FAST_MODE);
+
+ fsscll -= I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM;
+ fssclh -= I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM;
+ if (((fsscll < 0) || (fssclh < 0)) ||
+ ((fsscll > 255) || (fssclh > 255))) {
+ printf("Error : I2C initializing first phase clock\n");
+ return;
+ }
+
+ /* For second phase of HS mode */
+ hsscll = hssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);
+
+ hsscll -= I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM;
+ hssclh -= I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM;
+ if (((fsscll < 0) || (fssclh < 0)) ||
+ ((fsscll > 255) || (fssclh > 255))) {
+ printf("Error : I2C initializing second phase clock\n");
+ return;
+ }
+
+ scll = (unsigned int)hsscll << 8 | (unsigned int)fsscll;
+ sclh = (unsigned int)hssclh << 8 | (unsigned int)fssclh;
+
+ } else {
+ /* Standard and fast speed */
+ fsscll = fssclh = I2C_INTERNAL_SAMPLING_CLK / (2 * speed);
+
+ fsscll -= I2C_FASTSPEED_SCLL_TRIM;
+ fssclh -= I2C_FASTSPEED_SCLH_TRIM;
+ if (((fsscll < 0) || (fssclh < 0)) ||
+ ((fsscll > 255) || (fssclh > 255))) {
+ printf("Error : I2C initializing clock\n");
+ return;
+ }
+
+ scll = (unsigned int)fsscll;
+ sclh = (unsigned int)fssclh;
+ }
writew(0x2, I2C_SYSC); /* for ES2 after soft reset */
udelay(1000);
@@ -42,12 +104,10 @@ void i2c_init (int speed, int slaveadd)
udelay (50000);
}
- /* 12MHz I2C module clock */
- writew (0, I2C_PSC);
- speed = speed/1000; /* 100 or 400 */
- scl = ((12000/(speed*2)) - 7); /* use 7 when PSC = 0 */
- writew (scl, I2C_SCLL);
- writew (scl, I2C_SCLH);
+ writew(psc, I2C_PSC);
+ writew(scll, I2C_SCLL);
+ writew(sclh, I2C_SCLH);
+
/* own address */
writew (slaveadd, I2C_OA);
writew (I2C_CON_EN, I2C_CON);
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index ea2bf87ec8..f6df60faef 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -30,6 +30,7 @@ COBJS-$(CONFIG_DS4510) += ds4510.o
COBJS-$(CONFIG_FSL_LAW) += fsl_law.o
COBJS-$(CONFIG_NS87308) += ns87308.o
COBJS-$(CONFIG_STATUS_LED) += status_led.o
+COBJS-$(CONFIG_TWL4030_LED) += twl4030_led.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/misc/twl4030_led.c b/drivers/misc/twl4030_led.c
new file mode 100644
index 0000000000..bfdafef38b
--- /dev/null
+++ b/drivers/misc/twl4030_led.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix at windriver.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
+ *
+ * twl4030_led_init is from cpu/omap3/common.c, power_init_r
+ *
+ * (C) Copyright 2004-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ * Sunil Kumar <sunilsaini05 at gmail.com>
+ * Shashi Ranjan <shashiranjanmca05 at gmail.com>
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ * Richard Woodruff <r-woodruff2 at ti.com>
+ * Syed Mohammed Khasim <khasim at ti.com>
+ *
+ */
+
+#include <twl4030.h>
+
+#define LEDAON (0x1 << 0)
+#define LEDBON (0x1 << 1)
+#define LEDAPWM (0x1 << 4)
+#define LEDBPWM (0x1 << 5)
+
+void twl4030_led_init(void)
+{
+ unsigned char byte;
+
+ /* enable LED */
+ byte = LEDBPWM | LEDAPWM | LEDBON | LEDAON;
+
+ twl4030_i2c_write_u8(TWL4030_CHIP_LED, byte,
+ TWL4030_LED_LEDEN);
+
+}
diff --git a/drivers/mmc/omap3_mmc.c b/drivers/mmc/omap3_mmc.c
index e90db7ee33..9e09434c10 100644
--- a/drivers/mmc/omap3_mmc.c
+++ b/drivers/mmc/omap3_mmc.c
@@ -28,6 +28,7 @@
#include <mmc.h>
#include <part.h>
#include <i2c.h>
+#include <twl4030.h>
#include <asm/io.h>
#include <asm/arch/mmc.h>
@@ -58,21 +59,11 @@ block_dev_desc_t *mmc_get_dev(int dev)
return (block_dev_desc_t *) &mmc_blk_dev;
}
-void twl4030_mmc_config(void)
-{
- unsigned char data;
-
- data = DEV_GRP_P1;
- i2c_write(PWRMGT_ADDR_ID4, VMMC1_DEV_GRP, 1, &data, 1);
- data = VMMC1_VSEL_30;
- i2c_write(PWRMGT_ADDR_ID4, VMMC1_DEDICATED, 1, &data, 1);
-}
-
unsigned char mmc_board_init(void)
{
t2_t *t2_base = (t2_t *)T2_BASE;
- twl4030_mmc_config();
+ twl4030_power_mmc_init();
writel(readl(&t2_base->pbias_lite) | PBIASLITEPWRDNZ1 |
PBIASSPEEDCTRL0 | PBIASLITEPWRDNZ0,
diff --git a/board/omap3/common/Makefile b/drivers/power/Makefile
index b8a0b14a01..dd0651466f 100644
--- a/board/omap3/common/Makefile
+++ b/drivers/power/Makefile
@@ -1,6 +1,6 @@
#
-# (C) Copyright 2006
-# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+# Copyright (c) 2009 Wind River Systems, Inc.
+# Tom Rix <Tom.Rix at windriver.com>
#
# See file CREDITS for list of people who contributed to this
# project.
@@ -12,7 +12,7 @@
#
# 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
+# 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
@@ -23,27 +23,20 @@
include $(TOPDIR)/config.mk
-ifneq ($(OBJTREE),$(SRCTREE))
-$(shell mkdir -p $(obj)board/$(VENDOR)/common)
-endif
+LIB := $(obj)libpower.a
-LIB = $(obj)lib$(VENDOR).a
-
-COBJS-$(CONFIG_OMAP3_BEAGLE) += power.o
-COBJS-$(CONFIG_OMAP3_OVERO) += power.o
-COBJS-$(CONFIG_OMAP3_PANDORA) += power.o
-COBJS-$(CONFIG_OMAP3_ZOOM1) += power.o
-COBJS-$(CONFIG_OMAP3_ZOOM2) += power.o
+COBJS-$(CONFIG_TWL4030_POWER) += twl4030.o
COBJS := $(COBJS-y)
-SRCS := $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(COBJS))
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
all: $(LIB)
$(LIB): $(obj).depend $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
+
#########################################################################
# defines $(obj).depend target
@@ -51,4 +44,4 @@ include $(SRCTREE)/rules.mk
sinclude $(obj).depend
-#########################################################################
+########################################################################
diff --git a/drivers/power/twl4030.c b/drivers/power/twl4030.c
new file mode 100644
index 0000000000..eb066cb58d
--- /dev/null
+++ b/drivers/power/twl4030.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix at windriver.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
+ *
+ * twl4030_power_reset_init is derived from code on omapzoom,
+ * git://git.omapzoom.com/repo/u-boot.git
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ *
+ * twl4030_power_init is from cpu/omap3/common.c, power_init_r
+ *
+ * (C) Copyright 2004-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ * Sunil Kumar <sunilsaini05 at gmail.com>
+ * Shashi Ranjan <shashiranjanmca05 at gmail.com>
+ *
+ * Derived from Beagle Board and 3430 SDP code by
+ * Richard Woodruff <r-woodruff2 at ti.com>
+ * Syed Mohammed Khasim <khasim at ti.com>
+ *
+ */
+
+#include <twl4030.h>
+
+/*
+ * Power Reset
+ */
+void twl4030_power_reset_init(void)
+{
+ u8 val = 0;
+ if (twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, &val,
+ TWL4030_PM_MASTER_P1_SW_EVENTS)) {
+ printf("Error:TWL4030: failed to read the power register\n");
+ printf("Could not initialize hardware reset\n");
+ } else {
+ val |= TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON;
+ if (twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, val,
+ TWL4030_PM_MASTER_P1_SW_EVENTS)) {
+ printf("Error:TWL4030: failed to write the power register\n");
+ printf("Could not initialize hardware reset\n");
+ }
+ }
+}
+
+
+/*
+ * Power Init
+ */
+#define DEV_GRP_P1 0x20
+#define VAUX3_VSEL_28 0x03
+#define DEV_GRP_ALL 0xE0
+#define VPLL2_VSEL_18 0x05
+#define VDAC_VSEL_18 0x03
+
+void twl4030_power_init(void)
+{
+ unsigned char byte;
+
+ /* set VAUX3 to 2.8V */
+ byte = DEV_GRP_P1;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VAUX3_DEV_GRP);
+ byte = VAUX3_VSEL_28;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VAUX3_DEDICATED);
+
+ /* set VPLL2 to 1.8V */
+ byte = DEV_GRP_ALL;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VPLL2_DEV_GRP);
+ byte = VPLL2_VSEL_18;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VPLL2_DEDICATED);
+
+ /* set VDAC to 1.8V */
+ byte = DEV_GRP_P1;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VDAC_DEV_GRP);
+ byte = VDAC_VSEL_18;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VDAC_DEDICATED);
+}
+
+#define VMMC1_VSEL_30 0x02
+
+void twl4030_power_mmc_init(void)
+{
+ unsigned char byte;
+
+ byte = DEV_GRP_P1;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VMMC1_DEV_GRP);
+
+ /* 3 Volts */
+ byte = VMMC1_VSEL_30;
+ twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, byte,
+ TWL4030_PM_RECEIVER_VMMC1_DEDICATED);
+}
diff --git a/include/asm-arm/arch-nomadik/gpio.h b/include/asm-arm/arch-nomadik/gpio.h
new file mode 100644
index 0000000000..1d3c9ce0ab
--- /dev/null
+++ b/include/asm-arm/arch-nomadik/gpio.h
@@ -0,0 +1,42 @@
+/*
+ * (C) Copyright 2009 Alessandro Rubini
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 __NMK_GPIO_H__
+#define __NMK_GPIO_H__
+
+/*
+ * These functions are called from the soft-i2c driver, but
+ * are also used by board files to set output bits.
+ */
+
+enum nmk_af { /* alternate function settings */
+ GPIO_GPIO = 0,
+ GPIO_ALT_A,
+ GPIO_ALT_B,
+ GPIO_ALT_C
+};
+
+extern void nmk_gpio_af(int gpio, int alternate_function);
+extern void nmk_gpio_dir(int gpio, int dir);
+extern void nmk_gpio_set(int gpio, int val);
+extern int nmk_gpio_get(int gpio);
+
+#endif /* __NMK_GPIO_H__ */
diff --git a/include/asm-arm/arch-omap24xx/i2c.h b/include/asm-arm/arch-omap24xx/i2c.h
index 7248950e52..44db7a2d45 100644
--- a/include/asm-arm/arch-omap24xx/i2c.h
+++ b/include/asm-arm/arch-omap24xx/i2c.h
@@ -104,4 +104,48 @@
#define I2C_SYSTEST_SDA_I (1 << 1) /* SDA line sense input value */
#define I2C_SYSTEST_SDA_O (1 << 0) /* SDA line drive output value */
+/* These values were copied from omap3, include/asm-arm/arch-omap3/i2c.h. */
+#define OMAP_I2C_STANDARD 100000
+#define OMAP_I2C_FAST_MODE 400000
+#define OMAP_I2C_HIGH_SPEED 3400000
+
+#define SYSTEM_CLOCK_12 12000000
+#define SYSTEM_CLOCK_13 13000000
+#define SYSTEM_CLOCK_192 19200000
+#define SYSTEM_CLOCK_96 96000000
+
+#ifndef I2C_IP_CLK
+#define I2C_IP_CLK SYSTEM_CLOCK_96
+#endif
+
+#ifndef I2C_INTERNAL_SAMPLING_CLK
+#define I2C_INTERNAL_SAMPLING_CLK 19200000
+#endif
+
+/* These are the trim values for standard and fast speed */
+#ifndef I2C_FASTSPEED_SCLL_TRIM
+#define I2C_FASTSPEED_SCLL_TRIM 6
+#endif
+#ifndef I2C_FASTSPEED_SCLH_TRIM
+#define I2C_FASTSPEED_SCLH_TRIM 6
+#endif
+
+/* These are the trim values for high speed */
+#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM
+#define I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
+#endif
+#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM
+#define I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
+#endif
+#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM
+#define I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
+#endif
+#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM
+#define I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
+#endif
+
+#define I2C_PSC_MAX 0x0f
+#define I2C_PSC_MIN 0x00
+
+
#endif
diff --git a/include/asm-arm/arch-omap3/i2c.h b/include/asm-arm/arch-omap3/i2c.h
index 3937f35256..8b339cce9a 100644
--- a/include/asm-arm/arch-omap3/i2c.h
+++ b/include/asm-arm/arch-omap3/i2c.h
@@ -112,16 +112,72 @@
#define I2C_SCLH_HSSCLH 8
#define I2C_SCLH_HSSCLH_M 0xFF
-#define OMAP_I2C_STANDARD 100
-#define OMAP_I2C_FAST_MODE 400
-#define OMAP_I2C_HIGH_SPEED 3400
+#define OMAP_I2C_STANDARD 100000
+#define OMAP_I2C_FAST_MODE 400000
+#define OMAP_I2C_HIGH_SPEED 3400000
-#define SYSTEM_CLOCK_12 12000
-#define SYSTEM_CLOCK_13 13000
-#define SYSTEM_CLOCK_192 19200
-#define SYSTEM_CLOCK_96 96000
+#define SYSTEM_CLOCK_12 12000000
+#define SYSTEM_CLOCK_13 13000000
+#define SYSTEM_CLOCK_192 19200000
+#define SYSTEM_CLOCK_96 96000000
+/* Use the reference value of 96MHz if not explicitly set by the board */
+#ifndef I2C_IP_CLK
#define I2C_IP_CLK SYSTEM_CLOCK_96
+#endif
+
+/*
+ * The reference minimum clock for high speed is 19.2MHz.
+ * The linux 2.6.30 kernel uses this value.
+ * The reference minimum clock for fast mode is 9.6MHz
+ * The reference minimum clock for standard mode is 4MHz
+ * In TRM, the value of 12MHz is used.
+ */
+#ifndef I2C_INTERNAL_SAMPLING_CLK
+#define I2C_INTERNAL_SAMPLING_CLK 19200000
+#endif
+
+/*
+ * The equation for the low and high time is
+ * tlow = scll + scll_trim = (sampling clock * tlow_duty) / speed
+ * thigh = sclh + sclh_trim = (sampling clock * (1 - tlow_duty)) / speed
+ *
+ * If the duty cycle is 50%
+ *
+ * tlow = scll + scll_trim = sampling clock / (2 * speed)
+ * thigh = sclh + sclh_trim = sampling clock / (2 * speed)
+ *
+ * In TRM
+ * scll_trim = 7
+ * sclh_trim = 5
+ *
+ * The linux 2.6.30 kernel uses
+ * scll_trim = 6
+ * sclh_trim = 6
+ *
+ * These are the trim values for standard and fast speed
+ */
+#ifndef I2C_FASTSPEED_SCLL_TRIM
+#define I2C_FASTSPEED_SCLL_TRIM 6
+#endif
+#ifndef I2C_FASTSPEED_SCLH_TRIM
+#define I2C_FASTSPEED_SCLH_TRIM 6
+#endif
+
+/* These are the trim values for high speed */
+#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM
+#define I2C_HIGHSPEED_PHASE_ONE_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
+#endif
+#ifndef I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM
+#define I2C_HIGHSPEED_PHASE_ONE_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
+#endif
+#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM
+#define I2C_HIGHSPEED_PHASE_TWO_SCLL_TRIM I2C_FASTSPEED_SCLL_TRIM
+#endif
+#ifndef I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM
+#define I2C_HIGHSPEED_PHASE_TWO_SCLH_TRIM I2C_FASTSPEED_SCLH_TRIM
+#endif
+
#define I2C_PSC_MAX 0x0f
#define I2C_PSC_MIN 0x00
diff --git a/include/asm-arm/arch-omap3/omap3.h b/include/asm-arm/arch-omap3/omap3.h
index 7c1101969c..fa8f46d7f2 100644
--- a/include/asm-arm/arch-omap3/omap3.h
+++ b/include/asm-arm/arch-omap3/omap3.h
@@ -181,39 +181,4 @@ typedef struct gpio {
#define WIDTH_8BIT 0x0000
#define WIDTH_16BIT 0x1000 /* bit pos for 16 bit in gpmc */
-/* I2C power management companion definitions */
-#define PWRMGT_ADDR_ID1 0x48
-#define PWRMGT_ADDR_ID2 0x49
-#define PWRMGT_ADDR_ID3 0x4A
-#define PWRMGT_ADDR_ID4 0x4B
-
-/* I2C ID3 (slave3) register */
-#define LEDEN 0xEE
-
-#define LEDAON (0x1 << 0)
-#define LEDBON (0x1 << 1)
-#define LEDAPWM (0x1 << 4)
-#define LEDBPWM (0x1 << 5)
-
-/* I2C ID4 (slave4) register */
-#define VAUX2_DEV_GRP 0x76
-#define VAUX2_DEDICATED 0x79
-#define VAUX3_DEV_GRP 0x7A
-#define VAUX3_DEDICATED 0x7D
-#define VMMC1_DEV_GRP 0x82
-#define VMMC1_DEDICATED 0x85
-#define VPLL2_DEV_GRP 0x8E
-#define VPLL2_DEDICATED 0x91
-#define VDAC_DEV_GRP 0x96
-#define VDAC_DEDICATED 0x99
-
-#define DEV_GRP_P1 0x20
-#define DEV_GRP_ALL 0xE0
-
-#define VAUX2_VSEL_28 0x09
-#define VAUX3_VSEL_28 0x03
-#define VPLL2_VSEL_18 0x05
-#define VDAC_VSEL_18 0x03
-#define VMMC1_VSEL_30 0x02
-
#endif
diff --git a/include/configs/nhk8815.h b/include/configs/nhk8815.h
index 3e2e09fb83..8a83d924bb 100644
--- a/include/configs/nhk8815.h
+++ b/include/configs/nhk8815.h
@@ -93,7 +93,7 @@
#define CONFIG_SYS_GBL_DATA_SIZE 128 /* for initial data */
#define CONFIG_SYS_64BIT_VSPRINTF /* mtd desires this */
-#define CONFIG_MISC_INIT_R /* call misc_init_r during start up */
+#define BOARD_LATE_INIT /* call board_late_init during start up */
/* timing informazion */
#define CONFIG_SYS_HZ 1000 /* Mandatory... */
@@ -110,6 +110,22 @@
#define CONFIG_PL01x_PORTS { (void *)CFG_SERIAL0, (void *)CFG_SERIAL1 }
#define CONFIG_PL011_CLOCK 48000000
+/* i2c, for the port extenders (uses gpio.c in board directory) */
+#ifndef __ASSEMBLY__
+#include <asm/arch/gpio.h>
+#define CONFIG_CMD_I2C
+#define CONFIG_SOFT_I2C
+#define CONFIG_SYS_I2C_SPEED 400000
+#define __SDA 63
+#define __SCL 62
+#define I2C_SDA(x) nmk_gpio_set(__SDA, x)
+#define I2C_SCL(x) nmk_gpio_set(__SCL, x)
+#define I2C_READ (nmk_gpio_get(__SDA)!=0)
+#define I2C_ACTIVE nmk_gpio_dir(__SDA, 1)
+#define I2C_TRISTATE nmk_gpio_dir(__SDA, 0)
+#define I2C_DELAY (udelay(2))
+#endif /* __ASSEMBLY__ */
+
/* Ethernet */
#define PCI_MEMORY_VADDR 0xe8000000
#define PCI_IO_VADDR 0xee000000
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index a1a849e292..8fc6fb26c9 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -130,6 +130,12 @@
#define CONFIG_DRIVER_OMAP34XX_I2C 1
/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
* Board NAND Info.
*/
#define CONFIG_NAND_OMAP_GPMC
diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index 3d9d72caf3..809198b0f8 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -128,6 +128,11 @@
#define CONFIG_DRIVER_OMAP34XX_I2C 1
/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+
+/*
* Board NAND Info.
*/
#define CONFIG_SYS_NAND_ADDR NAND_BASE /* physical address */
diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h
index 3bf798a400..c359c60b18 100644
--- a/include/configs/omap3_overo.h
+++ b/include/configs/omap3_overo.h
@@ -116,6 +116,12 @@
#define CONFIG_DRIVER_OMAP34XX_I2C 1
/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
* Board NAND Info.
*/
#define CONFIG_NAND_OMAP_GPMC
diff --git a/include/configs/omap3_pandora.h b/include/configs/omap3_pandora.h
index d7e0ea1c44..d7b1cc1895 100644
--- a/include/configs/omap3_pandora.h
+++ b/include/configs/omap3_pandora.h
@@ -119,6 +119,12 @@
#define CONFIG_DRIVER_OMAP34XX_I2C 1
/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
* Board NAND Info.
*/
#define CONFIG_NAND_OMAP_GPMC
diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index 4034ea4291..676b425473 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -126,6 +126,12 @@
#define CONFIG_DRIVER_OMAP34XX_I2C 1
/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
* Board NAND Info.
*/
#define CONFIG_NAND_OMAP_GPMC
diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
index 701a296b3d..3f6f5451a3 100644
--- a/include/configs/omap3_zoom2.h
+++ b/include/configs/omap3_zoom2.h
@@ -147,6 +147,12 @@
#define CONFIG_DRIVER_OMAP34XX_I2C 1
/*
+ * TWL4030
+ */
+#define CONFIG_TWL4030_POWER 1
+#define CONFIG_TWL4030_LED 1
+
+/*
* Board NAND Info.
*/
#define CONFIG_NAND_OMAP_GPMC
diff --git a/include/twl4030.h b/include/twl4030.h
new file mode 100644
index 0000000000..f260ecb8b1
--- /dev/null
+++ b/include/twl4030.h
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2009 Wind River Systems, Inc.
+ * Tom Rix <Tom.Rix at windriver.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
+ *
+ * Derived from code on omapzoom, git://git.omapzoom.com/repo/u-boot.git
+ *
+ * Copyright (C) 2007-2009 Texas Instruments, Inc.
+ */
+
+#ifndef TWL4030_H
+#define TWL4030_H
+
+#include <common.h>
+#include <i2c.h>
+
+/* I2C chip addresses */
+
+/* USB */
+#define TWL4030_CHIP_USB 0x48
+/* AUD */
+#define TWL4030_CHIP_AUDIO_VOICE 0x49
+#define TWL4030_CHIP_GPIO 0x49
+#define TWL4030_CHIP_INTBR 0x49
+#define TWL4030_CHIP_PIH 0x49
+#define TWL4030_CHIP_TEST 0x49
+/* AUX */
+#define TWL4030_CHIP_KEYPAD 0x4a
+#define TWL4030_CHIP_MADC 0x4a
+#define TWL4030_CHIP_INTERRUPTS 0x4a
+#define TWL4030_CHIP_LED 0x4a
+#define TWL4030_CHIP_MAIN_CHARGE 0x4a
+#define TWL4030_CHIP_PRECHARGE 0x4a
+#define TWL4030_CHIP_PWM0 0x4a
+#define TWL4030_CHIP_PWM1 0x4a
+#define TWL4030_CHIP_PWMA 0x4a
+#define TWL4030_CHIP_PWMB 0x4a
+/* POWER */
+#define TWL4030_CHIP_BACKUP 0x4b
+#define TWL4030_CHIP_INT 0x4b
+#define TWL4030_CHIP_PM_MASTER 0x4b
+#define TWL4030_CHIP_PM_RECEIVER 0x4b
+#define TWL4030_CHIP_RTC 0x4b
+#define TWL4030_CHIP_SECURED_REG 0x4b
+
+/* Register base addresses */
+
+/* USB */
+#define TWL4030_BASEADD_USB 0x0000
+/* AUD */
+#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
+/* AUX */
+#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
+/* POWER */
+#define TWL4030_BASEADD_BACKUP 0x0014
+#define TWL4030_BASEADD_INT 0x002E
+#define TWL4030_BASEADD_PM_MASTER 0x0036
+#define TWL4030_BASEADD_PM_RECIEVER 0x005B
+#define TWL4030_BASEADD_RTC 0x001C
+#define TWL4030_BASEADD_SECURED_REG 0x0000
+
+/*
+ * Power Management Master
+ */
+#define TWL4030_PM_MASTER_CFG_P1_TRANSITION 0x36
+#define TWL4030_PM_MASTER_CFG_P2_TRANSITION 0x37
+#define TWL4030_PM_MASTER_CFG_P3_TRANSITION 0x38
+#define TWL4030_PM_MASTER_CFG_P123_TRANSITION 0x39
+#define TWL4030_PM_MASTER_STS_BOOT 0x3A
+#define TWL4030_PM_MASTER_CFG_BOOT 0x3B
+#define TWL4030_PM_MASTER_SHUNDAN 0x3C
+#define TWL4030_PM_MASTER_BOOT_BCI 0x3D
+#define TWL4030_PM_MASTER_CFG_PWRANA1 0x3E
+#define TWL4030_PM_MASTER_CFG_PWRANA2 0x3F
+#define TWL4030_PM_MASTER_BGAP_TRIM 0x40
+#define TWL4030_PM_MASTER_BACKUP_MISC_STS 0x41
+#define TWL4030_PM_MASTER_BACKUP_MISC_CFG 0x42
+#define TWL4030_PM_MASTER_BACKUP_MISC_TST 0x43
+#define TWL4030_PM_MASTER_PROTECT_KEY 0x44
+#define TWL4030_PM_MASTER_STS_HW_CONDITIONS 0x45
+#define TWL4030_PM_MASTER_P1_SW_EVENTS 0x46
+#define TWL4030_PM_MASTER_P2_SW_EVENTS 0x47
+#define TWL4030_PM_MASTER_P3_SW_EVENTS 0x48
+#define TWL4030_PM_MASTER_STS_P123_STATE 0x49
+#define TWL4030_PM_MASTER_PB_CFG 0x4A
+#define TWL4030_PM_MASTER_PB_WORD_MSB 0x4B
+#define TWL4030_PM_MASTER_PB_WORD_LSB 0x4C
+#define TWL4030_PM_MASTER_SEQ_ADD_W2P 0x52
+#define TWL4030_PM_MASTER_SEQ_ADD_P2A 0x53
+#define TWL4030_PM_MASTER_SEQ_ADD_A2W 0x54
+#define TWL4030_PM_MASTER_SEQ_ADD_A2S 0x55
+#define TWL4030_PM_MASTER_SEQ_ADD_S2A12 0x56
+#define TWL4030_PM_MASTER_SEQ_ADD_S2A3 0x57
+#define TWL4030_PM_MASTER_SEQ_ADD_WARM 0x58
+#define TWL4030_PM_MASTER_MEMORY_ADDRESS 0x59
+#define TWL4030_PM_MASTER_MEMORY_DATA 0x5A
+#define TWL4030_PM_MASTER_SC_CONFIG 0x5B
+#define TWL4030_PM_MASTER_SC_DETECT1 0x5C
+#define TWL4030_PM_MASTER_SC_DETECT2 0x5D
+#define TWL4030_PM_MASTER_WATCHDOG_CFG 0x5E
+#define TWL4030_PM_MASTER_IT_CHECK_CFG 0x5F
+#define TWL4030_PM_MASTER_VIBRATOR_CFG 0x60
+#define TWL4030_PM_MASTER_DCDC_GLOBAL_CFG 0x61
+#define TWL4030_PM_MASTER_VDD1_TRIM1 0x62
+#define TWL4030_PM_MASTER_VDD1_TRIM2 0x63
+#define TWL4030_PM_MASTER_VDD2_TRIM1 0x64
+#define TWL4030_PM_MASTER_VDD2_TRIM2 0x65
+#define TWL4030_PM_MASTER_VIO_TRIM1 0x66
+#define TWL4030_PM_MASTER_VIO_TRIM2 0x67
+#define TWL4030_PM_MASTER_MISC_CFG 0x68
+#define TWL4030_PM_MASTER_LS_TST_A 0x69
+#define TWL4030_PM_MASTER_LS_TST_B 0x6A
+#define TWL4030_PM_MASTER_LS_TST_C 0x6B
+#define TWL4030_PM_MASTER_LS_TST_D 0x6C
+#define TWL4030_PM_MASTER_BB_CFG 0x6D
+#define TWL4030_PM_MASTER_MISC_TST 0x6E
+#define TWL4030_PM_MASTER_TRIM1 0x6F
+/* P[1-3]_SW_EVENTS */
+#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON (1 << 6)
+#define TWL4030_PM_MASTER_SW_EVENTS_STOPON_SYSEN (1 << 5)
+#define TWL4030_PM_MASTER_SW_EVENTS_ENABLE_WARMRESET (1 << 4)
+#define TWL4030_PM_MASTER_SW_EVENTS_LVL_WAKEUP (1 << 3)
+#define TWL4030_PM_MASTER_SW_EVENTS_DEVACT (1 << 2)
+#define TWL4030_PM_MASTER_SW_EVENTS_DEVSLP (1 << 1)
+#define TWL4030_PM_MASTER_SW_EVENTS_DEVOFF (1 << 0)
+
+/* Power Managment Receiver */
+#define TWL4030_PM_RECEIVER_SC_CONFIG 0x5B
+#define TWL4030_PM_RECEIVER_SC_DETECT1 0x5C
+#define TWL4030_PM_RECEIVER_SC_DETECT2 0x5D
+#define TWL4030_PM_RECEIVER_WATCHDOG_CFG 0x5E
+#define TWL4030_PM_RECEIVER_IT_CHECK_CFG 0x5F
+#define TWL4030_PM_RECEIVER_VIBRATOR_CFG 0x5F
+#define TWL4030_PM_RECEIVER_DC_TO_DC_CFG 0x61
+#define TWL4030_PM_RECEIVER_VDD1_TRIM1 0x62
+#define TWL4030_PM_RECEIVER_VDD1_TRIM2 0x63
+#define TWL4030_PM_RECEIVER_VDD2_TRIM1 0x64
+#define TWL4030_PM_RECEIVER_VDD2_TRIM2 0x65
+#define TWL4030_PM_RECEIVER_VIO_TRIM1 0x66
+#define TWL4030_PM_RECEIVER_VIO_TRIM2 0x67
+#define TWL4030_PM_RECEIVER_MISC_CFG 0x68
+#define TWL4030_PM_RECEIVER_LS_TST_A 0x69
+#define TWL4030_PM_RECEIVER_LS_TST_B 0x6A
+#define TWL4030_PM_RECEIVER_LS_TST_C 0x6B
+#define TWL4030_PM_RECEIVER_LS_TST_D 0x6C
+#define TWL4030_PM_RECEIVER_BB_CFG 0x6D
+#define TWL4030_PM_RECEIVER_MISC_TST 0x6E
+#define TWL4030_PM_RECEIVER_TRIM1 0x6F
+#define TWL4030_PM_RECEIVER_TRIM2 0x70
+#define TWL4030_PM_RECEIVER_DC_DC_TIMEOUT 0x71
+#define TWL4030_PM_RECEIVER_VAUX1_DEV_GRP 0x72
+#define TWL4030_PM_RECEIVER_VAUX1_TYPE 0x73
+#define TWL4030_PM_RECEIVER_VAUX1_REMAP 0x74
+#define TWL4030_PM_RECEIVER_VAUX1_DEDICATED 0x75
+#define TWL4030_PM_RECEIVER_VAUX2_DEV_GRP 0x76
+#define TWL4030_PM_RECEIVER_VAUX2_TYPE 0x77
+#define TWL4030_PM_RECEIVER_VAUX2_REMAP 0x78
+#define TWL4030_PM_RECEIVER_VAUX2_DEDICATED 0x79
+#define TWL4030_PM_RECEIVER_VAUX3_DEV_GRP 0x7A
+#define TWL4030_PM_RECEIVER_VAUX3_TYPE 0x7B
+#define TWL4030_PM_RECEIVER_VAUX3_REMAP 0x7C
+#define TWL4030_PM_RECEIVER_VAUX3_DEDICATED 0x7D
+#define TWL4030_PM_RECEIVER_VAUX4_DEV_GRP 0x7E
+#define TWL4030_PM_RECEIVER_VAUX4_TYPE 0x7F
+#define TWL4030_PM_RECEIVER_VAUX4_REMAP 0x80
+#define TWL4030_PM_RECEIVER_VAUX4_DEDICATED 0x81
+#define TWL4030_PM_RECEIVER_VMMC1_DEV_GRP 0x82
+#define TWL4030_PM_RECEIVER_VMMC1_TYPE 0x83
+#define TWL4030_PM_RECEIVER_VMMC1_REMAP 0x84
+#define TWL4030_PM_RECEIVER_VMMC1_DEDICATED 0x85
+#define TWL4030_PM_RECEIVER_VMMC2_DEV_GRP 0x86
+#define TWL4030_PM_RECEIVER_VMMC2_TYPE 0x87
+#define TWL4030_PM_RECEIVER_VMMC2_REMAP 0x88
+#define TWL4030_PM_RECEIVER_VMMC2_DEDICATED 0x89
+#define TWL4030_PM_RECEIVER_VPLL1_DEV_GRP 0x8A
+#define TWL4030_PM_RECEIVER_VPLL1_TYPE 0x8B
+#define TWL4030_PM_RECEIVER_VPLL1_REMAP 0x8C
+#define TWL4030_PM_RECEIVER_VPLL1_DEDICATED 0x8D
+#define TWL4030_PM_RECEIVER_VPLL2_DEV_GRP 0x8E
+#define TWL4030_PM_RECEIVER_VPLL2_TYPE 0x8F
+#define TWL4030_PM_RECEIVER_VPLL2_REMAP 0x90
+#define TWL4030_PM_RECEIVER_VPLL2_DEDICATED 0x91
+#define TWL4030_PM_RECEIVER_VSIM_DEV_GRP 0x92
+#define TWL4030_PM_RECEIVER_VSIM_TYPE 0x93
+#define TWL4030_PM_RECEIVER_VSIM_REMAP 0x94
+#define TWL4030_PM_RECEIVER_VSIM_DEDICATED 0x95
+#define TWL4030_PM_RECEIVER_VDAC_DEV_GRP 0x96
+#define TWL4030_PM_RECEIVER_VDAC_TYPE 0x97
+#define TWL4030_PM_RECEIVER_VDAC_REMAP 0x98
+#define TWL4030_PM_RECEIVER_VDAC_DEDICATED 0x99
+#define TWL4030_PM_RECEIVER_VINTANA1_DEV_GRP 0x9A
+#define TWL4030_PM_RECEIVER_VINTANA1_TYP 0x9B
+#define TWL4030_PM_RECEIVER_VINTANA1_REMAP 0x9C
+#define TWL4030_PM_RECEIVER_VINTANA1_DEDICATED 0x9D
+#define TWL4030_PM_RECEIVER_VINTANA2_DEV_GRP 0x9E
+#define TWL4030_PM_RECEIVER_VINTANA2_TYPE 0x9F
+#define TWL4030_PM_RECEIVER_VINTANA2_REMAP 0xA0
+#define TWL4030_PM_RECEIVER_VINTANA2_DEDICATED 0xA1
+#define TWL4030_PM_RECEIVER_VINTDIG_DEV_GRP 0xA2
+#define TWL4030_PM_RECEIVER_VINTDIG_TYPE 0xA3
+#define TWL4030_PM_RECEIVER_VINTDIG_REMAP 0xA4
+#define TWL4030_PM_RECEIVER_VINTDIG_DEDICATED 0xA5
+#define TWL4030_PM_RECEIVER_VIO_DEV_GRP 0xA6
+#define TWL4030_PM_RECEIVER_VIO_TYPE 0xA7
+#define TWL4030_PM_RECEIVER_VIO_REMAP 0xA8
+#define TWL4030_PM_RECEIVER_VIO_CFG 0xA9
+#define TWL4030_PM_RECEIVER_VIO_MISC_CFG 0xAA
+#define TWL4030_PM_RECEIVER_VIO_TEST1 0xAB
+#define TWL4030_PM_RECEIVER_VIO_TEST2 0xAC
+#define TWL4030_PM_RECEIVER_VIO_OSC 0xAD
+#define TWL4030_PM_RECEIVER_VIO_RESERVED 0xAE
+#define TWL4030_PM_RECEIVER_VIO_VSEL 0xAF
+#define TWL4030_PM_RECEIVER_VDD1_DEV_GRP 0xB0
+#define TWL4030_PM_RECEIVER_VDD1_TYPE 0xB1
+#define TWL4030_PM_RECEIVER_VDD1_REMAP 0xB2
+#define TWL4030_PM_RECEIVER_VDD1_CFG 0xB3
+#define TWL4030_PM_RECEIVER_VDD1_MISC_CFG 0xB4
+#define TWL4030_PM_RECEIVER_VDD1_TEST1 0xB5
+#define TWL4030_PM_RECEIVER_VDD1_TEST2 0xB6
+#define TWL4030_PM_RECEIVER_VDD1_OSC 0xB7
+#define TWL4030_PM_RECEIVER_VDD1_RESERVED 0xB8
+#define TWL4030_PM_RECEIVER_VDD1_VSEL 0xB9
+#define TWL4030_PM_RECEIVER_VDD1_VMODE_CFG 0xBA
+#define TWL4030_PM_RECEIVER_VDD1_VFLOOR 0xBB
+#define TWL4030_PM_RECEIVER_VDD1_VROOF 0xBC
+#define TWL4030_PM_RECEIVER_VDD1_STEP 0xBD
+#define TWL4030_PM_RECEIVER_VDD2_DEV_GRP 0xBE
+#define TWL4030_PM_RECEIVER_VDD2_TYPE 0xBF
+#define TWL4030_PM_RECEIVER_VDD2_REMAP 0xC0
+#define TWL4030_PM_RECEIVER_VDD2_CFG 0xC1
+#define TWL4030_PM_RECEIVER_VDD2_MISC_CFG 0xC2
+#define TWL4030_PM_RECEIVER_VDD2_TEST1 0xC3
+#define TWL4030_PM_RECEIVER_VDD2_TEST2 0xC4
+#define TWL4030_PM_RECEIVER_VDD2_OSC 0xC5
+#define TWL4030_PM_RECEIVER_VDD2_RESERVED 0xC6
+#define TWL4030_PM_RECEIVER_VDD2_VSEL 0xC7
+#define TWL4030_PM_RECEIVER_VDD2_VMODE_CFG 0xC8
+#define TWL4030_PM_RECEIVER_VDD2_VFLOOR 0xC9
+#define TWL4030_PM_RECEIVER_VDD2_VROOF 0xCA
+#define TWL4030_PM_RECEIVER_VDD2_STEP 0xCB
+#define TWL4030_PM_RECEIVER_VUSB1V5_DEV_GRP 0xCC
+#define TWL4030_PM_RECEIVER_VUSB1V5_TYPE 0xCD
+#define TWL4030_PM_RECEIVER_VUSB1V5_REMAP 0xCE
+#define TWL4030_PM_RECEIVER_VUSB1V8_DEV_GRP 0xCF
+#define TWL4030_PM_RECEIVER_VUSB1V8_TYPE 0xD0
+#define TWL4030_PM_RECEIVER_VUSB1V8_REMAP 0xD1
+#define TWL4030_PM_RECEIVER_VUSB3V1_DEV_GRP 0xD2
+#define TWL4030_PM_RECEIVER_VUSB3V1_TYPE 0xD3
+#define TWL4030_PM_RECEIVER_VUSB3V1_REMAP 0xD4
+#define TWL4030_PM_RECEIVER_VUSBCP_DEV_GRP 0xD5
+#define TWL4030_PM_RECEIVER_VUSBCP_TYPE 0xD6
+#define TWL4030_PM_RECEIVER_VUSBCP_REMAP 0xD7
+#define TWL4030_PM_RECEIVER_VUSB_DEDICATED1 0xD8
+#define TWL4030_PM_RECEIVER_VUSB_DEDICATED2 0xD9
+#define TWL4030_PM_RECEIVER_REGEN_DEV_GRP 0xDA
+#define TWL4030_PM_RECEIVER_REGEN_TYPE 0xDB
+#define TWL4030_PM_RECEIVER_REGEN_REMAP 0xDC
+#define TWL4030_PM_RECEIVER_NRESPWRON_DEV_GRP 0xDD
+#define TWL4030_PM_RECEIVER_NRESPWRON_TYPE 0xDE
+#define TWL4030_PM_RECEIVER_NRESPWRON_REMAP 0xDF
+#define TWL4030_PM_RECEIVER_CLKEN_DEV_GRP 0xE0
+#define TWL4030_PM_RECEIVER_CLKEN_TYPE 0xE1
+#define TWL4030_PM_RECEIVER_CLKEN_REMAP 0xE2
+#define TWL4030_PM_RECEIVER_SYSEN_DEV_GRP 0xE3
+#define TWL4030_PM_RECEIVER_SYSEN_TYPE 0xE4
+#define TWL4030_PM_RECEIVER_SYSEN_REMAP 0xE5
+#define TWL4030_PM_RECEIVER_HFCLKOUT_DEV_GRP 0xE6
+#define TWL4030_PM_RECEIVER_HFCLKOUT_TYPE 0xE7
+#define TWL4030_PM_RECEIVER_HFCLKOUT_REMAP 0xE8
+#define TWL4030_PM_RECEIVER_32KCLKOUT_DEV_GRP 0xE9
+#define TWL4030_PM_RECEIVER_32KCLKOUT_TYPE 0xEA
+#define TWL4030_PM_RECEIVER_32KCLKOUT_REMAP 0xEB
+#define TWL4030_PM_RECEIVER_TRITON_RESET_DEV_GRP 0xEC
+#define TWL4030_PM_RECEIVER_TRITON_RESET_TYPE 0xED
+#define TWL4030_PM_RECEIVER_TRITON_RESET_REMAP 0xEE
+#define TWL4030_PM_RECEIVER_MAINREF_DEV_GRP 0xEF
+#define TWL4030_PM_RECEIVER_MAINREF_TYPE 0xF0
+#define TWL4030_PM_RECEIVER_MAINREF_REMAP 0xF1
+
+/* LED */
+#define TWL4030_LED_LEDEN 0xEE
+
+/* Keypad */
+#define TWL4030_KEYPAD_KEYP_CTRL_REG 0xD2
+#define TWL4030_KEYPAD_KEY_DEB_REG 0xD3
+#define TWL4030_KEYPAD_LONG_KEY_REG1 0xD4
+#define TWL4030_KEYPAD_LK_PTV_REG 0xD5
+#define TWL4030_KEYPAD_TIME_OUT_REG1 0xD6
+#define TWL4030_KEYPAD_TIME_OUT_REG2 0xD7
+#define TWL4030_KEYPAD_KBC_REG 0xD8
+#define TWL4030_KEYPAD_KBR_REG 0xD9
+#define TWL4030_KEYPAD_KEYP_SMS 0xDA
+#define TWL4030_KEYPAD_FULL_CODE_7_0 0xDB
+#define TWL4030_KEYPAD_FULL_CODE_15_8 0xDC
+#define TWL4030_KEYPAD_FULL_CODE_23_16 0xDD
+#define TWL4030_KEYPAD_FULL_CODE_31_24 0xDE
+#define TWL4030_KEYPAD_FULL_CODE_39_32 0xDF
+#define TWL4030_KEYPAD_FULL_CODE_47_40 0xE0
+#define TWL4030_KEYPAD_FULL_CODE_55_48 0xE1
+#define TWL4030_KEYPAD_FULL_CODE_63_56 0xE2
+#define TWL4030_KEYPAD_KEYP_ISR1 0xE3
+#define TWL4030_KEYPAD_KEYP_IMR1 0xE4
+#define TWL4030_KEYPAD_KEYP_ISR2 0xE5
+#define TWL4030_KEYPAD_KEYP_IMR2 0xE6
+#define TWL4030_KEYPAD_KEYP_SIR 0xE7
+#define TWL4030_KEYPAD_KEYP_EDR 0xE8
+#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0xE9
+
+#define TWL4030_KEYPAD_CTRL_KBD_ON (1 << 6)
+#define TWL4030_KEYPAD_CTRL_RP_EN (1 << 5)
+#define TWL4030_KEYPAD_CTRL_TOLE_EN (1 << 4)
+#define TWL4030_KEYPAD_CTRL_TOE_EN (1 << 3)
+#define TWL4030_KEYPAD_CTRL_LK_EN (1 << 2)
+#define TWL4030_KEYPAD_CTRL_SOFTMODEN (1 << 1)
+#define TWL4030_KEYPAD_CTRL_SOFT_NRST (1 << 0)
+
+/* USB */
+#define TWL4030_USB_FUNC_CTRL (0x04)
+#define TWL4030_USB_OPMODE_MASK (3 << 3)
+#define TWL4030_USB_XCVRSELECT_MASK (3 << 0)
+#define TWL4030_USB_IFC_CTRL (0x07)
+#define TWL4030_USB_CARKITMODE (1 << 2)
+#define TWL4030_USB_POWER_CTRL (0xAC)
+#define TWL4030_USB_OTG_ENAB (1 << 5)
+#define TWL4030_USB_PHY_PWR_CTRL (0xFD)
+#define TWL4030_USB_PHYPWD (1 << 0)
+#define TWL4030_USB_PHY_CLK_CTRL (0xFE)
+#define TWL4030_USB_CLOCKGATING_EN (1 << 2)
+#define TWL4030_USB_CLK32K_EN (1 << 1)
+#define TWL4030_USB_REQ_PHY_DPLL_CLK (1 << 0)
+#define TWL4030_USB_PHY_CLK_CTRL_STS (0xFF)
+#define TWL4030_USB_PHY_DPLL_CLK (1 << 0)
+
+/*
+ * Convience functions to read and write from TWL4030
+ *
+ * chip_no is the i2c address, it must be one of the chip addresses
+ * defined at the top of this file with the prefix TWL4030_CHIP_
+ * examples are TWL4030_CHIP_PM_RECEIVER and TWL4030_CHIP_KEYPAD
+ *
+ * val is the data either written to or read from the twl4030
+ *
+ * reg is the register to act on, it must be one of the defines
+ * above and with the format TWL4030_<chip suffix>_<register name>
+ * examples are TWL4030_PM_RECEIVER_VMMC1_DEV_GRP and
+ * TWL4030_LED_LEDEN.
+ */
+static inline int twl4030_i2c_write_u8(u8 chip_no, u8 val, u8 reg)
+{
+ return i2c_write(chip_no, reg, 1, &val, 1);
+}
+
+static inline int twl4030_i2c_read_u8(u8 chip_no, u8 *val, u8 reg)
+{
+ return i2c_read(chip_no, reg, 1, val, 1);
+}
+
+/*
+ * Power
+ */
+
+/* For hardware resetting */
+void twl4030_power_reset_init(void);
+/* For initializing power device */
+void twl4030_power_init(void);
+/* For initializing mmc power */
+void twl4030_power_mmc_init(void);
+
+/*
+ * LED
+ */
+void twl4030_led_init(void);
+
+#endif /* TWL4030_H */