xref: /linux/drivers/hwmon/ina209.c (revision ceeadc5c5187b78ffbea737c7a82ecc1e31e80df)
1*ceeadc5cSGuenter Roeck /*
2*ceeadc5cSGuenter Roeck  * Driver for the Texas Instruments / Burr Brown INA209
3*ceeadc5cSGuenter Roeck  * Bidirectional Current/Power Monitor
4*ceeadc5cSGuenter Roeck  *
5*ceeadc5cSGuenter Roeck  * Copyright (C) 2012 Guenter Roeck <linux@roeck-us.net>
6*ceeadc5cSGuenter Roeck  *
7*ceeadc5cSGuenter Roeck  * Derived from Ira W. Snyder's original driver submission
8*ceeadc5cSGuenter Roeck  *	Copyright (C) 2008 Paul Hays <Paul.Hays@cattail.ca>
9*ceeadc5cSGuenter Roeck  *	Copyright (C) 2008-2009 Ira W. Snyder <iws@ovro.caltech.edu>
10*ceeadc5cSGuenter Roeck  *
11*ceeadc5cSGuenter Roeck  * Aligned with ina2xx driver
12*ceeadc5cSGuenter Roeck  *	Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
13*ceeadc5cSGuenter Roeck  *	Thanks to Jan Volkering
14*ceeadc5cSGuenter Roeck  *
15*ceeadc5cSGuenter Roeck  * This program is free software; you can redistribute it and/or modify
16*ceeadc5cSGuenter Roeck  * it under the terms of the GNU General Public License as published by
17*ceeadc5cSGuenter Roeck  * the Free Software Foundation; version 2 of the License.
18*ceeadc5cSGuenter Roeck  *
19*ceeadc5cSGuenter Roeck  * Datasheet:
20*ceeadc5cSGuenter Roeck  * http://www.ti.com/lit/gpn/ina209
21*ceeadc5cSGuenter Roeck  */
22*ceeadc5cSGuenter Roeck 
23*ceeadc5cSGuenter Roeck #include <linux/kernel.h>
24*ceeadc5cSGuenter Roeck #include <linux/module.h>
25*ceeadc5cSGuenter Roeck #include <linux/init.h>
26*ceeadc5cSGuenter Roeck #include <linux/err.h>
27*ceeadc5cSGuenter Roeck #include <linux/slab.h>
28*ceeadc5cSGuenter Roeck #include <linux/bug.h>
29*ceeadc5cSGuenter Roeck #include <linux/i2c.h>
30*ceeadc5cSGuenter Roeck #include <linux/hwmon.h>
31*ceeadc5cSGuenter Roeck #include <linux/hwmon-sysfs.h>
32*ceeadc5cSGuenter Roeck 
33*ceeadc5cSGuenter Roeck #include <linux/platform_data/ina2xx.h>
34*ceeadc5cSGuenter Roeck 
35*ceeadc5cSGuenter Roeck /* register definitions */
36*ceeadc5cSGuenter Roeck #define INA209_CONFIGURATION		0x00
37*ceeadc5cSGuenter Roeck #define INA209_STATUS			0x01
38*ceeadc5cSGuenter Roeck #define INA209_STATUS_MASK		0x02
39*ceeadc5cSGuenter Roeck #define INA209_SHUNT_VOLTAGE		0x03
40*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE		0x04
41*ceeadc5cSGuenter Roeck #define INA209_POWER			0x05
42*ceeadc5cSGuenter Roeck #define INA209_CURRENT			0x06
43*ceeadc5cSGuenter Roeck #define INA209_SHUNT_VOLTAGE_POS_PEAK	0x07
44*ceeadc5cSGuenter Roeck #define INA209_SHUNT_VOLTAGE_NEG_PEAK	0x08
45*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE_MAX_PEAK	0x09
46*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE_MIN_PEAK	0x0a
47*ceeadc5cSGuenter Roeck #define INA209_POWER_PEAK		0x0b
48*ceeadc5cSGuenter Roeck #define INA209_SHUNT_VOLTAGE_POS_WARN	0x0c
49*ceeadc5cSGuenter Roeck #define INA209_SHUNT_VOLTAGE_NEG_WARN	0x0d
50*ceeadc5cSGuenter Roeck #define INA209_POWER_WARN		0x0e
51*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE_OVER_WARN	0x0f
52*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE_UNDER_WARN	0x10
53*ceeadc5cSGuenter Roeck #define INA209_POWER_OVER_LIMIT		0x11
54*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE_OVER_LIMIT	0x12
55*ceeadc5cSGuenter Roeck #define INA209_BUS_VOLTAGE_UNDER_LIMIT	0x13
56*ceeadc5cSGuenter Roeck #define INA209_CRITICAL_DAC_POS		0x14
57*ceeadc5cSGuenter Roeck #define INA209_CRITICAL_DAC_NEG		0x15
58*ceeadc5cSGuenter Roeck #define INA209_CALIBRATION		0x16
59*ceeadc5cSGuenter Roeck 
60*ceeadc5cSGuenter Roeck #define INA209_REGISTERS		0x17
61*ceeadc5cSGuenter Roeck 
62*ceeadc5cSGuenter Roeck #define INA209_CONFIG_DEFAULT		0x3c47	/* PGA=8, full range */
63*ceeadc5cSGuenter Roeck #define INA209_SHUNT_DEFAULT		10000	/* uOhm */
64*ceeadc5cSGuenter Roeck 
65*ceeadc5cSGuenter Roeck struct ina209_data {
66*ceeadc5cSGuenter Roeck 	struct device *hwmon_dev;
67*ceeadc5cSGuenter Roeck 
68*ceeadc5cSGuenter Roeck 	struct mutex update_lock;
69*ceeadc5cSGuenter Roeck 	bool valid;
70*ceeadc5cSGuenter Roeck 	unsigned long last_updated;	/* in jiffies */
71*ceeadc5cSGuenter Roeck 
72*ceeadc5cSGuenter Roeck 	u16 regs[INA209_REGISTERS];	/* All chip registers */
73*ceeadc5cSGuenter Roeck 
74*ceeadc5cSGuenter Roeck 	u16 config_orig;		/* Original configuration */
75*ceeadc5cSGuenter Roeck 	u16 calibration_orig;		/* Original calibration */
76*ceeadc5cSGuenter Roeck 	u16 update_interval;
77*ceeadc5cSGuenter Roeck };
78*ceeadc5cSGuenter Roeck 
79*ceeadc5cSGuenter Roeck static struct ina209_data *ina209_update_device(struct device *dev)
80*ceeadc5cSGuenter Roeck {
81*ceeadc5cSGuenter Roeck 	struct i2c_client *client = to_i2c_client(dev);
82*ceeadc5cSGuenter Roeck 	struct ina209_data *data = i2c_get_clientdata(client);
83*ceeadc5cSGuenter Roeck 	struct ina209_data *ret = data;
84*ceeadc5cSGuenter Roeck 	s32 val;
85*ceeadc5cSGuenter Roeck 	int i;
86*ceeadc5cSGuenter Roeck 
87*ceeadc5cSGuenter Roeck 	mutex_lock(&data->update_lock);
88*ceeadc5cSGuenter Roeck 
89*ceeadc5cSGuenter Roeck 	if (!data->valid ||
90*ceeadc5cSGuenter Roeck 	    time_after(jiffies, data->last_updated + data->update_interval)) {
91*ceeadc5cSGuenter Roeck 		for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
92*ceeadc5cSGuenter Roeck 			val = i2c_smbus_read_word_swapped(client, i);
93*ceeadc5cSGuenter Roeck 			if (val < 0) {
94*ceeadc5cSGuenter Roeck 				ret = ERR_PTR(val);
95*ceeadc5cSGuenter Roeck 				goto abort;
96*ceeadc5cSGuenter Roeck 			}
97*ceeadc5cSGuenter Roeck 			data->regs[i] = val;
98*ceeadc5cSGuenter Roeck 		}
99*ceeadc5cSGuenter Roeck 		data->last_updated = jiffies;
100*ceeadc5cSGuenter Roeck 		data->valid = true;
101*ceeadc5cSGuenter Roeck 	}
102*ceeadc5cSGuenter Roeck abort:
103*ceeadc5cSGuenter Roeck 	mutex_unlock(&data->update_lock);
104*ceeadc5cSGuenter Roeck 	return ret;
105*ceeadc5cSGuenter Roeck }
106*ceeadc5cSGuenter Roeck 
107*ceeadc5cSGuenter Roeck /*
108*ceeadc5cSGuenter Roeck  * Read a value from a device register and convert it to the
109*ceeadc5cSGuenter Roeck  * appropriate sysfs units
110*ceeadc5cSGuenter Roeck  */
111*ceeadc5cSGuenter Roeck static long ina209_from_reg(const u8 reg, const u16 val)
112*ceeadc5cSGuenter Roeck {
113*ceeadc5cSGuenter Roeck 	switch (reg) {
114*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE:
115*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE_POS_PEAK:
116*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE_NEG_PEAK:
117*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE_POS_WARN:
118*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE_NEG_WARN:
119*ceeadc5cSGuenter Roeck 		/* LSB=10 uV. Convert to mV. */
120*ceeadc5cSGuenter Roeck 		return DIV_ROUND_CLOSEST(val, 100);
121*ceeadc5cSGuenter Roeck 
122*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE:
123*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_MAX_PEAK:
124*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_MIN_PEAK:
125*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_OVER_WARN:
126*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_UNDER_WARN:
127*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_OVER_LIMIT:
128*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_UNDER_LIMIT:
129*ceeadc5cSGuenter Roeck 		/* LSB=4 mV, last 3 bits unused */
130*ceeadc5cSGuenter Roeck 		return (val >> 3) * 4;
131*ceeadc5cSGuenter Roeck 
132*ceeadc5cSGuenter Roeck 	case INA209_CRITICAL_DAC_POS:
133*ceeadc5cSGuenter Roeck 		/* LSB=1 mV, in the upper 8 bits */
134*ceeadc5cSGuenter Roeck 		return val >> 8;
135*ceeadc5cSGuenter Roeck 
136*ceeadc5cSGuenter Roeck 	case INA209_CRITICAL_DAC_NEG:
137*ceeadc5cSGuenter Roeck 		/* LSB=1 mV, in the upper 8 bits */
138*ceeadc5cSGuenter Roeck 		return -1 * (val >> 8);
139*ceeadc5cSGuenter Roeck 
140*ceeadc5cSGuenter Roeck 	case INA209_POWER:
141*ceeadc5cSGuenter Roeck 	case INA209_POWER_PEAK:
142*ceeadc5cSGuenter Roeck 	case INA209_POWER_WARN:
143*ceeadc5cSGuenter Roeck 	case INA209_POWER_OVER_LIMIT:
144*ceeadc5cSGuenter Roeck 		/* LSB=20 mW. Convert to uW */
145*ceeadc5cSGuenter Roeck 		return val * 20 * 1000L;
146*ceeadc5cSGuenter Roeck 
147*ceeadc5cSGuenter Roeck 	case INA209_CURRENT:
148*ceeadc5cSGuenter Roeck 		/* LSB=1 mA (selected). Is in mA */
149*ceeadc5cSGuenter Roeck 		return val;
150*ceeadc5cSGuenter Roeck 	}
151*ceeadc5cSGuenter Roeck 
152*ceeadc5cSGuenter Roeck 	/* programmer goofed */
153*ceeadc5cSGuenter Roeck 	WARN_ON_ONCE(1);
154*ceeadc5cSGuenter Roeck 	return 0;
155*ceeadc5cSGuenter Roeck }
156*ceeadc5cSGuenter Roeck 
157*ceeadc5cSGuenter Roeck /*
158*ceeadc5cSGuenter Roeck  * Take a value and convert it to register format, clamping the value
159*ceeadc5cSGuenter Roeck  * to the appropriate range.
160*ceeadc5cSGuenter Roeck  */
161*ceeadc5cSGuenter Roeck static int ina209_to_reg(u8 reg, u16 old, long val)
162*ceeadc5cSGuenter Roeck {
163*ceeadc5cSGuenter Roeck 	switch (reg) {
164*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE_POS_WARN:
165*ceeadc5cSGuenter Roeck 	case INA209_SHUNT_VOLTAGE_NEG_WARN:
166*ceeadc5cSGuenter Roeck 		/* Limit to +- 320 mV, 10 uV LSB */
167*ceeadc5cSGuenter Roeck 		return clamp_val(val, -320, 320) * 100;
168*ceeadc5cSGuenter Roeck 
169*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_OVER_WARN:
170*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_UNDER_WARN:
171*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_OVER_LIMIT:
172*ceeadc5cSGuenter Roeck 	case INA209_BUS_VOLTAGE_UNDER_LIMIT:
173*ceeadc5cSGuenter Roeck 		/*
174*ceeadc5cSGuenter Roeck 		 * Limit to 0-32000 mV, 4 mV LSB
175*ceeadc5cSGuenter Roeck 		 *
176*ceeadc5cSGuenter Roeck 		 * The last three bits aren't part of the value, but we'll
177*ceeadc5cSGuenter Roeck 		 * preserve them in their original state.
178*ceeadc5cSGuenter Roeck 		 */
179*ceeadc5cSGuenter Roeck 		return (DIV_ROUND_CLOSEST(clamp_val(val, 0, 32000), 4) << 3)
180*ceeadc5cSGuenter Roeck 		  | (old & 0x7);
181*ceeadc5cSGuenter Roeck 
182*ceeadc5cSGuenter Roeck 	case INA209_CRITICAL_DAC_NEG:
183*ceeadc5cSGuenter Roeck 		/*
184*ceeadc5cSGuenter Roeck 		 * Limit to -255-0 mV, 1 mV LSB
185*ceeadc5cSGuenter Roeck 		 * Convert the value to a positive value for the register
186*ceeadc5cSGuenter Roeck 		 *
187*ceeadc5cSGuenter Roeck 		 * The value lives in the top 8 bits only, be careful
188*ceeadc5cSGuenter Roeck 		 * and keep original value of other bits.
189*ceeadc5cSGuenter Roeck 		 */
190*ceeadc5cSGuenter Roeck 		return (clamp_val(-val, 0, 255) << 8) | (old & 0xff);
191*ceeadc5cSGuenter Roeck 
192*ceeadc5cSGuenter Roeck 	case INA209_CRITICAL_DAC_POS:
193*ceeadc5cSGuenter Roeck 		/*
194*ceeadc5cSGuenter Roeck 		 * Limit to 0-255 mV, 1 mV LSB
195*ceeadc5cSGuenter Roeck 		 *
196*ceeadc5cSGuenter Roeck 		 * The value lives in the top 8 bits only, be careful
197*ceeadc5cSGuenter Roeck 		 * and keep original value of other bits.
198*ceeadc5cSGuenter Roeck 		 */
199*ceeadc5cSGuenter Roeck 		return (clamp_val(val, 0, 255) << 8) | (old & 0xff);
200*ceeadc5cSGuenter Roeck 
201*ceeadc5cSGuenter Roeck 	case INA209_POWER_WARN:
202*ceeadc5cSGuenter Roeck 	case INA209_POWER_OVER_LIMIT:
203*ceeadc5cSGuenter Roeck 		/* 20 mW LSB */
204*ceeadc5cSGuenter Roeck 		return DIV_ROUND_CLOSEST(val, 20 * 1000);
205*ceeadc5cSGuenter Roeck 	}
206*ceeadc5cSGuenter Roeck 
207*ceeadc5cSGuenter Roeck 	/* Other registers are read-only, return access error */
208*ceeadc5cSGuenter Roeck 	return -EACCES;
209*ceeadc5cSGuenter Roeck }
210*ceeadc5cSGuenter Roeck 
211*ceeadc5cSGuenter Roeck static int ina209_interval_from_reg(u16 reg)
212*ceeadc5cSGuenter Roeck {
213*ceeadc5cSGuenter Roeck 	return 68 >> (15 - ((reg >> 3) & 0x0f));
214*ceeadc5cSGuenter Roeck }
215*ceeadc5cSGuenter Roeck 
216*ceeadc5cSGuenter Roeck static u16 ina209_reg_from_interval(u16 config, long interval)
217*ceeadc5cSGuenter Roeck {
218*ceeadc5cSGuenter Roeck 	int i, adc;
219*ceeadc5cSGuenter Roeck 
220*ceeadc5cSGuenter Roeck 	if (interval <= 0) {
221*ceeadc5cSGuenter Roeck 		adc = 8;
222*ceeadc5cSGuenter Roeck 	} else {
223*ceeadc5cSGuenter Roeck 		adc = 15;
224*ceeadc5cSGuenter Roeck 		for (i = 34 + 34 / 2; i; i >>= 1) {
225*ceeadc5cSGuenter Roeck 			if (i < interval)
226*ceeadc5cSGuenter Roeck 				break;
227*ceeadc5cSGuenter Roeck 			adc--;
228*ceeadc5cSGuenter Roeck 		}
229*ceeadc5cSGuenter Roeck 	}
230*ceeadc5cSGuenter Roeck 	return (config & 0xf807) | (adc << 3) | (adc << 7);
231*ceeadc5cSGuenter Roeck }
232*ceeadc5cSGuenter Roeck 
233*ceeadc5cSGuenter Roeck static ssize_t ina209_set_interval(struct device *dev,
234*ceeadc5cSGuenter Roeck 				   struct device_attribute *da,
235*ceeadc5cSGuenter Roeck 				   const char *buf, size_t count)
236*ceeadc5cSGuenter Roeck {
237*ceeadc5cSGuenter Roeck 	struct i2c_client *client = to_i2c_client(dev);
238*ceeadc5cSGuenter Roeck 	struct ina209_data *data = ina209_update_device(dev);
239*ceeadc5cSGuenter Roeck 	long val;
240*ceeadc5cSGuenter Roeck 	u16 regval;
241*ceeadc5cSGuenter Roeck 	int ret;
242*ceeadc5cSGuenter Roeck 
243*ceeadc5cSGuenter Roeck 	if (IS_ERR(data))
244*ceeadc5cSGuenter Roeck 		return PTR_ERR(data);
245*ceeadc5cSGuenter Roeck 
246*ceeadc5cSGuenter Roeck 	ret = kstrtol(buf, 10, &val);
247*ceeadc5cSGuenter Roeck 	if (ret < 0)
248*ceeadc5cSGuenter Roeck 		return ret;
249*ceeadc5cSGuenter Roeck 
250*ceeadc5cSGuenter Roeck 	mutex_lock(&data->update_lock);
251*ceeadc5cSGuenter Roeck 	regval = ina209_reg_from_interval(data->regs[INA209_CONFIGURATION],
252*ceeadc5cSGuenter Roeck 					  val);
253*ceeadc5cSGuenter Roeck 	i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION, regval);
254*ceeadc5cSGuenter Roeck 	data->regs[INA209_CONFIGURATION] = regval;
255*ceeadc5cSGuenter Roeck 	data->update_interval = ina209_interval_from_reg(regval);
256*ceeadc5cSGuenter Roeck 	mutex_unlock(&data->update_lock);
257*ceeadc5cSGuenter Roeck 	return count;
258*ceeadc5cSGuenter Roeck }
259*ceeadc5cSGuenter Roeck 
260*ceeadc5cSGuenter Roeck static ssize_t ina209_show_interval(struct device *dev,
261*ceeadc5cSGuenter Roeck 				    struct device_attribute *da, char *buf)
262*ceeadc5cSGuenter Roeck {
263*ceeadc5cSGuenter Roeck 	struct i2c_client *client = to_i2c_client(dev);
264*ceeadc5cSGuenter Roeck 	struct ina209_data *data = i2c_get_clientdata(client);
265*ceeadc5cSGuenter Roeck 
266*ceeadc5cSGuenter Roeck 	return snprintf(buf, PAGE_SIZE, "%d\n", data->update_interval);
267*ceeadc5cSGuenter Roeck }
268*ceeadc5cSGuenter Roeck 
269*ceeadc5cSGuenter Roeck /*
270*ceeadc5cSGuenter Roeck  * History is reset by writing 1 into bit 0 of the respective peak register.
271*ceeadc5cSGuenter Roeck  * Since more than one peak register may be affected by the scope of a
272*ceeadc5cSGuenter Roeck  * reset_history attribute write, use a bit mask in attr->index to identify
273*ceeadc5cSGuenter Roeck  * which registers are affected.
274*ceeadc5cSGuenter Roeck  */
275*ceeadc5cSGuenter Roeck static u16 ina209_reset_history_regs[] = {
276*ceeadc5cSGuenter Roeck 	INA209_SHUNT_VOLTAGE_POS_PEAK,
277*ceeadc5cSGuenter Roeck 	INA209_SHUNT_VOLTAGE_NEG_PEAK,
278*ceeadc5cSGuenter Roeck 	INA209_BUS_VOLTAGE_MAX_PEAK,
279*ceeadc5cSGuenter Roeck 	INA209_BUS_VOLTAGE_MIN_PEAK,
280*ceeadc5cSGuenter Roeck 	INA209_POWER_PEAK
281*ceeadc5cSGuenter Roeck };
282*ceeadc5cSGuenter Roeck 
283*ceeadc5cSGuenter Roeck static ssize_t ina209_reset_history(struct device *dev,
284*ceeadc5cSGuenter Roeck 				    struct device_attribute *da,
285*ceeadc5cSGuenter Roeck 				    const char *buf,
286*ceeadc5cSGuenter Roeck 				    size_t count)
287*ceeadc5cSGuenter Roeck {
288*ceeadc5cSGuenter Roeck 	struct i2c_client *client = to_i2c_client(dev);
289*ceeadc5cSGuenter Roeck 	struct ina209_data *data = i2c_get_clientdata(client);
290*ceeadc5cSGuenter Roeck 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
291*ceeadc5cSGuenter Roeck 	u32 mask = attr->index;
292*ceeadc5cSGuenter Roeck 	long val;
293*ceeadc5cSGuenter Roeck 	int i, ret;
294*ceeadc5cSGuenter Roeck 
295*ceeadc5cSGuenter Roeck 	ret = kstrtol(buf, 10, &val);
296*ceeadc5cSGuenter Roeck 	if (ret < 0)
297*ceeadc5cSGuenter Roeck 		return ret;
298*ceeadc5cSGuenter Roeck 
299*ceeadc5cSGuenter Roeck 	mutex_lock(&data->update_lock);
300*ceeadc5cSGuenter Roeck 	for (i = 0; i < ARRAY_SIZE(ina209_reset_history_regs); i++) {
301*ceeadc5cSGuenter Roeck 		if (mask & (1 << i))
302*ceeadc5cSGuenter Roeck 			i2c_smbus_write_word_swapped(client,
303*ceeadc5cSGuenter Roeck 					ina209_reset_history_regs[i], 1);
304*ceeadc5cSGuenter Roeck 	}
305*ceeadc5cSGuenter Roeck 	data->valid = false;
306*ceeadc5cSGuenter Roeck 	mutex_unlock(&data->update_lock);
307*ceeadc5cSGuenter Roeck 	return count;
308*ceeadc5cSGuenter Roeck }
309*ceeadc5cSGuenter Roeck 
310*ceeadc5cSGuenter Roeck static ssize_t ina209_set_value(struct device *dev,
311*ceeadc5cSGuenter Roeck 				struct device_attribute *da,
312*ceeadc5cSGuenter Roeck 				const char *buf,
313*ceeadc5cSGuenter Roeck 				size_t count)
314*ceeadc5cSGuenter Roeck {
315*ceeadc5cSGuenter Roeck 	struct i2c_client *client = to_i2c_client(dev);
316*ceeadc5cSGuenter Roeck 	struct ina209_data *data = ina209_update_device(dev);
317*ceeadc5cSGuenter Roeck 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
318*ceeadc5cSGuenter Roeck 	int reg = attr->index;
319*ceeadc5cSGuenter Roeck 	long val;
320*ceeadc5cSGuenter Roeck 	int ret;
321*ceeadc5cSGuenter Roeck 
322*ceeadc5cSGuenter Roeck 	if (IS_ERR(data))
323*ceeadc5cSGuenter Roeck 		return PTR_ERR(data);
324*ceeadc5cSGuenter Roeck 
325*ceeadc5cSGuenter Roeck 	ret = kstrtol(buf, 10, &val);
326*ceeadc5cSGuenter Roeck 	if (ret < 0)
327*ceeadc5cSGuenter Roeck 		return ret;
328*ceeadc5cSGuenter Roeck 
329*ceeadc5cSGuenter Roeck 	mutex_lock(&data->update_lock);
330*ceeadc5cSGuenter Roeck 	ret = ina209_to_reg(reg, data->regs[reg], val);
331*ceeadc5cSGuenter Roeck 	if (ret < 0) {
332*ceeadc5cSGuenter Roeck 		count = ret;
333*ceeadc5cSGuenter Roeck 		goto abort;
334*ceeadc5cSGuenter Roeck 	}
335*ceeadc5cSGuenter Roeck 	i2c_smbus_write_word_swapped(client, reg, ret);
336*ceeadc5cSGuenter Roeck 	data->regs[reg] = ret;
337*ceeadc5cSGuenter Roeck abort:
338*ceeadc5cSGuenter Roeck 	mutex_unlock(&data->update_lock);
339*ceeadc5cSGuenter Roeck 	return count;
340*ceeadc5cSGuenter Roeck }
341*ceeadc5cSGuenter Roeck 
342*ceeadc5cSGuenter Roeck static ssize_t ina209_show_value(struct device *dev,
343*ceeadc5cSGuenter Roeck 				 struct device_attribute *da,
344*ceeadc5cSGuenter Roeck 				 char *buf)
345*ceeadc5cSGuenter Roeck {
346*ceeadc5cSGuenter Roeck 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
347*ceeadc5cSGuenter Roeck 	struct ina209_data *data = ina209_update_device(dev);
348*ceeadc5cSGuenter Roeck 	long val;
349*ceeadc5cSGuenter Roeck 
350*ceeadc5cSGuenter Roeck 	if (IS_ERR(data))
351*ceeadc5cSGuenter Roeck 		return PTR_ERR(data);
352*ceeadc5cSGuenter Roeck 
353*ceeadc5cSGuenter Roeck 	val = ina209_from_reg(attr->index, data->regs[attr->index]);
354*ceeadc5cSGuenter Roeck 	return snprintf(buf, PAGE_SIZE, "%ld\n", val);
355*ceeadc5cSGuenter Roeck }
356*ceeadc5cSGuenter Roeck 
357*ceeadc5cSGuenter Roeck static ssize_t ina209_show_alarm(struct device *dev,
358*ceeadc5cSGuenter Roeck 				 struct device_attribute *da,
359*ceeadc5cSGuenter Roeck 				 char *buf)
360*ceeadc5cSGuenter Roeck {
361*ceeadc5cSGuenter Roeck 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
362*ceeadc5cSGuenter Roeck 	struct ina209_data *data = ina209_update_device(dev);
363*ceeadc5cSGuenter Roeck 	const unsigned int mask = attr->index;
364*ceeadc5cSGuenter Roeck 	u16 status;
365*ceeadc5cSGuenter Roeck 
366*ceeadc5cSGuenter Roeck 	if (IS_ERR(data))
367*ceeadc5cSGuenter Roeck 		return PTR_ERR(data);
368*ceeadc5cSGuenter Roeck 
369*ceeadc5cSGuenter Roeck 	status = data->regs[INA209_STATUS];
370*ceeadc5cSGuenter Roeck 
371*ceeadc5cSGuenter Roeck 	/*
372*ceeadc5cSGuenter Roeck 	 * All alarms are in the INA209_STATUS register. To avoid a long
373*ceeadc5cSGuenter Roeck 	 * switch statement, the mask is passed in attr->index
374*ceeadc5cSGuenter Roeck 	 */
375*ceeadc5cSGuenter Roeck 	return snprintf(buf, PAGE_SIZE, "%u\n", !!(status & mask));
376*ceeadc5cSGuenter Roeck }
377*ceeadc5cSGuenter Roeck 
378*ceeadc5cSGuenter Roeck /* Shunt voltage, history, limits, alarms */
379*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, ina209_show_value, NULL,
380*ceeadc5cSGuenter Roeck 			  INA209_SHUNT_VOLTAGE);
381*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_input_highest, S_IRUGO, ina209_show_value, NULL,
382*ceeadc5cSGuenter Roeck 			  INA209_SHUNT_VOLTAGE_POS_PEAK);
383*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_input_lowest, S_IRUGO, ina209_show_value, NULL,
384*ceeadc5cSGuenter Roeck 			  INA209_SHUNT_VOLTAGE_NEG_PEAK);
385*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_reset_history, S_IWUSR, NULL,
386*ceeadc5cSGuenter Roeck 			  ina209_reset_history, (1 << 0) | (1 << 1));
387*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, ina209_show_value,
388*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_SHUNT_VOLTAGE_POS_WARN);
389*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_min, S_IRUGO | S_IWUSR, ina209_show_value,
390*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_SHUNT_VOLTAGE_NEG_WARN);
391*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_crit_max, S_IRUGO | S_IWUSR, ina209_show_value,
392*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_CRITICAL_DAC_POS);
393*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_crit_min, S_IRUGO | S_IWUSR, ina209_show_value,
394*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_CRITICAL_DAC_NEG);
395*ceeadc5cSGuenter Roeck 
396*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_min_alarm,  S_IRUGO, ina209_show_alarm, NULL,
397*ceeadc5cSGuenter Roeck 			  1 << 11);
398*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
399*ceeadc5cSGuenter Roeck 			  1 << 12);
400*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_crit_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
401*ceeadc5cSGuenter Roeck 			  1 << 6);
402*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in0_crit_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
403*ceeadc5cSGuenter Roeck 			  1 << 7);
404*ceeadc5cSGuenter Roeck 
405*ceeadc5cSGuenter Roeck /* Bus voltage, history, limits, alarms */
406*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, ina209_show_value, NULL,
407*ceeadc5cSGuenter Roeck 			  INA209_BUS_VOLTAGE);
408*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_input_highest, S_IRUGO, ina209_show_value, NULL,
409*ceeadc5cSGuenter Roeck 			  INA209_BUS_VOLTAGE_MAX_PEAK);
410*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_input_lowest, S_IRUGO, ina209_show_value, NULL,
411*ceeadc5cSGuenter Roeck 			  INA209_BUS_VOLTAGE_MIN_PEAK);
412*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_reset_history, S_IWUSR, NULL,
413*ceeadc5cSGuenter Roeck 			  ina209_reset_history, (1 << 2) | (1 << 3));
414*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_max, S_IRUGO | S_IWUSR, ina209_show_value,
415*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_BUS_VOLTAGE_OVER_WARN);
416*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_min, S_IRUGO | S_IWUSR, ina209_show_value,
417*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_BUS_VOLTAGE_UNDER_WARN);
418*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_crit_max, S_IRUGO | S_IWUSR, ina209_show_value,
419*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_BUS_VOLTAGE_OVER_LIMIT);
420*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_crit_min, S_IRUGO | S_IWUSR, ina209_show_value,
421*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_BUS_VOLTAGE_UNDER_LIMIT);
422*ceeadc5cSGuenter Roeck 
423*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
424*ceeadc5cSGuenter Roeck 			  1 << 14);
425*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
426*ceeadc5cSGuenter Roeck 			  1 << 15);
427*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_crit_min_alarm, S_IRUGO, ina209_show_alarm, NULL,
428*ceeadc5cSGuenter Roeck 			  1 << 9);
429*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(in1_crit_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
430*ceeadc5cSGuenter Roeck 			  1 << 10);
431*ceeadc5cSGuenter Roeck 
432*ceeadc5cSGuenter Roeck /* Power */
433*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_input, S_IRUGO, ina209_show_value, NULL,
434*ceeadc5cSGuenter Roeck 			  INA209_POWER);
435*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_input_highest, S_IRUGO, ina209_show_value,
436*ceeadc5cSGuenter Roeck 			  NULL, INA209_POWER_PEAK);
437*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_reset_history, S_IWUSR, NULL,
438*ceeadc5cSGuenter Roeck 			  ina209_reset_history, 1 << 4);
439*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_max, S_IRUGO | S_IWUSR, ina209_show_value,
440*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_POWER_WARN);
441*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_crit, S_IRUGO | S_IWUSR, ina209_show_value,
442*ceeadc5cSGuenter Roeck 			  ina209_set_value, INA209_POWER_OVER_LIMIT);
443*ceeadc5cSGuenter Roeck 
444*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_max_alarm, S_IRUGO, ina209_show_alarm, NULL,
445*ceeadc5cSGuenter Roeck 			  1 << 13);
446*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(power1_crit_alarm, S_IRUGO, ina209_show_alarm, NULL,
447*ceeadc5cSGuenter Roeck 			  1 << 8);
448*ceeadc5cSGuenter Roeck 
449*ceeadc5cSGuenter Roeck /* Current */
450*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, ina209_show_value, NULL,
451*ceeadc5cSGuenter Roeck 			  INA209_CURRENT);
452*ceeadc5cSGuenter Roeck 
453*ceeadc5cSGuenter Roeck static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR,
454*ceeadc5cSGuenter Roeck 			  ina209_show_interval, ina209_set_interval, 0);
455*ceeadc5cSGuenter Roeck 
456*ceeadc5cSGuenter Roeck /*
457*ceeadc5cSGuenter Roeck  * Finally, construct an array of pointers to members of the above objects,
458*ceeadc5cSGuenter Roeck  * as required for sysfs_create_group()
459*ceeadc5cSGuenter Roeck  */
460*ceeadc5cSGuenter Roeck static struct attribute *ina209_attributes[] = {
461*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_input.dev_attr.attr,
462*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_input_highest.dev_attr.attr,
463*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_input_lowest.dev_attr.attr,
464*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_reset_history.dev_attr.attr,
465*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_max.dev_attr.attr,
466*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_min.dev_attr.attr,
467*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_crit_max.dev_attr.attr,
468*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_crit_min.dev_attr.attr,
469*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_max_alarm.dev_attr.attr,
470*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_min_alarm.dev_attr.attr,
471*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_crit_max_alarm.dev_attr.attr,
472*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in0_crit_min_alarm.dev_attr.attr,
473*ceeadc5cSGuenter Roeck 
474*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_input.dev_attr.attr,
475*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_input_highest.dev_attr.attr,
476*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_input_lowest.dev_attr.attr,
477*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_reset_history.dev_attr.attr,
478*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_max.dev_attr.attr,
479*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_min.dev_attr.attr,
480*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_crit_max.dev_attr.attr,
481*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_crit_min.dev_attr.attr,
482*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_max_alarm.dev_attr.attr,
483*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_min_alarm.dev_attr.attr,
484*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_crit_max_alarm.dev_attr.attr,
485*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_in1_crit_min_alarm.dev_attr.attr,
486*ceeadc5cSGuenter Roeck 
487*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_input.dev_attr.attr,
488*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_input_highest.dev_attr.attr,
489*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_reset_history.dev_attr.attr,
490*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_max.dev_attr.attr,
491*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_crit.dev_attr.attr,
492*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_max_alarm.dev_attr.attr,
493*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_power1_crit_alarm.dev_attr.attr,
494*ceeadc5cSGuenter Roeck 
495*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_curr1_input.dev_attr.attr,
496*ceeadc5cSGuenter Roeck 
497*ceeadc5cSGuenter Roeck 	&sensor_dev_attr_update_interval.dev_attr.attr,
498*ceeadc5cSGuenter Roeck 
499*ceeadc5cSGuenter Roeck 	NULL,
500*ceeadc5cSGuenter Roeck };
501*ceeadc5cSGuenter Roeck 
502*ceeadc5cSGuenter Roeck static const struct attribute_group ina209_group = {
503*ceeadc5cSGuenter Roeck 	.attrs = ina209_attributes,
504*ceeadc5cSGuenter Roeck };
505*ceeadc5cSGuenter Roeck 
506*ceeadc5cSGuenter Roeck static void ina209_restore_conf(struct i2c_client *client,
507*ceeadc5cSGuenter Roeck 				struct ina209_data *data)
508*ceeadc5cSGuenter Roeck {
509*ceeadc5cSGuenter Roeck 	/* Restore initial configuration */
510*ceeadc5cSGuenter Roeck 	i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
511*ceeadc5cSGuenter Roeck 				     data->config_orig);
512*ceeadc5cSGuenter Roeck 	i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
513*ceeadc5cSGuenter Roeck 				     data->calibration_orig);
514*ceeadc5cSGuenter Roeck }
515*ceeadc5cSGuenter Roeck 
516*ceeadc5cSGuenter Roeck static int ina209_init_client(struct i2c_client *client,
517*ceeadc5cSGuenter Roeck 			      struct ina209_data *data)
518*ceeadc5cSGuenter Roeck {
519*ceeadc5cSGuenter Roeck 	struct ina2xx_platform_data *pdata = dev_get_platdata(&client->dev);
520*ceeadc5cSGuenter Roeck 	u32 shunt;
521*ceeadc5cSGuenter Roeck 	int reg;
522*ceeadc5cSGuenter Roeck 
523*ceeadc5cSGuenter Roeck 	reg = i2c_smbus_read_word_swapped(client, INA209_CALIBRATION);
524*ceeadc5cSGuenter Roeck 	if (reg < 0)
525*ceeadc5cSGuenter Roeck 		return reg;
526*ceeadc5cSGuenter Roeck 	data->calibration_orig = reg;
527*ceeadc5cSGuenter Roeck 
528*ceeadc5cSGuenter Roeck 	reg = i2c_smbus_read_word_swapped(client, INA209_CONFIGURATION);
529*ceeadc5cSGuenter Roeck 	if (reg < 0)
530*ceeadc5cSGuenter Roeck 		return reg;
531*ceeadc5cSGuenter Roeck 	data->config_orig = reg;
532*ceeadc5cSGuenter Roeck 
533*ceeadc5cSGuenter Roeck 	if (pdata) {
534*ceeadc5cSGuenter Roeck 		if (pdata->shunt_uohms <= 0)
535*ceeadc5cSGuenter Roeck 			return -EINVAL;
536*ceeadc5cSGuenter Roeck 		shunt = pdata->shunt_uohms;
537*ceeadc5cSGuenter Roeck 	} else if (!of_property_read_u32(client->dev.of_node, "shunt-resistor",
538*ceeadc5cSGuenter Roeck 					 &shunt)) {
539*ceeadc5cSGuenter Roeck 		if (shunt == 0)
540*ceeadc5cSGuenter Roeck 			return -EINVAL;
541*ceeadc5cSGuenter Roeck 	} else {
542*ceeadc5cSGuenter Roeck 		shunt = data->calibration_orig ?
543*ceeadc5cSGuenter Roeck 		  40960000 / data->calibration_orig : INA209_SHUNT_DEFAULT;
544*ceeadc5cSGuenter Roeck 	}
545*ceeadc5cSGuenter Roeck 
546*ceeadc5cSGuenter Roeck 	i2c_smbus_write_word_swapped(client, INA209_CONFIGURATION,
547*ceeadc5cSGuenter Roeck 				     INA209_CONFIG_DEFAULT);
548*ceeadc5cSGuenter Roeck 	data->update_interval = ina209_interval_from_reg(INA209_CONFIG_DEFAULT);
549*ceeadc5cSGuenter Roeck 
550*ceeadc5cSGuenter Roeck 	/*
551*ceeadc5cSGuenter Roeck 	 * Calibrate current LSB to 1mA. Shunt is in uOhms.
552*ceeadc5cSGuenter Roeck 	 * See equation 13 in datasheet.
553*ceeadc5cSGuenter Roeck 	 */
554*ceeadc5cSGuenter Roeck 	i2c_smbus_write_word_swapped(client, INA209_CALIBRATION,
555*ceeadc5cSGuenter Roeck 				     clamp_val(40960000 / shunt, 1, 65535));
556*ceeadc5cSGuenter Roeck 
557*ceeadc5cSGuenter Roeck 	/* Clear status register */
558*ceeadc5cSGuenter Roeck 	i2c_smbus_read_word_swapped(client, INA209_STATUS);
559*ceeadc5cSGuenter Roeck 
560*ceeadc5cSGuenter Roeck 	return 0;
561*ceeadc5cSGuenter Roeck }
562*ceeadc5cSGuenter Roeck 
563*ceeadc5cSGuenter Roeck static int ina209_probe(struct i2c_client *client,
564*ceeadc5cSGuenter Roeck 			const struct i2c_device_id *id)
565*ceeadc5cSGuenter Roeck {
566*ceeadc5cSGuenter Roeck 	struct i2c_adapter *adapter = client->adapter;
567*ceeadc5cSGuenter Roeck 	struct ina209_data *data;
568*ceeadc5cSGuenter Roeck 	int ret;
569*ceeadc5cSGuenter Roeck 
570*ceeadc5cSGuenter Roeck 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
571*ceeadc5cSGuenter Roeck 		return -ENODEV;
572*ceeadc5cSGuenter Roeck 
573*ceeadc5cSGuenter Roeck 	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
574*ceeadc5cSGuenter Roeck 	if (!data)
575*ceeadc5cSGuenter Roeck 		return -ENOMEM;
576*ceeadc5cSGuenter Roeck 
577*ceeadc5cSGuenter Roeck 	i2c_set_clientdata(client, data);
578*ceeadc5cSGuenter Roeck 	mutex_init(&data->update_lock);
579*ceeadc5cSGuenter Roeck 
580*ceeadc5cSGuenter Roeck 	ret = ina209_init_client(client, data);
581*ceeadc5cSGuenter Roeck 	if (ret)
582*ceeadc5cSGuenter Roeck 		return ret;
583*ceeadc5cSGuenter Roeck 
584*ceeadc5cSGuenter Roeck 	/* Register sysfs hooks */
585*ceeadc5cSGuenter Roeck 	ret = sysfs_create_group(&client->dev.kobj, &ina209_group);
586*ceeadc5cSGuenter Roeck 	if (ret)
587*ceeadc5cSGuenter Roeck 		goto out_restore_conf;
588*ceeadc5cSGuenter Roeck 
589*ceeadc5cSGuenter Roeck 	data->hwmon_dev = hwmon_device_register(&client->dev);
590*ceeadc5cSGuenter Roeck 	if (IS_ERR(data->hwmon_dev)) {
591*ceeadc5cSGuenter Roeck 		ret = PTR_ERR(data->hwmon_dev);
592*ceeadc5cSGuenter Roeck 		goto out_hwmon_device_register;
593*ceeadc5cSGuenter Roeck 	}
594*ceeadc5cSGuenter Roeck 
595*ceeadc5cSGuenter Roeck 	return 0;
596*ceeadc5cSGuenter Roeck 
597*ceeadc5cSGuenter Roeck out_hwmon_device_register:
598*ceeadc5cSGuenter Roeck 	sysfs_remove_group(&client->dev.kobj, &ina209_group);
599*ceeadc5cSGuenter Roeck out_restore_conf:
600*ceeadc5cSGuenter Roeck 	ina209_restore_conf(client, data);
601*ceeadc5cSGuenter Roeck 	return ret;
602*ceeadc5cSGuenter Roeck }
603*ceeadc5cSGuenter Roeck 
604*ceeadc5cSGuenter Roeck static int ina209_remove(struct i2c_client *client)
605*ceeadc5cSGuenter Roeck {
606*ceeadc5cSGuenter Roeck 	struct ina209_data *data = i2c_get_clientdata(client);
607*ceeadc5cSGuenter Roeck 
608*ceeadc5cSGuenter Roeck 	hwmon_device_unregister(data->hwmon_dev);
609*ceeadc5cSGuenter Roeck 	sysfs_remove_group(&client->dev.kobj, &ina209_group);
610*ceeadc5cSGuenter Roeck 	ina209_restore_conf(client, data);
611*ceeadc5cSGuenter Roeck 
612*ceeadc5cSGuenter Roeck 	return 0;
613*ceeadc5cSGuenter Roeck }
614*ceeadc5cSGuenter Roeck 
615*ceeadc5cSGuenter Roeck static const struct i2c_device_id ina209_id[] = {
616*ceeadc5cSGuenter Roeck 	{ "ina209", 0 },
617*ceeadc5cSGuenter Roeck 	{ }
618*ceeadc5cSGuenter Roeck };
619*ceeadc5cSGuenter Roeck MODULE_DEVICE_TABLE(i2c, ina209_id);
620*ceeadc5cSGuenter Roeck 
621*ceeadc5cSGuenter Roeck /* This is the driver that will be inserted */
622*ceeadc5cSGuenter Roeck static struct i2c_driver ina209_driver = {
623*ceeadc5cSGuenter Roeck 	.class		= I2C_CLASS_HWMON,
624*ceeadc5cSGuenter Roeck 	.driver = {
625*ceeadc5cSGuenter Roeck 		.name	= "ina209",
626*ceeadc5cSGuenter Roeck 	},
627*ceeadc5cSGuenter Roeck 	.probe		= ina209_probe,
628*ceeadc5cSGuenter Roeck 	.remove		= ina209_remove,
629*ceeadc5cSGuenter Roeck 	.id_table	= ina209_id,
630*ceeadc5cSGuenter Roeck };
631*ceeadc5cSGuenter Roeck 
632*ceeadc5cSGuenter Roeck module_i2c_driver(ina209_driver);
633*ceeadc5cSGuenter Roeck 
634*ceeadc5cSGuenter Roeck MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>, Paul Hays <Paul.Hays@cattail.ca>, Guenter Roeck <linux@roeck-us.net>");
635*ceeadc5cSGuenter Roeck MODULE_DESCRIPTION("INA209 driver");
636*ceeadc5cSGuenter Roeck MODULE_LICENSE("GPL");
637