Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: Add support for Winbond W83L786NG/NR

Signed-off-by: Kevin Lo <kevlo@kevlo.org>
Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>

authored by

Kevin Lo and committed by
Mark M. Hoffman
85f03bcc ce9c2f44

+886
+54
Documentation/hwmon/w83l786ng
··· 1 + Kernel driver w83l786ng 2 + ===================== 3 + 4 + Supported chips: 5 + * Winbond W83L786NG/W83L786NR 6 + Prefix: 'w83l786ng' 7 + Addresses scanned: I2C 0x2e - 0x2f 8 + Datasheet: http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83L786NRNG09.pdf 9 + 10 + Author: Kevin Lo <kevlo@kevlo.org> 11 + 12 + 13 + Module Parameters 14 + ----------------- 15 + 16 + * reset boolean 17 + (default 0) 18 + Use 'reset=1' to reset the chip (via index 0x40, bit 7). The default 19 + behavior is no chip reset to preserve BIOS settings 20 + 21 + 22 + Description 23 + ----------- 24 + 25 + This driver implements support for Winbond W83L786NG/W83L786NR chips. 26 + 27 + The driver implements two temperature sensors, two fan rotation speed 28 + sensors, and three voltage sensors. 29 + 30 + Temperatures are measured in degrees Celsius and measurement resolution is 1 31 + degC for temp1 and temp2. 32 + 33 + Fan rotation speeds are reported in RPM (rotations per minute). Fan readings 34 + readings can be divided by a programmable divider (1, 2, 4, 8, 16, 32, 64 35 + or 128 for fan 1/2) to give the readings more range or accuracy. 36 + 37 + Voltage sensors (also known as IN sensors) report their values in millivolts. 38 + An alarm is triggered if the voltage has crossed a programmable minimum 39 + or maximum limit. 40 + 41 + /sys files 42 + ---------- 43 + 44 + pwm[1-2] - this file stores PWM duty cycle or DC value (fan speed) in range: 45 + 0 (stop) to 255 (full) 46 + pwm[1-2]_enable - this file controls mode of fan/temperature control: 47 + * 0 Manual Mode 48 + * 1 Thermal Cruise 49 + * 2 Smart Fan II 50 + * 4 FAN_SET 51 + pwm[1-2]_mode - Select PWM of DC mode 52 + * 0 DC 53 + * 1 PWM 54 + tolerance[1-2] - Value in degrees of Celsius (degC) for +- T
+10
drivers/hwmon/Kconfig
··· 683 683 This driver can also be built as a module. If so, the module 684 684 will be called w83l785ts. 685 685 686 + config SENSORS_W83L786NG 687 + tristate "Winbond W83L786NG, W83L786NR" 688 + depends on I2C && EXPERIMENTAL 689 + help 690 + If you say yes here you get support for the Winbond W83L786NG 691 + and W83L786NR sensor chips. 692 + 693 + This driver can also be built as a module. If so, the module 694 + will be called w83l786ng. 695 + 686 696 config SENSORS_W83627HF 687 697 tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF" 688 698 select HWMON_VID
+1
drivers/hwmon/Makefile
··· 68 68 obj-$(CONFIG_SENSORS_VT8231) += vt8231.o 69 69 obj-$(CONFIG_SENSORS_W83627EHF) += w83627ehf.o 70 70 obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o 71 + obj-$(CONFIG_SENSORS_W83L786NG) += w83l786ng.o 71 72 72 73 ifeq ($(CONFIG_HWMON_DEBUG_CHIP),y) 73 74 EXTRA_CFLAGS += -DDEBUG
+821
drivers/hwmon/w83l786ng.c
··· 1 + /* 2 + w83l786ng.c - Linux kernel driver for hardware monitoring 3 + Copyright (c) 2007 Kevin Lo <kevlo@kevlo.org> 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 - version 2. 8 + 9 + This program is distributed in the hope that it will be useful, 10 + but WITHOUT ANY WARRANTY; without even the implied warranty of 11 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 + GNU General Public License for more details. 13 + 14 + You should have received a copy of the GNU General Public License 15 + along with this program; if not, write to the Free Software 16 + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 17 + 02110-1301 USA. 18 + */ 19 + 20 + /* 21 + Supports following chips: 22 + 23 + Chip #vin #fanin #pwm #temp wchipid vendid i2c ISA 24 + w83l786ng 3 2 2 2 0x7b 0x5ca3 yes no 25 + */ 26 + 27 + #include <linux/module.h> 28 + #include <linux/init.h> 29 + #include <linux/slab.h> 30 + #include <linux/i2c.h> 31 + #include <linux/hwmon.h> 32 + #include <linux/hwmon-vid.h> 33 + #include <linux/hwmon-sysfs.h> 34 + #include <linux/err.h> 35 + #include <linux/mutex.h> 36 + 37 + /* Addresses to scan */ 38 + static unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END }; 39 + 40 + /* Insmod parameters */ 41 + I2C_CLIENT_INSMOD_1(w83l786ng); 42 + 43 + static int reset; 44 + module_param(reset, bool, 0); 45 + MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); 46 + 47 + #define W83L786NG_REG_IN_MIN(nr) (0x2C + (nr) * 2) 48 + #define W83L786NG_REG_IN_MAX(nr) (0x2B + (nr) * 2) 49 + #define W83L786NG_REG_IN(nr) ((nr) + 0x20) 50 + 51 + #define W83L786NG_REG_FAN(nr) ((nr) + 0x28) 52 + #define W83L786NG_REG_FAN_MIN(nr) ((nr) + 0x3B) 53 + 54 + #define W83L786NG_REG_CONFIG 0x40 55 + #define W83L786NG_REG_ALARM1 0x41 56 + #define W83L786NG_REG_ALARM2 0x42 57 + #define W83L786NG_REG_GPIO_EN 0x47 58 + #define W83L786NG_REG_MAN_ID2 0x4C 59 + #define W83L786NG_REG_MAN_ID1 0x4D 60 + #define W83L786NG_REG_CHIP_ID 0x4E 61 + 62 + #define W83L786NG_REG_DIODE 0x53 63 + #define W83L786NG_REG_FAN_DIV 0x54 64 + #define W83L786NG_REG_FAN_CFG 0x80 65 + 66 + #define W83L786NG_REG_TOLERANCE 0x8D 67 + 68 + static const u8 W83L786NG_REG_TEMP[2][3] = { 69 + { 0x25, /* TEMP 0 in DataSheet */ 70 + 0x35, /* TEMP 0 Over in DataSheet */ 71 + 0x36 }, /* TEMP 0 Hyst in DataSheet */ 72 + { 0x26, /* TEMP 1 in DataSheet */ 73 + 0x37, /* TEMP 1 Over in DataSheet */ 74 + 0x38 } /* TEMP 1 Hyst in DataSheet */ 75 + }; 76 + 77 + static const u8 W83L786NG_PWM_MODE_SHIFT[] = {6, 7}; 78 + static const u8 W83L786NG_PWM_ENABLE_SHIFT[] = {2, 4}; 79 + 80 + /* FAN Duty Cycle, be used to control */ 81 + static const u8 W83L786NG_REG_PWM[] = {0x81, 0x87}; 82 + 83 + 84 + static inline u8 85 + FAN_TO_REG(long rpm, int div) 86 + { 87 + if (rpm == 0) 88 + return 255; 89 + rpm = SENSORS_LIMIT(rpm, 1, 1000000); 90 + return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254); 91 + } 92 + 93 + #define FAN_FROM_REG(val,div) ((val) == 0 ? -1 : \ 94 + ((val) == 255 ? 0 : \ 95 + 1350000 / ((val) * (div)))) 96 + 97 + /* for temp */ 98 + #define TEMP_TO_REG(val) (SENSORS_LIMIT(((val) < 0 ? (val)+0x100*1000 \ 99 + : (val)) / 1000, 0, 0xff)) 100 + #define TEMP_FROM_REG(val) (((val) & 0x80 ? (val)-0x100 : (val)) * 1000) 101 + 102 + /* The analog voltage inputs have 8mV LSB. Since the sysfs output is 103 + in mV as would be measured on the chip input pin, need to just 104 + multiply/divide by 8 to translate from/to register values. */ 105 + #define IN_TO_REG(val) (SENSORS_LIMIT((((val) + 4) / 8), 0, 255)) 106 + #define IN_FROM_REG(val) ((val) * 8) 107 + 108 + #define DIV_FROM_REG(val) (1 << (val)) 109 + 110 + static inline u8 111 + DIV_TO_REG(long val) 112 + { 113 + int i; 114 + val = SENSORS_LIMIT(val, 1, 128) >> 1; 115 + for (i = 0; i < 7; i++) { 116 + if (val == 0) 117 + break; 118 + val >>= 1; 119 + } 120 + return ((u8) i); 121 + } 122 + 123 + struct w83l786ng_data { 124 + struct i2c_client client; 125 + struct device *hwmon_dev; 126 + struct mutex update_lock; 127 + char valid; /* !=0 if following fields are valid */ 128 + unsigned long last_updated; /* In jiffies */ 129 + unsigned long last_nonvolatile; /* In jiffies, last time we update the 130 + nonvolatile registers */ 131 + 132 + u8 in[3]; 133 + u8 in_max[3]; 134 + u8 in_min[3]; 135 + u8 fan[2]; 136 + u8 fan_div[2]; 137 + u8 fan_min[2]; 138 + u8 temp_type[2]; 139 + u8 temp[2][3]; 140 + u8 pwm[2]; 141 + u8 pwm_mode[2]; /* 0->DC variable voltage 142 + 1->PWM variable duty cycle */ 143 + 144 + u8 pwm_enable[2]; /* 1->manual 145 + 2->thermal cruise (also called SmartFan I) */ 146 + u8 tolerance[2]; 147 + }; 148 + 149 + static int w83l786ng_attach_adapter(struct i2c_adapter *adapter); 150 + static int w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind); 151 + static int w83l786ng_detach_client(struct i2c_client *client); 152 + static void w83l786ng_init_client(struct i2c_client *client); 153 + static struct w83l786ng_data *w83l786ng_update_device(struct device *dev); 154 + 155 + static struct i2c_driver w83l786ng_driver = { 156 + .driver = { 157 + .name = "w83l786ng", 158 + }, 159 + .attach_adapter = w83l786ng_attach_adapter, 160 + .detach_client = w83l786ng_detach_client, 161 + }; 162 + 163 + static u8 164 + w83l786ng_read_value(struct i2c_client *client, u8 reg) 165 + { 166 + return i2c_smbus_read_byte_data(client, reg); 167 + } 168 + 169 + static int 170 + w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value) 171 + { 172 + return i2c_smbus_write_byte_data(client, reg, value); 173 + } 174 + 175 + /* following are the sysfs callback functions */ 176 + #define show_in_reg(reg) \ 177 + static ssize_t \ 178 + show_##reg(struct device *dev, struct device_attribute *attr, \ 179 + char *buf) \ 180 + { \ 181 + int nr = to_sensor_dev_attr(attr)->index; \ 182 + struct w83l786ng_data *data = w83l786ng_update_device(dev); \ 183 + return sprintf(buf,"%d\n", IN_FROM_REG(data->reg[nr])); \ 184 + } 185 + 186 + show_in_reg(in) 187 + show_in_reg(in_min) 188 + show_in_reg(in_max) 189 + 190 + #define store_in_reg(REG, reg) \ 191 + static ssize_t \ 192 + store_in_##reg (struct device *dev, struct device_attribute *attr, \ 193 + const char *buf, size_t count) \ 194 + { \ 195 + int nr = to_sensor_dev_attr(attr)->index; \ 196 + struct i2c_client *client = to_i2c_client(dev); \ 197 + struct w83l786ng_data *data = i2c_get_clientdata(client); \ 198 + unsigned long val = simple_strtoul(buf, NULL, 10); \ 199 + mutex_lock(&data->update_lock); \ 200 + data->in_##reg[nr] = IN_TO_REG(val); \ 201 + w83l786ng_write_value(client, W83L786NG_REG_IN_##REG(nr), \ 202 + data->in_##reg[nr]); \ 203 + mutex_unlock(&data->update_lock); \ 204 + return count; \ 205 + } 206 + 207 + store_in_reg(MIN, min) 208 + store_in_reg(MAX, max) 209 + 210 + static struct sensor_device_attribute sda_in_input[] = { 211 + SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0), 212 + SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1), 213 + SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2), 214 + }; 215 + 216 + static struct sensor_device_attribute sda_in_min[] = { 217 + SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0), 218 + SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1), 219 + SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2), 220 + }; 221 + 222 + static struct sensor_device_attribute sda_in_max[] = { 223 + SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0), 224 + SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1), 225 + SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2), 226 + }; 227 + 228 + #define show_fan_reg(reg) \ 229 + static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \ 230 + char *buf) \ 231 + { \ 232 + int nr = to_sensor_dev_attr(attr)->index; \ 233 + struct w83l786ng_data *data = w83l786ng_update_device(dev); \ 234 + return sprintf(buf,"%d\n", \ 235 + FAN_FROM_REG(data->fan[nr], DIV_FROM_REG(data->fan_div[nr]))); \ 236 + } 237 + 238 + show_fan_reg(fan); 239 + show_fan_reg(fan_min); 240 + 241 + static ssize_t 242 + store_fan_min(struct device *dev, struct device_attribute *attr, 243 + const char *buf, size_t count) 244 + { 245 + int nr = to_sensor_dev_attr(attr)->index; 246 + struct i2c_client *client = to_i2c_client(dev); 247 + struct w83l786ng_data *data = i2c_get_clientdata(client); 248 + u32 val; 249 + 250 + val = simple_strtoul(buf, NULL, 10); 251 + mutex_lock(&data->update_lock); 252 + data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); 253 + w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr), 254 + data->fan_min[nr]); 255 + mutex_unlock(&data->update_lock); 256 + 257 + return count; 258 + } 259 + 260 + static ssize_t 261 + show_fan_div(struct device *dev, struct device_attribute *attr, 262 + char *buf) 263 + { 264 + int nr = to_sensor_dev_attr(attr)->index; 265 + struct w83l786ng_data *data = w83l786ng_update_device(dev); 266 + return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr])); 267 + } 268 + 269 + /* Note: we save and restore the fan minimum here, because its value is 270 + determined in part by the fan divisor. This follows the principle of 271 + least surprise; the user doesn't expect the fan minimum to change just 272 + because the divisor changed. */ 273 + static ssize_t 274 + store_fan_div(struct device *dev, struct device_attribute *attr, 275 + const char *buf, size_t count) 276 + { 277 + int nr = to_sensor_dev_attr(attr)->index; 278 + struct i2c_client *client = to_i2c_client(dev); 279 + struct w83l786ng_data *data = i2c_get_clientdata(client); 280 + 281 + unsigned long min; 282 + u8 tmp_fan_div; 283 + u8 fan_div_reg; 284 + u8 keep_mask = 0; 285 + u8 new_shift = 0; 286 + 287 + /* Save fan_min */ 288 + mutex_lock(&data->update_lock); 289 + min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); 290 + 291 + data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10)); 292 + 293 + switch (nr) { 294 + case 0: 295 + keep_mask = 0xf8; 296 + new_shift = 0; 297 + break; 298 + case 1: 299 + keep_mask = 0x8f; 300 + new_shift = 4; 301 + break; 302 + } 303 + 304 + fan_div_reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV) 305 + & keep_mask; 306 + 307 + tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask; 308 + 309 + w83l786ng_write_value(client, W83L786NG_REG_FAN_DIV, 310 + fan_div_reg | tmp_fan_div); 311 + 312 + /* Restore fan_min */ 313 + data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); 314 + w83l786ng_write_value(client, W83L786NG_REG_FAN_MIN(nr), 315 + data->fan_min[nr]); 316 + mutex_unlock(&data->update_lock); 317 + 318 + return count; 319 + } 320 + 321 + static struct sensor_device_attribute sda_fan_input[] = { 322 + SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0), 323 + SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1), 324 + }; 325 + 326 + static struct sensor_device_attribute sda_fan_min[] = { 327 + SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, 328 + store_fan_min, 0), 329 + SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, 330 + store_fan_min, 1), 331 + }; 332 + 333 + static struct sensor_device_attribute sda_fan_div[] = { 334 + SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div, 335 + store_fan_div, 0), 336 + SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div, 337 + store_fan_div, 1), 338 + }; 339 + 340 + 341 + /* read/write the temperature, includes measured value and limits */ 342 + 343 + static ssize_t 344 + show_temp(struct device *dev, struct device_attribute *attr, char *buf) 345 + { 346 + struct sensor_device_attribute_2 *sensor_attr = 347 + to_sensor_dev_attr_2(attr); 348 + int nr = sensor_attr->nr; 349 + int index = sensor_attr->index; 350 + struct w83l786ng_data *data = w83l786ng_update_device(dev); 351 + return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp[nr][index])); 352 + } 353 + 354 + static ssize_t 355 + store_temp(struct device *dev, struct device_attribute *attr, 356 + const char *buf, size_t count) 357 + { 358 + struct sensor_device_attribute_2 *sensor_attr = 359 + to_sensor_dev_attr_2(attr); 360 + int nr = sensor_attr->nr; 361 + int index = sensor_attr->index; 362 + struct i2c_client *client = to_i2c_client(dev); 363 + struct w83l786ng_data *data = i2c_get_clientdata(client); 364 + s32 val; 365 + 366 + val = simple_strtol(buf, NULL, 10); 367 + mutex_lock(&data->update_lock); 368 + data->temp[nr][index] = TEMP_TO_REG(val); 369 + w83l786ng_write_value(client, W83L786NG_REG_TEMP[nr][index], 370 + data->temp[nr][index]); 371 + mutex_unlock(&data->update_lock); 372 + 373 + return count; 374 + } 375 + 376 + static struct sensor_device_attribute_2 sda_temp_input[] = { 377 + SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0), 378 + SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, 0), 379 + }; 380 + 381 + static struct sensor_device_attribute_2 sda_temp_max[] = { 382 + SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, 383 + show_temp, store_temp, 0, 1), 384 + SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, 385 + show_temp, store_temp, 1, 1), 386 + }; 387 + 388 + static struct sensor_device_attribute_2 sda_temp_max_hyst[] = { 389 + SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, 390 + show_temp, store_temp, 0, 2), 391 + SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, 392 + show_temp, store_temp, 1, 2), 393 + }; 394 + 395 + #define show_pwm_reg(reg) \ 396 + static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \ 397 + char *buf) \ 398 + { \ 399 + struct w83l786ng_data *data = w83l786ng_update_device(dev); \ 400 + int nr = to_sensor_dev_attr(attr)->index; \ 401 + return sprintf(buf, "%d\n", data->reg[nr]); \ 402 + } 403 + 404 + show_pwm_reg(pwm_mode) 405 + show_pwm_reg(pwm_enable) 406 + show_pwm_reg(pwm) 407 + 408 + static ssize_t 409 + store_pwm_mode(struct device *dev, struct device_attribute *attr, 410 + const char *buf, size_t count) 411 + { 412 + int nr = to_sensor_dev_attr(attr)->index; 413 + struct i2c_client *client = to_i2c_client(dev); 414 + struct w83l786ng_data *data = i2c_get_clientdata(client); 415 + u32 val = simple_strtoul(buf, NULL, 10); 416 + u8 reg; 417 + 418 + if (val > 1) 419 + return -EINVAL; 420 + mutex_lock(&data->update_lock); 421 + data->pwm_mode[nr] = val; 422 + reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); 423 + reg &= ~(1 << W83L786NG_PWM_MODE_SHIFT[nr]); 424 + if (!val) 425 + reg |= 1 << W83L786NG_PWM_MODE_SHIFT[nr]; 426 + w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg); 427 + mutex_unlock(&data->update_lock); 428 + return count; 429 + } 430 + 431 + static ssize_t 432 + store_pwm(struct device *dev, struct device_attribute *attr, 433 + const char *buf, size_t count) 434 + { 435 + int nr = to_sensor_dev_attr(attr)->index; 436 + struct i2c_client *client = to_i2c_client(dev); 437 + struct w83l786ng_data *data = i2c_get_clientdata(client); 438 + u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 0, 255); 439 + 440 + mutex_lock(&data->update_lock); 441 + data->pwm[nr] = val; 442 + w83l786ng_write_value(client, W83L786NG_REG_PWM[nr], val); 443 + mutex_unlock(&data->update_lock); 444 + return count; 445 + } 446 + 447 + static ssize_t 448 + store_pwm_enable(struct device *dev, struct device_attribute *attr, 449 + const char *buf, size_t count) 450 + { 451 + int nr = to_sensor_dev_attr(attr)->index; 452 + struct i2c_client *client = to_i2c_client(dev); 453 + struct w83l786ng_data *data = i2c_get_clientdata(client); 454 + u32 val = simple_strtoul(buf, NULL, 10); 455 + 456 + u8 reg; 457 + 458 + if (!val || (val > 2)) /* only modes 1 and 2 are supported */ 459 + return -EINVAL; 460 + 461 + mutex_lock(&data->update_lock); 462 + reg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); 463 + data->pwm_enable[nr] = val; 464 + reg &= ~(0x02 << W83L786NG_PWM_ENABLE_SHIFT[nr]); 465 + reg |= (val - 1) << W83L786NG_PWM_ENABLE_SHIFT[nr]; 466 + w83l786ng_write_value(client, W83L786NG_REG_FAN_CFG, reg); 467 + mutex_unlock(&data->update_lock); 468 + return count; 469 + } 470 + 471 + static struct sensor_device_attribute sda_pwm[] = { 472 + SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0), 473 + SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1), 474 + }; 475 + 476 + static struct sensor_device_attribute sda_pwm_mode[] = { 477 + SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO, show_pwm_mode, 478 + store_pwm_mode, 0), 479 + SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO, show_pwm_mode, 480 + store_pwm_mode, 1), 481 + }; 482 + 483 + static struct sensor_device_attribute sda_pwm_enable[] = { 484 + SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, 485 + store_pwm_enable, 0), 486 + SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, 487 + store_pwm_enable, 1), 488 + }; 489 + 490 + /* For Smart Fan I/Thermal Cruise and Smart Fan II */ 491 + static ssize_t 492 + show_tolerance(struct device *dev, struct device_attribute *attr, char *buf) 493 + { 494 + int nr = to_sensor_dev_attr(attr)->index; 495 + struct w83l786ng_data *data = w83l786ng_update_device(dev); 496 + return sprintf(buf, "%ld\n", (long)data->tolerance[nr]); 497 + } 498 + 499 + static ssize_t 500 + store_tolerance(struct device *dev, struct device_attribute *attr, 501 + const char *buf, size_t count) 502 + { 503 + int nr = to_sensor_dev_attr(attr)->index; 504 + struct i2c_client *client = to_i2c_client(dev); 505 + struct w83l786ng_data *data = i2c_get_clientdata(client); 506 + u32 val; 507 + u8 tol_tmp, tol_mask; 508 + 509 + val = simple_strtoul(buf, NULL, 10); 510 + 511 + mutex_lock(&data->update_lock); 512 + tol_mask = w83l786ng_read_value(client, 513 + W83L786NG_REG_TOLERANCE) & ((nr == 1) ? 0x0f : 0xf0); 514 + tol_tmp = SENSORS_LIMIT(val, 0, 15); 515 + tol_tmp &= 0x0f; 516 + data->tolerance[nr] = tol_tmp; 517 + if (nr == 1) { 518 + tol_tmp <<= 4; 519 + } 520 + 521 + w83l786ng_write_value(client, W83L786NG_REG_TOLERANCE, 522 + tol_mask | tol_tmp); 523 + mutex_unlock(&data->update_lock); 524 + return count; 525 + } 526 + 527 + static struct sensor_device_attribute sda_tolerance[] = { 528 + SENSOR_ATTR(pwm1_tolerance, S_IWUSR | S_IRUGO, 529 + show_tolerance, store_tolerance, 0), 530 + SENSOR_ATTR(pwm2_tolerance, S_IWUSR | S_IRUGO, 531 + show_tolerance, store_tolerance, 1), 532 + }; 533 + 534 + 535 + #define IN_UNIT_ATTRS(X) \ 536 + &sda_in_input[X].dev_attr.attr, \ 537 + &sda_in_min[X].dev_attr.attr, \ 538 + &sda_in_max[X].dev_attr.attr 539 + 540 + #define FAN_UNIT_ATTRS(X) \ 541 + &sda_fan_input[X].dev_attr.attr, \ 542 + &sda_fan_min[X].dev_attr.attr, \ 543 + &sda_fan_div[X].dev_attr.attr 544 + 545 + #define TEMP_UNIT_ATTRS(X) \ 546 + &sda_temp_input[X].dev_attr.attr, \ 547 + &sda_temp_max[X].dev_attr.attr, \ 548 + &sda_temp_max_hyst[X].dev_attr.attr 549 + 550 + #define PWM_UNIT_ATTRS(X) \ 551 + &sda_pwm[X].dev_attr.attr, \ 552 + &sda_pwm_mode[X].dev_attr.attr, \ 553 + &sda_pwm_enable[X].dev_attr.attr 554 + 555 + #define TOLERANCE_UNIT_ATTRS(X) \ 556 + &sda_tolerance[X].dev_attr.attr 557 + 558 + static struct attribute *w83l786ng_attributes[] = { 559 + IN_UNIT_ATTRS(0), 560 + IN_UNIT_ATTRS(1), 561 + IN_UNIT_ATTRS(2), 562 + FAN_UNIT_ATTRS(0), 563 + FAN_UNIT_ATTRS(1), 564 + TEMP_UNIT_ATTRS(0), 565 + TEMP_UNIT_ATTRS(1), 566 + PWM_UNIT_ATTRS(0), 567 + PWM_UNIT_ATTRS(1), 568 + TOLERANCE_UNIT_ATTRS(0), 569 + TOLERANCE_UNIT_ATTRS(1), 570 + NULL 571 + }; 572 + 573 + static const struct attribute_group w83l786ng_group = { 574 + .attrs = w83l786ng_attributes, 575 + }; 576 + 577 + static int 578 + w83l786ng_attach_adapter(struct i2c_adapter *adapter) 579 + { 580 + if (!(adapter->class & I2C_CLASS_HWMON)) 581 + return 0; 582 + return i2c_probe(adapter, &addr_data, w83l786ng_detect); 583 + } 584 + 585 + static int 586 + w83l786ng_detect(struct i2c_adapter *adapter, int address, int kind) 587 + { 588 + struct i2c_client *client; 589 + struct device *dev; 590 + struct w83l786ng_data *data; 591 + int i, err = 0; 592 + u8 reg_tmp; 593 + 594 + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 595 + goto exit; 596 + } 597 + 598 + /* OK. For now, we presume we have a valid client. We now create the 599 + client structure, even though we cannot fill it completely yet. 600 + But it allows us to access w83l786ng_{read,write}_value. */ 601 + 602 + if (!(data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL))) { 603 + err = -ENOMEM; 604 + goto exit; 605 + } 606 + 607 + client = &data->client; 608 + dev = &client->dev; 609 + i2c_set_clientdata(client, data); 610 + client->addr = address; 611 + client->adapter = adapter; 612 + client->driver = &w83l786ng_driver; 613 + 614 + /* 615 + * Now we do the remaining detection. A negative kind means that 616 + * the driver was loaded with no force parameter (default), so we 617 + * must both detect and identify the chip (actually there is only 618 + * one possible kind of chip for now, W83L786NG). A zero kind means 619 + * that the driver was loaded with the force parameter, the detection 620 + * step shall be skipped. A positive kind means that the driver 621 + * was loaded with the force parameter and a given kind of chip is 622 + * requested, so both the detection and the identification steps 623 + * are skipped. 624 + */ 625 + if (kind < 0) { /* detection */ 626 + if (((w83l786ng_read_value(client, 627 + W83L786NG_REG_CONFIG) & 0x80) != 0x00)) { 628 + dev_dbg(&adapter->dev, 629 + "W83L786NG detection failed at 0x%02x.\n", 630 + address); 631 + goto exit_free; 632 + } 633 + } 634 + 635 + if (kind <= 0) { /* identification */ 636 + u16 man_id; 637 + u8 chip_id; 638 + 639 + man_id = (w83l786ng_read_value(client, 640 + W83L786NG_REG_MAN_ID1) << 8) + 641 + w83l786ng_read_value(client, W83L786NG_REG_MAN_ID2); 642 + chip_id = w83l786ng_read_value(client, W83L786NG_REG_CHIP_ID); 643 + 644 + if (man_id == 0x5CA3) { /* Winbond */ 645 + if (chip_id == 0x80) { /* W83L786NG */ 646 + kind = w83l786ng; 647 + } 648 + } 649 + 650 + if (kind <= 0) { /* identification failed */ 651 + dev_info(&adapter->dev, 652 + "Unsupported chip (man_id=0x%04X, " 653 + "chip_id=0x%02X).\n", man_id, chip_id); 654 + goto exit_free; 655 + } 656 + } 657 + 658 + /* Fill in the remaining client fields and put into the global list */ 659 + strlcpy(client->name, "w83l786ng", I2C_NAME_SIZE); 660 + mutex_init(&data->update_lock); 661 + 662 + /* Tell the I2C layer a new client has arrived */ 663 + if ((err = i2c_attach_client(client))) 664 + goto exit_free; 665 + 666 + /* Initialize the chip */ 667 + w83l786ng_init_client(client); 668 + 669 + /* A few vars need to be filled upon startup */ 670 + for (i = 0; i < 2; i++) { 671 + data->fan_min[i] = w83l786ng_read_value(client, 672 + W83L786NG_REG_FAN_MIN(i)); 673 + } 674 + 675 + /* Update the fan divisor */ 676 + reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV); 677 + data->fan_div[0] = reg_tmp & 0x07; 678 + data->fan_div[1] = (reg_tmp >> 4) & 0x07; 679 + 680 + /* Register sysfs hooks */ 681 + if ((err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group))) 682 + goto exit_remove; 683 + 684 + data->hwmon_dev = hwmon_device_register(dev); 685 + if (IS_ERR(data->hwmon_dev)) { 686 + err = PTR_ERR(data->hwmon_dev); 687 + goto exit_remove; 688 + } 689 + 690 + return 0; 691 + 692 + /* Unregister sysfs hooks */ 693 + 694 + exit_remove: 695 + sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); 696 + i2c_detach_client(client); 697 + exit_free: 698 + kfree(data); 699 + exit: 700 + return err; 701 + } 702 + 703 + static int 704 + w83l786ng_detach_client(struct i2c_client *client) 705 + { 706 + struct w83l786ng_data *data = i2c_get_clientdata(client); 707 + int err; 708 + 709 + hwmon_device_unregister(data->hwmon_dev); 710 + sysfs_remove_group(&client->dev.kobj, &w83l786ng_group); 711 + 712 + if ((err = i2c_detach_client(client))) 713 + return err; 714 + 715 + kfree(data); 716 + 717 + return 0; 718 + } 719 + 720 + static void 721 + w83l786ng_init_client(struct i2c_client *client) 722 + { 723 + u8 tmp; 724 + 725 + if (reset) 726 + w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80); 727 + 728 + /* Start monitoring */ 729 + tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG); 730 + if (!(tmp & 0x01)) 731 + w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01); 732 + } 733 + 734 + static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) 735 + { 736 + struct i2c_client *client = to_i2c_client(dev); 737 + struct w83l786ng_data *data = i2c_get_clientdata(client); 738 + int i, j; 739 + u8 reg_tmp, pwmcfg; 740 + 741 + mutex_lock(&data->update_lock); 742 + if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 743 + || !data->valid) { 744 + dev_dbg(&client->dev, "Updating w83l786ng data.\n"); 745 + 746 + /* Update the voltages measured value and limits */ 747 + for (i = 0; i < 3; i++) { 748 + data->in[i] = w83l786ng_read_value(client, 749 + W83L786NG_REG_IN(i)); 750 + data->in_min[i] = w83l786ng_read_value(client, 751 + W83L786NG_REG_IN_MIN(i)); 752 + data->in_max[i] = w83l786ng_read_value(client, 753 + W83L786NG_REG_IN_MAX(i)); 754 + } 755 + 756 + /* Update the fan counts and limits */ 757 + for (i = 0; i < 2; i++) { 758 + data->fan[i] = w83l786ng_read_value(client, 759 + W83L786NG_REG_FAN(i)); 760 + data->fan_min[i] = w83l786ng_read_value(client, 761 + W83L786NG_REG_FAN_MIN(i)); 762 + } 763 + 764 + /* Update the fan divisor */ 765 + reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV); 766 + data->fan_div[0] = reg_tmp & 0x07; 767 + data->fan_div[1] = (reg_tmp >> 4) & 0x07; 768 + 769 + pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); 770 + for (i = 0; i < 2; i++) { 771 + data->pwm_mode[i] = 772 + ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1) 773 + ? 0 : 1; 774 + data->pwm_enable[i] = 775 + ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 2) + 1; 776 + data->pwm[i] = w83l786ng_read_value(client, 777 + W83L786NG_REG_PWM[i]); 778 + } 779 + 780 + 781 + /* Update the temperature sensors */ 782 + for (i = 0; i < 2; i++) { 783 + for (j = 0; j < 3; j++) { 784 + data->temp[i][j] = w83l786ng_read_value(client, 785 + W83L786NG_REG_TEMP[i][j]); 786 + } 787 + } 788 + 789 + /* Update Smart Fan I/II tolerance */ 790 + reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE); 791 + data->tolerance[0] = reg_tmp & 0x0f; 792 + data->tolerance[1] = (reg_tmp >> 4) & 0x0f; 793 + 794 + data->last_updated = jiffies; 795 + data->valid = 1; 796 + 797 + } 798 + 799 + mutex_unlock(&data->update_lock); 800 + 801 + return data; 802 + } 803 + 804 + static int __init 805 + sensors_w83l786ng_init(void) 806 + { 807 + return i2c_add_driver(&w83l786ng_driver); 808 + } 809 + 810 + static void __exit 811 + sensors_w83l786ng_exit(void) 812 + { 813 + i2c_del_driver(&w83l786ng_driver); 814 + } 815 + 816 + MODULE_AUTHOR("Kevin Lo"); 817 + MODULE_DESCRIPTION("w83l786ng driver"); 818 + MODULE_LICENSE("GPL"); 819 + 820 + module_init(sensors_w83l786ng_init); 821 + module_exit(sensors_w83l786ng_exit);