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