1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/err.h>
32#include <linux/slab.h>
33#include <linux/i2c.h>
34#include <linux/hwmon.h>
35#include <linux/hwmon-sysfs.h>
36
37
38#define LTC4261_STATUS 0x00
39#define LTC4261_FAULT 0x01
40#define LTC4261_ALERT 0x02
41#define LTC4261_CONTROL 0x03
42#define LTC4261_SENSE_H 0x04
43#define LTC4261_SENSE_L 0x05
44#define LTC4261_ADIN2_H 0x06
45#define LTC4261_ADIN2_L 0x07
46#define LTC4261_ADIN_H 0x08
47#define LTC4261_ADIN_L 0x09
48
49
50
51
52#define FAULT_OV (1<<0)
53#define FAULT_UV (1<<1)
54#define FAULT_OC (1<<2)
55
56struct ltc4261_data {
57 struct device *hwmon_dev;
58
59 struct mutex update_lock;
60 bool valid;
61 unsigned long last_updated;
62
63
64 u8 regs[10];
65};
66
67static struct ltc4261_data *ltc4261_update_device(struct device *dev)
68{
69 struct i2c_client *client = to_i2c_client(dev);
70 struct ltc4261_data *data = i2c_get_clientdata(client);
71 struct ltc4261_data *ret = data;
72
73 mutex_lock(&data->update_lock);
74
75 if (time_after(jiffies, data->last_updated + HZ / 4) || !data->valid) {
76 int i;
77
78
79 for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
80 int val;
81
82 val = i2c_smbus_read_byte_data(client, i);
83 if (unlikely(val < 0)) {
84 dev_dbg(dev,
85 "Failed to read ADC value: error %d\n",
86 val);
87 ret = ERR_PTR(val);
88 data->valid = 0;
89 goto abort;
90 }
91 data->regs[i] = val;
92 }
93 data->last_updated = jiffies;
94 data->valid = 1;
95 }
96abort:
97 mutex_unlock(&data->update_lock);
98 return ret;
99}
100
101
102static int ltc4261_get_value(struct ltc4261_data *data, u8 reg)
103{
104 u32 val;
105
106 val = (data->regs[reg] << 2) + (data->regs[reg + 1] >> 6);
107
108 switch (reg) {
109 case LTC4261_ADIN_H:
110 case LTC4261_ADIN2_H:
111
112 val = val * 25 / 10;
113 break;
114 case LTC4261_SENSE_H:
115
116
117
118
119
120
121
122 val = val * 625 / 10;
123 break;
124 default:
125
126 WARN_ON_ONCE(1);
127 val = 0;
128 break;
129 }
130
131 return val;
132}
133
134static ssize_t ltc4261_show_value(struct device *dev,
135 struct device_attribute *da, char *buf)
136{
137 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
138 struct ltc4261_data *data = ltc4261_update_device(dev);
139 int value;
140
141 if (IS_ERR(data))
142 return PTR_ERR(data);
143
144 value = ltc4261_get_value(data, attr->index);
145 return snprintf(buf, PAGE_SIZE, "%d\n", value);
146}
147
148static ssize_t ltc4261_show_bool(struct device *dev,
149 struct device_attribute *da, char *buf)
150{
151 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
152 struct i2c_client *client = to_i2c_client(dev);
153 struct ltc4261_data *data = ltc4261_update_device(dev);
154 u8 fault;
155
156 if (IS_ERR(data))
157 return PTR_ERR(data);
158
159 fault = data->regs[LTC4261_FAULT] & attr->index;
160 if (fault)
161 i2c_smbus_write_byte_data(client, LTC4261_FAULT, ~fault);
162
163 return snprintf(buf, PAGE_SIZE, "%d\n", fault ? 1 : 0);
164}
165
166
167
168
169
170
171
172#define LTC4261_VALUE(name, ltc4261_cmd_idx) \
173 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
174 ltc4261_show_value, NULL, ltc4261_cmd_idx)
175
176#define LTC4261_BOOL(name, mask) \
177 static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
178 ltc4261_show_bool, NULL, (mask))
179
180
181
182
183LTC4261_VALUE(in1_input, LTC4261_ADIN_H);
184LTC4261_VALUE(in2_input, LTC4261_ADIN2_H);
185
186
187
188
189
190
191
192
193
194LTC4261_BOOL(in1_min_alarm, FAULT_UV);
195LTC4261_BOOL(in1_max_alarm, FAULT_OV);
196LTC4261_BOOL(in2_min_alarm, FAULT_UV);
197LTC4261_BOOL(in2_max_alarm, FAULT_OV);
198
199
200LTC4261_VALUE(curr1_input, LTC4261_SENSE_H);
201
202
203LTC4261_BOOL(curr1_max_alarm, FAULT_OC);
204
205static struct attribute *ltc4261_attributes[] = {
206 &sensor_dev_attr_in1_input.dev_attr.attr,
207 &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
208 &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
209 &sensor_dev_attr_in2_input.dev_attr.attr,
210 &sensor_dev_attr_in2_min_alarm.dev_attr.attr,
211 &sensor_dev_attr_in2_max_alarm.dev_attr.attr,
212
213 &sensor_dev_attr_curr1_input.dev_attr.attr,
214 &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
215
216 NULL,
217};
218
219static const struct attribute_group ltc4261_group = {
220 .attrs = ltc4261_attributes,
221};
222
223static int ltc4261_probe(struct i2c_client *client,
224 const struct i2c_device_id *id)
225{
226 struct i2c_adapter *adapter = client->adapter;
227 struct ltc4261_data *data;
228 int ret;
229
230 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
231 return -ENODEV;
232
233 if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) {
234 dev_err(&client->dev, "Failed to read status register\n");
235 return -ENODEV;
236 }
237
238 data = kzalloc(sizeof(*data), GFP_KERNEL);
239 if (!data) {
240 ret = -ENOMEM;
241 goto out_kzalloc;
242 }
243
244 i2c_set_clientdata(client, data);
245 mutex_init(&data->update_lock);
246
247
248 i2c_smbus_write_byte_data(client, LTC4261_FAULT, 0x00);
249
250
251 ret = sysfs_create_group(&client->dev.kobj, <c4261_group);
252 if (ret)
253 goto out_sysfs_create_group;
254
255 data->hwmon_dev = hwmon_device_register(&client->dev);
256 if (IS_ERR(data->hwmon_dev)) {
257 ret = PTR_ERR(data->hwmon_dev);
258 goto out_hwmon_device_register;
259 }
260
261 return 0;
262
263out_hwmon_device_register:
264 sysfs_remove_group(&client->dev.kobj, <c4261_group);
265out_sysfs_create_group:
266 kfree(data);
267out_kzalloc:
268 return ret;
269}
270
271static int ltc4261_remove(struct i2c_client *client)
272{
273 struct ltc4261_data *data = i2c_get_clientdata(client);
274
275 hwmon_device_unregister(data->hwmon_dev);
276 sysfs_remove_group(&client->dev.kobj, <c4261_group);
277
278 kfree(data);
279
280 return 0;
281}
282
283static const struct i2c_device_id ltc4261_id[] = {
284 {"ltc4261", 0},
285 {}
286};
287
288MODULE_DEVICE_TABLE(i2c, ltc4261_id);
289
290
291static struct i2c_driver ltc4261_driver = {
292 .driver = {
293 .name = "ltc4261",
294 },
295 .probe = ltc4261_probe,
296 .remove = ltc4261_remove,
297 .id_table = ltc4261_id,
298};
299
300static int __init ltc4261_init(void)
301{
302 return i2c_add_driver(<c4261_driver);
303}
304
305static void __exit ltc4261_exit(void)
306{
307 i2c_del_driver(<c4261_driver);
308}
309
310MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
311MODULE_DESCRIPTION("LTC4261 driver");
312MODULE_LICENSE("GPL");
313
314module_init(ltc4261_init);
315module_exit(ltc4261_exit);
316