summaryrefslogtreecommitdiffstats
path: root/drivers/mfd
diff options
context:
space:
mode:
authorAlexander Aring <a.aring@phytec.de>2011-12-21 08:50:28 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-12-21 12:46:01 +0100
commit5c115f335ec06fa1fd8a28740790a622e500a304 (patch)
treea565f58cd6047911b3d136f6a0e978603a0ea984 /drivers/mfd
parent8007b25bdfa353cbce71c849a41f474604648ebf (diff)
downloadbarebox-5c115f335ec06fa1fd8a28740790a622e500a304.tar.gz
barebox-5c115f335ec06fa1fd8a28740790a622e500a304.tar.xz
twl-core: abstract twl4030 and add twlcore driver
Add a general twl device driver twlcore to call i2c send/write functions. Abstract twl4030 to call twlcore functions. Fixed some code-styling issues pointed out by checkpatch. Signed-off-by: Alexander Aring <a.aring@phytec.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig8
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/twl-core.c157
-rw-r--r--drivers/mfd/twl4030.c142
4 files changed, 172 insertions, 136 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 96440d852f..72f87c23c3 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -16,11 +16,15 @@ config I2C_LP3972
depends on I2C
bool "LP3972 driver"
-config I2C_TWL4030
+config I2C_TWLCORE
depends on I2C
- bool "TWL4030 driver"
+ bool "TWL4030/TWL6030 driver"
select GPIO
+config I2C_TWL4030
+ depends on I2C_TWLCORE
+ bool "TWL4030 driver"
+
config DRIVER_SPI_MC13783
depends on SPI
bool "MC13783 a.k.a. PMIC driver"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d411f23b69..b05b2cd826 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -2,5 +2,6 @@ obj-$(CONFIG_I2C_MC13892) += mc13892.o
obj-$(CONFIG_I2C_MC34704) += mc34704.o
obj-$(CONFIG_I2C_MC9SDZ60) += mc9sdz60.o
obj-$(CONFIG_I2C_LP3972) += lp3972.o
+obj-$(CONFIG_I2C_TWLCORE) += twl-core.o
obj-$(CONFIG_I2C_TWL4030) += twl4030.o
obj-$(CONFIG_DRIVER_SPI_MC13783) += mc13783.o
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
new file mode 100644
index 0000000000..cb2c03dfca
--- /dev/null
+++ b/drivers/mfd/twl-core.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2011 Alexander Aring <a.aring@phytec.de>
+ *
+ * Based on:
+ * Copyright (C) 2010 Michael Grzeschik <mgr@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <xfuncs.h>
+#include <errno.h>
+
+#include <i2c/i2c.h>
+#include <mfd/twl-core.h>
+
+#define to_twlcore(a) container_of(a, struct twlcore, cdev)
+
+static struct twlcore *twl_dev;
+
+struct twlcore *twlcore_get(void)
+{
+ return twl_dev;
+}
+EXPORT_SYMBOL(twlcore_get);
+
+int twlcore_reg_read(struct twlcore *twlcore, u16 reg, u8 *val)
+{
+ int ret;
+ struct i2c_msg xfer_msg[2];
+ struct i2c_msg *msg;
+ int i2c_addr;
+ unsigned char buf = reg & 0xff;
+
+ i2c_addr = twlcore->client->addr + (reg / 0x100);
+
+ /* [MSG1] fill the register address data */
+ msg = &xfer_msg[0];
+ msg->addr = i2c_addr;
+ msg->len = 1;
+ msg->flags = 0;
+ msg->buf = &buf;
+ /* [MSG2] fill the data rx buffer */
+ msg = &xfer_msg[1];
+ msg->addr = i2c_addr;
+ msg->flags = I2C_M_RD;
+ msg->len = 1; /* only n bytes */
+ msg->buf = val;
+ ret = i2c_transfer(twlcore->client->adapter, xfer_msg, 2);
+
+ /* i2c_transfer returns number of messages transferred */
+ if (ret < 0) {
+ pr_err("%s: failed to transfer all messages: %s\n",
+ __func__, strerror(-ret));
+ return ret;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(twlcore_reg_read);
+
+int twlcore_reg_write(struct twlcore *twlcore, u16 reg, u8 val)
+{
+ int ret;
+ struct i2c_msg xfer_msg[1];
+ struct i2c_msg *msg;
+ int i2c_addr;
+ u8 buf[2];
+
+ buf[0] = reg & 0xff;
+ buf[1] = val;
+
+ i2c_addr = twlcore->client->addr + (reg / 0x100);
+
+ /*
+ * [MSG1]: fill the register address data
+ * fill the data Tx buffer
+ */
+ msg = xfer_msg;
+ msg->addr = i2c_addr;
+ msg->len = 2;
+ msg->flags = 0;
+ msg->buf = buf;
+ /* over write the first byte of buffer with the register address */
+ ret = i2c_transfer(twlcore->client->adapter, xfer_msg, 1);
+
+ /* i2c_transfer returns number of messages transferred */
+ if (ret < 0) {
+ pr_err("%s: failed to transfer all messages: %s\n",
+ __func__, strerror(-ret));
+ return ret;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(twlcore_reg_write);
+
+int twlcore_set_bits(struct twlcore *twlcore, u16 reg, u8 mask, u8 val)
+{
+ u8 tmp;
+ int ret;
+
+ ret = twlcore_reg_read(twlcore, reg, &tmp);
+ tmp = (tmp & ~mask) | val;
+
+ if (ret)
+ ret = twlcore_reg_write(twlcore, reg, tmp);
+
+ return ret;
+}
+EXPORT_SYMBOL(twlcore_set_bits);
+
+static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count,
+ ulong offset, ulong flags)
+{
+ struct twlcore *priv = to_twlcore(cdev);
+ u8 *buf = _buf;
+ size_t i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = twlcore_reg_read(priv, offset, buf);
+ if (ret)
+ return (ssize_t)ret;
+ buf++;
+ offset++;
+ }
+
+ return count;
+}
+
+static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count,
+ ulong offset, ulong flags)
+{
+ struct twlcore *twlcore = to_twlcore(cdev);
+ const u8 *buf = _buf;
+ size_t i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = twlcore_reg_write(twlcore, offset, *buf);
+ if (ret)
+ return (ssize_t)ret;
+ buf++;
+ offset++;
+ }
+
+ return count;
+}
+
+struct file_operations twl_fops = {
+ .lseek = dev_lseek_default,
+ .read = twl_read,
+ .write = twl_write,
+};
+EXPORT_SYMBOL(twl_fops);
diff --git a/drivers/mfd/twl4030.c b/drivers/mfd/twl4030.c
index 6a06bd44bb..191c91f36a 100644
--- a/drivers/mfd/twl4030.c
+++ b/drivers/mfd/twl4030.c
@@ -29,145 +29,19 @@ struct twl4030 *twl4030_get(void)
}
EXPORT_SYMBOL(twl4030_get);
-int twl4030_reg_read(struct twl4030 *twl4030, u16 reg, u8 *val)
-{
- int ret;
- struct i2c_msg xfer_msg[2];
- struct i2c_msg *msg;
- int i2c_addr;
- unsigned char buf = reg & 0xff;
-
- i2c_addr = twl4030->client->addr + (reg / 0x100);
-
- /* [MSG1] fill the register address data */
- msg = &xfer_msg[0];
- msg->addr = i2c_addr;
- msg->len = 1;
- msg->flags = 0; /* Read the register value */
- msg->buf = &buf;
- /* [MSG2] fill the data rx buffer */
- msg = &xfer_msg[1];
- msg->addr = i2c_addr;
- msg->flags = I2C_M_RD; /* Read the register value */
- msg->len = 1; /* only n bytes */
- msg->buf = val;
- ret = i2c_transfer(twl4030->client->adapter, xfer_msg, 2);
-
- /* i2c_transfer returns number of messages transferred */
- if (ret < 0) {
- pr_err("%s: failed to transfer all messages: %s\n", __func__, strerror(-ret));
- return ret;
- }
- return 0;
-}
-EXPORT_SYMBOL(twl4030_reg_read);
-
-int twl4030_reg_write(struct twl4030 *twl4030, u16 reg, u8 val)
-{
- int ret;
- struct i2c_msg xfer_msg[1];
- struct i2c_msg *msg;
- int i2c_addr;
- u8 buf[2];
-
- buf[0] = reg & 0xff;
- buf[1] = val;
-
- i2c_addr = twl4030->client->addr + (reg / 0x100);
-
- /*
- * [MSG1]: fill the register address data
- * fill the data Tx buffer
- */
- msg = xfer_msg;
- msg->addr = i2c_addr;
- msg->len = 2;
- msg->flags = 0;
- msg->buf = buf;
- /* over write the first byte of buffer with the register address */
- ret = i2c_transfer(twl4030->client->adapter, xfer_msg, 1);
-
- /* i2c_transfer returns number of messages transferred */
- if (ret < 0) {
- pr_err("%s: failed to transfer all messages: %s\n", __func__, strerror(-ret));
- return ret;
- }
- return 0;
-}
-EXPORT_SYMBOL(twl4030_reg_write);
-
-int twl4030_set_bits(struct twl4030 *twl4030, enum twl4030_reg reg, u8 mask, u8 val)
-{
- u8 tmp;
- int err;
-
- err = twl4030_reg_read(twl4030, reg, &tmp);
- tmp = (tmp & ~mask) | val;
-
- if (!err)
- err = twl4030_reg_write(twl4030, reg, tmp);
-
- return err;
-}
-EXPORT_SYMBOL(twl4030_set_bits);
-
-static ssize_t twl_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags)
-{
- struct twl4030 *priv = to_twl4030(cdev);
- u8 *buf = _buf;
- size_t i = count;
- int err;
-
- while (i) {
- err = twl4030_reg_read(priv, offset, buf);
- if (err)
- return (ssize_t)err;
- buf++;
- i--;
- offset++;
- }
-
- return count;
-}
-
-static ssize_t twl_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags)
-{
- struct twl4030 *twl4030 = to_twl4030(cdev);
- const u8 *buf = _buf;
- size_t i = count;
- int err;
-
- while (i) {
- err = twl4030_reg_write(twl4030, offset, *buf);
- if (err)
- return (ssize_t)err;
- buf++;
- i--;
- offset++;
- }
-
- return count;
-}
-
-static struct file_operations twl_fops = {
- .lseek = dev_lseek_default,
- .read = twl_read,
- .write = twl_write,
-};
-
static int twl_probe(struct device_d *dev)
{
if (twl_dev)
return -EBUSY;
twl_dev = xzalloc(sizeof(struct twl4030));
- twl_dev->cdev.name = DRIVERNAME;
- twl_dev->client = to_i2c_client(dev);
- twl_dev->cdev.size = 1024;
- twl_dev->cdev.dev = dev;
- twl_dev->cdev.ops = &twl_fops;
+ twl_dev->core.cdev.name = DRIVERNAME;
+ twl_dev->core.client = to_i2c_client(dev);
+ twl_dev->core.cdev.size = 1024;
+ twl_dev->core.cdev.dev = dev;
+ twl_dev->core.cdev.ops = &twl_fops;
- devfs_create(&twl_dev->cdev);
+ devfs_create(&(twl_dev->core.cdev));
return 0;
}
@@ -179,8 +53,8 @@ static struct driver_d twl_driver = {
static int twl_init(void)
{
- register_driver(&twl_driver);
- return 0;
+ register_driver(&twl_driver);
+ return 0;
}
device_initcall(twl_init);