blob: c77644d45a026b2f52b9672ac1a925d225acb22d [file] [log] [blame]
George Josephd58de032010-03-05 22:17:25 +01001/*
2 * asc7621.c - Part of lm_sensors, Linux kernel modules for hardware monitoring
3 * Copyright (c) 2007, 2010 George Joseph <george.joseph@fairview5.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/slab.h>
23#include <linux/jiffies.h>
24#include <linux/i2c.h>
25#include <linux/hwmon.h>
26#include <linux/hwmon-sysfs.h>
27#include <linux/err.h>
28#include <linux/mutex.h>
29
30/* Addresses to scan */
Jean Delvare918ee912010-10-28 20:31:50 +020031static const unsigned short normal_i2c[] = {
George Josephd58de032010-03-05 22:17:25 +010032 0x2c, 0x2d, 0x2e, I2C_CLIENT_END
33};
34
35enum asc7621_type {
36 asc7621,
37 asc7621a
38};
39
40#define INTERVAL_HIGH (HZ + HZ / 2)
41#define INTERVAL_LOW (1 * 60 * HZ)
42#define PRI_NONE 0
43#define PRI_LOW 1
44#define PRI_HIGH 2
45#define FIRST_CHIP asc7621
46#define LAST_CHIP asc7621a
47
48struct asc7621_chip {
49 char *name;
50 enum asc7621_type chip_type;
51 u8 company_reg;
52 u8 company_id;
53 u8 verstep_reg;
54 u8 verstep_id;
Jean Delvare918ee912010-10-28 20:31:50 +020055 const unsigned short *addresses;
George Josephd58de032010-03-05 22:17:25 +010056};
57
58static struct asc7621_chip asc7621_chips[] = {
59 {
60 .name = "asc7621",
61 .chip_type = asc7621,
62 .company_reg = 0x3e,
63 .company_id = 0x61,
64 .verstep_reg = 0x3f,
65 .verstep_id = 0x6c,
66 .addresses = normal_i2c,
67 },
68 {
69 .name = "asc7621a",
70 .chip_type = asc7621a,
71 .company_reg = 0x3e,
72 .company_id = 0x61,
73 .verstep_reg = 0x3f,
74 .verstep_id = 0x6d,
75 .addresses = normal_i2c,
76 },
77};
78
79/*
80 * Defines the highest register to be used, not the count.
81 * The actual count will probably be smaller because of gaps
82 * in the implementation (unused register locations).
83 * This define will safely set the array size of both the parameter
84 * and data arrays.
85 * This comes from the data sheet register description table.
86 */
87#define LAST_REGISTER 0xff
88
89struct asc7621_data {
90 struct i2c_client client;
91 struct device *class_dev;
92 struct mutex update_lock;
93 int valid; /* !=0 if following fields are valid */
94 unsigned long last_high_reading; /* In jiffies */
95 unsigned long last_low_reading; /* In jiffies */
96 /*
97 * Registers we care about occupy the corresponding index
98 * in the array. Registers we don't care about are left
99 * at 0.
100 */
101 u8 reg[LAST_REGISTER + 1];
102};
103
104/*
105 * Macro to get the parent asc7621_param structure
106 * from a sensor_device_attribute passed into the
107 * show/store functions.
108 */
109#define to_asc7621_param(_sda) \
110 container_of(_sda, struct asc7621_param, sda)
111
112/*
113 * Each parameter to be retrieved needs an asc7621_param structure
114 * allocated. It contains the sensor_device_attribute structure
115 * and the control info needed to retrieve the value from the register map.
116 */
117struct asc7621_param {
118 struct sensor_device_attribute sda;
119 u8 priority;
120 u8 msb[3];
121 u8 lsb[3];
122 u8 mask[3];
123 u8 shift[3];
124};
125
126/*
127 * This is the map that ultimately indicates whether we'll be
128 * retrieving a register value or not, and at what frequency.
129 */
130static u8 asc7621_register_priorities[255];
131
132static struct asc7621_data *asc7621_update_device(struct device *dev);
133
134static inline u8 read_byte(struct i2c_client *client, u8 reg)
135{
136 int res = i2c_smbus_read_byte_data(client, reg);
137 if (res < 0) {
138 dev_err(&client->dev,
139 "Unable to read from register 0x%02x.\n", reg);
140 return 0;
Guenter Roecka0393712013-03-29 13:54:50 -0700141 }
George Josephd58de032010-03-05 22:17:25 +0100142 return res & 0xff;
143}
144
145static inline int write_byte(struct i2c_client *client, u8 reg, u8 data)
146{
147 int res = i2c_smbus_write_byte_data(client, reg, data);
148 if (res < 0) {
149 dev_err(&client->dev,
150 "Unable to write value 0x%02x to register 0x%02x.\n",
151 data, reg);
Guenter Roecka0393712013-03-29 13:54:50 -0700152 }
George Josephd58de032010-03-05 22:17:25 +0100153 return res;
154}
155
156/*
157 * Data Handlers
158 * Each function handles the formatting, storage
159 * and retrieval of like parameters.
160 */
161
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700162#define SETUP_SHOW_DATA_PARAM(d, a) \
George Josephd58de032010-03-05 22:17:25 +0100163 struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
164 struct asc7621_data *data = asc7621_update_device(d); \
165 struct asc7621_param *param = to_asc7621_param(sda)
166
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700167#define SETUP_STORE_DATA_PARAM(d, a) \
George Josephd58de032010-03-05 22:17:25 +0100168 struct sensor_device_attribute *sda = to_sensor_dev_attr(a); \
169 struct i2c_client *client = to_i2c_client(d); \
170 struct asc7621_data *data = i2c_get_clientdata(client); \
171 struct asc7621_param *param = to_asc7621_param(sda)
172
173/*
174 * u8 is just what it sounds like...an unsigned byte with no
175 * special formatting.
176 */
177static ssize_t show_u8(struct device *dev, struct device_attribute *attr,
178 char *buf)
179{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700180 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100181
182 return sprintf(buf, "%u\n", data->reg[param->msb[0]]);
183}
184
185static ssize_t store_u8(struct device *dev, struct device_attribute *attr,
186 const char *buf, size_t count)
187{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700188 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100189 long reqval;
190
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100191 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100192 return -EINVAL;
193
Guenter Roeck2a844c12013-01-09 08:09:34 -0800194 reqval = clamp_val(reqval, 0, 255);
George Josephd58de032010-03-05 22:17:25 +0100195
196 mutex_lock(&data->update_lock);
197 data->reg[param->msb[0]] = reqval;
198 write_byte(client, param->msb[0], reqval);
199 mutex_unlock(&data->update_lock);
200 return count;
201}
202
203/*
204 * Many of the config values occupy only a few bits of a register.
205 */
206static ssize_t show_bitmask(struct device *dev,
207 struct device_attribute *attr, char *buf)
208{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700209 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100210
211 return sprintf(buf, "%u\n",
212 (data->reg[param->msb[0]] >> param->
213 shift[0]) & param->mask[0]);
214}
215
216static ssize_t store_bitmask(struct device *dev,
217 struct device_attribute *attr,
218 const char *buf, size_t count)
219{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700220 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100221 long reqval;
222 u8 currval;
223
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100224 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100225 return -EINVAL;
226
Guenter Roeck2a844c12013-01-09 08:09:34 -0800227 reqval = clamp_val(reqval, 0, param->mask[0]);
George Josephd58de032010-03-05 22:17:25 +0100228
229 reqval = (reqval & param->mask[0]) << param->shift[0];
230
231 mutex_lock(&data->update_lock);
232 currval = read_byte(client, param->msb[0]);
233 reqval |= (currval & ~(param->mask[0] << param->shift[0]));
234 data->reg[param->msb[0]] = reqval;
235 write_byte(client, param->msb[0], reqval);
236 mutex_unlock(&data->update_lock);
237 return count;
238}
239
240/*
241 * 16 bit fan rpm values
242 * reported by the device as the number of 11.111us periods (90khz)
243 * between full fan rotations. Therefore...
244 * RPM = (90000 * 60) / register value
245 */
246static ssize_t show_fan16(struct device *dev,
247 struct device_attribute *attr, char *buf)
248{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700249 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100250 u16 regval;
251
252 mutex_lock(&data->update_lock);
253 regval = (data->reg[param->msb[0]] << 8) | data->reg[param->lsb[0]];
254 mutex_unlock(&data->update_lock);
255
256 return sprintf(buf, "%u\n",
257 (regval == 0 ? -1 : (regval) ==
258 0xffff ? 0 : 5400000 / regval));
259}
260
261static ssize_t store_fan16(struct device *dev,
262 struct device_attribute *attr, const char *buf,
263 size_t count)
264{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700265 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100266 long reqval;
267
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100268 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100269 return -EINVAL;
270
Guenter Roeck3c56b062012-01-19 11:02:16 -0800271 /*
272 * If a minimum RPM of zero is requested, then we set the register to
273 * 0xffff. This value allows the fan to be stopped completely without
274 * generating an alarm.
275 */
George Josephd58de032010-03-05 22:17:25 +0100276 reqval =
Guenter Roeck2a844c12013-01-09 08:09:34 -0800277 (reqval <= 0 ? 0xffff : clamp_val(5400000 / reqval, 0, 0xfffe));
George Josephd58de032010-03-05 22:17:25 +0100278
279 mutex_lock(&data->update_lock);
280 data->reg[param->msb[0]] = (reqval >> 8) & 0xff;
281 data->reg[param->lsb[0]] = reqval & 0xff;
282 write_byte(client, param->msb[0], data->reg[param->msb[0]]);
283 write_byte(client, param->lsb[0], data->reg[param->lsb[0]]);
284 mutex_unlock(&data->update_lock);
285
286 return count;
287}
288
289/*
290 * Voltages are scaled in the device so that the nominal voltage
291 * is 3/4ths of the 0-255 range (i.e. 192).
292 * If all voltages are 'normal' then all voltage registers will
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200293 * read 0xC0.
294 *
295 * The data sheet provides us with the 3/4 scale value for each voltage
George Josephd58de032010-03-05 22:17:25 +0100296 * which is stored in in_scaling. The sda->index parameter value provides
297 * the index into in_scaling.
298 *
299 * NOTE: The chip expects the first 2 inputs be 2.5 and 2.25 volts
300 * respectively. That doesn't mean that's what the motherboard provides. :)
301 */
302
Axel Lin7a7176a2014-07-15 19:15:01 +0800303static const int asc7621_in_scaling[] = {
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200304 2500, 2250, 3300, 5000, 12000
George Josephd58de032010-03-05 22:17:25 +0100305};
306
307static ssize_t show_in10(struct device *dev, struct device_attribute *attr,
308 char *buf)
309{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700310 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100311 u16 regval;
312 u8 nr = sda->index;
313
314 mutex_lock(&data->update_lock);
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200315 regval = (data->reg[param->msb[0]] << 8) | (data->reg[param->lsb[0]]);
George Josephd58de032010-03-05 22:17:25 +0100316 mutex_unlock(&data->update_lock);
317
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200318 /* The LSB value is a 2-bit scaling of the MSB's LSbit value. */
319 regval = (regval >> 6) * asc7621_in_scaling[nr] / (0xc0 << 2);
320
George Josephd58de032010-03-05 22:17:25 +0100321 return sprintf(buf, "%u\n", regval);
322}
323
324/* 8 bit voltage values (the mins and maxs) */
325static ssize_t show_in8(struct device *dev, struct device_attribute *attr,
326 char *buf)
327{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700328 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100329 u8 nr = sda->index;
330
331 return sprintf(buf, "%u\n",
332 ((data->reg[param->msb[0]] *
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200333 asc7621_in_scaling[nr]) / 0xc0));
George Josephd58de032010-03-05 22:17:25 +0100334}
335
336static ssize_t store_in8(struct device *dev, struct device_attribute *attr,
337 const char *buf, size_t count)
338{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700339 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100340 long reqval;
341 u8 nr = sda->index;
342
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100343 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100344 return -EINVAL;
345
Guenter Roeck2a844c12013-01-09 08:09:34 -0800346 reqval = clamp_val(reqval, 0, 0xffff);
George Josephd58de032010-03-05 22:17:25 +0100347
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200348 reqval = reqval * 0xc0 / asc7621_in_scaling[nr];
349
Guenter Roeck2a844c12013-01-09 08:09:34 -0800350 reqval = clamp_val(reqval, 0, 0xff);
George Josephd58de032010-03-05 22:17:25 +0100351
352 mutex_lock(&data->update_lock);
353 data->reg[param->msb[0]] = reqval;
354 write_byte(client, param->msb[0], reqval);
355 mutex_unlock(&data->update_lock);
356
357 return count;
358}
359
360static ssize_t show_temp8(struct device *dev,
361 struct device_attribute *attr, char *buf)
362{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700363 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100364
365 return sprintf(buf, "%d\n", ((s8) data->reg[param->msb[0]]) * 1000);
366}
367
368static ssize_t store_temp8(struct device *dev,
369 struct device_attribute *attr, const char *buf,
370 size_t count)
371{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700372 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100373 long reqval;
374 s8 temp;
375
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100376 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100377 return -EINVAL;
378
Guenter Roeck2a844c12013-01-09 08:09:34 -0800379 reqval = clamp_val(reqval, -127000, 127000);
George Josephd58de032010-03-05 22:17:25 +0100380
381 temp = reqval / 1000;
382
383 mutex_lock(&data->update_lock);
384 data->reg[param->msb[0]] = temp;
385 write_byte(client, param->msb[0], temp);
386 mutex_unlock(&data->update_lock);
387 return count;
388}
389
390/*
391 * Temperatures that occupy 2 bytes always have the whole
392 * number of degrees in the MSB with some part of the LSB
393 * indicating fractional degrees.
394 */
395
396/* mmmmmmmm.llxxxxxx */
397static ssize_t show_temp10(struct device *dev,
398 struct device_attribute *attr, char *buf)
399{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700400 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100401 u8 msb, lsb;
402 int temp;
403
404 mutex_lock(&data->update_lock);
405 msb = data->reg[param->msb[0]];
406 lsb = (data->reg[param->lsb[0]] >> 6) & 0x03;
407 temp = (((s8) msb) * 1000) + (lsb * 250);
408 mutex_unlock(&data->update_lock);
409
410 return sprintf(buf, "%d\n", temp);
411}
412
413/* mmmmmm.ll */
414static ssize_t show_temp62(struct device *dev,
415 struct device_attribute *attr, char *buf)
416{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700417 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100418 u8 regval = data->reg[param->msb[0]];
419 int temp = ((s8) (regval & 0xfc) * 1000) + ((regval & 0x03) * 250);
420
421 return sprintf(buf, "%d\n", temp);
422}
423
424static ssize_t store_temp62(struct device *dev,
425 struct device_attribute *attr, const char *buf,
426 size_t count)
427{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700428 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100429 long reqval, i, f;
430 s8 temp;
431
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100432 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100433 return -EINVAL;
434
Guenter Roeck2a844c12013-01-09 08:09:34 -0800435 reqval = clamp_val(reqval, -32000, 31750);
George Josephd58de032010-03-05 22:17:25 +0100436 i = reqval / 1000;
437 f = reqval - (i * 1000);
438 temp = i << 2;
439 temp |= f / 250;
440
441 mutex_lock(&data->update_lock);
442 data->reg[param->msb[0]] = temp;
443 write_byte(client, param->msb[0], temp);
444 mutex_unlock(&data->update_lock);
445 return count;
446}
447
448/*
449 * The aSC7621 doesn't provide an "auto_point2". Instead, you
450 * specify the auto_point1 and a range. To keep with the sysfs
451 * hwmon specs, we synthesize the auto_point_2 from them.
452 */
453
Axel Lin7a7176a2014-07-15 19:15:01 +0800454static const u32 asc7621_range_map[] = {
George Josephd58de032010-03-05 22:17:25 +0100455 2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
456 13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
457};
458
459static ssize_t show_ap2_temp(struct device *dev,
460 struct device_attribute *attr, char *buf)
461{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700462 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100463 long auto_point1;
464 u8 regval;
465 int temp;
466
467 mutex_lock(&data->update_lock);
468 auto_point1 = ((s8) data->reg[param->msb[1]]) * 1000;
469 regval =
470 ((data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0]);
Guenter Roeck2a844c12013-01-09 08:09:34 -0800471 temp = auto_point1 + asc7621_range_map[clamp_val(regval, 0, 15)];
George Josephd58de032010-03-05 22:17:25 +0100472 mutex_unlock(&data->update_lock);
473
474 return sprintf(buf, "%d\n", temp);
475
476}
477
478static ssize_t store_ap2_temp(struct device *dev,
479 struct device_attribute *attr,
480 const char *buf, size_t count)
481{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700482 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100483 long reqval, auto_point1;
484 int i;
485 u8 currval, newval = 0;
486
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100487 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100488 return -EINVAL;
489
490 mutex_lock(&data->update_lock);
491 auto_point1 = data->reg[param->msb[1]] * 1000;
Guenter Roeck2a844c12013-01-09 08:09:34 -0800492 reqval = clamp_val(reqval, auto_point1 + 2000, auto_point1 + 80000);
George Josephd58de032010-03-05 22:17:25 +0100493
494 for (i = ARRAY_SIZE(asc7621_range_map) - 1; i >= 0; i--) {
495 if (reqval >= auto_point1 + asc7621_range_map[i]) {
496 newval = i;
497 break;
498 }
499 }
500
501 newval = (newval & param->mask[0]) << param->shift[0];
502 currval = read_byte(client, param->msb[0]);
503 newval |= (currval & ~(param->mask[0] << param->shift[0]));
504 data->reg[param->msb[0]] = newval;
505 write_byte(client, param->msb[0], newval);
506 mutex_unlock(&data->update_lock);
507 return count;
508}
509
510static ssize_t show_pwm_ac(struct device *dev,
511 struct device_attribute *attr, char *buf)
512{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700513 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100514 u8 config, altbit, regval;
Axel Lin7a7176a2014-07-15 19:15:01 +0800515 const u8 map[] = {
George Josephd58de032010-03-05 22:17:25 +0100516 0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
517 0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
518 };
519
520 mutex_lock(&data->update_lock);
521 config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
522 altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
523 regval = config | (altbit << 3);
524 mutex_unlock(&data->update_lock);
525
Guenter Roeck2a844c12013-01-09 08:09:34 -0800526 return sprintf(buf, "%u\n", map[clamp_val(regval, 0, 15)]);
George Josephd58de032010-03-05 22:17:25 +0100527}
528
529static ssize_t store_pwm_ac(struct device *dev,
530 struct device_attribute *attr,
531 const char *buf, size_t count)
532{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700533 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100534 unsigned long reqval;
535 u8 currval, config, altbit, newval;
Axel Lin7a7176a2014-07-15 19:15:01 +0800536 const u16 map[] = {
George Josephd58de032010-03-05 22:17:25 +0100537 0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
538 0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
539 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
540 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
541 };
542
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100543 if (kstrtoul(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100544 return -EINVAL;
545
546 if (reqval > 31)
547 return -EINVAL;
548
549 reqval = map[reqval];
550 if (reqval == 0xff)
551 return -EINVAL;
552
553 config = reqval & 0x07;
554 altbit = (reqval >> 3) & 0x01;
555
556 config = (config & param->mask[0]) << param->shift[0];
557 altbit = (altbit & param->mask[1]) << param->shift[1];
558
559 mutex_lock(&data->update_lock);
560 currval = read_byte(client, param->msb[0]);
561 newval = config | (currval & ~(param->mask[0] << param->shift[0]));
562 newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
563 data->reg[param->msb[0]] = newval;
564 write_byte(client, param->msb[0], newval);
565 mutex_unlock(&data->update_lock);
566 return count;
567}
568
569static ssize_t show_pwm_enable(struct device *dev,
570 struct device_attribute *attr, char *buf)
571{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700572 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100573 u8 config, altbit, minoff, val, newval;
574
575 mutex_lock(&data->update_lock);
576 config = (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
577 altbit = (data->reg[param->msb[1]] >> param->shift[1]) & param->mask[1];
578 minoff = (data->reg[param->msb[2]] >> param->shift[2]) & param->mask[2];
579 mutex_unlock(&data->update_lock);
580
581 val = config | (altbit << 3);
582 newval = 0;
583
584 if (val == 3 || val >= 10)
585 newval = 255;
586 else if (val == 4)
587 newval = 0;
588 else if (val == 7)
589 newval = 1;
590 else if (minoff == 1)
591 newval = 2;
592 else
593 newval = 3;
594
595 return sprintf(buf, "%u\n", newval);
596}
597
598static ssize_t store_pwm_enable(struct device *dev,
599 struct device_attribute *attr,
600 const char *buf, size_t count)
601{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700602 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100603 long reqval;
604 u8 currval, config, altbit, newval, minoff = 255;
605
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100606 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100607 return -EINVAL;
608
609 switch (reqval) {
610 case 0:
611 newval = 0x04;
612 break;
613 case 1:
614 newval = 0x07;
615 break;
616 case 2:
617 newval = 0x00;
618 minoff = 1;
619 break;
620 case 3:
621 newval = 0x00;
622 minoff = 0;
623 break;
624 case 255:
625 newval = 0x03;
626 break;
627 default:
628 return -EINVAL;
629 }
630
631 config = newval & 0x07;
632 altbit = (newval >> 3) & 0x01;
633
634 mutex_lock(&data->update_lock);
635 config = (config & param->mask[0]) << param->shift[0];
636 altbit = (altbit & param->mask[1]) << param->shift[1];
637 currval = read_byte(client, param->msb[0]);
638 newval = config | (currval & ~(param->mask[0] << param->shift[0]));
639 newval = altbit | (newval & ~(param->mask[1] << param->shift[1]));
640 data->reg[param->msb[0]] = newval;
641 write_byte(client, param->msb[0], newval);
642 if (minoff < 255) {
643 minoff = (minoff & param->mask[2]) << param->shift[2];
644 currval = read_byte(client, param->msb[2]);
645 newval =
646 minoff | (currval & ~(param->mask[2] << param->shift[2]));
647 data->reg[param->msb[2]] = newval;
648 write_byte(client, param->msb[2], newval);
649 }
650 mutex_unlock(&data->update_lock);
651 return count;
652}
653
Axel Lin7a7176a2014-07-15 19:15:01 +0800654static const u32 asc7621_pwm_freq_map[] = {
George Josephd58de032010-03-05 22:17:25 +0100655 10, 15, 23, 30, 38, 47, 62, 94,
656 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
657};
658
659static ssize_t show_pwm_freq(struct device *dev,
660 struct device_attribute *attr, char *buf)
661{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700662 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100663 u8 regval =
664 (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
665
Guenter Roeck2a844c12013-01-09 08:09:34 -0800666 regval = clamp_val(regval, 0, 15);
George Josephd58de032010-03-05 22:17:25 +0100667
668 return sprintf(buf, "%u\n", asc7621_pwm_freq_map[regval]);
669}
670
671static ssize_t store_pwm_freq(struct device *dev,
672 struct device_attribute *attr,
673 const char *buf, size_t count)
674{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700675 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100676 unsigned long reqval;
677 u8 currval, newval = 255;
678 int i;
679
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100680 if (kstrtoul(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100681 return -EINVAL;
682
683 for (i = 0; i < ARRAY_SIZE(asc7621_pwm_freq_map); i++) {
684 if (reqval == asc7621_pwm_freq_map[i]) {
685 newval = i;
686 break;
687 }
688 }
689 if (newval == 255)
690 return -EINVAL;
691
692 newval = (newval & param->mask[0]) << param->shift[0];
693
694 mutex_lock(&data->update_lock);
695 currval = read_byte(client, param->msb[0]);
696 newval |= (currval & ~(param->mask[0] << param->shift[0]));
697 data->reg[param->msb[0]] = newval;
698 write_byte(client, param->msb[0], newval);
699 mutex_unlock(&data->update_lock);
700 return count;
701}
702
Axel Lin7a7176a2014-07-15 19:15:01 +0800703static const u32 asc7621_pwm_auto_spinup_map[] = {
George Josephd58de032010-03-05 22:17:25 +0100704 0, 100, 250, 400, 700, 1000, 2000, 4000
705};
706
707static ssize_t show_pwm_ast(struct device *dev,
708 struct device_attribute *attr, char *buf)
709{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700710 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100711 u8 regval =
712 (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
713
Guenter Roeck2a844c12013-01-09 08:09:34 -0800714 regval = clamp_val(regval, 0, 7);
George Josephd58de032010-03-05 22:17:25 +0100715
716 return sprintf(buf, "%u\n", asc7621_pwm_auto_spinup_map[regval]);
717
718}
719
720static ssize_t store_pwm_ast(struct device *dev,
721 struct device_attribute *attr,
722 const char *buf, size_t count)
723{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700724 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100725 long reqval;
726 u8 currval, newval = 255;
727 u32 i;
728
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100729 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100730 return -EINVAL;
731
732 for (i = 0; i < ARRAY_SIZE(asc7621_pwm_auto_spinup_map); i++) {
733 if (reqval == asc7621_pwm_auto_spinup_map[i]) {
734 newval = i;
735 break;
736 }
737 }
738 if (newval == 255)
739 return -EINVAL;
740
741 newval = (newval & param->mask[0]) << param->shift[0];
742
743 mutex_lock(&data->update_lock);
744 currval = read_byte(client, param->msb[0]);
745 newval |= (currval & ~(param->mask[0] << param->shift[0]));
746 data->reg[param->msb[0]] = newval;
747 write_byte(client, param->msb[0], newval);
748 mutex_unlock(&data->update_lock);
749 return count;
750}
751
Axel Lin7a7176a2014-07-15 19:15:01 +0800752static const u32 asc7621_temp_smoothing_time_map[] = {
George Josephd58de032010-03-05 22:17:25 +0100753 35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
754};
755
756static ssize_t show_temp_st(struct device *dev,
757 struct device_attribute *attr, char *buf)
758{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700759 SETUP_SHOW_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100760 u8 regval =
761 (data->reg[param->msb[0]] >> param->shift[0]) & param->mask[0];
Guenter Roeck2a844c12013-01-09 08:09:34 -0800762 regval = clamp_val(regval, 0, 7);
George Josephd58de032010-03-05 22:17:25 +0100763
764 return sprintf(buf, "%u\n", asc7621_temp_smoothing_time_map[regval]);
765}
766
767static ssize_t store_temp_st(struct device *dev,
768 struct device_attribute *attr,
769 const char *buf, size_t count)
770{
Guenter Roeck088ce2a2013-03-13 16:40:39 -0700771 SETUP_STORE_DATA_PARAM(dev, attr);
George Josephd58de032010-03-05 22:17:25 +0100772 long reqval;
773 u8 currval, newval = 255;
774 u32 i;
775
Frans Meulenbroeks179c4fd2012-01-04 20:58:52 +0100776 if (kstrtol(buf, 10, &reqval))
George Josephd58de032010-03-05 22:17:25 +0100777 return -EINVAL;
778
779 for (i = 0; i < ARRAY_SIZE(asc7621_temp_smoothing_time_map); i++) {
780 if (reqval == asc7621_temp_smoothing_time_map[i]) {
781 newval = i;
782 break;
783 }
784 }
785
786 if (newval == 255)
787 return -EINVAL;
788
789 newval = (newval & param->mask[0]) << param->shift[0];
790
791 mutex_lock(&data->update_lock);
792 currval = read_byte(client, param->msb[0]);
793 newval |= (currval & ~(param->mask[0] << param->shift[0]));
794 data->reg[param->msb[0]] = newval;
795 write_byte(client, param->msb[0], newval);
796 mutex_unlock(&data->update_lock);
797 return count;
798}
799
800/*
801 * End of data handlers
802 *
803 * These defines do nothing more than make the table easier
804 * to read when wrapped at column 80.
805 */
806
807/*
808 * Creates a variable length array inititalizer.
809 * VAA(1,3,5,7) would produce {1,3,5,7}
810 */
811#define VAA(args...) {args}
812
813#define PREAD(name, n, pri, rm, rl, m, s, r) \
814 {.sda = SENSOR_ATTR(name, S_IRUGO, show_##r, NULL, n), \
815 .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
816 .shift[0] = s,}
817
818#define PWRITE(name, n, pri, rm, rl, m, s, r) \
819 {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
820 .priority = pri, .msb[0] = rm, .lsb[0] = rl, .mask[0] = m, \
821 .shift[0] = s,}
822
823/*
824 * PWRITEM assumes that the initializers for the .msb, .lsb, .mask and .shift
825 * were created using the VAA macro.
826 */
827#define PWRITEM(name, n, pri, rm, rl, m, s, r) \
828 {.sda = SENSOR_ATTR(name, S_IRUGO | S_IWUSR, show_##r, store_##r, n), \
829 .priority = pri, .msb = rm, .lsb = rl, .mask = m, .shift = s,}
830
831static struct asc7621_param asc7621_params[] = {
832 PREAD(in0_input, 0, PRI_HIGH, 0x20, 0x13, 0, 0, in10),
833 PREAD(in1_input, 1, PRI_HIGH, 0x21, 0x18, 0, 0, in10),
834 PREAD(in2_input, 2, PRI_HIGH, 0x22, 0x11, 0, 0, in10),
835 PREAD(in3_input, 3, PRI_HIGH, 0x23, 0x12, 0, 0, in10),
836 PREAD(in4_input, 4, PRI_HIGH, 0x24, 0x14, 0, 0, in10),
837
838 PWRITE(in0_min, 0, PRI_LOW, 0x44, 0, 0, 0, in8),
839 PWRITE(in1_min, 1, PRI_LOW, 0x46, 0, 0, 0, in8),
840 PWRITE(in2_min, 2, PRI_LOW, 0x48, 0, 0, 0, in8),
841 PWRITE(in3_min, 3, PRI_LOW, 0x4a, 0, 0, 0, in8),
842 PWRITE(in4_min, 4, PRI_LOW, 0x4c, 0, 0, 0, in8),
843
844 PWRITE(in0_max, 0, PRI_LOW, 0x45, 0, 0, 0, in8),
845 PWRITE(in1_max, 1, PRI_LOW, 0x47, 0, 0, 0, in8),
846 PWRITE(in2_max, 2, PRI_LOW, 0x49, 0, 0, 0, in8),
847 PWRITE(in3_max, 3, PRI_LOW, 0x4b, 0, 0, 0, in8),
848 PWRITE(in4_max, 4, PRI_LOW, 0x4d, 0, 0, 0, in8),
849
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200850 PREAD(in0_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 0, bitmask),
851 PREAD(in1_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 1, bitmask),
852 PREAD(in2_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 2, bitmask),
853 PREAD(in3_alarm, 3, PRI_HIGH, 0x41, 0, 0x01, 3, bitmask),
854 PREAD(in4_alarm, 4, PRI_HIGH, 0x42, 0, 0x01, 0, bitmask),
George Josephd58de032010-03-05 22:17:25 +0100855
856 PREAD(fan1_input, 0, PRI_HIGH, 0x29, 0x28, 0, 0, fan16),
857 PREAD(fan2_input, 1, PRI_HIGH, 0x2b, 0x2a, 0, 0, fan16),
858 PREAD(fan3_input, 2, PRI_HIGH, 0x2d, 0x2c, 0, 0, fan16),
859 PREAD(fan4_input, 3, PRI_HIGH, 0x2f, 0x2e, 0, 0, fan16),
860
861 PWRITE(fan1_min, 0, PRI_LOW, 0x55, 0x54, 0, 0, fan16),
862 PWRITE(fan2_min, 1, PRI_LOW, 0x57, 0x56, 0, 0, fan16),
863 PWRITE(fan3_min, 2, PRI_LOW, 0x59, 0x58, 0, 0, fan16),
864 PWRITE(fan4_min, 3, PRI_LOW, 0x5b, 0x5a, 0, 0, fan16),
865
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200866 PREAD(fan1_alarm, 0, PRI_HIGH, 0x42, 0, 0x01, 2, bitmask),
867 PREAD(fan2_alarm, 1, PRI_HIGH, 0x42, 0, 0x01, 3, bitmask),
868 PREAD(fan3_alarm, 2, PRI_HIGH, 0x42, 0, 0x01, 4, bitmask),
869 PREAD(fan4_alarm, 3, PRI_HIGH, 0x42, 0, 0x01, 5, bitmask),
George Josephd58de032010-03-05 22:17:25 +0100870
871 PREAD(temp1_input, 0, PRI_HIGH, 0x25, 0x10, 0, 0, temp10),
872 PREAD(temp2_input, 1, PRI_HIGH, 0x26, 0x15, 0, 0, temp10),
873 PREAD(temp3_input, 2, PRI_HIGH, 0x27, 0x16, 0, 0, temp10),
874 PREAD(temp4_input, 3, PRI_HIGH, 0x33, 0x17, 0, 0, temp10),
875 PREAD(temp5_input, 4, PRI_HIGH, 0xf7, 0xf6, 0, 0, temp10),
876 PREAD(temp6_input, 5, PRI_HIGH, 0xf9, 0xf8, 0, 0, temp10),
877 PREAD(temp7_input, 6, PRI_HIGH, 0xfb, 0xfa, 0, 0, temp10),
878 PREAD(temp8_input, 7, PRI_HIGH, 0xfd, 0xfc, 0, 0, temp10),
879
880 PWRITE(temp1_min, 0, PRI_LOW, 0x4e, 0, 0, 0, temp8),
881 PWRITE(temp2_min, 1, PRI_LOW, 0x50, 0, 0, 0, temp8),
882 PWRITE(temp3_min, 2, PRI_LOW, 0x52, 0, 0, 0, temp8),
883 PWRITE(temp4_min, 3, PRI_LOW, 0x34, 0, 0, 0, temp8),
884
885 PWRITE(temp1_max, 0, PRI_LOW, 0x4f, 0, 0, 0, temp8),
886 PWRITE(temp2_max, 1, PRI_LOW, 0x51, 0, 0, 0, temp8),
887 PWRITE(temp3_max, 2, PRI_LOW, 0x53, 0, 0, 0, temp8),
888 PWRITE(temp4_max, 3, PRI_LOW, 0x35, 0, 0, 0, temp8),
889
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200890 PREAD(temp1_alarm, 0, PRI_HIGH, 0x41, 0, 0x01, 4, bitmask),
891 PREAD(temp2_alarm, 1, PRI_HIGH, 0x41, 0, 0x01, 5, bitmask),
892 PREAD(temp3_alarm, 2, PRI_HIGH, 0x41, 0, 0x01, 6, bitmask),
893 PREAD(temp4_alarm, 3, PRI_HIGH, 0x43, 0, 0x01, 0, bitmask),
George Josephd58de032010-03-05 22:17:25 +0100894
895 PWRITE(temp1_source, 0, PRI_LOW, 0x02, 0, 0x07, 4, bitmask),
896 PWRITE(temp2_source, 1, PRI_LOW, 0x02, 0, 0x07, 0, bitmask),
897 PWRITE(temp3_source, 2, PRI_LOW, 0x03, 0, 0x07, 4, bitmask),
898 PWRITE(temp4_source, 3, PRI_LOW, 0x03, 0, 0x07, 0, bitmask),
899
900 PWRITE(temp1_smoothing_enable, 0, PRI_LOW, 0x62, 0, 0x01, 3, bitmask),
901 PWRITE(temp2_smoothing_enable, 1, PRI_LOW, 0x63, 0, 0x01, 7, bitmask),
Ken Milmored1bf8cf2010-05-11 09:17:46 +0200902 PWRITE(temp3_smoothing_enable, 2, PRI_LOW, 0x63, 0, 0x01, 3, bitmask),
George Josephd58de032010-03-05 22:17:25 +0100903 PWRITE(temp4_smoothing_enable, 3, PRI_LOW, 0x3c, 0, 0x01, 3, bitmask),
904
905 PWRITE(temp1_smoothing_time, 0, PRI_LOW, 0x62, 0, 0x07, 0, temp_st),
906 PWRITE(temp2_smoothing_time, 1, PRI_LOW, 0x63, 0, 0x07, 4, temp_st),
907 PWRITE(temp3_smoothing_time, 2, PRI_LOW, 0x63, 0, 0x07, 0, temp_st),
908 PWRITE(temp4_smoothing_time, 3, PRI_LOW, 0x3c, 0, 0x07, 0, temp_st),
909
910 PWRITE(temp1_auto_point1_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
911 bitmask),
912 PWRITE(temp2_auto_point1_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
913 bitmask),
914 PWRITE(temp3_auto_point1_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
915 bitmask),
916 PWRITE(temp4_auto_point1_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
917 bitmask),
918
919 PREAD(temp1_auto_point2_temp_hyst, 0, PRI_LOW, 0x6d, 0, 0x0f, 4,
920 bitmask),
921 PREAD(temp2_auto_point2_temp_hyst, 1, PRI_LOW, 0x6d, 0, 0x0f, 0,
922 bitmask),
923 PREAD(temp3_auto_point2_temp_hyst, 2, PRI_LOW, 0x6e, 0, 0x0f, 4,
924 bitmask),
925 PREAD(temp4_auto_point2_temp_hyst, 3, PRI_LOW, 0x6e, 0, 0x0f, 0,
926 bitmask),
927
928 PWRITE(temp1_auto_point1_temp, 0, PRI_LOW, 0x67, 0, 0, 0, temp8),
929 PWRITE(temp2_auto_point1_temp, 1, PRI_LOW, 0x68, 0, 0, 0, temp8),
930 PWRITE(temp3_auto_point1_temp, 2, PRI_LOW, 0x69, 0, 0, 0, temp8),
931 PWRITE(temp4_auto_point1_temp, 3, PRI_LOW, 0x3b, 0, 0, 0, temp8),
932
933 PWRITEM(temp1_auto_point2_temp, 0, PRI_LOW, VAA(0x5f, 0x67), VAA(0),
934 VAA(0x0f), VAA(4), ap2_temp),
935 PWRITEM(temp2_auto_point2_temp, 1, PRI_LOW, VAA(0x60, 0x68), VAA(0),
936 VAA(0x0f), VAA(4), ap2_temp),
937 PWRITEM(temp3_auto_point2_temp, 2, PRI_LOW, VAA(0x61, 0x69), VAA(0),
938 VAA(0x0f), VAA(4), ap2_temp),
939 PWRITEM(temp4_auto_point2_temp, 3, PRI_LOW, VAA(0x3c, 0x3b), VAA(0),
940 VAA(0x0f), VAA(4), ap2_temp),
941
942 PWRITE(temp1_crit, 0, PRI_LOW, 0x6a, 0, 0, 0, temp8),
943 PWRITE(temp2_crit, 1, PRI_LOW, 0x6b, 0, 0, 0, temp8),
944 PWRITE(temp3_crit, 2, PRI_LOW, 0x6c, 0, 0, 0, temp8),
945 PWRITE(temp4_crit, 3, PRI_LOW, 0x3d, 0, 0, 0, temp8),
946
947 PWRITE(temp5_enable, 4, PRI_LOW, 0x0e, 0, 0x01, 0, bitmask),
948 PWRITE(temp6_enable, 5, PRI_LOW, 0x0e, 0, 0x01, 1, bitmask),
949 PWRITE(temp7_enable, 6, PRI_LOW, 0x0e, 0, 0x01, 2, bitmask),
950 PWRITE(temp8_enable, 7, PRI_LOW, 0x0e, 0, 0x01, 3, bitmask),
951
952 PWRITE(remote1_offset, 0, PRI_LOW, 0x1c, 0, 0, 0, temp62),
953 PWRITE(remote2_offset, 1, PRI_LOW, 0x1d, 0, 0, 0, temp62),
954
955 PWRITE(pwm1, 0, PRI_HIGH, 0x30, 0, 0, 0, u8),
956 PWRITE(pwm2, 1, PRI_HIGH, 0x31, 0, 0, 0, u8),
957 PWRITE(pwm3, 2, PRI_HIGH, 0x32, 0, 0, 0, u8),
958
959 PWRITE(pwm1_invert, 0, PRI_LOW, 0x5c, 0, 0x01, 4, bitmask),
960 PWRITE(pwm2_invert, 1, PRI_LOW, 0x5d, 0, 0x01, 4, bitmask),
961 PWRITE(pwm3_invert, 2, PRI_LOW, 0x5e, 0, 0x01, 4, bitmask),
962
963 PWRITEM(pwm1_enable, 0, PRI_LOW, VAA(0x5c, 0x5c, 0x62), VAA(0, 0, 0),
964 VAA(0x07, 0x01, 0x01), VAA(5, 3, 5), pwm_enable),
965 PWRITEM(pwm2_enable, 1, PRI_LOW, VAA(0x5d, 0x5d, 0x62), VAA(0, 0, 0),
966 VAA(0x07, 0x01, 0x01), VAA(5, 3, 6), pwm_enable),
967 PWRITEM(pwm3_enable, 2, PRI_LOW, VAA(0x5e, 0x5e, 0x62), VAA(0, 0, 0),
968 VAA(0x07, 0x01, 0x01), VAA(5, 3, 7), pwm_enable),
969
970 PWRITEM(pwm1_auto_channels, 0, PRI_LOW, VAA(0x5c, 0x5c), VAA(0, 0),
971 VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
972 PWRITEM(pwm2_auto_channels, 1, PRI_LOW, VAA(0x5d, 0x5d), VAA(0, 0),
973 VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
974 PWRITEM(pwm3_auto_channels, 2, PRI_LOW, VAA(0x5e, 0x5e), VAA(0, 0),
975 VAA(0x07, 0x01), VAA(5, 3), pwm_ac),
976
977 PWRITE(pwm1_auto_point1_pwm, 0, PRI_LOW, 0x64, 0, 0, 0, u8),
978 PWRITE(pwm2_auto_point1_pwm, 1, PRI_LOW, 0x65, 0, 0, 0, u8),
979 PWRITE(pwm3_auto_point1_pwm, 2, PRI_LOW, 0x66, 0, 0, 0, u8),
980
981 PWRITE(pwm1_auto_point2_pwm, 0, PRI_LOW, 0x38, 0, 0, 0, u8),
982 PWRITE(pwm2_auto_point2_pwm, 1, PRI_LOW, 0x39, 0, 0, 0, u8),
983 PWRITE(pwm3_auto_point2_pwm, 2, PRI_LOW, 0x3a, 0, 0, 0, u8),
984
985 PWRITE(pwm1_freq, 0, PRI_LOW, 0x5f, 0, 0x0f, 0, pwm_freq),
986 PWRITE(pwm2_freq, 1, PRI_LOW, 0x60, 0, 0x0f, 0, pwm_freq),
987 PWRITE(pwm3_freq, 2, PRI_LOW, 0x61, 0, 0x0f, 0, pwm_freq),
988
989 PREAD(pwm1_auto_zone_assigned, 0, PRI_LOW, 0, 0, 0x03, 2, bitmask),
990 PREAD(pwm2_auto_zone_assigned, 1, PRI_LOW, 0, 0, 0x03, 4, bitmask),
991 PREAD(pwm3_auto_zone_assigned, 2, PRI_LOW, 0, 0, 0x03, 6, bitmask),
992
993 PWRITE(pwm1_auto_spinup_time, 0, PRI_LOW, 0x5c, 0, 0x07, 0, pwm_ast),
994 PWRITE(pwm2_auto_spinup_time, 1, PRI_LOW, 0x5d, 0, 0x07, 0, pwm_ast),
995 PWRITE(pwm3_auto_spinup_time, 2, PRI_LOW, 0x5e, 0, 0x07, 0, pwm_ast),
996
997 PWRITE(peci_enable, 0, PRI_LOW, 0x40, 0, 0x01, 4, bitmask),
998 PWRITE(peci_avg, 0, PRI_LOW, 0x36, 0, 0x07, 0, bitmask),
999 PWRITE(peci_domain, 0, PRI_LOW, 0x36, 0, 0x01, 3, bitmask),
1000 PWRITE(peci_legacy, 0, PRI_LOW, 0x36, 0, 0x01, 4, bitmask),
1001 PWRITE(peci_diode, 0, PRI_LOW, 0x0e, 0, 0x07, 4, bitmask),
1002 PWRITE(peci_4domain, 0, PRI_LOW, 0x0e, 0, 0x01, 4, bitmask),
1003
1004};
1005
1006static struct asc7621_data *asc7621_update_device(struct device *dev)
1007{
1008 struct i2c_client *client = to_i2c_client(dev);
1009 struct asc7621_data *data = i2c_get_clientdata(client);
1010 int i;
1011
1012/*
1013 * The asc7621 chips guarantee consistent reads of multi-byte values
1014 * regardless of the order of the reads. No special logic is needed
1015 * so we can just read the registers in whatever order they appear
1016 * in the asc7621_params array.
1017 */
1018
1019 mutex_lock(&data->update_lock);
1020
1021 /* Read all the high priority registers */
1022
1023 if (!data->valid ||
1024 time_after(jiffies, data->last_high_reading + INTERVAL_HIGH)) {
1025
1026 for (i = 0; i < ARRAY_SIZE(asc7621_register_priorities); i++) {
1027 if (asc7621_register_priorities[i] == PRI_HIGH) {
1028 data->reg[i] =
1029 i2c_smbus_read_byte_data(client, i) & 0xff;
1030 }
1031 }
1032 data->last_high_reading = jiffies;
Guenter Roecka0393712013-03-29 13:54:50 -07001033 } /* last_reading */
George Josephd58de032010-03-05 22:17:25 +01001034
1035 /* Read all the low priority registers. */
1036
1037 if (!data->valid ||
1038 time_after(jiffies, data->last_low_reading + INTERVAL_LOW)) {
1039
1040 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1041 if (asc7621_register_priorities[i] == PRI_LOW) {
1042 data->reg[i] =
1043 i2c_smbus_read_byte_data(client, i) & 0xff;
1044 }
1045 }
1046 data->last_low_reading = jiffies;
Guenter Roecka0393712013-03-29 13:54:50 -07001047 } /* last_reading */
George Josephd58de032010-03-05 22:17:25 +01001048
1049 data->valid = 1;
1050
1051 mutex_unlock(&data->update_lock);
1052
1053 return data;
1054}
1055
1056/*
1057 * Standard detection and initialization below
1058 *
1059 * Helper function that checks if an address is valid
1060 * for a particular chip.
1061 */
1062
1063static inline int valid_address_for_chip(int chip_type, int address)
1064{
1065 int i;
1066
1067 for (i = 0; asc7621_chips[chip_type].addresses[i] != I2C_CLIENT_END;
1068 i++) {
1069 if (asc7621_chips[chip_type].addresses[i] == address)
1070 return 1;
1071 }
1072 return 0;
1073}
1074
1075static void asc7621_init_client(struct i2c_client *client)
1076{
1077 int value;
1078
1079 /* Warn if part was not "READY" */
1080
1081 value = read_byte(client, 0x40);
1082
1083 if (value & 0x02) {
1084 dev_err(&client->dev,
1085 "Client (%d,0x%02x) config is locked.\n",
1086 i2c_adapter_id(client->adapter), client->addr);
Guenter Roecka0393712013-03-29 13:54:50 -07001087 }
George Josephd58de032010-03-05 22:17:25 +01001088 if (!(value & 0x04)) {
1089 dev_err(&client->dev, "Client (%d,0x%02x) is not ready.\n",
1090 i2c_adapter_id(client->adapter), client->addr);
Guenter Roecka0393712013-03-29 13:54:50 -07001091 }
George Josephd58de032010-03-05 22:17:25 +01001092
1093/*
1094 * Start monitoring
1095 *
1096 * Try to clear LOCK, Set START, save everything else
1097 */
1098 value = (value & ~0x02) | 0x01;
1099 write_byte(client, 0x40, value & 0xff);
1100
1101}
1102
1103static int
1104asc7621_probe(struct i2c_client *client, const struct i2c_device_id *id)
1105{
1106 struct asc7621_data *data;
1107 int i, err;
1108
1109 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1110 return -EIO;
1111
Guenter Roeck35bb95a2012-06-02 09:58:02 -07001112 data = devm_kzalloc(&client->dev, sizeof(struct asc7621_data),
1113 GFP_KERNEL);
George Josephd58de032010-03-05 22:17:25 +01001114 if (data == NULL)
1115 return -ENOMEM;
1116
1117 i2c_set_clientdata(client, data);
George Josephd58de032010-03-05 22:17:25 +01001118 mutex_init(&data->update_lock);
1119
1120 /* Initialize the asc7621 chip */
1121 asc7621_init_client(client);
1122
1123 /* Create the sysfs entries */
1124 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1125 err =
1126 device_create_file(&client->dev,
1127 &(asc7621_params[i].sda.dev_attr));
1128 if (err)
1129 goto exit_remove;
1130 }
1131
1132 data->class_dev = hwmon_device_register(&client->dev);
1133 if (IS_ERR(data->class_dev)) {
1134 err = PTR_ERR(data->class_dev);
1135 goto exit_remove;
1136 }
1137
1138 return 0;
1139
1140exit_remove:
1141 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1142 device_remove_file(&client->dev,
1143 &(asc7621_params[i].sda.dev_attr));
1144 }
1145
George Josephd58de032010-03-05 22:17:25 +01001146 return err;
1147}
1148
1149static int asc7621_detect(struct i2c_client *client,
1150 struct i2c_board_info *info)
1151{
1152 struct i2c_adapter *adapter = client->adapter;
1153 int company, verstep, chip_index;
George Josephd58de032010-03-05 22:17:25 +01001154
1155 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1156 return -ENODEV;
1157
1158 for (chip_index = FIRST_CHIP; chip_index <= LAST_CHIP; chip_index++) {
1159
1160 if (!valid_address_for_chip(chip_index, client->addr))
1161 continue;
1162
1163 company = read_byte(client,
1164 asc7621_chips[chip_index].company_reg);
1165 verstep = read_byte(client,
1166 asc7621_chips[chip_index].verstep_reg);
1167
1168 if (company == asc7621_chips[chip_index].company_id &&
1169 verstep == asc7621_chips[chip_index].verstep_id) {
George Josephd58de032010-03-05 22:17:25 +01001170 strlcpy(info->type, asc7621_chips[chip_index].name,
1171 I2C_NAME_SIZE);
1172
Jean Delvare28cbd462010-08-14 21:08:52 +02001173 dev_info(&adapter->dev, "Matched %s at 0x%02x\n",
1174 asc7621_chips[chip_index].name, client->addr);
George Josephd58de032010-03-05 22:17:25 +01001175 return 0;
1176 }
1177 }
1178
1179 return -ENODEV;
1180}
1181
1182static int asc7621_remove(struct i2c_client *client)
1183{
1184 struct asc7621_data *data = i2c_get_clientdata(client);
1185 int i;
1186
1187 hwmon_device_unregister(data->class_dev);
1188
1189 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1190 device_remove_file(&client->dev,
1191 &(asc7621_params[i].sda.dev_attr));
1192 }
1193
George Josephd58de032010-03-05 22:17:25 +01001194 return 0;
1195}
1196
1197static const struct i2c_device_id asc7621_id[] = {
1198 {"asc7621", asc7621},
1199 {"asc7621a", asc7621a},
1200 {},
1201};
1202
1203MODULE_DEVICE_TABLE(i2c, asc7621_id);
1204
1205static struct i2c_driver asc7621_driver = {
1206 .class = I2C_CLASS_HWMON,
1207 .driver = {
1208 .name = "asc7621",
1209 },
1210 .probe = asc7621_probe,
1211 .remove = asc7621_remove,
1212 .id_table = asc7621_id,
1213 .detect = asc7621_detect,
1214 .address_list = normal_i2c,
1215};
1216
1217static int __init sm_asc7621_init(void)
1218{
1219 int i, j;
1220/*
1221 * Collect all the registers needed into a single array.
1222 * This way, if a register isn't actually used for anything,
1223 * we don't retrieve it.
1224 */
1225
1226 for (i = 0; i < ARRAY_SIZE(asc7621_params); i++) {
1227 for (j = 0; j < ARRAY_SIZE(asc7621_params[i].msb); j++)
1228 asc7621_register_priorities[asc7621_params[i].msb[j]] =
1229 asc7621_params[i].priority;
1230 for (j = 0; j < ARRAY_SIZE(asc7621_params[i].lsb); j++)
1231 asc7621_register_priorities[asc7621_params[i].lsb[j]] =
1232 asc7621_params[i].priority;
1233 }
1234 return i2c_add_driver(&asc7621_driver);
1235}
1236
1237static void __exit sm_asc7621_exit(void)
1238{
1239 i2c_del_driver(&asc7621_driver);
1240}
1241
1242MODULE_LICENSE("GPL");
1243MODULE_AUTHOR("George Joseph");
1244MODULE_DESCRIPTION("Andigilog aSC7621 and aSC7621a driver");
1245
1246module_init(sm_asc7621_init);
1247module_exit(sm_asc7621_exit);