From 09b034191acd1f95a749630fe366a84d3029930c Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Mon, 7 Mar 2011 23:43:16 +0800 Subject: [PATCH] mfd: Append additional read write on 88pm860x Append the additional read/write operation on 88pm860x for accessing test page in 88PM860x. Signed-off-by: Haojian Zhuang Signed-off-by: Samuel Ortiz --- drivers/mfd/88pm860x-i2c.c | 103 +++++++++++++++++++++++++++++++++++ include/linux/mfd/88pm860x.h | 8 +++ 2 files changed, 111 insertions(+) diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index bc02e6b21608..e017dc88622a 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c @@ -126,6 +126,109 @@ int pm860x_set_bits(struct i2c_client *i2c, int reg, } EXPORT_SYMBOL(pm860x_set_bits); +int pm860x_page_reg_read(struct i2c_client *i2c, int reg) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char zero = 0; + unsigned char data; + int ret; + + mutex_lock(&chip->io_lock); + pm860x_write_device(i2c, 0xFA, 0, &zero); + pm860x_write_device(i2c, 0xFB, 0, &zero); + pm860x_write_device(i2c, 0xFF, 0, &zero); + ret = pm860x_read_device(i2c, reg, 1, &data); + if (ret >= 0) + ret = (int)data; + pm860x_write_device(i2c, 0xFE, 0, &zero); + pm860x_write_device(i2c, 0xFC, 0, &zero); + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(pm860x_page_reg_read); + +int pm860x_page_reg_write(struct i2c_client *i2c, int reg, + unsigned char data) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char zero; + int ret; + + mutex_lock(&chip->io_lock); + pm860x_write_device(i2c, 0xFA, 0, &zero); + pm860x_write_device(i2c, 0xFB, 0, &zero); + pm860x_write_device(i2c, 0xFF, 0, &zero); + ret = pm860x_write_device(i2c, reg, 1, &data); + pm860x_write_device(i2c, 0xFE, 0, &zero); + pm860x_write_device(i2c, 0xFC, 0, &zero); + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(pm860x_page_reg_write); + +int pm860x_page_bulk_read(struct i2c_client *i2c, int reg, + int count, unsigned char *buf) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char zero = 0; + int ret; + + mutex_lock(&chip->io_lock); + pm860x_write_device(i2c, 0xFA, 0, &zero); + pm860x_write_device(i2c, 0xFB, 0, &zero); + pm860x_write_device(i2c, 0xFF, 0, &zero); + ret = pm860x_read_device(i2c, reg, count, buf); + pm860x_write_device(i2c, 0xFE, 0, &zero); + pm860x_write_device(i2c, 0xFC, 0, &zero); + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(pm860x_page_bulk_read); + +int pm860x_page_bulk_write(struct i2c_client *i2c, int reg, + int count, unsigned char *buf) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char zero = 0; + int ret; + + mutex_lock(&chip->io_lock); + pm860x_write_device(i2c, 0xFA, 0, &zero); + pm860x_write_device(i2c, 0xFB, 0, &zero); + pm860x_write_device(i2c, 0xFF, 0, &zero); + ret = pm860x_write_device(i2c, reg, count, buf); + pm860x_write_device(i2c, 0xFE, 0, &zero); + pm860x_write_device(i2c, 0xFC, 0, &zero); + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(pm860x_page_bulk_write); + +int pm860x_page_set_bits(struct i2c_client *i2c, int reg, + unsigned char mask, unsigned char data) +{ + struct pm860x_chip *chip = i2c_get_clientdata(i2c); + unsigned char zero; + unsigned char value; + int ret; + + mutex_lock(&chip->io_lock); + pm860x_write_device(i2c, 0xFA, 0, &zero); + pm860x_write_device(i2c, 0xFB, 0, &zero); + pm860x_write_device(i2c, 0xFF, 0, &zero); + ret = pm860x_read_device(i2c, reg, 1, &value); + if (ret < 0) + goto out; + value &= ~mask; + value |= data; + ret = pm860x_write_device(i2c, reg, 1, &value); +out: + pm860x_write_device(i2c, 0xFE, 0, &zero); + pm860x_write_device(i2c, 0xFC, 0, &zero); + mutex_unlock(&chip->io_lock); + return ret; +} +EXPORT_SYMBOL(pm860x_page_set_bits); static const struct i2c_device_id pm860x_id_table[] = { { "88PM860x", 0 }, diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h index a6f6f81efece..8fba7972ff5f 100644 --- a/include/linux/mfd/88pm860x.h +++ b/include/linux/mfd/88pm860x.h @@ -368,6 +368,14 @@ extern int pm860x_bulk_read(struct i2c_client *, int, int, unsigned char *); extern int pm860x_bulk_write(struct i2c_client *, int, int, unsigned char *); extern int pm860x_set_bits(struct i2c_client *, int, unsigned char, unsigned char); +extern int pm860x_page_reg_read(struct i2c_client *, int); +extern int pm860x_page_reg_write(struct i2c_client *, int, unsigned char); +extern int pm860x_page_bulk_read(struct i2c_client *, int, int, + unsigned char *); +extern int pm860x_page_bulk_write(struct i2c_client *, int, int, + unsigned char *); +extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char, + unsigned char); extern int pm860x_device_init(struct pm860x_chip *chip, struct pm860x_platform_data *pdata) __devinit ;