diff options
author | Marc Kleine-Budde <mkl@pengutronix.de> | 2009-12-09 02:05:07 +0100 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2010-01-18 12:19:28 +0100 |
commit | 23f4449b78851d8a21ca42ecec57f48982f9d0e3 (patch) | |
tree | c147307ba8ecd7f6674dd25fee2864766832ea41 /drivers | |
parent | fc268d55844d6a714ab1a6131dc5cc9b8043cca9 (diff) | |
download | barebox-23f4449b78851d8a21ca42ecec57f48982f9d0e3.tar.gz barebox-23f4449b78851d8a21ca42ecec57f48982f9d0e3.tar.xz |
mc13892: clean up driver interface
Export mc13892_reg_read, mc13892_reg_write and mc13892_set_bits
function instead of exposing the i2c interface.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/i2c/mc13892.c | 91 |
1 files changed, 72 insertions, 19 deletions
diff --git a/drivers/i2c/mc13892.c b/drivers/i2c/mc13892.c index 54661d4f5e..67d4232a23 100644 --- a/drivers/i2c/mc13892.c +++ b/drivers/i2c/mc13892.c @@ -26,47 +26,99 @@ #include <errno.h> #include <i2c/i2c.h> - -#include <asm/byteorder.h> +#include <i2c/mc13892.h> #define DRIVERNAME "mc13892" -struct mc_priv { - struct cdev cdev; - struct i2c_client *client; -}; - -#define to_mc_priv(a) container_of(a, struct mc_priv, cdev) +#define to_mc13892(a) container_of(a, struct mc13892, cdev) -static struct mc_priv *mc_dev; +static struct mc13892 *mc_dev; -struct i2c_client *mc13892_get_client(void) +struct mc13892 *mc13892_get(void) { if (!mc_dev) return NULL; - return mc_dev->client; + return mc_dev; +} +EXPORT_SYMBOL(mc13892_get); + +int mc13892_reg_read(struct mc13892 *mc13892, enum mc13892_reg reg, u32 *val) +{ + u8 buf[3]; + int ret; + + ret = i2c_read_reg(mc13892->client, reg, buf, 3); + *val = buf[0] << 16 | buf[1] << 8 | buf[2] << 0; + + return ret == 3 ? 0 : ret; } +EXPORT_SYMBOL(mc13892_reg_read) -static u32 mc_read_reg(struct mc_priv *mc, int reg) +int mc13892_reg_write(struct mc13892 *mc13892, enum mc13892_reg reg, u32 val) { - u32 buf; + u8 buf[] = { + val >> 16, + val >> 8, + val >> 0, + }; + int ret; + + ret = i2c_write_reg(mc13892->client, reg, buf, 3); + + return ret == 3 ? 0 : ret; +} +EXPORT_SYMBOL(mc13892_reg_write) + +int mc13892_set_bits(struct mc13892 *mc13892, enum mc13892_reg reg, u32 mask, u32 val) +{ + u32 tmp; + int err; + + err = mc13892_reg_read(mc13892, reg, &tmp); + tmp = (tmp & ~mask) | val; - i2c_read_reg(mc->client, reg, (u8 *)&buf, sizeof(buf)); + if (!err) + err = mc13892_reg_write(mc13892, reg, tmp); - return buf; + return err; } +EXPORT_SYMBOL(mc13892_set_bits); static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset, ulong flags) { - struct mc_priv *priv = to_mc_priv(cdev); - int i = count >> 2; + struct mc13892 *priv = to_mc13892(cdev); u32 *buf = _buf; + size_t i = count >> 2; + int err; + + offset >>= 2; + + while (i) { + err = mc13892_reg_read(priv, offset, buf); + if (err) + return (ssize_t)err; + buf++; + i--; + offset++; + } + + return count; +} + +static ssize_t mc_write(struct cdev *cdev, const void *_buf, size_t count, ulong offset, ulong flags) +{ + struct mc13892 *mc13892 = to_mc13892(cdev); + const u32 *buf = _buf; + size_t i = count >> 2; + int err; offset >>= 2; while (i) { - *buf = mc_read_reg(priv, offset); + err = mc13892_reg_write(mc13892, offset, *buf); + if (err) + return (ssize_t)err; buf++; i--; offset++; @@ -78,6 +130,7 @@ static ssize_t mc_read(struct cdev *cdev, void *_buf, size_t count, ulong offset static struct file_operations mc_fops = { .lseek = dev_lseek_default, .read = mc_read, + .write = mc_write, }; static int mc_probe(struct device_d *dev) @@ -85,7 +138,7 @@ static int mc_probe(struct device_d *dev) if (mc_dev) return -EBUSY; - mc_dev = xzalloc(sizeof(struct mc_priv)); + mc_dev = xzalloc(sizeof(struct mc13892)); mc_dev->cdev.name = DRIVERNAME; mc_dev->client = to_i2c_client(dev); mc_dev->cdev.size = 256; |