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