alistair23-linux/drivers/staging/iio/meter/ade7854-i2c.c
Alison Schofield a04b4e5005 staging: iio: ade7854: use devm_iio_device_register
Replace iio_device_register with the device managed version.
This change is safe because it does not change the order of
any device removal actions. Unregistering the device was the
only removal action. The newly emptied .remove functions are
deleted.

Signed-off-by: Alison Schofield <amsfield22@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2016-03-11 22:09:09 -08:00

251 lines
5.6 KiB
C

/*
* 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 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,
.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");