diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/hwmon/adm1026.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'drivers/hwmon/adm1026.c')
-rw-r--r-- | drivers/hwmon/adm1026.c | 519 |
1 files changed, 200 insertions, 319 deletions
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 0f068e7297e..0531867484f 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -1,27 +1,27 @@ | |||
1 | /* | 1 | /* |
2 | * adm1026.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | adm1026.c - Part of lm_sensors, Linux kernel modules for hardware |
3 | * monitoring | 3 | monitoring |
4 | * Copyright (C) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> | 4 | Copyright (C) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> |
5 | * Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com> | 5 | Copyright (C) 2004 Justin Thiessen <jthiessen@penguincomputing.com> |
6 | * | 6 | |
7 | * Chip details at: | 7 | Chip details at: |
8 | * | 8 | |
9 | * <http://www.onsemi.com/PowerSolutions/product.do?id=ADM1026> | 9 | <http://www.onsemi.com/PowerSolutions/product.do?id=ADM1026> |
10 | * | 10 | |
11 | * This program is free software; you can redistribute it and/or modify | 11 | This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 14 | (at your option) any later version. |
15 | * | 15 | |
16 | * This program is distributed in the hope that it will be useful, | 16 | This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 19 | GNU General Public License for more details. |
20 | * | 20 | |
21 | * You should have received a copy of the GNU General Public License | 21 | You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 22 | along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
@@ -90,8 +90,7 @@ MODULE_PARM_DESC(gpio_fan, "List of GPIO pins (0-7) to program as fan tachs"); | |||
90 | #define E2CFG_ROM 0x08 | 90 | #define E2CFG_ROM 0x08 |
91 | #define E2CFG_CLK_EXT 0x80 | 91 | #define E2CFG_CLK_EXT 0x80 |
92 | 92 | ||
93 | /* | 93 | /* There are 10 general analog inputs and 7 dedicated inputs |
94 | * There are 10 general analog inputs and 7 dedicated inputs | ||
95 | * They are: | 94 | * They are: |
96 | * 0 - 9 = AIN0 - AIN9 | 95 | * 0 - 9 = AIN0 - AIN9 |
97 | * 10 = Vbat | 96 | * 10 = Vbat |
@@ -118,8 +117,7 @@ static u16 ADM1026_REG_IN_MAX[] = { | |||
118 | 0x43, 0x44, 0x45, 0x46, 0x47 | 117 | 0x43, 0x44, 0x45, 0x46, 0x47 |
119 | }; | 118 | }; |
120 | 119 | ||
121 | /* | 120 | /* Temperatures are: |
122 | * Temperatures are: | ||
123 | * 0 - Internal | 121 | * 0 - Internal |
124 | * 1 - External 1 | 122 | * 1 - External 1 |
125 | * 2 - External 2 | 123 | * 2 - External 2 |
@@ -172,14 +170,12 @@ static u16 ADM1026_REG_TEMP_OFFSET[] = { 0x1e, 0x6e, 0x6f }; | |||
172 | #define ADM1026_FAN_CONTROL_TEMP_RANGE 20 | 170 | #define ADM1026_FAN_CONTROL_TEMP_RANGE 20 |
173 | #define ADM1026_PWM_MAX 255 | 171 | #define ADM1026_PWM_MAX 255 |
174 | 172 | ||
175 | /* | 173 | /* Conversions. Rounding and limit checking is only done on the TO_REG |
176 | * Conversions. Rounding and limit checking is only done on the TO_REG | ||
177 | * variants. Note that you should be a bit careful with which arguments | 174 | * variants. Note that you should be a bit careful with which arguments |
178 | * these macros are called: arguments may be evaluated more than once. | 175 | * these macros are called: arguments may be evaluated more than once. |
179 | */ | 176 | */ |
180 | 177 | ||
181 | /* | 178 | /* IN are scaled according to built-in resistors. These are the |
182 | * IN are scaled according to built-in resistors. These are the | ||
183 | * voltages corresponding to 3/4 of full scale (192 or 0xc0) | 179 | * voltages corresponding to 3/4 of full scale (192 or 0xc0) |
184 | * NOTE: The -12V input needs an additional factor to account | 180 | * NOTE: The -12V input needs an additional factor to account |
185 | * for the Vref pullup resistor. | 181 | * for the Vref pullup resistor. |
@@ -201,25 +197,23 @@ static int adm1026_scaling[] = { /* .001 Volts */ | |||
201 | 0, 255)) | 197 | 0, 255)) |
202 | #define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n])) | 198 | #define INS_FROM_REG(n, val) (SCALE(val, 192, adm1026_scaling[n])) |
203 | 199 | ||
204 | /* | 200 | /* FAN speed is measured using 22.5kHz clock and counts for 2 pulses |
205 | * FAN speed is measured using 22.5kHz clock and counts for 2 pulses | ||
206 | * and we assume a 2 pulse-per-rev fan tach signal | 201 | * and we assume a 2 pulse-per-rev fan tach signal |
207 | * 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000 | 202 | * 22500 kHz * 60 (sec/min) * 2 (pulse) / 2 (pulse/rev) == 1350000 |
208 | */ | 203 | */ |
209 | #define FAN_TO_REG(val, div) ((val) <= 0 ? 0xff : \ | 204 | #define FAN_TO_REG(val, div) ((val) <= 0 ? 0xff : \ |
210 | SENSORS_LIMIT(1350000 / ((val) * (div)), \ | 205 | SENSORS_LIMIT(1350000/((val)*(div)), 1, 254)) |
211 | 1, 254)) | 206 | #define FAN_FROM_REG(val, div) ((val) == 0 ? -1:(val) == 0xff ? 0 : \ |
212 | #define FAN_FROM_REG(val, div) ((val) == 0 ? -1 : (val) == 0xff ? 0 : \ | 207 | 1350000/((val)*(div))) |
213 | 1350000 / ((val) * (div))) | 208 | #define DIV_FROM_REG(val) (1<<(val)) |
214 | #define DIV_FROM_REG(val) (1 << (val)) | ||
215 | #define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0) | 209 | #define DIV_TO_REG(val) ((val) >= 8 ? 3 : (val) >= 4 ? 2 : (val) >= 2 ? 1 : 0) |
216 | 210 | ||
217 | /* Temperature is reported in 1 degC increments */ | 211 | /* Temperature is reported in 1 degC increments */ |
218 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \ | 212 | #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\ |
219 | / 1000, -127, 127)) | 213 | -127, 127)) |
220 | #define TEMP_FROM_REG(val) ((val) * 1000) | 214 | #define TEMP_FROM_REG(val) ((val) * 1000) |
221 | #define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val) + ((val) < 0 ? -500 : 500)) \ | 215 | #define OFFSET_TO_REG(val) (SENSORS_LIMIT(((val)+((val)<0 ? -500 : 500))/1000,\ |
222 | / 1000, -127, 127)) | 216 | -127, 127)) |
223 | #define OFFSET_FROM_REG(val) ((val) * 1000) | 217 | #define OFFSET_FROM_REG(val) ((val) * 1000) |
224 | 218 | ||
225 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val, 0, 255)) | 219 | #define PWM_TO_REG(val) (SENSORS_LIMIT(val, 0, 255)) |
@@ -228,16 +222,14 @@ static int adm1026_scaling[] = { /* .001 Volts */ | |||
228 | #define PWM_MIN_TO_REG(val) ((val) & 0xf0) | 222 | #define PWM_MIN_TO_REG(val) ((val) & 0xf0) |
229 | #define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4)) | 223 | #define PWM_MIN_FROM_REG(val) (((val) & 0xf0) + ((val) >> 4)) |
230 | 224 | ||
231 | /* | 225 | /* Analog output is a voltage, and scaled to millivolts. The datasheet |
232 | * Analog output is a voltage, and scaled to millivolts. The datasheet | ||
233 | * indicates that the DAC could be used to drive the fans, but in our | 226 | * indicates that the DAC could be used to drive the fans, but in our |
234 | * example board (Arima HDAMA) it isn't connected to the fans at all. | 227 | * example board (Arima HDAMA) it isn't connected to the fans at all. |
235 | */ | 228 | */ |
236 | #define DAC_TO_REG(val) (SENSORS_LIMIT(((((val) * 255) + 500) / 2500), 0, 255)) | 229 | #define DAC_TO_REG(val) (SENSORS_LIMIT(((((val)*255)+500)/2500), 0, 255)) |
237 | #define DAC_FROM_REG(val) (((val) * 2500) / 255) | 230 | #define DAC_FROM_REG(val) (((val)*2500)/255) |
238 | 231 | ||
239 | /* | 232 | /* Chip sampling rates |
240 | * Chip sampling rates | ||
241 | * | 233 | * |
242 | * Some sensors are not updated more frequently than once per second | 234 | * Some sensors are not updated more frequently than once per second |
243 | * so it doesn't make sense to read them more often than that. | 235 | * so it doesn't make sense to read them more often than that. |
@@ -251,13 +243,11 @@ static int adm1026_scaling[] = { /* .001 Volts */ | |||
251 | #define ADM1026_DATA_INTERVAL (1 * HZ) | 243 | #define ADM1026_DATA_INTERVAL (1 * HZ) |
252 | #define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ) | 244 | #define ADM1026_CONFIG_INTERVAL (5 * 60 * HZ) |
253 | 245 | ||
254 | /* | 246 | /* We allow for multiple chips in a single system. |
255 | * We allow for multiple chips in a single system. | ||
256 | * | 247 | * |
257 | * For each registered ADM1026, we need to keep state information | 248 | * For each registered ADM1026, we need to keep state information |
258 | * at client->data. The adm1026_data structure is dynamically | 249 | * at client->data. The adm1026_data structure is dynamically |
259 | * allocated, when a new client structure is allocated. | 250 | * allocated, when a new client structure is allocated. */ |
260 | */ | ||
261 | 251 | ||
262 | struct pwm_data { | 252 | struct pwm_data { |
263 | u8 pwm; | 253 | u8 pwm; |
@@ -398,16 +388,17 @@ static void adm1026_init_client(struct i2c_client *client) | |||
398 | dev_dbg(&client->dev, "THERM pin enabled. " | 388 | dev_dbg(&client->dev, "THERM pin enabled. " |
399 | "GPIO16 disabled.\n"); | 389 | "GPIO16 disabled.\n"); |
400 | } | 390 | } |
401 | if (data->config3 & CFG3_VREF_250) | 391 | if (data->config3 & CFG3_VREF_250) { |
402 | dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); | 392 | dev_dbg(&client->dev, "Vref is 2.50 Volts.\n"); |
403 | else | 393 | } else { |
404 | dev_dbg(&client->dev, "Vref is 1.82 Volts.\n"); | 394 | dev_dbg(&client->dev, "Vref is 1.82 Volts.\n"); |
395 | } | ||
405 | /* Read and pick apart the existing GPIO configuration */ | 396 | /* Read and pick apart the existing GPIO configuration */ |
406 | value = 0; | 397 | value = 0; |
407 | for (i = 0; i <= 15; ++i) { | 398 | for (i = 0;i <= 15;++i) { |
408 | if ((i & 0x03) == 0) { | 399 | if ((i & 0x03) == 0) { |
409 | value = adm1026_read_value(client, | 400 | value = adm1026_read_value(client, |
410 | ADM1026_REG_GPIO_CFG_0_3 + i / 4); | 401 | ADM1026_REG_GPIO_CFG_0_3 + i/4); |
411 | } | 402 | } |
412 | data->gpio_config[i] = value & 0x03; | 403 | data->gpio_config[i] = value & 0x03; |
413 | value >>= 2; | 404 | value >>= 2; |
@@ -417,8 +408,7 @@ static void adm1026_init_client(struct i2c_client *client) | |||
417 | /* ... and then print it */ | 408 | /* ... and then print it */ |
418 | adm1026_print_gpio(client); | 409 | adm1026_print_gpio(client); |
419 | 410 | ||
420 | /* | 411 | /* If the user asks us to reprogram the GPIO config, then |
421 | * If the user asks us to reprogram the GPIO config, then | ||
422 | * do it now. | 412 | * do it now. |
423 | */ | 413 | */ |
424 | if (gpio_input[0] != -1 || gpio_output[0] != -1 | 414 | if (gpio_input[0] != -1 || gpio_output[0] != -1 |
@@ -427,8 +417,7 @@ static void adm1026_init_client(struct i2c_client *client) | |||
427 | adm1026_fixup_gpio(client); | 417 | adm1026_fixup_gpio(client); |
428 | } | 418 | } |
429 | 419 | ||
430 | /* | 420 | /* WE INTENTIONALLY make no changes to the limits, |
431 | * WE INTENTIONALLY make no changes to the limits, | ||
432 | * offsets, pwms, fans and zones. If they were | 421 | * offsets, pwms, fans and zones. If they were |
433 | * configured, we don't want to mess with them. | 422 | * configured, we don't want to mess with them. |
434 | * If they weren't, the default is 100% PWM, no | 423 | * If they weren't, the default is 100% PWM, no |
@@ -439,7 +428,7 @@ static void adm1026_init_client(struct i2c_client *client) | |||
439 | * without first setting a value for pwm1.auto_pwm_min | 428 | * without first setting a value for pwm1.auto_pwm_min |
440 | * will not result in potentially dangerous fan speed decrease. | 429 | * will not result in potentially dangerous fan speed decrease. |
441 | */ | 430 | */ |
442 | data->pwm1.auto_pwm_min = 255; | 431 | data->pwm1.auto_pwm_min=255; |
443 | /* Start monitoring */ | 432 | /* Start monitoring */ |
444 | value = adm1026_read_value(client, ADM1026_REG_CONFIG1); | 433 | value = adm1026_read_value(client, ADM1026_REG_CONFIG1); |
445 | /* Set MONITOR, clear interrupt acknowledge and s/w reset */ | 434 | /* Set MONITOR, clear interrupt acknowledge and s/w reset */ |
@@ -451,7 +440,7 @@ static void adm1026_init_client(struct i2c_client *client) | |||
451 | /* initialize fan_div[] to hardware defaults */ | 440 | /* initialize fan_div[] to hardware defaults */ |
452 | value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | | 441 | value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | |
453 | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); | 442 | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8); |
454 | for (i = 0; i <= 7; ++i) { | 443 | for (i = 0;i <= 7;++i) { |
455 | data->fan_div[i] = DIV_FROM_REG(value & 0x03); | 444 | data->fan_div[i] = DIV_FROM_REG(value & 0x03); |
456 | value >>= 2; | 445 | value >>= 2; |
457 | } | 446 | } |
@@ -463,7 +452,7 @@ static void adm1026_print_gpio(struct i2c_client *client) | |||
463 | int i; | 452 | int i; |
464 | 453 | ||
465 | dev_dbg(&client->dev, "GPIO config is:\n"); | 454 | dev_dbg(&client->dev, "GPIO config is:\n"); |
466 | for (i = 0; i <= 7; ++i) { | 455 | for (i = 0;i <= 7;++i) { |
467 | if (data->config2 & (1 << i)) { | 456 | if (data->config2 & (1 << i)) { |
468 | dev_dbg(&client->dev, "\t%sGP%s%d\n", | 457 | dev_dbg(&client->dev, "\t%sGP%s%d\n", |
469 | data->gpio_config[i] & 0x02 ? "" : "!", | 458 | data->gpio_config[i] & 0x02 ? "" : "!", |
@@ -473,7 +462,7 @@ static void adm1026_print_gpio(struct i2c_client *client) | |||
473 | dev_dbg(&client->dev, "\tFAN%d\n", i); | 462 | dev_dbg(&client->dev, "\tFAN%d\n", i); |
474 | } | 463 | } |
475 | } | 464 | } |
476 | for (i = 8; i <= 15; ++i) { | 465 | for (i = 8;i <= 15;++i) { |
477 | dev_dbg(&client->dev, "\t%sGP%s%d\n", | 466 | dev_dbg(&client->dev, "\t%sGP%s%d\n", |
478 | data->gpio_config[i] & 0x02 ? "" : "!", | 467 | data->gpio_config[i] & 0x02 ? "" : "!", |
479 | data->gpio_config[i] & 0x01 ? "OUT" : "IN", | 468 | data->gpio_config[i] & 0x01 ? "OUT" : "IN", |
@@ -496,46 +485,52 @@ static void adm1026_fixup_gpio(struct i2c_client *client) | |||
496 | int value; | 485 | int value; |
497 | 486 | ||
498 | /* Make the changes requested. */ | 487 | /* Make the changes requested. */ |
499 | /* | 488 | /* We may need to unlock/stop monitoring or soft-reset the |
500 | * We may need to unlock/stop monitoring or soft-reset the | ||
501 | * chip before we can make changes. This hasn't been | 489 | * chip before we can make changes. This hasn't been |
502 | * tested much. FIXME | 490 | * tested much. FIXME |
503 | */ | 491 | */ |
504 | 492 | ||
505 | /* Make outputs */ | 493 | /* Make outputs */ |
506 | for (i = 0; i <= 16; ++i) { | 494 | for (i = 0;i <= 16;++i) { |
507 | if (gpio_output[i] >= 0 && gpio_output[i] <= 16) | 495 | if (gpio_output[i] >= 0 && gpio_output[i] <= 16) { |
508 | data->gpio_config[gpio_output[i]] |= 0x01; | 496 | data->gpio_config[gpio_output[i]] |= 0x01; |
497 | } | ||
509 | /* if GPIO0-7 is output, it isn't a FAN tach */ | 498 | /* if GPIO0-7 is output, it isn't a FAN tach */ |
510 | if (gpio_output[i] >= 0 && gpio_output[i] <= 7) | 499 | if (gpio_output[i] >= 0 && gpio_output[i] <= 7) { |
511 | data->config2 |= 1 << gpio_output[i]; | 500 | data->config2 |= 1 << gpio_output[i]; |
501 | } | ||
512 | } | 502 | } |
513 | 503 | ||
514 | /* Input overrides output */ | 504 | /* Input overrides output */ |
515 | for (i = 0; i <= 16; ++i) { | 505 | for (i = 0;i <= 16;++i) { |
516 | if (gpio_input[i] >= 0 && gpio_input[i] <= 16) | 506 | if (gpio_input[i] >= 0 && gpio_input[i] <= 16) { |
517 | data->gpio_config[gpio_input[i]] &= ~0x01; | 507 | data->gpio_config[gpio_input[i]] &= ~ 0x01; |
508 | } | ||
518 | /* if GPIO0-7 is input, it isn't a FAN tach */ | 509 | /* if GPIO0-7 is input, it isn't a FAN tach */ |
519 | if (gpio_input[i] >= 0 && gpio_input[i] <= 7) | 510 | if (gpio_input[i] >= 0 && gpio_input[i] <= 7) { |
520 | data->config2 |= 1 << gpio_input[i]; | 511 | data->config2 |= 1 << gpio_input[i]; |
512 | } | ||
521 | } | 513 | } |
522 | 514 | ||
523 | /* Inverted */ | 515 | /* Inverted */ |
524 | for (i = 0; i <= 16; ++i) { | 516 | for (i = 0;i <= 16;++i) { |
525 | if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) | 517 | if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16) { |
526 | data->gpio_config[gpio_inverted[i]] &= ~0x02; | 518 | data->gpio_config[gpio_inverted[i]] &= ~ 0x02; |
519 | } | ||
527 | } | 520 | } |
528 | 521 | ||
529 | /* Normal overrides inverted */ | 522 | /* Normal overrides inverted */ |
530 | for (i = 0; i <= 16; ++i) { | 523 | for (i = 0;i <= 16;++i) { |
531 | if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) | 524 | if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16) { |
532 | data->gpio_config[gpio_normal[i]] |= 0x02; | 525 | data->gpio_config[gpio_normal[i]] |= 0x02; |
526 | } | ||
533 | } | 527 | } |
534 | 528 | ||
535 | /* Fan overrides input and output */ | 529 | /* Fan overrides input and output */ |
536 | for (i = 0; i <= 7; ++i) { | 530 | for (i = 0;i <= 7;++i) { |
537 | if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) | 531 | if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7) { |
538 | data->config2 &= ~(1 << gpio_fan[i]); | 532 | data->config2 &= ~(1 << gpio_fan[i]); |
533 | } | ||
539 | } | 534 | } |
540 | 535 | ||
541 | /* Write new configs to registers */ | 536 | /* Write new configs to registers */ |
@@ -543,7 +538,7 @@ static void adm1026_fixup_gpio(struct i2c_client *client) | |||
543 | data->config3 = (data->config3 & 0x3f) | 538 | data->config3 = (data->config3 & 0x3f) |
544 | | ((data->gpio_config[16] & 0x03) << 6); | 539 | | ((data->gpio_config[16] & 0x03) << 6); |
545 | adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3); | 540 | adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3); |
546 | for (i = 15, value = 0; i >= 0; --i) { | 541 | for (i = 15, value = 0;i >= 0;--i) { |
547 | value <<= 2; | 542 | value <<= 2; |
548 | value |= data->gpio_config[i] & 0x03; | 543 | value |= data->gpio_config[i] & 0x03; |
549 | if ((i & 0x03) == 0) { | 544 | if ((i & 0x03) == 0) { |
@@ -568,25 +563,22 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | |||
568 | 563 | ||
569 | mutex_lock(&data->update_lock); | 564 | mutex_lock(&data->update_lock); |
570 | if (!data->valid | 565 | if (!data->valid |
571 | || time_after(jiffies, | 566 | || time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) { |
572 | data->last_reading + ADM1026_DATA_INTERVAL)) { | ||
573 | /* Things that change quickly */ | 567 | /* Things that change quickly */ |
574 | dev_dbg(&client->dev, "Reading sensor values\n"); | 568 | dev_dbg(&client->dev, "Reading sensor values\n"); |
575 | for (i = 0; i <= 16; ++i) { | 569 | for (i = 0;i <= 16;++i) { |
576 | data->in[i] = | 570 | data->in[i] = |
577 | adm1026_read_value(client, ADM1026_REG_IN[i]); | 571 | adm1026_read_value(client, ADM1026_REG_IN[i]); |
578 | } | 572 | } |
579 | 573 | ||
580 | for (i = 0; i <= 7; ++i) { | 574 | for (i = 0;i <= 7;++i) { |
581 | data->fan[i] = | 575 | data->fan[i] = |
582 | adm1026_read_value(client, ADM1026_REG_FAN(i)); | 576 | adm1026_read_value(client, ADM1026_REG_FAN(i)); |
583 | } | 577 | } |
584 | 578 | ||
585 | for (i = 0; i <= 2; ++i) { | 579 | for (i = 0;i <= 2;++i) { |
586 | /* | 580 | /* NOTE: temp[] is s8 and we assume 2's complement |
587 | * NOTE: temp[] is s8 and we assume 2's complement | 581 | * "conversion" in the assignment */ |
588 | * "conversion" in the assignment | ||
589 | */ | ||
590 | data->temp[i] = | 582 | data->temp[i] = |
591 | adm1026_read_value(client, ADM1026_REG_TEMP[i]); | 583 | adm1026_read_value(client, ADM1026_REG_TEMP[i]); |
592 | } | 584 | } |
@@ -622,7 +614,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | |||
622 | time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) { | 614 | time_after(jiffies, data->last_config + ADM1026_CONFIG_INTERVAL)) { |
623 | /* Things that don't change often */ | 615 | /* Things that don't change often */ |
624 | dev_dbg(&client->dev, "Reading config values\n"); | 616 | dev_dbg(&client->dev, "Reading config values\n"); |
625 | for (i = 0; i <= 16; ++i) { | 617 | for (i = 0;i <= 16;++i) { |
626 | data->in_min[i] = adm1026_read_value(client, | 618 | data->in_min[i] = adm1026_read_value(client, |
627 | ADM1026_REG_IN_MIN[i]); | 619 | ADM1026_REG_IN_MIN[i]); |
628 | data->in_max[i] = adm1026_read_value(client, | 620 | data->in_max[i] = adm1026_read_value(client, |
@@ -632,7 +624,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | |||
632 | value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) | 624 | value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
633 | | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) | 625 | | (adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) |
634 | << 8); | 626 | << 8); |
635 | for (i = 0; i <= 7; ++i) { | 627 | for (i = 0;i <= 7;++i) { |
636 | data->fan_min[i] = adm1026_read_value(client, | 628 | data->fan_min[i] = adm1026_read_value(client, |
637 | ADM1026_REG_FAN_MIN(i)); | 629 | ADM1026_REG_FAN_MIN(i)); |
638 | data->fan_div[i] = DIV_FROM_REG(value & 0x03); | 630 | data->fan_div[i] = DIV_FROM_REG(value & 0x03); |
@@ -640,8 +632,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | |||
640 | } | 632 | } |
641 | 633 | ||
642 | for (i = 0; i <= 2; ++i) { | 634 | for (i = 0; i <= 2; ++i) { |
643 | /* | 635 | /* NOTE: temp_xxx[] are s8 and we assume 2's |
644 | * NOTE: temp_xxx[] are s8 and we assume 2's | ||
645 | * complement "conversion" in the assignment | 636 | * complement "conversion" in the assignment |
646 | */ | 637 | */ |
647 | data->temp_min[i] = adm1026_read_value(client, | 638 | data->temp_min[i] = adm1026_read_value(client, |
@@ -690,7 +681,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev) | |||
690 | data->gpio_config[16] = (data->config3 >> 6) & 0x03; | 681 | data->gpio_config[16] = (data->config3 >> 6) & 0x03; |
691 | 682 | ||
692 | value = 0; | 683 | value = 0; |
693 | for (i = 0; i <= 15; ++i) { | 684 | for (i = 0;i <= 15;++i) { |
694 | if ((i & 0x03) == 0) { | 685 | if ((i & 0x03) == 0) { |
695 | value = adm1026_read_value(client, | 686 | value = adm1026_read_value(client, |
696 | ADM1026_REG_GPIO_CFG_0_3 + i/4); | 687 | ADM1026_REG_GPIO_CFG_0_3 + i/4); |
@@ -730,12 +721,7 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr, | |||
730 | int nr = sensor_attr->index; | 721 | int nr = sensor_attr->index; |
731 | struct i2c_client *client = to_i2c_client(dev); | 722 | struct i2c_client *client = to_i2c_client(dev); |
732 | struct adm1026_data *data = i2c_get_clientdata(client); | 723 | struct adm1026_data *data = i2c_get_clientdata(client); |
733 | long val; | 724 | int val = simple_strtol(buf, NULL, 10); |
734 | int err; | ||
735 | |||
736 | err = kstrtol(buf, 10, &val); | ||
737 | if (err) | ||
738 | return err; | ||
739 | 725 | ||
740 | mutex_lock(&data->update_lock); | 726 | mutex_lock(&data->update_lock); |
741 | data->in_min[nr] = INS_TO_REG(nr, val); | 727 | data->in_min[nr] = INS_TO_REG(nr, val); |
@@ -758,12 +744,7 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr, | |||
758 | int nr = sensor_attr->index; | 744 | int nr = sensor_attr->index; |
759 | struct i2c_client *client = to_i2c_client(dev); | 745 | struct i2c_client *client = to_i2c_client(dev); |
760 | struct adm1026_data *data = i2c_get_clientdata(client); | 746 | struct adm1026_data *data = i2c_get_clientdata(client); |
761 | long val; | 747 | int val = simple_strtol(buf, NULL, 10); |
762 | int err; | ||
763 | |||
764 | err = kstrtol(buf, 10, &val); | ||
765 | if (err) | ||
766 | return err; | ||
767 | 748 | ||
768 | mutex_lock(&data->update_lock); | 749 | mutex_lock(&data->update_lock); |
769 | data->in_max[nr] = INS_TO_REG(nr, val); | 750 | data->in_max[nr] = INS_TO_REG(nr, val); |
@@ -798,31 +779,23 @@ in_reg(13); | |||
798 | in_reg(14); | 779 | in_reg(14); |
799 | in_reg(15); | 780 | in_reg(15); |
800 | 781 | ||
801 | static ssize_t show_in16(struct device *dev, struct device_attribute *attr, | 782 | static ssize_t show_in16(struct device *dev, struct device_attribute *attr, char *buf) |
802 | char *buf) | ||
803 | { | 783 | { |
804 | struct adm1026_data *data = adm1026_update_device(dev); | 784 | struct adm1026_data *data = adm1026_update_device(dev); |
805 | return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in[16]) - | 785 | return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in[16]) - |
806 | NEG12_OFFSET); | 786 | NEG12_OFFSET); |
807 | } | 787 | } |
808 | static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, | 788 | static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr, char *buf) |
809 | char *buf) | ||
810 | { | 789 | { |
811 | struct adm1026_data *data = adm1026_update_device(dev); | 790 | struct adm1026_data *data = adm1026_update_device(dev); |
812 | return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_min[16]) | 791 | return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_min[16]) |
813 | - NEG12_OFFSET); | 792 | - NEG12_OFFSET); |
814 | } | 793 | } |
815 | static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, | 794 | static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
816 | const char *buf, size_t count) | ||
817 | { | 795 | { |
818 | struct i2c_client *client = to_i2c_client(dev); | 796 | struct i2c_client *client = to_i2c_client(dev); |
819 | struct adm1026_data *data = i2c_get_clientdata(client); | 797 | struct adm1026_data *data = i2c_get_clientdata(client); |
820 | long val; | 798 | int val = simple_strtol(buf, NULL, 10); |
821 | int err; | ||
822 | |||
823 | err = kstrtol(buf, 10, &val); | ||
824 | if (err) | ||
825 | return err; | ||
826 | 799 | ||
827 | mutex_lock(&data->update_lock); | 800 | mutex_lock(&data->update_lock); |
828 | data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); | 801 | data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); |
@@ -830,24 +803,17 @@ static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, | |||
830 | mutex_unlock(&data->update_lock); | 803 | mutex_unlock(&data->update_lock); |
831 | return count; | 804 | return count; |
832 | } | 805 | } |
833 | static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, | 806 | static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf) |
834 | char *buf) | ||
835 | { | 807 | { |
836 | struct adm1026_data *data = adm1026_update_device(dev); | 808 | struct adm1026_data *data = adm1026_update_device(dev); |
837 | return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_max[16]) | 809 | return sprintf(buf, "%d\n", INS_FROM_REG(16, data->in_max[16]) |
838 | - NEG12_OFFSET); | 810 | - NEG12_OFFSET); |
839 | } | 811 | } |
840 | static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, | 812 | static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
841 | const char *buf, size_t count) | ||
842 | { | 813 | { |
843 | struct i2c_client *client = to_i2c_client(dev); | 814 | struct i2c_client *client = to_i2c_client(dev); |
844 | struct adm1026_data *data = i2c_get_clientdata(client); | 815 | struct adm1026_data *data = i2c_get_clientdata(client); |
845 | long val; | 816 | int val = simple_strtol(buf, NULL, 10); |
846 | int err; | ||
847 | |||
848 | err = kstrtol(buf, 10, &val); | ||
849 | if (err) | ||
850 | return err; | ||
851 | 817 | ||
852 | mutex_lock(&data->update_lock); | 818 | mutex_lock(&data->update_lock); |
853 | data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET); | 819 | data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET); |
@@ -857,10 +823,10 @@ static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, | |||
857 | } | 823 | } |
858 | 824 | ||
859 | static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16); | 825 | static SENSOR_DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL, 16); |
860 | static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, | 826 | static SENSOR_DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min, 16); |
861 | set_in16_min, 16); | 827 | static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max, 16); |
862 | static SENSOR_DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, | 828 | |
863 | set_in16_max, 16); | 829 | |
864 | 830 | ||
865 | 831 | ||
866 | /* Now add fan read/write functions */ | 832 | /* Now add fan read/write functions */ |
@@ -890,12 +856,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
890 | int nr = sensor_attr->index; | 856 | int nr = sensor_attr->index; |
891 | struct i2c_client *client = to_i2c_client(dev); | 857 | struct i2c_client *client = to_i2c_client(dev); |
892 | struct adm1026_data *data = i2c_get_clientdata(client); | 858 | struct adm1026_data *data = i2c_get_clientdata(client); |
893 | long val; | 859 | int val = simple_strtol(buf, NULL, 10); |
894 | int err; | ||
895 | |||
896 | err = kstrtol(buf, 10, &val); | ||
897 | if (err) | ||
898 | return err; | ||
899 | 860 | ||
900 | mutex_lock(&data->update_lock); | 861 | mutex_lock(&data->update_lock); |
901 | data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]); | 862 | data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]); |
@@ -929,8 +890,9 @@ static void fixup_fan_min(struct device *dev, int fan, int old_div) | |||
929 | int new_div = data->fan_div[fan]; | 890 | int new_div = data->fan_div[fan]; |
930 | 891 | ||
931 | /* 0 and 0xff are special. Don't adjust them */ | 892 | /* 0 and 0xff are special. Don't adjust them */ |
932 | if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) | 893 | if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) { |
933 | return; | 894 | return; |
895 | } | ||
934 | 896 | ||
935 | new_min = data->fan_min[fan] * old_div / new_div; | 897 | new_min = data->fan_min[fan] * old_div / new_div; |
936 | new_min = SENSORS_LIMIT(new_min, 1, 254); | 898 | new_min = SENSORS_LIMIT(new_min, 1, 254); |
@@ -954,14 +916,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
954 | int nr = sensor_attr->index; | 916 | int nr = sensor_attr->index; |
955 | struct i2c_client *client = to_i2c_client(dev); | 917 | struct i2c_client *client = to_i2c_client(dev); |
956 | struct adm1026_data *data = i2c_get_clientdata(client); | 918 | struct adm1026_data *data = i2c_get_clientdata(client); |
957 | long val; | 919 | int val, orig_div, new_div; |
958 | int orig_div, new_div; | ||
959 | int err; | ||
960 | |||
961 | err = kstrtol(buf, 10, &val); | ||
962 | if (err) | ||
963 | return err; | ||
964 | 920 | ||
921 | val = simple_strtol(buf, NULL, 10); | ||
965 | new_div = DIV_TO_REG(val); | 922 | new_div = DIV_TO_REG(val); |
966 | 923 | ||
967 | mutex_lock(&data->update_lock); | 924 | mutex_lock(&data->update_lock); |
@@ -982,9 +939,9 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
982 | (DIV_TO_REG(data->fan_div[7]) << 6)); | 939 | (DIV_TO_REG(data->fan_div[7]) << 6)); |
983 | } | 940 | } |
984 | 941 | ||
985 | if (data->fan_div[nr] != orig_div) | 942 | if (data->fan_div[nr] != orig_div) { |
986 | fixup_fan_min(dev, nr, orig_div); | 943 | fixup_fan_min(dev, nr, orig_div); |
987 | 944 | } | |
988 | mutex_unlock(&data->update_lock); | 945 | mutex_unlock(&data->update_lock); |
989 | return count; | 946 | return count; |
990 | } | 947 | } |
@@ -1026,12 +983,7 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, | |||
1026 | int nr = sensor_attr->index; | 983 | int nr = sensor_attr->index; |
1027 | struct i2c_client *client = to_i2c_client(dev); | 984 | struct i2c_client *client = to_i2c_client(dev); |
1028 | struct adm1026_data *data = i2c_get_clientdata(client); | 985 | struct adm1026_data *data = i2c_get_clientdata(client); |
1029 | long val; | 986 | int val = simple_strtol(buf, NULL, 10); |
1030 | int err; | ||
1031 | |||
1032 | err = kstrtol(buf, 10, &val); | ||
1033 | if (err) | ||
1034 | return err; | ||
1035 | 987 | ||
1036 | mutex_lock(&data->update_lock); | 988 | mutex_lock(&data->update_lock); |
1037 | data->temp_min[nr] = TEMP_TO_REG(val); | 989 | data->temp_min[nr] = TEMP_TO_REG(val); |
@@ -1055,12 +1007,7 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, | |||
1055 | int nr = sensor_attr->index; | 1007 | int nr = sensor_attr->index; |
1056 | struct i2c_client *client = to_i2c_client(dev); | 1008 | struct i2c_client *client = to_i2c_client(dev); |
1057 | struct adm1026_data *data = i2c_get_clientdata(client); | 1009 | struct adm1026_data *data = i2c_get_clientdata(client); |
1058 | long val; | 1010 | int val = simple_strtol(buf, NULL, 10); |
1059 | int err; | ||
1060 | |||
1061 | err = kstrtol(buf, 10, &val); | ||
1062 | if (err) | ||
1063 | return err; | ||
1064 | 1011 | ||
1065 | mutex_lock(&data->update_lock); | 1012 | mutex_lock(&data->update_lock); |
1066 | data->temp_max[nr] = TEMP_TO_REG(val); | 1013 | data->temp_max[nr] = TEMP_TO_REG(val); |
@@ -1099,12 +1046,7 @@ static ssize_t set_temp_offset(struct device *dev, | |||
1099 | int nr = sensor_attr->index; | 1046 | int nr = sensor_attr->index; |
1100 | struct i2c_client *client = to_i2c_client(dev); | 1047 | struct i2c_client *client = to_i2c_client(dev); |
1101 | struct adm1026_data *data = i2c_get_clientdata(client); | 1048 | struct adm1026_data *data = i2c_get_clientdata(client); |
1102 | long val; | 1049 | int val = simple_strtol(buf, NULL, 10); |
1103 | int err; | ||
1104 | |||
1105 | err = kstrtol(buf, 10, &val); | ||
1106 | if (err) | ||
1107 | return err; | ||
1108 | 1050 | ||
1109 | mutex_lock(&data->update_lock); | 1051 | mutex_lock(&data->update_lock); |
1110 | data->temp_offset[nr] = TEMP_TO_REG(val); | 1052 | data->temp_offset[nr] = TEMP_TO_REG(val); |
@@ -1114,8 +1056,8 @@ static ssize_t set_temp_offset(struct device *dev, | |||
1114 | return count; | 1056 | return count; |
1115 | } | 1057 | } |
1116 | 1058 | ||
1117 | #define temp_offset_reg(offset) \ | 1059 | #define temp_offset_reg(offset) \ |
1118 | static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \ | 1060 | static SENSOR_DEVICE_ATTR(temp##offset##_offset, S_IRUGO | S_IWUSR, \ |
1119 | show_temp_offset, set_temp_offset, offset - 1); | 1061 | show_temp_offset, set_temp_offset, offset - 1); |
1120 | 1062 | ||
1121 | temp_offset_reg(1); | 1063 | temp_offset_reg(1); |
@@ -1155,12 +1097,7 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev, | |||
1155 | int nr = sensor_attr->index; | 1097 | int nr = sensor_attr->index; |
1156 | struct i2c_client *client = to_i2c_client(dev); | 1098 | struct i2c_client *client = to_i2c_client(dev); |
1157 | struct adm1026_data *data = i2c_get_clientdata(client); | 1099 | struct adm1026_data *data = i2c_get_clientdata(client); |
1158 | long val; | 1100 | int val = simple_strtol(buf, NULL, 10); |
1159 | int err; | ||
1160 | |||
1161 | err = kstrtol(buf, 10, &val); | ||
1162 | if (err) | ||
1163 | return err; | ||
1164 | 1101 | ||
1165 | mutex_lock(&data->update_lock); | 1102 | mutex_lock(&data->update_lock); |
1166 | data->temp_tmin[nr] = TEMP_TO_REG(val); | 1103 | data->temp_tmin[nr] = TEMP_TO_REG(val); |
@@ -1194,21 +1131,15 @@ static ssize_t set_temp_crit_enable(struct device *dev, | |||
1194 | { | 1131 | { |
1195 | struct i2c_client *client = to_i2c_client(dev); | 1132 | struct i2c_client *client = to_i2c_client(dev); |
1196 | struct adm1026_data *data = i2c_get_clientdata(client); | 1133 | struct adm1026_data *data = i2c_get_clientdata(client); |
1197 | unsigned long val; | 1134 | int val = simple_strtol(buf, NULL, 10); |
1198 | int err; | ||
1199 | |||
1200 | err = kstrtoul(buf, 10, &val); | ||
1201 | if (err) | ||
1202 | return err; | ||
1203 | |||
1204 | if (val > 1) | ||
1205 | return -EINVAL; | ||
1206 | |||
1207 | mutex_lock(&data->update_lock); | ||
1208 | data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4); | ||
1209 | adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1); | ||
1210 | mutex_unlock(&data->update_lock); | ||
1211 | 1135 | ||
1136 | if ((val == 1) || (val==0)) { | ||
1137 | mutex_lock(&data->update_lock); | ||
1138 | data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4); | ||
1139 | adm1026_write_value(client, ADM1026_REG_CONFIG1, | ||
1140 | data->config1); | ||
1141 | mutex_unlock(&data->update_lock); | ||
1142 | } | ||
1212 | return count; | 1143 | return count; |
1213 | } | 1144 | } |
1214 | 1145 | ||
@@ -1235,12 +1166,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr, | |||
1235 | int nr = sensor_attr->index; | 1166 | int nr = sensor_attr->index; |
1236 | struct i2c_client *client = to_i2c_client(dev); | 1167 | struct i2c_client *client = to_i2c_client(dev); |
1237 | struct adm1026_data *data = i2c_get_clientdata(client); | 1168 | struct adm1026_data *data = i2c_get_clientdata(client); |
1238 | long val; | 1169 | int val = simple_strtol(buf, NULL, 10); |
1239 | int err; | ||
1240 | |||
1241 | err = kstrtol(buf, 10, &val); | ||
1242 | if (err) | ||
1243 | return err; | ||
1244 | 1170 | ||
1245 | mutex_lock(&data->update_lock); | 1171 | mutex_lock(&data->update_lock); |
1246 | data->temp_crit[nr] = TEMP_TO_REG(val); | 1172 | data->temp_crit[nr] = TEMP_TO_REG(val); |
@@ -1258,24 +1184,17 @@ temp_crit_reg(1); | |||
1258 | temp_crit_reg(2); | 1184 | temp_crit_reg(2); |
1259 | temp_crit_reg(3); | 1185 | temp_crit_reg(3); |
1260 | 1186 | ||
1261 | static ssize_t show_analog_out_reg(struct device *dev, | 1187 | static ssize_t show_analog_out_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1262 | struct device_attribute *attr, char *buf) | ||
1263 | { | 1188 | { |
1264 | struct adm1026_data *data = adm1026_update_device(dev); | 1189 | struct adm1026_data *data = adm1026_update_device(dev); |
1265 | return sprintf(buf, "%d\n", DAC_FROM_REG(data->analog_out)); | 1190 | return sprintf(buf, "%d\n", DAC_FROM_REG(data->analog_out)); |
1266 | } | 1191 | } |
1267 | static ssize_t set_analog_out_reg(struct device *dev, | 1192 | static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *attr, const char *buf, |
1268 | struct device_attribute *attr, | 1193 | size_t count) |
1269 | const char *buf, size_t count) | ||
1270 | { | 1194 | { |
1271 | struct i2c_client *client = to_i2c_client(dev); | 1195 | struct i2c_client *client = to_i2c_client(dev); |
1272 | struct adm1026_data *data = i2c_get_clientdata(client); | 1196 | struct adm1026_data *data = i2c_get_clientdata(client); |
1273 | long val; | 1197 | int val = simple_strtol(buf, NULL, 10); |
1274 | int err; | ||
1275 | |||
1276 | err = kstrtol(buf, 10, &val); | ||
1277 | if (err) | ||
1278 | return err; | ||
1279 | 1198 | ||
1280 | mutex_lock(&data->update_lock); | 1199 | mutex_lock(&data->update_lock); |
1281 | data->analog_out = DAC_TO_REG(val); | 1200 | data->analog_out = DAC_TO_REG(val); |
@@ -1287,8 +1206,7 @@ static ssize_t set_analog_out_reg(struct device *dev, | |||
1287 | static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, | 1206 | static DEVICE_ATTR(analog_out, S_IRUGO | S_IWUSR, show_analog_out_reg, |
1288 | set_analog_out_reg); | 1207 | set_analog_out_reg); |
1289 | 1208 | ||
1290 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, | 1209 | static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1291 | char *buf) | ||
1292 | { | 1210 | { |
1293 | struct adm1026_data *data = adm1026_update_device(dev); | 1211 | struct adm1026_data *data = adm1026_update_device(dev); |
1294 | int vid = (data->gpio >> 11) & 0x1f; | 1212 | int vid = (data->gpio >> 11) & 0x1f; |
@@ -1296,35 +1214,25 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, | |||
1296 | dev_dbg(dev, "Setting VID from GPIO11-15.\n"); | 1214 | dev_dbg(dev, "Setting VID from GPIO11-15.\n"); |
1297 | return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm)); | 1215 | return sprintf(buf, "%d\n", vid_from_reg(vid, data->vrm)); |
1298 | } | 1216 | } |
1299 | |||
1300 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); | 1217 | static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); |
1301 | 1218 | ||
1302 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, | 1219 | static ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1303 | char *buf) | ||
1304 | { | 1220 | { |
1305 | struct adm1026_data *data = dev_get_drvdata(dev); | 1221 | struct adm1026_data *data = dev_get_drvdata(dev); |
1306 | return sprintf(buf, "%d\n", data->vrm); | 1222 | return sprintf(buf, "%d\n", data->vrm); |
1307 | } | 1223 | } |
1308 | 1224 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, const char *buf, | |
1309 | static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, | 1225 | size_t count) |
1310 | const char *buf, size_t count) | ||
1311 | { | 1226 | { |
1312 | struct adm1026_data *data = dev_get_drvdata(dev); | 1227 | struct adm1026_data *data = dev_get_drvdata(dev); |
1313 | unsigned long val; | ||
1314 | int err; | ||
1315 | |||
1316 | err = kstrtoul(buf, 10, &val); | ||
1317 | if (err) | ||
1318 | return err; | ||
1319 | 1228 | ||
1320 | data->vrm = val; | 1229 | data->vrm = simple_strtol(buf, NULL, 10); |
1321 | return count; | 1230 | return count; |
1322 | } | 1231 | } |
1323 | 1232 | ||
1324 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); | 1233 | static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); |
1325 | 1234 | ||
1326 | static ssize_t show_alarms_reg(struct device *dev, | 1235 | static ssize_t show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1327 | struct device_attribute *attr, char *buf) | ||
1328 | { | 1236 | { |
1329 | struct adm1026_data *data = adm1026_update_device(dev); | 1237 | struct adm1026_data *data = adm1026_update_device(dev); |
1330 | return sprintf(buf, "%ld\n", data->alarms); | 1238 | return sprintf(buf, "%ld\n", data->alarms); |
@@ -1369,24 +1277,18 @@ static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 24); | |||
1369 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 25); | 1277 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, 25); |
1370 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 26); | 1278 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 26); |
1371 | 1279 | ||
1372 | static ssize_t show_alarm_mask(struct device *dev, | 1280 | static ssize_t show_alarm_mask(struct device *dev, struct device_attribute *attr, char *buf) |
1373 | struct device_attribute *attr, char *buf) | ||
1374 | { | 1281 | { |
1375 | struct adm1026_data *data = adm1026_update_device(dev); | 1282 | struct adm1026_data *data = adm1026_update_device(dev); |
1376 | return sprintf(buf, "%ld\n", data->alarm_mask); | 1283 | return sprintf(buf, "%ld\n", data->alarm_mask); |
1377 | } | 1284 | } |
1378 | static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, | 1285 | static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr, const char *buf, |
1379 | const char *buf, size_t count) | 1286 | size_t count) |
1380 | { | 1287 | { |
1381 | struct i2c_client *client = to_i2c_client(dev); | 1288 | struct i2c_client *client = to_i2c_client(dev); |
1382 | struct adm1026_data *data = i2c_get_clientdata(client); | 1289 | struct adm1026_data *data = i2c_get_clientdata(client); |
1290 | int val = simple_strtol(buf, NULL, 10); | ||
1383 | unsigned long mask; | 1291 | unsigned long mask; |
1384 | long val; | ||
1385 | int err; | ||
1386 | |||
1387 | err = kstrtol(buf, 10, &val); | ||
1388 | if (err) | ||
1389 | return err; | ||
1390 | 1292 | ||
1391 | mutex_lock(&data->update_lock); | 1293 | mutex_lock(&data->update_lock); |
1392 | data->alarm_mask = val & 0x7fffffff; | 1294 | data->alarm_mask = val & 0x7fffffff; |
@@ -1411,24 +1313,18 @@ static DEVICE_ATTR(alarm_mask, S_IRUGO | S_IWUSR, show_alarm_mask, | |||
1411 | set_alarm_mask); | 1313 | set_alarm_mask); |
1412 | 1314 | ||
1413 | 1315 | ||
1414 | static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, | 1316 | static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf) |
1415 | char *buf) | ||
1416 | { | 1317 | { |
1417 | struct adm1026_data *data = adm1026_update_device(dev); | 1318 | struct adm1026_data *data = adm1026_update_device(dev); |
1418 | return sprintf(buf, "%ld\n", data->gpio); | 1319 | return sprintf(buf, "%ld\n", data->gpio); |
1419 | } | 1320 | } |
1420 | static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, | 1321 | static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf, |
1421 | const char *buf, size_t count) | 1322 | size_t count) |
1422 | { | 1323 | { |
1423 | struct i2c_client *client = to_i2c_client(dev); | 1324 | struct i2c_client *client = to_i2c_client(dev); |
1424 | struct adm1026_data *data = i2c_get_clientdata(client); | 1325 | struct adm1026_data *data = i2c_get_clientdata(client); |
1326 | int val = simple_strtol(buf, NULL, 10); | ||
1425 | long gpio; | 1327 | long gpio; |
1426 | long val; | ||
1427 | int err; | ||
1428 | |||
1429 | err = kstrtol(buf, 10, &val); | ||
1430 | if (err) | ||
1431 | return err; | ||
1432 | 1328 | ||
1433 | mutex_lock(&data->update_lock); | 1329 | mutex_lock(&data->update_lock); |
1434 | data->gpio = val & 0x1ffff; | 1330 | data->gpio = val & 0x1ffff; |
@@ -1444,24 +1340,19 @@ static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, | |||
1444 | 1340 | ||
1445 | static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio); | 1341 | static DEVICE_ATTR(gpio, S_IRUGO | S_IWUSR, show_gpio, set_gpio); |
1446 | 1342 | ||
1447 | static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, | 1343 | |
1448 | char *buf) | 1344 | static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr, char *buf) |
1449 | { | 1345 | { |
1450 | struct adm1026_data *data = adm1026_update_device(dev); | 1346 | struct adm1026_data *data = adm1026_update_device(dev); |
1451 | return sprintf(buf, "%ld\n", data->gpio_mask); | 1347 | return sprintf(buf, "%ld\n", data->gpio_mask); |
1452 | } | 1348 | } |
1453 | static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, | 1349 | static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, const char *buf, |
1454 | const char *buf, size_t count) | 1350 | size_t count) |
1455 | { | 1351 | { |
1456 | struct i2c_client *client = to_i2c_client(dev); | 1352 | struct i2c_client *client = to_i2c_client(dev); |
1457 | struct adm1026_data *data = i2c_get_clientdata(client); | 1353 | struct adm1026_data *data = i2c_get_clientdata(client); |
1354 | int val = simple_strtol(buf, NULL, 10); | ||
1458 | long mask; | 1355 | long mask; |
1459 | long val; | ||
1460 | int err; | ||
1461 | |||
1462 | err = kstrtol(buf, 10, &val); | ||
1463 | if (err) | ||
1464 | return err; | ||
1465 | 1356 | ||
1466 | mutex_lock(&data->update_lock); | 1357 | mutex_lock(&data->update_lock); |
1467 | data->gpio_mask = val & 0x1ffff; | 1358 | data->gpio_mask = val & 0x1ffff; |
@@ -1477,26 +1368,19 @@ static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr, | |||
1477 | 1368 | ||
1478 | static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask); | 1369 | static DEVICE_ATTR(gpio_mask, S_IRUGO | S_IWUSR, show_gpio_mask, set_gpio_mask); |
1479 | 1370 | ||
1480 | static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, | 1371 | static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr, char *buf) |
1481 | char *buf) | ||
1482 | { | 1372 | { |
1483 | struct adm1026_data *data = adm1026_update_device(dev); | 1373 | struct adm1026_data *data = adm1026_update_device(dev); |
1484 | return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm1.pwm)); | 1374 | return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm1.pwm)); |
1485 | } | 1375 | } |
1486 | 1376 | static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, const char *buf, | |
1487 | static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, | 1377 | size_t count) |
1488 | const char *buf, size_t count) | ||
1489 | { | 1378 | { |
1490 | struct i2c_client *client = to_i2c_client(dev); | 1379 | struct i2c_client *client = to_i2c_client(dev); |
1491 | struct adm1026_data *data = i2c_get_clientdata(client); | 1380 | struct adm1026_data *data = i2c_get_clientdata(client); |
1492 | 1381 | ||
1493 | if (data->pwm1.enable == 1) { | 1382 | if (data->pwm1.enable == 1) { |
1494 | long val; | 1383 | int val = simple_strtol(buf, NULL, 10); |
1495 | int err; | ||
1496 | |||
1497 | err = kstrtol(buf, 10, &val); | ||
1498 | if (err) | ||
1499 | return err; | ||
1500 | 1384 | ||
1501 | mutex_lock(&data->update_lock); | 1385 | mutex_lock(&data->update_lock); |
1502 | data->pwm1.pwm = PWM_TO_REG(val); | 1386 | data->pwm1.pwm = PWM_TO_REG(val); |
@@ -1505,26 +1389,17 @@ static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, | |||
1505 | } | 1389 | } |
1506 | return count; | 1390 | return count; |
1507 | } | 1391 | } |
1508 | 1392 | static ssize_t show_auto_pwm_min(struct device *dev, struct device_attribute *attr, char *buf) | |
1509 | static ssize_t show_auto_pwm_min(struct device *dev, | ||
1510 | struct device_attribute *attr, char *buf) | ||
1511 | { | 1393 | { |
1512 | struct adm1026_data *data = adm1026_update_device(dev); | 1394 | struct adm1026_data *data = adm1026_update_device(dev); |
1513 | return sprintf(buf, "%d\n", data->pwm1.auto_pwm_min); | 1395 | return sprintf(buf, "%d\n", data->pwm1.auto_pwm_min); |
1514 | } | 1396 | } |
1515 | 1397 | static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *attr, const char *buf, | |
1516 | static ssize_t set_auto_pwm_min(struct device *dev, | 1398 | size_t count) |
1517 | struct device_attribute *attr, const char *buf, | ||
1518 | size_t count) | ||
1519 | { | 1399 | { |
1520 | struct i2c_client *client = to_i2c_client(dev); | 1400 | struct i2c_client *client = to_i2c_client(dev); |
1521 | struct adm1026_data *data = i2c_get_clientdata(client); | 1401 | struct adm1026_data *data = i2c_get_clientdata(client); |
1522 | unsigned long val; | 1402 | int val = simple_strtol(buf, NULL, 10); |
1523 | int err; | ||
1524 | |||
1525 | err = kstrtoul(buf, 10, &val); | ||
1526 | if (err) | ||
1527 | return err; | ||
1528 | 1403 | ||
1529 | mutex_lock(&data->update_lock); | 1404 | mutex_lock(&data->update_lock); |
1530 | data->pwm1.auto_pwm_min = SENSORS_LIMIT(val, 0, 255); | 1405 | data->pwm1.auto_pwm_min = SENSORS_LIMIT(val, 0, 255); |
@@ -1536,53 +1411,44 @@ static ssize_t set_auto_pwm_min(struct device *dev, | |||
1536 | mutex_unlock(&data->update_lock); | 1411 | mutex_unlock(&data->update_lock); |
1537 | return count; | 1412 | return count; |
1538 | } | 1413 | } |
1539 | 1414 | static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf) | |
1540 | static ssize_t show_auto_pwm_max(struct device *dev, | ||
1541 | struct device_attribute *attr, char *buf) | ||
1542 | { | 1415 | { |
1543 | return sprintf(buf, "%d\n", ADM1026_PWM_MAX); | 1416 | return sprintf(buf, "%d\n", ADM1026_PWM_MAX); |
1544 | } | 1417 | } |
1545 | 1418 | static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) | |
1546 | static ssize_t show_pwm_enable(struct device *dev, | ||
1547 | struct device_attribute *attr, char *buf) | ||
1548 | { | 1419 | { |
1549 | struct adm1026_data *data = adm1026_update_device(dev); | 1420 | struct adm1026_data *data = adm1026_update_device(dev); |
1550 | return sprintf(buf, "%d\n", data->pwm1.enable); | 1421 | return sprintf(buf, "%d\n", data->pwm1.enable); |
1551 | } | 1422 | } |
1552 | 1423 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf, | |
1553 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | 1424 | size_t count) |
1554 | const char *buf, size_t count) | ||
1555 | { | 1425 | { |
1556 | struct i2c_client *client = to_i2c_client(dev); | 1426 | struct i2c_client *client = to_i2c_client(dev); |
1557 | struct adm1026_data *data = i2c_get_clientdata(client); | 1427 | struct adm1026_data *data = i2c_get_clientdata(client); |
1428 | int val = simple_strtol(buf, NULL, 10); | ||
1558 | int old_enable; | 1429 | int old_enable; |
1559 | unsigned long val; | ||
1560 | int err; | ||
1561 | 1430 | ||
1562 | err = kstrtoul(buf, 10, &val); | 1431 | if ((val >= 0) && (val < 3)) { |
1563 | if (err) | 1432 | mutex_lock(&data->update_lock); |
1564 | return err; | 1433 | old_enable = data->pwm1.enable; |
1565 | 1434 | data->pwm1.enable = val; | |
1566 | if (val >= 3) | 1435 | data->config1 = (data->config1 & ~CFG1_PWM_AFC) |
1567 | return -EINVAL; | 1436 | | ((val == 2) ? CFG1_PWM_AFC : 0); |
1568 | 1437 | adm1026_write_value(client, ADM1026_REG_CONFIG1, | |
1569 | mutex_lock(&data->update_lock); | 1438 | data->config1); |
1570 | old_enable = data->pwm1.enable; | 1439 | if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */ |
1571 | data->pwm1.enable = val; | 1440 | data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | |
1572 | data->config1 = (data->config1 & ~CFG1_PWM_AFC) | 1441 | PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); |
1573 | | ((val == 2) ? CFG1_PWM_AFC : 0); | 1442 | adm1026_write_value(client, ADM1026_REG_PWM, |
1574 | adm1026_write_value(client, ADM1026_REG_CONFIG1, data->config1); | 1443 | data->pwm1.pwm); |
1575 | if (val == 2) { /* apply pwm1_auto_pwm_min to pwm1 */ | 1444 | } else if (!((old_enable == 1) && (val == 1))) { |
1576 | data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) | | 1445 | /* set pwm to safe value */ |
1577 | PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); | 1446 | data->pwm1.pwm = 255; |
1578 | adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); | 1447 | adm1026_write_value(client, ADM1026_REG_PWM, |
1579 | } else if (!((old_enable == 1) && (val == 1))) { | 1448 | data->pwm1.pwm); |
1580 | /* set pwm to safe value */ | 1449 | } |
1581 | data->pwm1.pwm = 255; | 1450 | mutex_unlock(&data->update_lock); |
1582 | adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm); | ||
1583 | } | 1451 | } |
1584 | mutex_unlock(&data->update_lock); | ||
1585 | |||
1586 | return count; | 1452 | return count; |
1587 | } | 1453 | } |
1588 | 1454 | ||
@@ -1834,10 +1700,11 @@ static int adm1026_probe(struct i2c_client *client, | |||
1834 | struct adm1026_data *data; | 1700 | struct adm1026_data *data; |
1835 | int err; | 1701 | int err; |
1836 | 1702 | ||
1837 | data = devm_kzalloc(&client->dev, sizeof(struct adm1026_data), | 1703 | data = kzalloc(sizeof(struct adm1026_data), GFP_KERNEL); |
1838 | GFP_KERNEL); | 1704 | if (!data) { |
1839 | if (!data) | 1705 | err = -ENOMEM; |
1840 | return -ENOMEM; | 1706 | goto exit; |
1707 | } | ||
1841 | 1708 | ||
1842 | i2c_set_clientdata(client, data); | 1709 | i2c_set_clientdata(client, data); |
1843 | mutex_init(&data->update_lock); | 1710 | mutex_init(&data->update_lock); |
@@ -1849,9 +1716,8 @@ static int adm1026_probe(struct i2c_client *client, | |||
1849 | adm1026_init_client(client); | 1716 | adm1026_init_client(client); |
1850 | 1717 | ||
1851 | /* Register sysfs hooks */ | 1718 | /* Register sysfs hooks */ |
1852 | err = sysfs_create_group(&client->dev.kobj, &adm1026_group); | 1719 | if ((err = sysfs_create_group(&client->dev.kobj, &adm1026_group))) |
1853 | if (err) | 1720 | goto exitfree; |
1854 | return err; | ||
1855 | if (data->config1 & CFG1_AIN8_9) | 1721 | if (data->config1 & CFG1_AIN8_9) |
1856 | err = sysfs_create_group(&client->dev.kobj, | 1722 | err = sysfs_create_group(&client->dev.kobj, |
1857 | &adm1026_group_in8_9); | 1723 | &adm1026_group_in8_9); |
@@ -1876,6 +1742,9 @@ exitremove: | |||
1876 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); | 1742 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); |
1877 | else | 1743 | else |
1878 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); | 1744 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); |
1745 | exitfree: | ||
1746 | kfree(data); | ||
1747 | exit: | ||
1879 | return err; | 1748 | return err; |
1880 | } | 1749 | } |
1881 | 1750 | ||
@@ -1888,12 +1757,24 @@ static int adm1026_remove(struct i2c_client *client) | |||
1888 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); | 1757 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9); |
1889 | else | 1758 | else |
1890 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); | 1759 | sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3); |
1760 | kfree(data); | ||
1891 | return 0; | 1761 | return 0; |
1892 | } | 1762 | } |
1893 | 1763 | ||
1894 | module_i2c_driver(adm1026_driver); | 1764 | static int __init sm_adm1026_init(void) |
1765 | { | ||
1766 | return i2c_add_driver(&adm1026_driver); | ||
1767 | } | ||
1768 | |||
1769 | static void __exit sm_adm1026_exit(void) | ||
1770 | { | ||
1771 | i2c_del_driver(&adm1026_driver); | ||
1772 | } | ||
1895 | 1773 | ||
1896 | MODULE_LICENSE("GPL"); | 1774 | MODULE_LICENSE("GPL"); |
1897 | MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " | 1775 | MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " |
1898 | "Justin Thiessen <jthiessen@penguincomputing.com>"); | 1776 | "Justin Thiessen <jthiessen@penguincomputing.com>"); |
1899 | MODULE_DESCRIPTION("ADM1026 driver"); | 1777 | MODULE_DESCRIPTION("ADM1026 driver"); |
1778 | |||
1779 | module_init(sm_adm1026_init); | ||
1780 | module_exit(sm_adm1026_exit); | ||