• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (I2C Bus)
3  *
4  * Copyright 2010 Analog Devices Inc.
5  *
6  * Licensed under the GPL-2 or later.
7  */
8 
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/i2c.h>
12 #include <linux/slab.h>
13 #include <linux/module.h>
14 
15 #include "../iio.h"
16 #include "ade7854.h"
17 
ade7854_i2c_write_reg_8(struct device * dev,u16 reg_address,u8 value)18 static int ade7854_i2c_write_reg_8(struct device *dev,
19 		u16 reg_address,
20 		u8 value)
21 {
22 	int ret;
23 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
24 	struct ade7854_state *st = iio_priv(indio_dev);
25 
26 	mutex_lock(&st->buf_lock);
27 	st->tx[0] = (reg_address >> 8) & 0xFF;
28 	st->tx[1] = reg_address & 0xFF;
29 	st->tx[2] = value;
30 
31 	ret = i2c_master_send(st->i2c, st->tx, 3);
32 	mutex_unlock(&st->buf_lock);
33 
34 	return ret;
35 }
36 
ade7854_i2c_write_reg_16(struct device * dev,u16 reg_address,u16 value)37 static int ade7854_i2c_write_reg_16(struct device *dev,
38 		u16 reg_address,
39 		u16 value)
40 {
41 	int ret;
42 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
43 	struct ade7854_state *st = iio_priv(indio_dev);
44 
45 	mutex_lock(&st->buf_lock);
46 	st->tx[0] = (reg_address >> 8) & 0xFF;
47 	st->tx[1] = reg_address & 0xFF;
48 	st->tx[2] = (value >> 8) & 0xFF;
49 	st->tx[3] = value & 0xFF;
50 
51 	ret = i2c_master_send(st->i2c, st->tx, 4);
52 	mutex_unlock(&st->buf_lock);
53 
54 	return ret;
55 }
56 
ade7854_i2c_write_reg_24(struct device * dev,u16 reg_address,u32 value)57 static int ade7854_i2c_write_reg_24(struct device *dev,
58 		u16 reg_address,
59 		u32 value)
60 {
61 	int ret;
62 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
63 	struct ade7854_state *st = iio_priv(indio_dev);
64 
65 	mutex_lock(&st->buf_lock);
66 	st->tx[0] = (reg_address >> 8) & 0xFF;
67 	st->tx[1] = reg_address & 0xFF;
68 	st->tx[2] = (value >> 16) & 0xFF;
69 	st->tx[3] = (value >> 8) & 0xFF;
70 	st->tx[4] = value & 0xFF;
71 
72 	ret = i2c_master_send(st->i2c, st->tx, 5);
73 	mutex_unlock(&st->buf_lock);
74 
75 	return ret;
76 }
77 
ade7854_i2c_write_reg_32(struct device * dev,u16 reg_address,u32 value)78 static int ade7854_i2c_write_reg_32(struct device *dev,
79 		u16 reg_address,
80 		u32 value)
81 {
82 	int ret;
83 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
84 	struct ade7854_state *st = iio_priv(indio_dev);
85 
86 	mutex_lock(&st->buf_lock);
87 	st->tx[0] = (reg_address >> 8) & 0xFF;
88 	st->tx[1] = reg_address & 0xFF;
89 	st->tx[2] = (value >> 24) & 0xFF;
90 	st->tx[3] = (value >> 16) & 0xFF;
91 	st->tx[4] = (value >> 8) & 0xFF;
92 	st->tx[5] = value & 0xFF;
93 
94 	ret = i2c_master_send(st->i2c, st->tx, 6);
95 	mutex_unlock(&st->buf_lock);
96 
97 	return ret;
98 }
99 
ade7854_i2c_read_reg_8(struct device * dev,u16 reg_address,u8 * val)100 static int ade7854_i2c_read_reg_8(struct device *dev,
101 		u16 reg_address,
102 		u8 *val)
103 {
104 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
105 	struct ade7854_state *st = iio_priv(indio_dev);
106 	int ret;
107 
108 	mutex_lock(&st->buf_lock);
109 	st->tx[0] = (reg_address >> 8) & 0xFF;
110 	st->tx[1] = reg_address & 0xFF;
111 
112 	ret = i2c_master_send(st->i2c, st->tx, 2);
113 	if (ret)
114 		goto out;
115 
116 	ret = i2c_master_recv(st->i2c, st->rx, 1);
117 	if (ret)
118 		goto out;
119 
120 	*val = st->rx[0];
121 out:
122 	mutex_unlock(&st->buf_lock);
123 	return ret;
124 }
125 
ade7854_i2c_read_reg_16(struct device * dev,u16 reg_address,u16 * val)126 static int ade7854_i2c_read_reg_16(struct device *dev,
127 		u16 reg_address,
128 		u16 *val)
129 {
130 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
131 	struct ade7854_state *st = iio_priv(indio_dev);
132 	int ret;
133 
134 	mutex_lock(&st->buf_lock);
135 	st->tx[0] = (reg_address >> 8) & 0xFF;
136 	st->tx[1] = reg_address & 0xFF;
137 
138 	ret = i2c_master_send(st->i2c, st->tx, 2);
139 	if (ret)
140 		goto out;
141 
142 	ret = i2c_master_recv(st->i2c, st->rx, 2);
143 	if (ret)
144 		goto out;
145 
146 	*val = (st->rx[0] << 8) | st->rx[1];
147 out:
148 	mutex_unlock(&st->buf_lock);
149 	return ret;
150 }
151 
ade7854_i2c_read_reg_24(struct device * dev,u16 reg_address,u32 * val)152 static int ade7854_i2c_read_reg_24(struct device *dev,
153 		u16 reg_address,
154 		u32 *val)
155 {
156 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
157 	struct ade7854_state *st = iio_priv(indio_dev);
158 	int ret;
159 
160 	mutex_lock(&st->buf_lock);
161 	st->tx[0] = (reg_address >> 8) & 0xFF;
162 	st->tx[1] = reg_address & 0xFF;
163 
164 	ret = i2c_master_send(st->i2c, st->tx, 2);
165 	if (ret)
166 		goto out;
167 
168 	ret = i2c_master_recv(st->i2c, st->rx, 3);
169 	if (ret)
170 		goto out;
171 
172 	*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
173 out:
174 	mutex_unlock(&st->buf_lock);
175 	return ret;
176 }
177 
ade7854_i2c_read_reg_32(struct device * dev,u16 reg_address,u32 * val)178 static int ade7854_i2c_read_reg_32(struct device *dev,
179 		u16 reg_address,
180 		u32 *val)
181 {
182 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
183 	struct ade7854_state *st = iio_priv(indio_dev);
184 	int ret;
185 
186 	mutex_lock(&st->buf_lock);
187 	st->tx[0] = (reg_address >> 8) & 0xFF;
188 	st->tx[1] = reg_address & 0xFF;
189 
190 	ret = i2c_master_send(st->i2c, st->tx, 2);
191 	if (ret)
192 		goto out;
193 
194 	ret = i2c_master_recv(st->i2c, st->rx, 3);
195 	if (ret)
196 		goto out;
197 
198 	*val = (st->rx[0] << 24) | (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
199 out:
200 	mutex_unlock(&st->buf_lock);
201 	return ret;
202 }
203 
ade7854_i2c_probe(struct i2c_client * client,const struct i2c_device_id * id)204 static int __devinit ade7854_i2c_probe(struct i2c_client *client,
205 		const struct i2c_device_id *id)
206 {
207 	int ret;
208 	struct ade7854_state *st;
209 	struct iio_dev *indio_dev;
210 
211 	indio_dev = iio_allocate_device(sizeof(*st));
212 	if (indio_dev == NULL)
213 		return -ENOMEM;
214 	st = iio_priv(indio_dev);
215 	i2c_set_clientdata(client, indio_dev);
216 	st->read_reg_8 = ade7854_i2c_read_reg_8;
217 	st->read_reg_16 = ade7854_i2c_read_reg_16;
218 	st->read_reg_24 = ade7854_i2c_read_reg_24;
219 	st->read_reg_32 = ade7854_i2c_read_reg_32;
220 	st->write_reg_8 = ade7854_i2c_write_reg_8;
221 	st->write_reg_16 = ade7854_i2c_write_reg_16;
222 	st->write_reg_24 = ade7854_i2c_write_reg_24;
223 	st->write_reg_32 = ade7854_i2c_write_reg_32;
224 	st->i2c = client;
225 	st->irq = client->irq;
226 
227 	ret = ade7854_probe(indio_dev, &client->dev);
228 	if (ret)
229 		iio_free_device(indio_dev);
230 
231 	return ret;
232 }
233 
ade7854_i2c_remove(struct i2c_client * client)234 static int __devexit ade7854_i2c_remove(struct i2c_client *client)
235 {
236 	return ade7854_remove(i2c_get_clientdata(client));
237 }
238 
239 static const struct i2c_device_id ade7854_id[] = {
240 	{ "ade7854", 0 },
241 	{ "ade7858", 0 },
242 	{ "ade7868", 0 },
243 	{ "ade7878", 0 },
244 	{ }
245 };
246 MODULE_DEVICE_TABLE(i2c, ade7854_id);
247 
248 static struct i2c_driver ade7854_i2c_driver = {
249 	.driver = {
250 		.name = "ade7854",
251 	},
252 	.probe    = ade7854_i2c_probe,
253 	.remove   = __devexit_p(ade7854_i2c_remove),
254 	.id_table = ade7854_id,
255 };
256 module_i2c_driver(ade7854_i2c_driver);
257 
258 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
259 MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC I2C Driver");
260 MODULE_LICENSE("GPL v2");
261