diff options
author | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 12:17:53 -0700 |
---|---|---|
committer | Yunhong Jiang <yunhong.jiang@intel.com> | 2015-08-04 15:44:42 -0700 |
commit | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (patch) | |
tree | 1c9cafbcd35f783a87880a10f85d1a060db1a563 /kernel/drivers/staging/iio/meter/ade7854-i2c.c | |
parent | 98260f3884f4a202f9ca5eabed40b1354c489b29 (diff) |
Add the rt linux 4.1.3-rt3 as base
Import the rt linux 4.1.3-rt3 as OPNFV kvm base.
It's from git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git linux-4.1.y-rt and
the base is:
commit 0917f823c59692d751951bf5ea699a2d1e2f26a2
Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Date: Sat Jul 25 12:13:34 2015 +0200
Prepare v4.1.3-rt3
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
We lose all the git history this way and it's not good. We
should apply another opnfv project repo in future.
Change-Id: I87543d81c9df70d99c5001fbdf646b202c19f423
Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
Diffstat (limited to 'kernel/drivers/staging/iio/meter/ade7854-i2c.c')
-rw-r--r-- | kernel/drivers/staging/iio/meter/ade7854-i2c.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/kernel/drivers/staging/iio/meter/ade7854-i2c.c b/kernel/drivers/staging/iio/meter/ade7854-i2c.c new file mode 100644 index 000000000..07cfe28b2 --- /dev/null +++ b/kernel/drivers/staging/iio/meter/ade7854-i2c.c @@ -0,0 +1,256 @@ +/* + * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (I2C Bus) + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/slab.h> +#include <linux/module.h> + +#include <linux/iio/iio.h> +#include "ade7854.h" + +static int ade7854_i2c_write_reg_8(struct device *dev, + u16 reg_address, + u8 value) +{ + int ret; + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = value; + + ret = i2c_master_send(st->i2c, st->tx, 3); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_write_reg_16(struct device *dev, + u16 reg_address, + u16 value) +{ + int ret; + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = (value >> 8) & 0xFF; + st->tx[3] = value & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 4); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_write_reg_24(struct device *dev, + u16 reg_address, + u32 value) +{ + int ret; + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = (value >> 16) & 0xFF; + st->tx[3] = (value >> 8) & 0xFF; + st->tx[4] = value & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 5); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_write_reg_32(struct device *dev, + u16 reg_address, + u32 value) +{ + int ret; + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = (value >> 24) & 0xFF; + st->tx[3] = (value >> 16) & 0xFF; + st->tx[4] = (value >> 8) & 0xFF; + st->tx[5] = value & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 6); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_read_reg_8(struct device *dev, + u16 reg_address, + u8 *val) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 1); + if (ret) + goto out; + + *val = st->rx[0]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_read_reg_16(struct device *dev, + u16 reg_address, + u16 *val) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 2); + if (ret) + goto out; + + *val = (st->rx[0] << 8) | st->rx[1]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_read_reg_24(struct device *dev, + u16 reg_address, + u32 *val) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 3); + if (ret) + goto out; + + *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_read_reg_32(struct device *dev, + u16 reg_address, + u32 *val) +{ + struct iio_dev *indio_dev = dev_to_iio_dev(dev); + struct ade7854_state *st = iio_priv(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 3); + if (ret) + goto out; + + *val = (st->rx[0] << 24) | (st->rx[1] << 16) | + (st->rx[2] << 8) | st->rx[3]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ade7854_state *st; + struct iio_dev *indio_dev; + + indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); + if (!indio_dev) + return -ENOMEM; + st = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + st->read_reg_8 = ade7854_i2c_read_reg_8; + st->read_reg_16 = ade7854_i2c_read_reg_16; + st->read_reg_24 = ade7854_i2c_read_reg_24; + st->read_reg_32 = ade7854_i2c_read_reg_32; + st->write_reg_8 = ade7854_i2c_write_reg_8; + st->write_reg_16 = ade7854_i2c_write_reg_16; + st->write_reg_24 = ade7854_i2c_write_reg_24; + st->write_reg_32 = ade7854_i2c_write_reg_32; + st->i2c = client; + st->irq = client->irq; + + return ade7854_probe(indio_dev, &client->dev); +} + +static int ade7854_i2c_remove(struct i2c_client *client) +{ + return ade7854_remove(i2c_get_clientdata(client)); +} + +static const struct i2c_device_id ade7854_id[] = { + { "ade7854", 0 }, + { "ade7858", 0 }, + { "ade7868", 0 }, + { "ade7878", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ade7854_id); + +static struct i2c_driver ade7854_i2c_driver = { + .driver = { + .name = "ade7854", + }, + .probe = ade7854_i2c_probe, + .remove = ade7854_i2c_remove, + .id_table = ade7854_id, +}; +module_i2c_driver(ade7854_i2c_driver); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC I2C Driver"); +MODULE_LICENSE("GPL v2"); |