Blame view

drivers/hwmon/max16065.c 18.9 KB
b886d83c5   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
f5bae2642   Guenter Roeck   hwmon: Driver for...
2
3
4
5
6
7
8
9
10
11
  /*
   * Driver for
   *  Maxim MAX16065/MAX16066 12-Channel/8-Channel, Flash-Configurable
   *  System Managers with Nonvolatile Fault Registers
   *  Maxim MAX16067/MAX16068 6-Channel, Flash-Configurable System Managers
   *  with Nonvolatile Fault Registers
   *  Maxim MAX16070/MAX16071 12-Channel/8-Channel, Flash-Configurable System
   *  Monitors with Nonvolatile Fault Registers
   *
   * Copyright (C) 2011 Ericsson AB.
f5bae2642   Guenter Roeck   hwmon: Driver for...
12
13
14
15
16
17
18
19
20
21
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/err.h>
  #include <linux/slab.h>
  #include <linux/i2c.h>
  #include <linux/hwmon.h>
  #include <linux/hwmon-sysfs.h>
f5bae2642   Guenter Roeck   hwmon: Driver for...
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  #include <linux/jiffies.h>
  
  enum chips { max16065, max16066, max16067, max16068, max16070, max16071 };
  
  /*
   * Registers
   */
  #define MAX16065_ADC(x)		((x) * 2)
  
  #define MAX16065_CURR_SENSE	0x18
  #define MAX16065_CSP_ADC	0x19
  #define MAX16065_FAULT(x)	(0x1b + (x))
  #define MAX16065_SCALE(x)	(0x43 + (x))
  #define MAX16065_CURR_CONTROL	0x47
  #define MAX16065_LIMIT(l, x)	(0x48 + (l) + (x) * 3)	/*
  							 * l: limit
  							 *  0: min/max
  							 *  1: crit
  							 *  2: lcrit
  							 * x: ADC index
  							 */
  
  #define MAX16065_SW_ENABLE	0x73
  
  #define MAX16065_WARNING_OV	(1 << 3) /* Set if secondary threshold is OV
  					    warning */
  
  #define MAX16065_CURR_ENABLE	(1 << 0)
  
  #define MAX16065_NUM_LIMIT	3
  #define MAX16065_NUM_ADC	12	/* maximum number of ADC channels */
  
  static const int max16065_num_adc[] = {
  	[max16065] = 12,
  	[max16066] = 8,
  	[max16067] = 6,
  	[max16068] = 6,
  	[max16070] = 12,
  	[max16071] = 8,
  };
  
  static const bool max16065_have_secondary[] = {
  	[max16065] = true,
  	[max16066] = true,
  	[max16067] = false,
  	[max16068] = false,
  	[max16070] = true,
  	[max16071] = true,
  };
  
  static const bool max16065_have_current[] = {
  	[max16065] = true,
  	[max16066] = true,
  	[max16067] = false,
  	[max16068] = false,
  	[max16070] = true,
  	[max16071] = true,
  };
  
  struct max16065_data {
  	enum chips type;
38c75dc36   Guenter Roeck   hwmon: (max16065)...
83
84
  	struct i2c_client *client;
  	const struct attribute_group *groups[4];
f5bae2642   Guenter Roeck   hwmon: Driver for...
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
  	struct mutex update_lock;
  	bool valid;
  	unsigned long last_updated; /* in jiffies */
  	int num_adc;
  	bool have_current;
  	int curr_gain;
  	/* limits are in mV */
  	int limit[MAX16065_NUM_LIMIT][MAX16065_NUM_ADC];
  	int range[MAX16065_NUM_ADC + 1];/* voltage range */
  	int adc[MAX16065_NUM_ADC + 1];	/* adc values (raw) including csp_adc */
  	int curr_sense;
  	int fault[2];
  };
  
  static const int max16065_adc_range[] = { 5560, 2780, 1390, 0 };
  static const int max16065_csp_adc_range[] = { 7000, 14000 };
  
  /* ADC registers have 10 bit resolution. */
  static inline int ADC_TO_MV(int adc, int range)
  {
  	return (adc * range) / 1024;
  }
  
  /*
   * Limit registers have 8 bit resolution and match upper 8 bits of ADC
   * registers.
   */
  static inline int LIMIT_TO_MV(int limit, int range)
  {
  	return limit * range / 256;
  }
  
  static inline int MV_TO_LIMIT(int mv, int range)
  {
2a844c148   Guenter Roeck   hwmon: Replace SE...
119
  	return clamp_val(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
f5bae2642   Guenter Roeck   hwmon: Driver for...
120
121
122
123
  }
  
  static inline int ADC_TO_CURR(int adc, int gain)
  {
ff71c182f   Guenter Roeck   hwmon: (max16065)...
124
  	return adc * 1400000 / (gain * 255);
f5bae2642   Guenter Roeck   hwmon: Driver for...
125
126
127
128
129
130
131
132
133
134
135
  }
  
  /*
   * max16065_read_adc()
   *
   * Read 16 bit value from <reg>, <reg+1>.
   * Upper 8 bits are in <reg>, lower 2 bits are in bits 7:6 of <reg+1>.
   */
  static int max16065_read_adc(struct i2c_client *client, int reg)
  {
  	int rv;
90f4102ce   Jean Delvare   hwmon: Use i2c_sm...
136
  	rv = i2c_smbus_read_word_swapped(client, reg);
f5bae2642   Guenter Roeck   hwmon: Driver for...
137
138
  	if (unlikely(rv < 0))
  		return rv;
90f4102ce   Jean Delvare   hwmon: Use i2c_sm...
139
  	return rv >> 6;
f5bae2642   Guenter Roeck   hwmon: Driver for...
140
141
142
143
  }
  
  static struct max16065_data *max16065_update_device(struct device *dev)
  {
38c75dc36   Guenter Roeck   hwmon: (max16065)...
144
145
  	struct max16065_data *data = dev_get_drvdata(dev);
  	struct i2c_client *client = data->client;
f5bae2642   Guenter Roeck   hwmon: Driver for...
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
  
  	mutex_lock(&data->update_lock);
  	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
  		int i;
  
  		for (i = 0; i < data->num_adc; i++)
  			data->adc[i]
  			  = max16065_read_adc(client, MAX16065_ADC(i));
  
  		if (data->have_current) {
  			data->adc[MAX16065_NUM_ADC]
  			  = max16065_read_adc(client, MAX16065_CSP_ADC);
  			data->curr_sense
  			  = i2c_smbus_read_byte_data(client,
  						     MAX16065_CURR_SENSE);
  		}
  
  		for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++)
  			data->fault[i]
  			  = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i));
  
  		data->last_updated = jiffies;
  		data->valid = 1;
  	}
  	mutex_unlock(&data->update_lock);
  	return data;
  }
9d6c12557   Guenter Roeck   hwmon: (max16065)...
173
  static ssize_t max16065_alarm_show(struct device *dev,
f5bae2642   Guenter Roeck   hwmon: Driver for...
174
175
176
177
178
179
180
181
182
183
184
  				   struct device_attribute *da, char *buf)
  {
  	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
  	struct max16065_data *data = max16065_update_device(dev);
  	int val = data->fault[attr2->nr];
  
  	if (val < 0)
  		return val;
  
  	val &= (1 << attr2->index);
  	if (val)
38c75dc36   Guenter Roeck   hwmon: (max16065)...
185
  		i2c_smbus_write_byte_data(data->client,
f5bae2642   Guenter Roeck   hwmon: Driver for...
186
187
188
189
190
  					  MAX16065_FAULT(attr2->nr), val);
  
  	return snprintf(buf, PAGE_SIZE, "%d
  ", !!val);
  }
9d6c12557   Guenter Roeck   hwmon: (max16065)...
191
  static ssize_t max16065_input_show(struct device *dev,
f5bae2642   Guenter Roeck   hwmon: Driver for...
192
193
194
195
196
197
198
199
200
201
202
203
204
  				   struct device_attribute *da, char *buf)
  {
  	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
  	struct max16065_data *data = max16065_update_device(dev);
  	int adc = data->adc[attr->index];
  
  	if (unlikely(adc < 0))
  		return adc;
  
  	return snprintf(buf, PAGE_SIZE, "%d
  ",
  			ADC_TO_MV(adc, data->range[attr->index]));
  }
9d6c12557   Guenter Roeck   hwmon: (max16065)...
205
  static ssize_t max16065_current_show(struct device *dev,
f5bae2642   Guenter Roeck   hwmon: Driver for...
206
207
208
209
210
211
212
213
214
215
216
  				     struct device_attribute *da, char *buf)
  {
  	struct max16065_data *data = max16065_update_device(dev);
  
  	if (unlikely(data->curr_sense < 0))
  		return data->curr_sense;
  
  	return snprintf(buf, PAGE_SIZE, "%d
  ",
  			ADC_TO_CURR(data->curr_sense, data->curr_gain));
  }
9d6c12557   Guenter Roeck   hwmon: (max16065)...
217
218
219
  static ssize_t max16065_limit_store(struct device *dev,
  				    struct device_attribute *da,
  				    const char *buf, size_t count)
f5bae2642   Guenter Roeck   hwmon: Driver for...
220
221
  {
  	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
38c75dc36   Guenter Roeck   hwmon: (max16065)...
222
  	struct max16065_data *data = dev_get_drvdata(dev);
f5bae2642   Guenter Roeck   hwmon: Driver for...
223
224
225
  	unsigned long val;
  	int err;
  	int limit;
179c4fdb5   Frans Meulenbroeks   hwmon: replaced s...
226
  	err = kstrtoul(buf, 10, &val);
f5bae2642   Guenter Roeck   hwmon: Driver for...
227
228
229
230
231
232
233
234
  	if (unlikely(err < 0))
  		return err;
  
  	limit = MV_TO_LIMIT(val, data->range[attr2->index]);
  
  	mutex_lock(&data->update_lock);
  	data->limit[attr2->nr][attr2->index]
  	  = LIMIT_TO_MV(limit, data->range[attr2->index]);
38c75dc36   Guenter Roeck   hwmon: (max16065)...
235
  	i2c_smbus_write_byte_data(data->client,
f5bae2642   Guenter Roeck   hwmon: Driver for...
236
237
238
239
240
241
  				  MAX16065_LIMIT(attr2->nr, attr2->index),
  				  limit);
  	mutex_unlock(&data->update_lock);
  
  	return count;
  }
9d6c12557   Guenter Roeck   hwmon: (max16065)...
242
  static ssize_t max16065_limit_show(struct device *dev,
f5bae2642   Guenter Roeck   hwmon: Driver for...
243
244
245
  				   struct device_attribute *da, char *buf)
  {
  	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
38c75dc36   Guenter Roeck   hwmon: (max16065)...
246
  	struct max16065_data *data = dev_get_drvdata(dev);
f5bae2642   Guenter Roeck   hwmon: Driver for...
247
248
249
250
251
252
253
254
255
  
  	return snprintf(buf, PAGE_SIZE, "%d
  ",
  			data->limit[attr2->nr][attr2->index]);
  }
  
  /* Construct a sensor_device_attribute structure for each register */
  
  /* Input voltages */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
256
257
258
259
260
261
262
263
264
265
266
267
268
  static SENSOR_DEVICE_ATTR_RO(in0_input, max16065_input, 0);
  static SENSOR_DEVICE_ATTR_RO(in1_input, max16065_input, 1);
  static SENSOR_DEVICE_ATTR_RO(in2_input, max16065_input, 2);
  static SENSOR_DEVICE_ATTR_RO(in3_input, max16065_input, 3);
  static SENSOR_DEVICE_ATTR_RO(in4_input, max16065_input, 4);
  static SENSOR_DEVICE_ATTR_RO(in5_input, max16065_input, 5);
  static SENSOR_DEVICE_ATTR_RO(in6_input, max16065_input, 6);
  static SENSOR_DEVICE_ATTR_RO(in7_input, max16065_input, 7);
  static SENSOR_DEVICE_ATTR_RO(in8_input, max16065_input, 8);
  static SENSOR_DEVICE_ATTR_RO(in9_input, max16065_input, 9);
  static SENSOR_DEVICE_ATTR_RO(in10_input, max16065_input, 10);
  static SENSOR_DEVICE_ATTR_RO(in11_input, max16065_input, 11);
  static SENSOR_DEVICE_ATTR_RO(in12_input, max16065_input, 12);
f5bae2642   Guenter Roeck   hwmon: Driver for...
269
270
  
  /* Input voltages lcrit */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
271
272
273
274
275
276
277
278
279
280
281
282
  static SENSOR_DEVICE_ATTR_2_RW(in0_lcrit, max16065_limit, 2, 0);
  static SENSOR_DEVICE_ATTR_2_RW(in1_lcrit, max16065_limit, 2, 1);
  static SENSOR_DEVICE_ATTR_2_RW(in2_lcrit, max16065_limit, 2, 2);
  static SENSOR_DEVICE_ATTR_2_RW(in3_lcrit, max16065_limit, 2, 3);
  static SENSOR_DEVICE_ATTR_2_RW(in4_lcrit, max16065_limit, 2, 4);
  static SENSOR_DEVICE_ATTR_2_RW(in5_lcrit, max16065_limit, 2, 5);
  static SENSOR_DEVICE_ATTR_2_RW(in6_lcrit, max16065_limit, 2, 6);
  static SENSOR_DEVICE_ATTR_2_RW(in7_lcrit, max16065_limit, 2, 7);
  static SENSOR_DEVICE_ATTR_2_RW(in8_lcrit, max16065_limit, 2, 8);
  static SENSOR_DEVICE_ATTR_2_RW(in9_lcrit, max16065_limit, 2, 9);
  static SENSOR_DEVICE_ATTR_2_RW(in10_lcrit, max16065_limit, 2, 10);
  static SENSOR_DEVICE_ATTR_2_RW(in11_lcrit, max16065_limit, 2, 11);
f5bae2642   Guenter Roeck   hwmon: Driver for...
283
284
  
  /* Input voltages crit */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
285
286
287
288
289
290
291
292
293
294
295
296
  static SENSOR_DEVICE_ATTR_2_RW(in0_crit, max16065_limit, 1, 0);
  static SENSOR_DEVICE_ATTR_2_RW(in1_crit, max16065_limit, 1, 1);
  static SENSOR_DEVICE_ATTR_2_RW(in2_crit, max16065_limit, 1, 2);
  static SENSOR_DEVICE_ATTR_2_RW(in3_crit, max16065_limit, 1, 3);
  static SENSOR_DEVICE_ATTR_2_RW(in4_crit, max16065_limit, 1, 4);
  static SENSOR_DEVICE_ATTR_2_RW(in5_crit, max16065_limit, 1, 5);
  static SENSOR_DEVICE_ATTR_2_RW(in6_crit, max16065_limit, 1, 6);
  static SENSOR_DEVICE_ATTR_2_RW(in7_crit, max16065_limit, 1, 7);
  static SENSOR_DEVICE_ATTR_2_RW(in8_crit, max16065_limit, 1, 8);
  static SENSOR_DEVICE_ATTR_2_RW(in9_crit, max16065_limit, 1, 9);
  static SENSOR_DEVICE_ATTR_2_RW(in10_crit, max16065_limit, 1, 10);
  static SENSOR_DEVICE_ATTR_2_RW(in11_crit, max16065_limit, 1, 11);
f5bae2642   Guenter Roeck   hwmon: Driver for...
297
298
  
  /* Input voltages min */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
299
300
301
302
303
304
305
306
307
308
309
310
  static SENSOR_DEVICE_ATTR_2_RW(in0_min, max16065_limit, 0, 0);
  static SENSOR_DEVICE_ATTR_2_RW(in1_min, max16065_limit, 0, 1);
  static SENSOR_DEVICE_ATTR_2_RW(in2_min, max16065_limit, 0, 2);
  static SENSOR_DEVICE_ATTR_2_RW(in3_min, max16065_limit, 0, 3);
  static SENSOR_DEVICE_ATTR_2_RW(in4_min, max16065_limit, 0, 4);
  static SENSOR_DEVICE_ATTR_2_RW(in5_min, max16065_limit, 0, 5);
  static SENSOR_DEVICE_ATTR_2_RW(in6_min, max16065_limit, 0, 6);
  static SENSOR_DEVICE_ATTR_2_RW(in7_min, max16065_limit, 0, 7);
  static SENSOR_DEVICE_ATTR_2_RW(in8_min, max16065_limit, 0, 8);
  static SENSOR_DEVICE_ATTR_2_RW(in9_min, max16065_limit, 0, 9);
  static SENSOR_DEVICE_ATTR_2_RW(in10_min, max16065_limit, 0, 10);
  static SENSOR_DEVICE_ATTR_2_RW(in11_min, max16065_limit, 0, 11);
f5bae2642   Guenter Roeck   hwmon: Driver for...
311
312
  
  /* Input voltages max */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
313
314
315
316
317
318
319
320
321
322
323
324
  static SENSOR_DEVICE_ATTR_2_RW(in0_max, max16065_limit, 0, 0);
  static SENSOR_DEVICE_ATTR_2_RW(in1_max, max16065_limit, 0, 1);
  static SENSOR_DEVICE_ATTR_2_RW(in2_max, max16065_limit, 0, 2);
  static SENSOR_DEVICE_ATTR_2_RW(in3_max, max16065_limit, 0, 3);
  static SENSOR_DEVICE_ATTR_2_RW(in4_max, max16065_limit, 0, 4);
  static SENSOR_DEVICE_ATTR_2_RW(in5_max, max16065_limit, 0, 5);
  static SENSOR_DEVICE_ATTR_2_RW(in6_max, max16065_limit, 0, 6);
  static SENSOR_DEVICE_ATTR_2_RW(in7_max, max16065_limit, 0, 7);
  static SENSOR_DEVICE_ATTR_2_RW(in8_max, max16065_limit, 0, 8);
  static SENSOR_DEVICE_ATTR_2_RW(in9_max, max16065_limit, 0, 9);
  static SENSOR_DEVICE_ATTR_2_RW(in10_max, max16065_limit, 0, 10);
  static SENSOR_DEVICE_ATTR_2_RW(in11_max, max16065_limit, 0, 11);
f5bae2642   Guenter Roeck   hwmon: Driver for...
325
326
  
  /* alarms */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
327
328
329
330
331
332
333
334
335
336
337
338
  static SENSOR_DEVICE_ATTR_2_RO(in0_alarm, max16065_alarm, 0, 0);
  static SENSOR_DEVICE_ATTR_2_RO(in1_alarm, max16065_alarm, 0, 1);
  static SENSOR_DEVICE_ATTR_2_RO(in2_alarm, max16065_alarm, 0, 2);
  static SENSOR_DEVICE_ATTR_2_RO(in3_alarm, max16065_alarm, 0, 3);
  static SENSOR_DEVICE_ATTR_2_RO(in4_alarm, max16065_alarm, 0, 4);
  static SENSOR_DEVICE_ATTR_2_RO(in5_alarm, max16065_alarm, 0, 5);
  static SENSOR_DEVICE_ATTR_2_RO(in6_alarm, max16065_alarm, 0, 6);
  static SENSOR_DEVICE_ATTR_2_RO(in7_alarm, max16065_alarm, 0, 7);
  static SENSOR_DEVICE_ATTR_2_RO(in8_alarm, max16065_alarm, 1, 0);
  static SENSOR_DEVICE_ATTR_2_RO(in9_alarm, max16065_alarm, 1, 1);
  static SENSOR_DEVICE_ATTR_2_RO(in10_alarm, max16065_alarm, 1, 2);
  static SENSOR_DEVICE_ATTR_2_RO(in11_alarm, max16065_alarm, 1, 3);
f5bae2642   Guenter Roeck   hwmon: Driver for...
339
340
  
  /* Current and alarm */
9d6c12557   Guenter Roeck   hwmon: (max16065)...
341
342
  static SENSOR_DEVICE_ATTR_RO(curr1_input, max16065_current, 0);
  static SENSOR_DEVICE_ATTR_2_RO(curr1_alarm, max16065_alarm, 1, 4);
f5bae2642   Guenter Roeck   hwmon: Driver for...
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
  
  /*
   * Finally, construct an array of pointers to members of the above objects,
   * as required for sysfs_create_group()
   */
  static struct attribute *max16065_basic_attributes[] = {
  	&sensor_dev_attr_in0_input.dev_attr.attr,
  	&sensor_dev_attr_in0_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in0_crit.dev_attr.attr,
  	&sensor_dev_attr_in0_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in1_input.dev_attr.attr,
  	&sensor_dev_attr_in1_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in1_crit.dev_attr.attr,
  	&sensor_dev_attr_in1_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in2_input.dev_attr.attr,
  	&sensor_dev_attr_in2_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in2_crit.dev_attr.attr,
  	&sensor_dev_attr_in2_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in3_input.dev_attr.attr,
  	&sensor_dev_attr_in3_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in3_crit.dev_attr.attr,
  	&sensor_dev_attr_in3_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in4_input.dev_attr.attr,
  	&sensor_dev_attr_in4_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in4_crit.dev_attr.attr,
  	&sensor_dev_attr_in4_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in5_input.dev_attr.attr,
  	&sensor_dev_attr_in5_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in5_crit.dev_attr.attr,
  	&sensor_dev_attr_in5_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in6_input.dev_attr.attr,
  	&sensor_dev_attr_in6_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in6_crit.dev_attr.attr,
  	&sensor_dev_attr_in6_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in7_input.dev_attr.attr,
  	&sensor_dev_attr_in7_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in7_crit.dev_attr.attr,
  	&sensor_dev_attr_in7_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in8_input.dev_attr.attr,
  	&sensor_dev_attr_in8_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in8_crit.dev_attr.attr,
  	&sensor_dev_attr_in8_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in9_input.dev_attr.attr,
  	&sensor_dev_attr_in9_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in9_crit.dev_attr.attr,
  	&sensor_dev_attr_in9_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in10_input.dev_attr.attr,
  	&sensor_dev_attr_in10_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in10_crit.dev_attr.attr,
  	&sensor_dev_attr_in10_alarm.dev_attr.attr,
  
  	&sensor_dev_attr_in11_input.dev_attr.attr,
  	&sensor_dev_attr_in11_lcrit.dev_attr.attr,
  	&sensor_dev_attr_in11_crit.dev_attr.attr,
  	&sensor_dev_attr_in11_alarm.dev_attr.attr,
  
  	NULL
  };
  
  static struct attribute *max16065_current_attributes[] = {
  	&sensor_dev_attr_in12_input.dev_attr.attr,
  	&sensor_dev_attr_curr1_input.dev_attr.attr,
  	&sensor_dev_attr_curr1_alarm.dev_attr.attr,
  	NULL
  };
  
  static struct attribute *max16065_min_attributes[] = {
  	&sensor_dev_attr_in0_min.dev_attr.attr,
  	&sensor_dev_attr_in1_min.dev_attr.attr,
  	&sensor_dev_attr_in2_min.dev_attr.attr,
  	&sensor_dev_attr_in3_min.dev_attr.attr,
  	&sensor_dev_attr_in4_min.dev_attr.attr,
  	&sensor_dev_attr_in5_min.dev_attr.attr,
  	&sensor_dev_attr_in6_min.dev_attr.attr,
  	&sensor_dev_attr_in7_min.dev_attr.attr,
  	&sensor_dev_attr_in8_min.dev_attr.attr,
  	&sensor_dev_attr_in9_min.dev_attr.attr,
  	&sensor_dev_attr_in10_min.dev_attr.attr,
  	&sensor_dev_attr_in11_min.dev_attr.attr,
  	NULL
  };
  
  static struct attribute *max16065_max_attributes[] = {
  	&sensor_dev_attr_in0_max.dev_attr.attr,
  	&sensor_dev_attr_in1_max.dev_attr.attr,
  	&sensor_dev_attr_in2_max.dev_attr.attr,
  	&sensor_dev_attr_in3_max.dev_attr.attr,
  	&sensor_dev_attr_in4_max.dev_attr.attr,
  	&sensor_dev_attr_in5_max.dev_attr.attr,
  	&sensor_dev_attr_in6_max.dev_attr.attr,
  	&sensor_dev_attr_in7_max.dev_attr.attr,
  	&sensor_dev_attr_in8_max.dev_attr.attr,
  	&sensor_dev_attr_in9_max.dev_attr.attr,
  	&sensor_dev_attr_in10_max.dev_attr.attr,
  	&sensor_dev_attr_in11_max.dev_attr.attr,
  	NULL
  };
38c75dc36   Guenter Roeck   hwmon: (max16065)...
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
  static umode_t max16065_basic_is_visible(struct kobject *kobj,
  					 struct attribute *a, int n)
  {
  	struct device *dev = container_of(kobj, struct device, kobj);
  	struct max16065_data *data = dev_get_drvdata(dev);
  	int index = n / 4;
  
  	if (index >= data->num_adc || !data->range[index])
  		return 0;
  	return a->mode;
  }
  
  static umode_t max16065_secondary_is_visible(struct kobject *kobj,
  					     struct attribute *a, int index)
  {
  	struct device *dev = container_of(kobj, struct device, kobj);
  	struct max16065_data *data = dev_get_drvdata(dev);
  
  	if (index >= data->num_adc)
  		return 0;
  	return a->mode;
  }
f5bae2642   Guenter Roeck   hwmon: Driver for...
472
473
  static const struct attribute_group max16065_basic_group = {
  	.attrs = max16065_basic_attributes,
38c75dc36   Guenter Roeck   hwmon: (max16065)...
474
  	.is_visible = max16065_basic_is_visible,
f5bae2642   Guenter Roeck   hwmon: Driver for...
475
476
477
478
479
480
481
482
  };
  
  static const struct attribute_group max16065_current_group = {
  	.attrs = max16065_current_attributes,
  };
  
  static const struct attribute_group max16065_min_group = {
  	.attrs = max16065_min_attributes,
38c75dc36   Guenter Roeck   hwmon: (max16065)...
483
  	.is_visible = max16065_secondary_is_visible,
f5bae2642   Guenter Roeck   hwmon: Driver for...
484
485
486
487
  };
  
  static const struct attribute_group max16065_max_group = {
  	.attrs = max16065_max_attributes,
38c75dc36   Guenter Roeck   hwmon: (max16065)...
488
  	.is_visible = max16065_secondary_is_visible,
f5bae2642   Guenter Roeck   hwmon: Driver for...
489
  };
674870385   Stephen Kitt   hwmon: use simple...
490
491
492
  static const struct i2c_device_id max16065_id[];
  
  static int max16065_probe(struct i2c_client *client)
f5bae2642   Guenter Roeck   hwmon: Driver for...
493
494
495
  {
  	struct i2c_adapter *adapter = client->adapter;
  	struct max16065_data *data;
38c75dc36   Guenter Roeck   hwmon: (max16065)...
496
497
498
  	struct device *dev = &client->dev;
  	struct device *hwmon_dev;
  	int i, j, val;
f5bae2642   Guenter Roeck   hwmon: Driver for...
499
500
  	bool have_secondary;		/* true if chip has secondary limits */
  	bool secondary_is_max = false;	/* secondary limits reflect max */
38c75dc36   Guenter Roeck   hwmon: (max16065)...
501
  	int groups = 0;
674870385   Stephen Kitt   hwmon: use simple...
502
  	const struct i2c_device_id *id = i2c_match_id(max16065_id, client);
f5bae2642   Guenter Roeck   hwmon: Driver for...
503
504
505
506
  
  	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
  				     | I2C_FUNC_SMBUS_READ_WORD_DATA))
  		return -ENODEV;
38c75dc36   Guenter Roeck   hwmon: (max16065)...
507
  	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
f5bae2642   Guenter Roeck   hwmon: Driver for...
508
509
  	if (unlikely(!data))
  		return -ENOMEM;
38c75dc36   Guenter Roeck   hwmon: (max16065)...
510
  	data->client = client;
f5bae2642   Guenter Roeck   hwmon: Driver for...
511
512
513
514
515
516
517
518
  	mutex_init(&data->update_lock);
  
  	data->num_adc = max16065_num_adc[id->driver_data];
  	data->have_current = max16065_have_current[id->driver_data];
  	have_secondary = max16065_have_secondary[id->driver_data];
  
  	if (have_secondary) {
  		val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE);
918ddef35   Guenter Roeck   hwmon: (max16065)...
519
520
  		if (unlikely(val < 0))
  			return val;
f5bae2642   Guenter Roeck   hwmon: Driver for...
521
522
523
524
525
526
  		secondary_is_max = val & MAX16065_WARNING_OV;
  	}
  
  	/* Read scale registers, convert to range */
  	for (i = 0; i < DIV_ROUND_UP(data->num_adc, 4); i++) {
  		val = i2c_smbus_read_byte_data(client, MAX16065_SCALE(i));
918ddef35   Guenter Roeck   hwmon: (max16065)...
527
528
  		if (unlikely(val < 0))
  			return val;
f5bae2642   Guenter Roeck   hwmon: Driver for...
529
530
531
532
533
534
535
536
537
538
539
540
541
542
  		for (j = 0; j < 4 && i * 4 + j < data->num_adc; j++) {
  			data->range[i * 4 + j] =
  			  max16065_adc_range[(val >> (j * 2)) & 0x3];
  		}
  	}
  
  	/* Read limits */
  	for (i = 0; i < MAX16065_NUM_LIMIT; i++) {
  		if (i == 0 && !have_secondary)
  			continue;
  
  		for (j = 0; j < data->num_adc; j++) {
  			val = i2c_smbus_read_byte_data(client,
  						       MAX16065_LIMIT(i, j));
918ddef35   Guenter Roeck   hwmon: (max16065)...
543
544
  			if (unlikely(val < 0))
  				return val;
f5bae2642   Guenter Roeck   hwmon: Driver for...
545
546
547
  			data->limit[i][j] = LIMIT_TO_MV(val, data->range[j]);
  		}
  	}
38c75dc36   Guenter Roeck   hwmon: (max16065)...
548
549
550
551
552
  	/* sysfs hooks */
  	data->groups[groups++] = &max16065_basic_group;
  	if (have_secondary)
  		data->groups[groups++] = secondary_is_max ?
  			&max16065_max_group : &max16065_min_group;
f5bae2642   Guenter Roeck   hwmon: Driver for...
553
554
555
  
  	if (data->have_current) {
  		val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL);
38c75dc36   Guenter Roeck   hwmon: (max16065)...
556
557
  		if (unlikely(val < 0))
  			return val;
f5bae2642   Guenter Roeck   hwmon: Driver for...
558
559
560
561
562
563
564
565
  		if (val & MAX16065_CURR_ENABLE) {
  			/*
  			 * Current gain is 6, 12, 24, 48 based on values in
  			 * bit 2,3.
  			 */
  			data->curr_gain = 6 << ((val >> 2) & 0x03);
  			data->range[MAX16065_NUM_ADC]
  			  = max16065_csp_adc_range[(val >> 1) & 0x01];
38c75dc36   Guenter Roeck   hwmon: (max16065)...
566
  			data->groups[groups++] = &max16065_current_group;
f5bae2642   Guenter Roeck   hwmon: Driver for...
567
568
569
570
  		} else {
  			data->have_current = false;
  		}
  	}
38c75dc36   Guenter Roeck   hwmon: (max16065)...
571
572
  	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
  							   data, data->groups);
a7b30ea50   Axel Lin   hwmon: (max16065)...
573
  	return PTR_ERR_OR_ZERO(hwmon_dev);
f5bae2642   Guenter Roeck   hwmon: Driver for...
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  }
  
  static const struct i2c_device_id max16065_id[] = {
  	{ "max16065", max16065 },
  	{ "max16066", max16066 },
  	{ "max16067", max16067 },
  	{ "max16068", max16068 },
  	{ "max16070", max16070 },
  	{ "max16071", max16071 },
  	{ }
  };
  
  MODULE_DEVICE_TABLE(i2c, max16065_id);
  
  /* This is the driver that will be inserted */
  static struct i2c_driver max16065_driver = {
  	.driver = {
  		.name = "max16065",
  	},
674870385   Stephen Kitt   hwmon: use simple...
593
  	.probe_new = max16065_probe,
f5bae2642   Guenter Roeck   hwmon: Driver for...
594
595
  	.id_table = max16065_id,
  };
f0967eea8   Axel Lin   hwmon: convert dr...
596
  module_i2c_driver(max16065_driver);
f5bae2642   Guenter Roeck   hwmon: Driver for...
597

bb9a80e57   Guenter Roeck   hwmon: Update my ...
598
  MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
f5bae2642   Guenter Roeck   hwmon: Driver for...
599
600
  MODULE_DESCRIPTION("MAX16065 driver");
  MODULE_LICENSE("GPL");