hwmon: ina219: Fix error case return values
[linux-3.10.git] / drivers / hwmon / ina219.c
1 /*
2  * ina219.c - driver for TI INA219 current / power monitor sensor
3  *
4  * Copyright (c) 2011-2013, NVIDIA Corporation.
5  *
6  * The INA219 is a sensor chip made by Texas Instruments. It measures
7  * power, voltage and current on a power rail.
8  * Complete datasheet can be obtained from website:
9  *   http://focus.ti.com/lit/ds/symlink/ina219.pdf
10  *
11  * This program is free software. you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation.
14  *
15  * This program is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18  * more details.
19  *
20  * You should have received a copy of the GNU General Public License along
21  * with this program; if not, write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23  */
24
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/spinlock.h>
28 #include <linux/sysfs.h>
29 #include <linux/kobject.h>
30 #include <linux/hrtimer.h>
31 #include <linux/slab.h>
32 #include <linux/interrupt.h>
33 #include <linux/mutex.h>
34 #include <linux/i2c.h>
35 #include <linux/slab.h>
36 #include <linux/err.h>
37 #include <linux/gpio.h>
38 #include <linux/device.h>
39 #include "linux/ina219.h"
40 #include <linux/init.h>
41 #include <linux/hwmon-sysfs.h>
42 #include <linux/hwmon.h>
43
44 #define DRIVER_NAME "ina219"
45
46 /* INA219 register offsets */
47 #define INA219_CONFIG   0
48 #define INA219_SHUNT    1
49 #define INA219_VOLTAGE  2
50 #define INA219_POWER    3
51 #define INA219_CURRENT  4
52 #define INA219_CAL      5
53
54 #define INA219_RESET 0x8000
55
56 #define busv_register_to_mv(x) (((x) >> 3) * 4)
57 #define shuntv_register_to_uv(x) ((x) * 10)
58 struct power_mon_data {
59         s32 voltage;
60         s32 currentInMillis;
61         s32 power;
62 };
63
64 struct ina219_data {
65         struct device *hwmon_dev;
66         struct i2c_client *client;
67         struct ina219_platform_data *pInfo;
68         struct power_mon_data pm_data;
69         struct mutex mutex;
70         int state;
71 };
72
73 #define STOPPED 0
74 #define RUNNING 1
75
76 /* Set non-zero to enable debug prints */
77 #define INA219_DEBUG_PRINTS 0
78
79 #if INA219_DEBUG_PRINTS
80 #define DEBUG_INA219(x) printk x
81 #else
82 #define DEBUG_INA219(x)
83 #endif
84
85 static s32 power_down_INA219(struct i2c_client *client)
86 {
87         s32 retval;
88         retval = i2c_smbus_write_word_data(client, INA219_CONFIG, 0);
89         if (retval < 0)
90                 dev_err(&client->dev, "power down failure sts: 0x%x\n", retval);
91         return retval;
92 }
93
94 static s32 power_up_INA219(struct i2c_client *client, u16 config_data)
95 {
96         s32 retval;
97         struct ina219_data *data = i2c_get_clientdata(client);
98         retval = i2c_smbus_write_word_data(client, INA219_CONFIG,
99                                 __constant_cpu_to_be16(config_data));
100         if (retval < 0)
101                 goto error;
102
103         retval = i2c_smbus_write_word_data(client, INA219_CAL,
104                         __constant_cpu_to_be16(data->pInfo->calibration_data));
105         if (retval < 0)
106                 goto error;
107
108         return 0;
109 error:
110         dev_err(&client->dev, "power up failure sts: 0x%x\n", retval);
111         return retval;
112
113 }
114
115 static s32 show_rail_name(struct device *dev,
116                         struct device_attribute *attr,
117                         char *buf)
118 {
119         struct i2c_client *client = to_i2c_client(dev);
120         struct ina219_data *data = i2c_get_clientdata(client);
121         return sprintf(buf, "%s\n", data->pInfo->rail_name);
122 }
123
124 static s32 show_voltage(struct device *dev,
125                         struct device_attribute *attr,
126                         char *buf)
127 {
128         struct i2c_client *client = to_i2c_client(dev);
129         struct ina219_data *data = i2c_get_clientdata(client);
130         s32 voltage_mV;
131         int cur_state;
132
133         mutex_lock(&data->mutex);
134         cur_state = data->state;
135
136         if (data->state == STOPPED)
137                 if (power_up_INA219(client, data->pInfo->trig_conf) < 0)
138                         goto error;
139         /* getting voltage readings in milli volts*/
140         voltage_mV =
141                 (s16)be16_to_cpu(i2c_smbus_read_word_data(client,
142                         INA219_VOLTAGE));
143
144         DEBUG_INA219(("Ina219 voltage reg Value: 0x%x\n", voltage_mV));
145         if (voltage_mV < 0)
146                 goto error;
147         voltage_mV = busv_register_to_mv(voltage_mV);
148         DEBUG_INA219(("Ina219 voltage in mv: %d\n", voltage_mV));
149
150         DEBUG_INA219(("%s volt = %d\n", __func__, voltage_mV));
151
152         if (cur_state == STOPPED)
153                 if (power_down_INA219(client) < 0)
154                         goto error;
155
156         mutex_unlock(&data->mutex);
157         return sprintf(buf, "%d mV\n", voltage_mV);
158 error:
159         mutex_unlock(&data->mutex);
160         dev_err(dev, "%s: failed\n", __func__);
161         return -EAGAIN;
162 }
163
164 static s32 show_shunt_voltage(struct device *dev,
165                         struct device_attribute *attr,
166                         char *buf)
167 {
168         struct i2c_client *client = to_i2c_client(dev);
169         struct ina219_data *data = i2c_get_clientdata(client);
170         s32 voltage_uV;
171         int cur_state;
172         mutex_lock(&data->mutex);
173         cur_state = data->state;
174         if (data->state == STOPPED)
175                 if (power_up_INA219(client, data->pInfo->trig_conf) < 0)
176                         goto error;
177         /* getting voltage readings in milli volts*/
178         voltage_uV =
179                 be16_to_cpu(i2c_smbus_read_word_data(client,
180                         INA219_SHUNT));
181
182         DEBUG_INA219(("Ina219 voltage reg Value: 0x%x\n", voltage_uV));
183         if (voltage_uV < 0)
184                 goto error;
185         voltage_uV = shuntv_register_to_uv(voltage_uV);
186
187         if (cur_state == STOPPED)
188                 if (power_down_INA219(client) < 0)
189                         goto error;
190
191         mutex_unlock(&data->mutex);
192
193         DEBUG_INA219(("%s volt = %d\n", __func__, voltage_uV));
194         return sprintf(buf, "%d uV\n", voltage_uV);
195 error:
196         mutex_unlock(&data->mutex);
197         dev_err(dev, "%s: failed\n", __func__);
198         return -EAGAIN;
199 }
200
201 static s32 show_power2(struct device *dev,
202                         struct device_attribute *attr,
203                         char *buf)
204 {
205         struct i2c_client *client = to_i2c_client(dev);
206         struct ina219_data *data = i2c_get_clientdata(client);
207         s32 power_mW;
208         s32 voltage_shunt_uV;
209         s32 voltage_bus_mV;
210         s32 inverse_shunt_resistor;
211         int cur_state;
212 #if INA219_DEBUG_PRINTS
213         s32 power_raw;
214 #endif
215
216         mutex_lock(&data->mutex);
217         cur_state = data->state;
218         if (data->state == STOPPED)
219                 if (power_up_INA219(client, data->pInfo->trig_conf) < 0)
220                         goto error;
221
222         voltage_shunt_uV = be16_to_cpu(i2c_smbus_read_word_data(client,
223                         INA219_SHUNT));
224         if (voltage_shunt_uV < 0)
225                 goto error;
226         voltage_shunt_uV = shuntv_register_to_uv(voltage_shunt_uV);
227
228         voltage_bus_mV = be16_to_cpu(i2c_smbus_read_word_data(client,
229                         INA219_VOLTAGE));
230         if (voltage_bus_mV < 0)
231                 goto error;
232
233         voltage_bus_mV = busv_register_to_mv(voltage_bus_mV);
234
235         /*avoid overflow*/
236         inverse_shunt_resistor = 1000/(data->pInfo->shunt_resistor);
237         power_mW = voltage_shunt_uV * inverse_shunt_resistor; /*current uAmps*/
238         power_mW = power_mW / 1000; /*current mAmps*/
239         power_mW = power_mW * (voltage_bus_mV); /*Power uW*/
240         power_mW = power_mW / 1000; /*Power mW*/
241
242 #if INA219_DEBUG_PRINTS
243         power_raw = be16_to_cpu(i2c_smbus_read_word_data(client, INA219_POWER));
244         power_raw *= data->pInfo->power_lsb;
245         power_raw /= data->pInfo->precision_multiplier;
246         DEBUG_INA219(("INA219: power_mW: %d, power_raw:%d\n", power_mW,
247                                                                 power_raw));
248 #endif
249         if (cur_state == STOPPED)
250                 if (power_down_INA219(client) < 0)
251                         goto error;
252
253
254         mutex_unlock(&data->mutex);
255         DEBUG_INA219(("%s pow = %d\n", __func__, power_mW));
256         return sprintf(buf, "%d mW\n", power_mW);
257 error:
258         mutex_unlock(&data->mutex);
259         dev_err(dev, "%s: failed\n", __func__);
260         return -EAGAIN;
261 }
262
263 /*This function is kept to support INA219 on cardhu*/
264 static s32 show_power(struct device *dev,
265                         struct device_attribute *attr,
266                         char *buf)
267 {
268         struct i2c_client *client = to_i2c_client(dev);
269         struct ina219_data *data = i2c_get_clientdata(client);
270         s32 retval;
271         s32 power_mW;
272         s32 voltage_mV;
273         s32 overflow, conversion;
274         int cur_state;
275
276         mutex_lock(&data->mutex);
277         cur_state = data->state;
278         if (data->state == STOPPED) {
279                 if (power_up_INA219(client, data->pInfo->trig_conf) < 0) {
280                         retval = -EAGAIN;
281                         goto error;
282                 }
283         } else {
284                 mutex_unlock(&data->mutex);
285                 return show_power2(dev, attr, buf);
286         }
287
288         /* check if the readings are valid */
289         do {
290                 /* read power register to clear conversion bit */
291                 retval = be16_to_cpu(i2c_smbus_read_word_data(client,
292                         INA219_POWER));
293                 if (retval < 0) {
294                         dev_err(dev, "CNVR bit clearing failure sts: 0x%x\n",
295                                 retval);
296                         goto error;
297                 }
298
299                 voltage_mV =
300                         be16_to_cpu(i2c_smbus_read_word_data(client,
301                                 INA219_VOLTAGE));
302                 DEBUG_INA219(("Ina219 voltage reg Value: 0x%x\n", voltage_mV));
303                 overflow = voltage_mV & 1;
304                 if (overflow) {
305                         dev_err(dev, "overflow error\n");
306                         goto error;
307                 }
308                 conversion = (voltage_mV >> 1) & 1;
309                 DEBUG_INA219(("\n ina219 CNVR value:%d", conversion));
310         } while (!conversion);
311
312         /* getting power readings in milli watts*/
313         power_mW = be16_to_cpu(i2c_smbus_read_word_data(client,
314                 INA219_POWER));
315         DEBUG_INA219(("Ina219 power Reg: 0x%x\n", power_mW));
316         power_mW *= data->pInfo->power_lsb;
317         if (data->pInfo->precision_multiplier)
318                 power_mW /= data->pInfo->precision_multiplier;
319         DEBUG_INA219(("Ina219 power Val: %d\n", power_mW));
320         if (power_mW < 0)
321                 goto error;
322
323         /* set ina219 to power down mode */
324         retval = power_down_INA219(client);
325         if (retval < 0)
326                 goto error;
327         mutex_unlock(&data->mutex);
328         DEBUG_INA219(("%s pow = %d\n", __func__, power_mW));
329         return sprintf(buf, "%d mW\n", power_mW);
330 error:
331         mutex_unlock(&data->mutex);
332         dev_err(dev, "%s: failed\n", __func__);
333         return retval;
334 }
335 static s32 show_current2(struct device *dev,
336                         struct device_attribute *attr,
337                         char *buf)
338 {
339         struct i2c_client *client = to_i2c_client(dev);
340         struct ina219_data *data = i2c_get_clientdata(client);
341         s32 current_mA;
342         s32 voltage_uV;
343         s32 inverse_shunt_resistor;
344         int cur_state;
345 #if INA219_DEBUG_PRINTS
346         s32 current_raw;
347 #endif
348         mutex_lock(&data->mutex);
349         cur_state = data->state;
350         if (data->state == STOPPED)
351                 if (power_up_INA219(client, data->pInfo->trig_conf) < 0)
352                         goto error;
353
354         voltage_uV =
355                 (s16)be16_to_cpu(i2c_smbus_read_word_data(client,
356                                                         INA219_SHUNT));
357         if (voltage_uV < 0)
358                 goto error;
359         inverse_shunt_resistor = 1000/(data->pInfo->shunt_resistor);
360         voltage_uV = shuntv_register_to_uv(voltage_uV);
361         current_mA = voltage_uV * inverse_shunt_resistor;
362         current_mA = current_mA / 1000;
363
364 #if INA219_DEBUG_PRINTS
365         current_raw =
366                 (s16)be16_to_cpu(i2c_smbus_read_word_data(client,
367                                                         INA219_CURRENT));
368         current_raw *= data->pInfo->power_lsb;
369         current_raw /= data->pInfo->divisor;
370         current_raw /= data->pInfo->precision_multiplier;
371
372         DEBUG_INA219(("%s current = %d current_raw=%d\n", __func__, current_mA,
373         current_raw));
374 #endif
375         if (cur_state == STOPPED)
376                 if (power_down_INA219(client) < 0)
377                         goto error;
378         mutex_unlock(&data->mutex);
379         return sprintf(buf, "%d mA\n", current_mA);
380 error:
381         dev_err(dev, "%s: failed\n", __func__);
382         mutex_unlock(&data->mutex);
383         return -EAGAIN;
384 }
385
386 /*This function is kept to support INA219 on cardhu*/
387 static s32 show_current(struct device *dev,
388                         struct device_attribute *attr,
389                         char *buf)
390 {
391         struct i2c_client *client = to_i2c_client(dev);
392         struct ina219_data *data = i2c_get_clientdata(client);
393         s32 retval;
394         s32 current_mA;
395         s32 voltage_mV;
396         s32 overflow, conversion;
397         int cur_state;
398
399         mutex_lock(&data->mutex);
400
401         cur_state = data->state;
402         if (data->state == STOPPED) {
403                 if (power_up_INA219(client, data->pInfo->trig_conf) < 0) {
404                         retval = -EAGAIN;
405                         goto error;
406                 }
407         } else {
408                 mutex_unlock(&data->mutex);
409                 show_current2(dev, attr, buf);
410         }
411         /* check if the readings are valid */
412         do {
413                 /* read power register to clear conversion bit */
414                 retval = be16_to_cpu(i2c_smbus_read_word_data(client,
415                         INA219_POWER));
416                 if (retval < 0) {
417                         dev_err(dev, "CNVR bit clearing failure sts: 0x%x\n",
418                                 retval);
419                         goto error;
420                 }
421
422                 voltage_mV =
423                         be16_to_cpu(i2c_smbus_read_word_data(client,
424                                 INA219_VOLTAGE));
425                 DEBUG_INA219(("Ina219 voltage reg Value: 0x%x\n", voltage_mV));
426                 overflow = voltage_mV & 1;
427                 if (overflow) {
428                         dev_err(dev, "overflow error\n");
429                         goto error;
430                 }
431                 conversion = (voltage_mV >> 1) & 1;
432                 DEBUG_INA219(("\n ina219 CNVR value:%d", conversion));
433         } while (!conversion);
434
435         /* getting current readings in milli amps*/
436         current_mA = be16_to_cpu(i2c_smbus_read_word_data(client,
437                 INA219_CURRENT));
438         DEBUG_INA219(("Ina219 current Reg: 0x%x\n", current_mA));
439         if (current_mA < 0)
440                 goto error;
441         current_mA =
442                 (current_mA * data->pInfo->power_lsb) / data->pInfo->divisor;
443         if (data->pInfo->precision_multiplier)
444                 current_mA /= data->pInfo->precision_multiplier;
445         DEBUG_INA219(("Ina219 current Value: %d\n", current_mA));
446
447         if (cur_state == STOPPED)
448                 if (power_down_INA219(client) < 0)
449                         goto error;
450
451         mutex_unlock(&data->mutex);
452
453         DEBUG_INA219(("%s current = %d\n", __func__, current_mA));
454         return sprintf(buf, "%d mA\n", current_mA);
455 error:
456         mutex_unlock(&data->mutex);
457         dev_err(dev, "%s: failed\n", __func__);
458         return retval;
459 }
460
461 static int ina219_state_show(struct device *dev,
462                                 struct device_attribute *attr, char *buf)
463 {
464         struct i2c_client *client = to_i2c_client(dev);
465         struct ina219_data *data = i2c_get_clientdata(client);
466         int count;
467         mutex_lock(&data->mutex);
468         count = sprintf(buf, "%d\n", data->state);
469         mutex_unlock(&data->mutex);
470         return count;
471 }
472
473 static int ina219_state_set(struct device *dev,
474                         struct device_attribute *attr,
475                         const char *buf, size_t size)
476 {
477         struct i2c_client *client = to_i2c_client(dev);
478         struct ina219_data *data = i2c_get_clientdata(client);
479         int retval = -1;
480         long new;
481         retval = kstrtol(buf, 10, &new);
482         if (retval < 0 || new > INT_MAX || new < INT_MIN)
483                 return -EINVAL;
484         mutex_lock(&data->mutex);
485
486         if ((new > 0) && (data->state == STOPPED))
487                 retval = power_up_INA219(client, data->pInfo->cont_conf);
488         else if ((new == 0) && (data->state == RUNNING))
489                 retval = power_down_INA219(client);
490
491         if (retval < 0) {
492                 dev_err(dev, "Error in switching INA on/off!");
493                 mutex_unlock(&data->mutex);
494                 return -EAGAIN;
495         }
496
497         if (new)
498                 data->state = RUNNING;
499         else
500                 data->state = STOPPED;
501
502         mutex_unlock(&data->mutex);
503         return 1;
504 }
505
506 static struct sensor_device_attribute ina219[] = {
507         SENSOR_ATTR(shunt_voltage, S_IRUGO, show_shunt_voltage, NULL, 0),
508         SENSOR_ATTR(rail_name, S_IRUGO, show_rail_name, NULL, 0),
509         SENSOR_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0),
510         SENSOR_ATTR(curr1_input, S_IRUGO, show_current, NULL, 0),
511         SENSOR_ATTR(curr2_input, S_IRUGO, show_current2, NULL, 0),
512         SENSOR_ATTR(power1_input, S_IRUGO, show_power, NULL, 0),
513         SENSOR_ATTR(power2_input, S_IRUGO, show_power2, NULL, 0),
514         SENSOR_ATTR(cur_state, 0644, ina219_state_show, ina219_state_set, 0),
515 };
516
517 static int ina219_probe(struct i2c_client *client,
518                                 const struct i2c_device_id *id)
519 {
520         struct ina219_data *data;
521         int err;
522         u8 i;
523         data = kzalloc(sizeof(struct ina219_data), GFP_KERNEL);
524         if (!data) {
525                 err = -ENOMEM;
526                 goto exit;
527         }
528
529         i2c_set_clientdata(client, data);
530         data->pInfo = client->dev.platform_data;
531         mutex_init(&data->mutex);
532         data->state = STOPPED;
533         /* reset ina219 */
534         err = i2c_smbus_write_word_data(client, INA219_CONFIG,
535                 __constant_cpu_to_be16(INA219_RESET));
536         if (err < 0) {
537                 dev_err(&client->dev, "ina219 reset failure status: 0x%x\n",
538                         err);
539                 goto exit_free;
540         }
541
542         for (i = 0; i < ARRAY_SIZE(ina219); i++) {
543                 err = device_create_file(&client->dev, &ina219[i].dev_attr);
544                 if (err) {
545                         dev_err(&client->dev, "device_create_file failed.\n");
546                         goto exit_free;
547                 }
548         }
549
550         data->hwmon_dev = hwmon_device_register(&client->dev);
551         if (IS_ERR(data->hwmon_dev)) {
552                 err = PTR_ERR(data->hwmon_dev);
553                 goto exit_remove;
554         }
555
556         err = power_down_INA219(client);
557         if (err < 0) {
558                 dev_err(&client->dev, "ina219 power-down failure status: 0x%x\n",
559                         err);
560                 goto exit_remove;
561         }
562
563         return 0;
564
565 exit_remove:
566         for (i = 0; i < ARRAY_SIZE(ina219); i++)
567                 device_remove_file(&client->dev, &ina219[i].dev_attr);
568 exit_free:
569         kfree(data);
570 exit:
571         return err;
572 }
573
574 static int ina219_remove(struct i2c_client *client)
575 {
576         u8 i;
577         struct ina219_data *data = i2c_get_clientdata(client);
578         mutex_lock(&data->mutex);
579         power_down_INA219(client);
580         data->state = STOPPED;
581         mutex_unlock(&data->mutex);
582         hwmon_device_unregister(data->hwmon_dev);
583         for (i = 0; i < ARRAY_SIZE(ina219); i++)
584                 device_remove_file(&client->dev, &ina219[i].dev_attr);
585         kfree(data);
586         return 0;
587 }
588
589 static const struct i2c_device_id ina219_id[] = {
590         {DRIVER_NAME, 0 },
591         {}
592 };
593 MODULE_DEVICE_TABLE(i2c, ina219_id);
594
595 static struct i2c_driver ina219_driver = {
596         .class          = I2C_CLASS_HWMON,
597         .driver = {
598                 .name   = DRIVER_NAME,
599         },
600         .probe          = ina219_probe,
601         .remove         = ina219_remove,
602         .id_table       = ina219_id,
603 };
604
605 static int __init ina219_init(void)
606 {
607         return i2c_add_driver(&ina219_driver);
608 }
609
610 static void __exit ina219_exit(void)
611 {
612         i2c_del_driver(&ina219_driver);
613 }
614
615 module_init(ina219_init);
616 module_exit(ina219_exit);
617 MODULE_LICENSE("GPL");