xref: /openbmc/linux/drivers/hwmon/powr1220.c (revision f4ff4155)
1f4ff4155SScott Kanowitz /*
2f4ff4155SScott Kanowitz  * powr1220.c - Driver for the Lattice POWR1220 programmable power supply
3f4ff4155SScott Kanowitz  * and monitor. Users can read all ADC inputs along with their labels
4f4ff4155SScott Kanowitz  * using the sysfs nodes.
5f4ff4155SScott Kanowitz  *
6f4ff4155SScott Kanowitz  * Copyright (c) 2014 Echo360 http://www.echo360.com
7f4ff4155SScott Kanowitz  * Scott Kanowitz <skanowitz@echo360.com> <scott.kanowitz@gmail.com>
8f4ff4155SScott Kanowitz  *
9f4ff4155SScott Kanowitz  * This program is free software; you can redistribute it and/or modify
10f4ff4155SScott Kanowitz  * it under the terms of the GNU General Public License as published by
11f4ff4155SScott Kanowitz  * the Free Software Foundation; either version 2 of the License, or
12f4ff4155SScott Kanowitz  * (at your option) any later version.
13f4ff4155SScott Kanowitz  *
14f4ff4155SScott Kanowitz  * This program is distributed in the hope that it will be useful,
15f4ff4155SScott Kanowitz  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16f4ff4155SScott Kanowitz  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17f4ff4155SScott Kanowitz  * GNU General Public License for more details.
18f4ff4155SScott Kanowitz  */
19f4ff4155SScott Kanowitz 
20f4ff4155SScott Kanowitz #include <linux/module.h>
21f4ff4155SScott Kanowitz #include <linux/init.h>
22f4ff4155SScott Kanowitz #include <linux/slab.h>
23f4ff4155SScott Kanowitz #include <linux/jiffies.h>
24f4ff4155SScott Kanowitz #include <linux/i2c.h>
25f4ff4155SScott Kanowitz #include <linux/hwmon.h>
26f4ff4155SScott Kanowitz #include <linux/hwmon-sysfs.h>
27f4ff4155SScott Kanowitz #include <linux/err.h>
28f4ff4155SScott Kanowitz #include <linux/mutex.h>
29f4ff4155SScott Kanowitz #include <linux/delay.h>
30f4ff4155SScott Kanowitz 
31f4ff4155SScott Kanowitz #define ADC_STEP_MV			2
32f4ff4155SScott Kanowitz #define ADC_MAX_LOW_MEASUREMENT_MV	2000
33f4ff4155SScott Kanowitz 
34f4ff4155SScott Kanowitz enum powr1220_regs {
35f4ff4155SScott Kanowitz 	VMON_STATUS0,
36f4ff4155SScott Kanowitz 	VMON_STATUS1,
37f4ff4155SScott Kanowitz 	VMON_STATUS2,
38f4ff4155SScott Kanowitz 	OUTPUT_STATUS0,
39f4ff4155SScott Kanowitz 	OUTPUT_STATUS1,
40f4ff4155SScott Kanowitz 	OUTPUT_STATUS2,
41f4ff4155SScott Kanowitz 	INPUT_STATUS,
42f4ff4155SScott Kanowitz 	ADC_VALUE_LOW,
43f4ff4155SScott Kanowitz 	ADC_VALUE_HIGH,
44f4ff4155SScott Kanowitz 	ADC_MUX,
45f4ff4155SScott Kanowitz 	UES_BYTE0,
46f4ff4155SScott Kanowitz 	UES_BYTE1,
47f4ff4155SScott Kanowitz 	UES_BYTE2,
48f4ff4155SScott Kanowitz 	UES_BYTE3,
49f4ff4155SScott Kanowitz 	GP_OUTPUT1,
50f4ff4155SScott Kanowitz 	GP_OUTPUT2,
51f4ff4155SScott Kanowitz 	GP_OUTPUT3,
52f4ff4155SScott Kanowitz 	INPUT_VALUE,
53f4ff4155SScott Kanowitz 	RESET,
54f4ff4155SScott Kanowitz 	TRIM1_TRIM,
55f4ff4155SScott Kanowitz 	TRIM2_TRIM,
56f4ff4155SScott Kanowitz 	TRIM3_TRIM,
57f4ff4155SScott Kanowitz 	TRIM4_TRIM,
58f4ff4155SScott Kanowitz 	TRIM5_TRIM,
59f4ff4155SScott Kanowitz 	TRIM6_TRIM,
60f4ff4155SScott Kanowitz 	TRIM7_TRIM,
61f4ff4155SScott Kanowitz 	TRIM8_TRIM,
62f4ff4155SScott Kanowitz 	MAX_POWR1220_REGS
63f4ff4155SScott Kanowitz };
64f4ff4155SScott Kanowitz 
65f4ff4155SScott Kanowitz enum powr1220_adc_values {
66f4ff4155SScott Kanowitz 	VMON1,
67f4ff4155SScott Kanowitz 	VMON2,
68f4ff4155SScott Kanowitz 	VMON3,
69f4ff4155SScott Kanowitz 	VMON4,
70f4ff4155SScott Kanowitz 	VMON5,
71f4ff4155SScott Kanowitz 	VMON6,
72f4ff4155SScott Kanowitz 	VMON7,
73f4ff4155SScott Kanowitz 	VMON8,
74f4ff4155SScott Kanowitz 	VMON9,
75f4ff4155SScott Kanowitz 	VMON10,
76f4ff4155SScott Kanowitz 	VMON11,
77f4ff4155SScott Kanowitz 	VMON12,
78f4ff4155SScott Kanowitz 	VCCA,
79f4ff4155SScott Kanowitz 	VCCINP,
80f4ff4155SScott Kanowitz 	MAX_POWR1220_ADC_VALUES
81f4ff4155SScott Kanowitz };
82f4ff4155SScott Kanowitz 
83f4ff4155SScott Kanowitz struct powr1220_data {
84f4ff4155SScott Kanowitz 	struct i2c_client *client;
85f4ff4155SScott Kanowitz 	struct mutex update_lock;
86f4ff4155SScott Kanowitz 	bool adc_valid[MAX_POWR1220_ADC_VALUES];
87f4ff4155SScott Kanowitz 	 /* the next value is in jiffies */
88f4ff4155SScott Kanowitz 	unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES];
89f4ff4155SScott Kanowitz 
90f4ff4155SScott Kanowitz 	/* values */
91f4ff4155SScott Kanowitz 	int adc_maxes[MAX_POWR1220_ADC_VALUES];
92f4ff4155SScott Kanowitz 	int adc_values[MAX_POWR1220_ADC_VALUES];
93f4ff4155SScott Kanowitz };
94f4ff4155SScott Kanowitz 
95f4ff4155SScott Kanowitz static const char * const input_names[] = {
96f4ff4155SScott Kanowitz 	[VMON1]    = "vmon1",
97f4ff4155SScott Kanowitz 	[VMON2]    = "vmon2",
98f4ff4155SScott Kanowitz 	[VMON3]    = "vmon3",
99f4ff4155SScott Kanowitz 	[VMON4]    = "vmon4",
100f4ff4155SScott Kanowitz 	[VMON5]    = "vmon5",
101f4ff4155SScott Kanowitz 	[VMON6]    = "vmon6",
102f4ff4155SScott Kanowitz 	[VMON7]    = "vmon7",
103f4ff4155SScott Kanowitz 	[VMON8]    = "vmon8",
104f4ff4155SScott Kanowitz 	[VMON9]    = "vmon9",
105f4ff4155SScott Kanowitz 	[VMON10]   = "vmon10",
106f4ff4155SScott Kanowitz 	[VMON11]   = "vmon11",
107f4ff4155SScott Kanowitz 	[VMON12]   = "vmon12",
108f4ff4155SScott Kanowitz 	[VCCA]     = "vcca",
109f4ff4155SScott Kanowitz 	[VCCINP]   = "vccinp",
110f4ff4155SScott Kanowitz };
111f4ff4155SScott Kanowitz 
112f4ff4155SScott Kanowitz /* Reads the specified ADC channel */
113f4ff4155SScott Kanowitz static int powr1220_read_adc(struct device *dev, int ch_num)
114f4ff4155SScott Kanowitz {
115f4ff4155SScott Kanowitz 	struct powr1220_data *data = dev_get_drvdata(dev);
116f4ff4155SScott Kanowitz 	int reading;
117f4ff4155SScott Kanowitz 	int result;
118f4ff4155SScott Kanowitz 	int adc_range = 0;
119f4ff4155SScott Kanowitz 
120f4ff4155SScott Kanowitz 	mutex_lock(&data->update_lock);
121f4ff4155SScott Kanowitz 
122f4ff4155SScott Kanowitz 	if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) ||
123f4ff4155SScott Kanowitz 			!data->adc_valid[ch_num]) {
124f4ff4155SScott Kanowitz 		/*
125f4ff4155SScott Kanowitz 		 * figure out if we need to use the attenuator for
126f4ff4155SScott Kanowitz 		 * high inputs or inputs that we don't yet have a measurement
127f4ff4155SScott Kanowitz 		 * for. We dynamically set the attenuator depending on the
128f4ff4155SScott Kanowitz 		 * max reading.
129f4ff4155SScott Kanowitz 		 */
130f4ff4155SScott Kanowitz 		if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV ||
131f4ff4155SScott Kanowitz 				data->adc_maxes[ch_num] == 0)
132f4ff4155SScott Kanowitz 			adc_range = 1 << 4;
133f4ff4155SScott Kanowitz 
134f4ff4155SScott Kanowitz 		/* set the attenuator and mux */
135f4ff4155SScott Kanowitz 		result = i2c_smbus_write_byte_data(data->client, ADC_MUX,
136f4ff4155SScott Kanowitz 				adc_range | ch_num);
137f4ff4155SScott Kanowitz 		if (result)
138f4ff4155SScott Kanowitz 			goto exit;
139f4ff4155SScott Kanowitz 
140f4ff4155SScott Kanowitz 		/*
141f4ff4155SScott Kanowitz 		 * wait at least Tconvert time (200 us) for the
142f4ff4155SScott Kanowitz 		 * conversion to complete
143f4ff4155SScott Kanowitz 		 */
144f4ff4155SScott Kanowitz 		udelay(200);
145f4ff4155SScott Kanowitz 
146f4ff4155SScott Kanowitz 		/* get the ADC reading */
147f4ff4155SScott Kanowitz 		result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW);
148f4ff4155SScott Kanowitz 		if (result < 0)
149f4ff4155SScott Kanowitz 			goto exit;
150f4ff4155SScott Kanowitz 
151f4ff4155SScott Kanowitz 		reading = result >> 4;
152f4ff4155SScott Kanowitz 
153f4ff4155SScott Kanowitz 		/* get the upper half of the reading */
154f4ff4155SScott Kanowitz 		result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH);
155f4ff4155SScott Kanowitz 		if (result < 0)
156f4ff4155SScott Kanowitz 			goto exit;
157f4ff4155SScott Kanowitz 
158f4ff4155SScott Kanowitz 		reading |= result << 4;
159f4ff4155SScott Kanowitz 
160f4ff4155SScott Kanowitz 		/* now convert the reading to a voltage */
161f4ff4155SScott Kanowitz 		reading *= ADC_STEP_MV;
162f4ff4155SScott Kanowitz 		data->adc_values[ch_num] = reading;
163f4ff4155SScott Kanowitz 		data->adc_valid[ch_num] = true;
164f4ff4155SScott Kanowitz 		data->adc_last_updated[ch_num] = jiffies;
165f4ff4155SScott Kanowitz 		result = reading;
166f4ff4155SScott Kanowitz 
167f4ff4155SScott Kanowitz 		if (reading > data->adc_maxes[ch_num])
168f4ff4155SScott Kanowitz 			data->adc_maxes[ch_num] = reading;
169f4ff4155SScott Kanowitz 	} else {
170f4ff4155SScott Kanowitz 		result = data->adc_values[ch_num];
171f4ff4155SScott Kanowitz 	}
172f4ff4155SScott Kanowitz 
173f4ff4155SScott Kanowitz exit:
174f4ff4155SScott Kanowitz 	mutex_unlock(&data->update_lock);
175f4ff4155SScott Kanowitz 
176f4ff4155SScott Kanowitz 	return result;
177f4ff4155SScott Kanowitz }
178f4ff4155SScott Kanowitz 
179f4ff4155SScott Kanowitz /* Shows the voltage associated with the specified ADC channel */
180f4ff4155SScott Kanowitz static ssize_t powr1220_show_voltage(struct device *dev,
181f4ff4155SScott Kanowitz 	struct device_attribute *dev_attr, char *buf)
182f4ff4155SScott Kanowitz {
183f4ff4155SScott Kanowitz 	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
184f4ff4155SScott Kanowitz 	int adc_val = powr1220_read_adc(dev, attr->index);
185f4ff4155SScott Kanowitz 
186f4ff4155SScott Kanowitz 	if (adc_val < 0)
187f4ff4155SScott Kanowitz 		return adc_val;
188f4ff4155SScott Kanowitz 
189f4ff4155SScott Kanowitz 	return sprintf(buf, "%d\n", adc_val);
190f4ff4155SScott Kanowitz }
191f4ff4155SScott Kanowitz 
192f4ff4155SScott Kanowitz /* Shows the maximum setting associated with the specified ADC channel */
193f4ff4155SScott Kanowitz static ssize_t powr1220_show_max(struct device *dev,
194f4ff4155SScott Kanowitz 	struct device_attribute *dev_attr, char *buf)
195f4ff4155SScott Kanowitz {
196f4ff4155SScott Kanowitz 	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
197f4ff4155SScott Kanowitz 	struct powr1220_data *data = dev_get_drvdata(dev);
198f4ff4155SScott Kanowitz 
199f4ff4155SScott Kanowitz 	return sprintf(buf, "%d\n", data->adc_maxes[attr->index]);
200f4ff4155SScott Kanowitz }
201f4ff4155SScott Kanowitz 
202f4ff4155SScott Kanowitz /* Shows the label associated with the specified ADC channel */
203f4ff4155SScott Kanowitz static ssize_t powr1220_show_label(struct device *dev,
204f4ff4155SScott Kanowitz 	struct device_attribute *dev_attr, char *buf)
205f4ff4155SScott Kanowitz {
206f4ff4155SScott Kanowitz 	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
207f4ff4155SScott Kanowitz 
208f4ff4155SScott Kanowitz 	return sprintf(buf, "%s\n", input_names[attr->index]);
209f4ff4155SScott Kanowitz }
210f4ff4155SScott Kanowitz 
211f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, powr1220_show_voltage, NULL,
212f4ff4155SScott Kanowitz 	VMON1);
213f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, powr1220_show_voltage, NULL,
214f4ff4155SScott Kanowitz 	VMON2);
215f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, powr1220_show_voltage, NULL,
216f4ff4155SScott Kanowitz 	VMON3);
217f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, powr1220_show_voltage, NULL,
218f4ff4155SScott Kanowitz 	VMON4);
219f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, powr1220_show_voltage, NULL,
220f4ff4155SScott Kanowitz 	VMON5);
221f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, powr1220_show_voltage, NULL,
222f4ff4155SScott Kanowitz 	VMON6);
223f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, powr1220_show_voltage, NULL,
224f4ff4155SScott Kanowitz 	VMON7);
225f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, powr1220_show_voltage, NULL,
226f4ff4155SScott Kanowitz 	VMON8);
227f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, powr1220_show_voltage, NULL,
228f4ff4155SScott Kanowitz 	VMON9);
229f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, powr1220_show_voltage, NULL,
230f4ff4155SScott Kanowitz 	VMON10);
231f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, powr1220_show_voltage, NULL,
232f4ff4155SScott Kanowitz 	VMON11);
233f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, powr1220_show_voltage, NULL,
234f4ff4155SScott Kanowitz 	VMON12);
235f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, powr1220_show_voltage, NULL,
236f4ff4155SScott Kanowitz 	VCCA);
237f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, powr1220_show_voltage, NULL,
238f4ff4155SScott Kanowitz 	VCCINP);
239f4ff4155SScott Kanowitz 
240f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in0_highest, S_IRUGO, powr1220_show_max, NULL,
241f4ff4155SScott Kanowitz 	VMON1);
242f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in1_highest, S_IRUGO, powr1220_show_max, NULL,
243f4ff4155SScott Kanowitz 	VMON2);
244f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in2_highest, S_IRUGO, powr1220_show_max, NULL,
245f4ff4155SScott Kanowitz 	VMON3);
246f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in3_highest, S_IRUGO, powr1220_show_max, NULL,
247f4ff4155SScott Kanowitz 	VMON4);
248f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in4_highest, S_IRUGO, powr1220_show_max, NULL,
249f4ff4155SScott Kanowitz 	VMON5);
250f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in5_highest, S_IRUGO, powr1220_show_max, NULL,
251f4ff4155SScott Kanowitz 	VMON6);
252f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in6_highest, S_IRUGO, powr1220_show_max, NULL,
253f4ff4155SScott Kanowitz 	VMON7);
254f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in7_highest, S_IRUGO, powr1220_show_max, NULL,
255f4ff4155SScott Kanowitz 	VMON8);
256f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in8_highest, S_IRUGO, powr1220_show_max, NULL,
257f4ff4155SScott Kanowitz 	VMON9);
258f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in9_highest, S_IRUGO, powr1220_show_max, NULL,
259f4ff4155SScott Kanowitz 	VMON10);
260f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in10_highest, S_IRUGO, powr1220_show_max, NULL,
261f4ff4155SScott Kanowitz 	VMON11);
262f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in11_highest, S_IRUGO, powr1220_show_max, NULL,
263f4ff4155SScott Kanowitz 	VMON12);
264f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in12_highest, S_IRUGO, powr1220_show_max, NULL,
265f4ff4155SScott Kanowitz 	VCCA);
266f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in13_highest, S_IRUGO, powr1220_show_max, NULL,
267f4ff4155SScott Kanowitz 	VCCINP);
268f4ff4155SScott Kanowitz 
269f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, powr1220_show_label, NULL,
270f4ff4155SScott Kanowitz 	VMON1);
271f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, powr1220_show_label, NULL,
272f4ff4155SScott Kanowitz 	VMON2);
273f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, powr1220_show_label, NULL,
274f4ff4155SScott Kanowitz 	VMON3);
275f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, powr1220_show_label, NULL,
276f4ff4155SScott Kanowitz 	VMON4);
277f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, powr1220_show_label, NULL,
278f4ff4155SScott Kanowitz 	VMON5);
279f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, powr1220_show_label, NULL,
280f4ff4155SScott Kanowitz 	VMON6);
281f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, powr1220_show_label, NULL,
282f4ff4155SScott Kanowitz 	VMON7);
283f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, powr1220_show_label, NULL,
284f4ff4155SScott Kanowitz 	VMON8);
285f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, powr1220_show_label, NULL,
286f4ff4155SScott Kanowitz 	VMON9);
287f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, powr1220_show_label, NULL,
288f4ff4155SScott Kanowitz 	VMON10);
289f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, powr1220_show_label, NULL,
290f4ff4155SScott Kanowitz 	VMON11);
291f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, powr1220_show_label, NULL,
292f4ff4155SScott Kanowitz 	VMON12);
293f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, powr1220_show_label, NULL,
294f4ff4155SScott Kanowitz 	VCCA);
295f4ff4155SScott Kanowitz static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, powr1220_show_label, NULL,
296f4ff4155SScott Kanowitz 	VCCINP);
297f4ff4155SScott Kanowitz 
298f4ff4155SScott Kanowitz static struct attribute *powr1220_attrs[] = {
299f4ff4155SScott Kanowitz 	&sensor_dev_attr_in0_input.dev_attr.attr,
300f4ff4155SScott Kanowitz 	&sensor_dev_attr_in1_input.dev_attr.attr,
301f4ff4155SScott Kanowitz 	&sensor_dev_attr_in2_input.dev_attr.attr,
302f4ff4155SScott Kanowitz 	&sensor_dev_attr_in3_input.dev_attr.attr,
303f4ff4155SScott Kanowitz 	&sensor_dev_attr_in4_input.dev_attr.attr,
304f4ff4155SScott Kanowitz 	&sensor_dev_attr_in5_input.dev_attr.attr,
305f4ff4155SScott Kanowitz 	&sensor_dev_attr_in6_input.dev_attr.attr,
306f4ff4155SScott Kanowitz 	&sensor_dev_attr_in7_input.dev_attr.attr,
307f4ff4155SScott Kanowitz 	&sensor_dev_attr_in8_input.dev_attr.attr,
308f4ff4155SScott Kanowitz 	&sensor_dev_attr_in9_input.dev_attr.attr,
309f4ff4155SScott Kanowitz 	&sensor_dev_attr_in10_input.dev_attr.attr,
310f4ff4155SScott Kanowitz 	&sensor_dev_attr_in11_input.dev_attr.attr,
311f4ff4155SScott Kanowitz 	&sensor_dev_attr_in12_input.dev_attr.attr,
312f4ff4155SScott Kanowitz 	&sensor_dev_attr_in13_input.dev_attr.attr,
313f4ff4155SScott Kanowitz 
314f4ff4155SScott Kanowitz 	&sensor_dev_attr_in0_highest.dev_attr.attr,
315f4ff4155SScott Kanowitz 	&sensor_dev_attr_in1_highest.dev_attr.attr,
316f4ff4155SScott Kanowitz 	&sensor_dev_attr_in2_highest.dev_attr.attr,
317f4ff4155SScott Kanowitz 	&sensor_dev_attr_in3_highest.dev_attr.attr,
318f4ff4155SScott Kanowitz 	&sensor_dev_attr_in4_highest.dev_attr.attr,
319f4ff4155SScott Kanowitz 	&sensor_dev_attr_in5_highest.dev_attr.attr,
320f4ff4155SScott Kanowitz 	&sensor_dev_attr_in6_highest.dev_attr.attr,
321f4ff4155SScott Kanowitz 	&sensor_dev_attr_in7_highest.dev_attr.attr,
322f4ff4155SScott Kanowitz 	&sensor_dev_attr_in8_highest.dev_attr.attr,
323f4ff4155SScott Kanowitz 	&sensor_dev_attr_in9_highest.dev_attr.attr,
324f4ff4155SScott Kanowitz 	&sensor_dev_attr_in10_highest.dev_attr.attr,
325f4ff4155SScott Kanowitz 	&sensor_dev_attr_in11_highest.dev_attr.attr,
326f4ff4155SScott Kanowitz 	&sensor_dev_attr_in12_highest.dev_attr.attr,
327f4ff4155SScott Kanowitz 	&sensor_dev_attr_in13_highest.dev_attr.attr,
328f4ff4155SScott Kanowitz 
329f4ff4155SScott Kanowitz 	&sensor_dev_attr_in0_label.dev_attr.attr,
330f4ff4155SScott Kanowitz 	&sensor_dev_attr_in1_label.dev_attr.attr,
331f4ff4155SScott Kanowitz 	&sensor_dev_attr_in2_label.dev_attr.attr,
332f4ff4155SScott Kanowitz 	&sensor_dev_attr_in3_label.dev_attr.attr,
333f4ff4155SScott Kanowitz 	&sensor_dev_attr_in4_label.dev_attr.attr,
334f4ff4155SScott Kanowitz 	&sensor_dev_attr_in5_label.dev_attr.attr,
335f4ff4155SScott Kanowitz 	&sensor_dev_attr_in6_label.dev_attr.attr,
336f4ff4155SScott Kanowitz 	&sensor_dev_attr_in7_label.dev_attr.attr,
337f4ff4155SScott Kanowitz 	&sensor_dev_attr_in8_label.dev_attr.attr,
338f4ff4155SScott Kanowitz 	&sensor_dev_attr_in9_label.dev_attr.attr,
339f4ff4155SScott Kanowitz 	&sensor_dev_attr_in10_label.dev_attr.attr,
340f4ff4155SScott Kanowitz 	&sensor_dev_attr_in11_label.dev_attr.attr,
341f4ff4155SScott Kanowitz 	&sensor_dev_attr_in12_label.dev_attr.attr,
342f4ff4155SScott Kanowitz 	&sensor_dev_attr_in13_label.dev_attr.attr,
343f4ff4155SScott Kanowitz 
344f4ff4155SScott Kanowitz 	NULL
345f4ff4155SScott Kanowitz };
346f4ff4155SScott Kanowitz 
347f4ff4155SScott Kanowitz ATTRIBUTE_GROUPS(powr1220);
348f4ff4155SScott Kanowitz 
349f4ff4155SScott Kanowitz static int powr1220_probe(struct i2c_client *client,
350f4ff4155SScott Kanowitz 		const struct i2c_device_id *id)
351f4ff4155SScott Kanowitz {
352f4ff4155SScott Kanowitz 	struct powr1220_data *data;
353f4ff4155SScott Kanowitz 	struct device *hwmon_dev;
354f4ff4155SScott Kanowitz 
355f4ff4155SScott Kanowitz 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
356f4ff4155SScott Kanowitz 		return -ENODEV;
357f4ff4155SScott Kanowitz 
358f4ff4155SScott Kanowitz 	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
359f4ff4155SScott Kanowitz 	if (!data)
360f4ff4155SScott Kanowitz 		return -ENOMEM;
361f4ff4155SScott Kanowitz 
362f4ff4155SScott Kanowitz 	mutex_init(&data->update_lock);
363f4ff4155SScott Kanowitz 	data->client = client;
364f4ff4155SScott Kanowitz 
365f4ff4155SScott Kanowitz 	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
366f4ff4155SScott Kanowitz 			client->name, data, powr1220_groups);
367f4ff4155SScott Kanowitz 
368f4ff4155SScott Kanowitz 	return PTR_ERR_OR_ZERO(hwmon_dev);
369f4ff4155SScott Kanowitz }
370f4ff4155SScott Kanowitz 
371f4ff4155SScott Kanowitz static const struct i2c_device_id powr1220_ids[] = {
372f4ff4155SScott Kanowitz 	{ "powr1220", 0, },
373f4ff4155SScott Kanowitz 	{ }
374f4ff4155SScott Kanowitz };
375f4ff4155SScott Kanowitz 
376f4ff4155SScott Kanowitz MODULE_DEVICE_TABLE(i2c, powr1220_ids);
377f4ff4155SScott Kanowitz 
378f4ff4155SScott Kanowitz static struct i2c_driver powr1220_driver = {
379f4ff4155SScott Kanowitz 	.class		= I2C_CLASS_HWMON,
380f4ff4155SScott Kanowitz 	.driver = {
381f4ff4155SScott Kanowitz 		.name	= "powr1220",
382f4ff4155SScott Kanowitz 	},
383f4ff4155SScott Kanowitz 	.probe		= powr1220_probe,
384f4ff4155SScott Kanowitz 	.id_table	= powr1220_ids,
385f4ff4155SScott Kanowitz };
386f4ff4155SScott Kanowitz 
387f4ff4155SScott Kanowitz module_i2c_driver(powr1220_driver);
388f4ff4155SScott Kanowitz 
389f4ff4155SScott Kanowitz MODULE_AUTHOR("Scott Kanowitz");
390f4ff4155SScott Kanowitz MODULE_DESCRIPTION("POWR1220 driver");
391f4ff4155SScott Kanowitz MODULE_LICENSE("GPL");
392