11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * lm85.c - Part of lm_sensors, Linux kernel modules for hardware 309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * monitoring 409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> 509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 2002, 2003 Philip Pokorny <ppokorny@penguincomputing.com> 609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 2003 Margit Schubert-While <margitsw@t-online.de> 709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Copyright (c) 2004 Justin Thiessen <jthiessen@penguincomputing.com> 8590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare * Copyright (C) 2007--2014 Jean Delvare <jdelvare@suse.de> 909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * 1009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Chip details at <http://www.national.com/ds/LM/LM85.pdf> 1109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * 1209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * This program is free software; you can redistribute it and/or modify 1309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * it under the terms of the GNU General Public License as published by 1409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * the Free Software Foundation; either version 2 of the License, or 1509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * (at your option) any later version. 1609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * 1709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * This program is distributed in the hope that it will be useful, 1809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * but WITHOUT ANY WARRANTY; without even the implied warranty of 1909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * GNU General Public License for more details. 2109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * 2209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * You should have received a copy of the GNU General Public License 2309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * along with this program; if not, write to the Free Software 2409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 2509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/jiffies.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/i2c.h> 32943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/hwmon.h> 33303760b44a7a142cb9f4c9df4609fb63bbda98dbJean Delvare#include <linux/hwmon-vid.h> 34b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare#include <linux/hwmon-sysfs.h> 35943b0830cebe4711354945ed3cb44e84152aaca0Mark M. Hoffman#include <linux/err.h> 369a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar#include <linux/mutex.h> 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Addresses to scan */ 3925e9c86d5a6d82ea45eb680fc66bf73ac5e50dffMark M. Hoffmanstatic const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41e5e9f44c246fbafe723e579e9fe887677beb40e4Jean Delvareenum chips { 42590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare lm85, 43e5e9f44c246fbafe723e579e9fe887677beb40e4Jean Delvare adm1027, adt7463, adt7468, 4406923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck emc6d100, emc6d102, emc6d103, emc6d103s 45e5e9f44c246fbafe723e579e9fe887677beb40e4Jean Delvare}; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The LM85 registers */ 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_IN(nr) (0x20 + (nr)) 5009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_IN_MIN(nr) (0x44 + (nr) * 2) 5109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_IN_MAX(nr) (0x45 + (nr) * 2) 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_TEMP(nr) (0x25 + (nr)) 5409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_TEMP_MIN(nr) (0x4e + (nr) * 2) 5509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_TEMP_MAX(nr) (0x4f + (nr) * 2) 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Fan speeds are LSB, MSB (2 bytes) */ 5809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_FAN(nr) (0x28 + (nr) * 2) 5909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_FAN_MIN(nr) (0x54 + (nr) * 2) 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_PWM(nr) (0x30 + (nr)) 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_COMPANY 0x3e 6409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_VERSTEP 0x3f 6579b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong 6609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADT7468_REG_CFG5 0x7c 6709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADT7468_OFF64 (1 << 0) 6809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADT7468_HFPWM (1 << 1) 6909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define IS_ADT7468_OFF64(data) \ 7079b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_OFF64)) 7109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define IS_ADT7468_HFPWM(data) \ 72f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare ((data)->type == adt7468 && !((data)->cfg5 & ADT7468_HFPWM)) 7379b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These are the recognized values for the above regs */ 7509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_COMPANY_NATIONAL 0x01 7609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_COMPANY_ANALOG_DEV 0x41 7709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_COMPANY_SMSC 0x5c 7809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM85C 0x60 7909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM85B 0x62 8009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM96000_1 0x68 8109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_LM96000_2 0x69 8209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADM1027 0x60 8309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7463 0x62 8409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7463C 0x6A 8509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7468_1 0x71 8609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_ADT7468_2 0x72 8709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D100_A0 0x60 8809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D100_A1 0x61 8909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D102 0x65 9009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D103_A0 0x68 9109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D103_A1 0x69 9209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_VERSTEP_EMC6D103S 0x6A /* Also known as EMC6D103:A2 */ 9309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 9409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_CONFIG 0x40 9509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 9609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_ALARM1 0x41 9709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_ALARM2 0x42 9809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 9909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_VID 0x43 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Automated FAN control */ 10209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_CONFIG(nr) (0x5c + (nr)) 10309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_RANGE(nr) (0x5f + (nr)) 10409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_SPIKE1 0x62 10509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_MINPWM(nr) (0x64 + (nr)) 10609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_LIMIT(nr) (0x67 + (nr)) 10709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_CRITICAL(nr) (0x6a + (nr)) 10809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_HYST1 0x6d 10909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define LM85_REG_AFAN_HYST2 0x6e 11009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 11109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADM1027_REG_EXTEND_ADC1 0x76 11209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define ADM1027_REG_EXTEND_ADC2 0x77 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define EMC6D100_REG_ALARM3 0x7d 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* IN5, IN6 and IN7 */ 11609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D100_REG_IN(nr) (0x70 + ((nr) - 5)) 11709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D100_REG_IN_MIN(nr) (0x73 + ((nr) - 5) * 2) 11809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D100_REG_IN_MAX(nr) (0x74 + ((nr) - 5) * 2) 11909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC1 0x85 12009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC2 0x86 12109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC3 0x87 12209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck#define EMC6D102_REG_EXTEND_ADC4 0x88 12309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 12409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/* 12509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Conversions. Rounding and limit checking is only done on the TO_REG 12609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * variants. Note that you should be a bit careful with which arguments 12709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * these macros are called: arguments may be evaluated more than once. 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi/* IN are scaled according to built-in resistors */ 131e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvarestatic const int lm85_scaling[] = { /* .001 Volts */ 1321f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 2500, 2250, 3300, 5000, 12000, 1331f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 3300, 1500, 1800 /*EMC6D100*/ 1341f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare}; 1351f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define SCALE(val, from, to) (((val) * (to) + ((from) / 2)) / (from)) 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1371f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define INS_TO_REG(n, val) \ 1382a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck clamp_val(SCALE(val, lm85_scaling[n], 192), 0, 255) 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1401f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define INSEXT_FROM_REG(n, val, ext) \ 1415a4d3ef317c845893fe3f9d3517cb0a99375da53Jean Delvare SCALE(((val) << 4) + (ext), 192 << 4, lm85_scaling[n]) 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1431f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define INS_FROM_REG(n, val) SCALE((val), 192, lm85_scaling[n]) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* FAN speed is measured using 90kHz clock */ 14663f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvarestatic inline u16 FAN_TO_REG(unsigned long val) 14763f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare{ 14863f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare if (!val) 14963f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare return 0xffff; 1502a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck return clamp_val(5400000 / val, 1, 0xfffe); 15163f281a6e32ebc93c62dac0d399d8e054eb7b2ecJean Delvare} 1521f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define FAN_FROM_REG(val) ((val) == 0 ? -1 : (val) == 0xffff ? 0 : \ 1531f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 5400000 / (val)) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Temperature is reported in .001 degC increments */ 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define TEMP_TO_REG(val) \ 1573248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck DIV_ROUND_CLOSEST(clamp_val((val), -127000, 127000), 1000) 1581f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define TEMPEXT_FROM_REG(val, ext) \ 1595a4d3ef317c845893fe3f9d3517cb0a99375da53Jean Delvare SCALE(((val) << 4) + (ext), 16, 1000) 1605a4d3ef317c845893fe3f9d3517cb0a99375da53Jean Delvare#define TEMP_FROM_REG(val) ((val) * 1000) 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1622a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck#define PWM_TO_REG(val) clamp_val(val, 0, 255) 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define PWM_FROM_REG(val) (val) 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/* 16709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * ZONEs have the following parameters: 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Limit (low) temp, 1. degC 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Hysteresis (below limit), 1. degC (0-15) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Range of speed control, .1 degC (2-80) 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Critical (high) temp, 1. degC 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * FAN PWMs have the following parameters: 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reference Zone, 1, 2, 3, etc. 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Spinup time, .05 sec 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PWM value at limit/low temp, 1 count 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PWM Frequency, 1. Hz 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PWM is Min or OFF below limit, flag 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Invert PWM output, flag 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some chips filter the temp, others the fan. 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Filter constant (or disabled) .1 seconds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These are the zone temperature range encodings in .001 degree C */ 186e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvarestatic const int lm85_range_map[] = { 1871f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 2000, 2500, 3300, 4000, 5000, 6600, 8000, 10000, 1881f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000 1891f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare}; 1901f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 1913248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeckstatic int RANGE_TO_REG(long range) 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 195d38b149794e7444a55e741446717147e7f0467f8Jean Delvare /* Find the closest match */ 1961b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare for (i = 0; i < 15; ++i) { 1971b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare if (range <= (lm85_range_map[i] + lm85_range_map[i + 1]) / 2) 1981b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare break; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 200d38b149794e7444a55e741446717147e7f0467f8Jean Delvare 2011b92adaddd7e96e1ba68d4f17a25747ab8057efeJean Delvare return i; 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2031f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define RANGE_FROM_REG(val) lm85_range_map[(val) & 0x0f] 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* These are the PWM frequency encodings */ 20634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic const int lm85_freq_map[8] = { /* 1 Hz */ 2078a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare 10, 15, 23, 30, 38, 47, 61, 94 2088a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare}; 2098a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvarestatic const int adm1027_freq_map[8] = { /* 1 Hz */ 2108a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare 11, 15, 22, 29, 35, 44, 59, 88 2111f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare}; 2121f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare 2133248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeckstatic int FREQ_TO_REG(const int *map, unsigned long freq) 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21786010c982db2030aad2c31f178b208964f5f6806Jean Delvare /* Find the closest match */ 2181f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare for (i = 0; i < 7; ++i) 2198a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare if (freq <= (map[i] + map[i + 1]) / 2) 2201f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare break; 221e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare return i; 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2238a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare 2248a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvarestatic int FREQ_FROM_REG(const int *map, u8 reg) 2258a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare{ 2268a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare return map[reg & 0x07]; 2278a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare} 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/* 23009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Since we can't use strings, I'm abusing these numbers 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to stand in for the following meanings: 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 1 -- PWM responds to Zone 1 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2 -- PWM responds to Zone 2 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3 -- PWM responds to Zone 3 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 23 -- PWM responds to the higher temp of Zone 2 or 3 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 123 -- PWM responds to highest of Zone 1, 2, or 3 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 0 -- PWM is always at 0% (ie, off) 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -1 -- PWM is always at 100% 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * -2 -- PWM responds to manual control 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 242e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvarestatic const int lm85_zone_map[] = { 1, 2, 3, -1, 0, 23, 123, -2 }; 243e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare#define ZONE_FROM_REG(val) lm85_zone_map[(val) >> 5] 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2451f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic int ZONE_TO_REG(int zone) 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2491f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare for (i = 0; i <= 7; ++i) 2501f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare if (zone == lm85_zone_map[i]) 2511f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare break; 2521f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare if (i > 7) /* Not found. */ 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 3; /* Always 100% */ 254e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare return i << 5; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2572a844c148e1f714ebf42cb96e1b172ce394c36c9Guenter Roeck#define HYST_TO_REG(val) clamp_val(((val) + 500) / 1000, 0, 15) 2581f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare#define HYST_FROM_REG(val) ((val) * 1000) 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/* 26109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Chip sampling rates 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Some sensors are not updated more frequently than once per second 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * so it doesn't make sense to read them more often than that. 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We cache the results and return the saved data if the driver 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * is called again before a second has elapsed. 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Also, there is significant configuration data for this chip 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * given the automatic PWM fan control that is possible. There 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are about 47 bytes of config data to only 22 bytes of actual 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * readings. So, we keep the config data up to date in the cache 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * when it is written and only sample it once every 1 *minute* 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM85_DATA_INTERVAL (HZ + HZ / 2) 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LM85_CONFIG_INTERVAL (1 * 60 * HZ) 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 27709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/* 27809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * LM85 can automatically adjust fan speeds based on temperature 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This structure encapsulates an entire Zone config. There are 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * three zones (one for each temperature input) on the lm85 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm85_zone { 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s8 limit; /* Low temp limit */ 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 hyst; /* Low limit hysteresis. (0-15) */ 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 range; /* Temp range, encoded */ 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s8 critical; /* "All fans ON" temp limit */ 28709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck u8 max_desired; /* 28809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Actual "max" temperature specified. Preserved 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * to prevent "drift" as other autofan control 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * values change. 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm85_autofan { 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 config; /* Register value */ 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 min_pwm; /* Minimum PWM value, encoded */ 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 min_off; /* Min PWM or OFF below "limit", flag */ 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 30009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck/* 30109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * For each registered chip, we need to keep some data in memory. 30209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * The structure is dynamically allocated. 30309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */ 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct lm85_data { 305746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client; 306746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin const struct attribute_group *groups[6]; 3078a0795d9b8ce2247f9b34da81f8a229702c90f2dJean Delvare const int *freq_map; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds enum chips type; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 310de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck bool has_vid5; /* true if VID5 is configured for ADT7463 or ADT7468 */ 311de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck 3129a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar struct mutex update_lock; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int valid; /* !=0 if following fields are valid */ 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long last_reading; /* In jiffies */ 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long last_config; /* In jiffies */ 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in[8]; /* Register value */ 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_max[8]; /* Register value */ 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_min[8]; /* Register value */ 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s8 temp[3]; /* Register value */ 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s8 temp_min[3]; /* Register value */ 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s8 temp_max[3]; /* Register value */ 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 fan[4]; /* Register value */ 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 fan_min[4]; /* Register value */ 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 pwm[3]; /* Register value */ 32634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare u8 pwm_freq[3]; /* Register encoding */ 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 temp_ext[3]; /* Decoded values */ 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 in_ext[8]; /* Decoded values */ 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vid; /* Register value */ 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vrm; /* VRM version */ 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u32 alarms; /* Register encoding, combined */ 33279b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong u8 cfg5; /* Config Register 5 on ADT7468 */ 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_autofan autofan[3]; 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_zone zone[3]; 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic int lm85_read_value(struct i2c_client *client, u8 reg) 3386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin{ 3396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int res; 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* What size location is it? */ 3426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin switch (reg) { 3436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(0): /* Read WORD data */ 3446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(1): 3456fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(2): 3466fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(3): 3476fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(0): 3486fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(1): 3496fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(2): 3506fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(3): 3516fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_ALARM1: /* Read both bytes at once */ 3526fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin res = i2c_smbus_read_byte_data(client, reg) & 0xff; 3536fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin res |= i2c_smbus_read_byte_data(client, reg + 1) << 8; 3546fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin break; 3556fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin default: /* Read BYTE data */ 3566fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin res = i2c_smbus_read_byte_data(client, reg); 3576fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin break; 3586fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3606fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin return res; 3616fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin} 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3636fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic void lm85_write_value(struct i2c_client *client, u8 reg, int value) 3646fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin{ 3656fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin switch (reg) { 3666fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(0): /* Write WORD data */ 3676fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(1): 3686fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(2): 3696fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN(3): 3706fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(0): 3716fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(1): 3726fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(2): 3736fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin case LM85_REG_FAN_MIN(3): 3746fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* NOTE: ALARM is read only, so not included here */ 3756fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin i2c_smbus_write_byte_data(client, reg, value & 0xff); 3766fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin i2c_smbus_write_byte_data(client, reg + 1, value >> 8); 3776fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin break; 3786fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin default: /* Write BYTE data */ 3796fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin i2c_smbus_write_byte_data(client, reg, value); 3806fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin break; 3816fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 3826fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin} 38367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare 3846fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic struct lm85_data *lm85_update_device(struct device *dev) 3856fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin{ 386746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 387746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 3886fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int i; 3896fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 3906fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin mutex_lock(&data->update_lock); 3916fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 3926fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (!data->valid || 3936fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) { 3946fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* Things that change quickly */ 3956fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin dev_dbg(&client->dev, "Reading sensor values\n"); 3966fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 3976fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* 3986fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * Have to read extended bits first to "freeze" the 3996fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * more significant bits that are read later. 4006fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * There are 2 additional resolution bits per channel and we 4016fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * have room for 4, so we shift them to the left. 4026fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin */ 4036fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (data->type == adm1027 || data->type == adt7463 || 4046fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->type == adt7468) { 4056fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int ext1 = lm85_read_value(client, 4066fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin ADM1027_REG_EXTEND_ADC1); 4076fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int ext2 = lm85_read_value(client, 4086fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin ADM1027_REG_EXTEND_ADC2); 4096fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int val = (ext1 << 8) + ext2; 4106fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4116fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 0; i <= 4; i++) 4126fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_ext[i] = 4136fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin ((val >> (i * 2)) & 0x03) << 2; 4146fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4156fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 0; i <= 2; i++) 4166fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_ext[i] = 4176fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin (val >> ((i + 4) * 2)) & 0x0c; 4186fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 4196fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4206fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->vid = lm85_read_value(client, LM85_REG_VID); 4216fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4226fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 0; i <= 3; ++i) { 4236fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in[i] = 4246fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_IN(i)); 4256fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->fan[i] = 4266fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_FAN(i)); 4276fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 4286fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4296fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (!data->has_vid5) 4306fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in[4] = lm85_read_value(client, LM85_REG_IN(4)); 4316fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4326fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (data->type == adt7468) 4336fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5); 4346fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4356fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 0; i <= 2; ++i) { 4366fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp[i] = 4376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_TEMP(i)); 4386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->pwm[i] = 4396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_PWM(i)); 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (IS_ADT7468_OFF64(data)) 4426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp[i] -= 64; 4436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 4446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4456fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->alarms = lm85_read_value(client, LM85_REG_ALARM1); 4466fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4476fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (data->type == emc6d100) { 4486fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* Three more voltage sensors */ 4496fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 5; i <= 7; ++i) { 4506fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in[i] = lm85_read_value(client, 4516fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D100_REG_IN(i)); 4526fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 4536fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* More alarm bits */ 4546fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->alarms |= lm85_read_value(client, 4556fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D100_REG_ALARM3) << 16; 4566fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } else if (data->type == emc6d102 || data->type == emc6d103 || 4576fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->type == emc6d103s) { 4586fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* 4596fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * Have to read LSB bits after the MSB ones because 4606fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * the reading of the MSB bits has frozen the 4616fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin * LSBs (backward from the ADM1027). 4626fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin */ 4636fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int ext1 = lm85_read_value(client, 4646fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D102_REG_EXTEND_ADC1); 4656fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int ext2 = lm85_read_value(client, 4666fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D102_REG_EXTEND_ADC2); 4676fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int ext3 = lm85_read_value(client, 4686fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D102_REG_EXTEND_ADC3); 4696fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int ext4 = lm85_read_value(client, 4706fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D102_REG_EXTEND_ADC4); 4716fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_ext[0] = ext3 & 0x0f; 4726fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_ext[1] = ext4 & 0x0f; 4736fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_ext[2] = ext4 >> 4; 4746fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_ext[3] = ext3 >> 4; 4756fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_ext[4] = ext2 >> 4; 4766fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4776fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_ext[0] = ext1 & 0x0f; 4786fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_ext[1] = ext2 & 0x0f; 4796fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_ext[2] = ext1 >> 4; 4806fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 4816fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4826fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->last_reading = jiffies; 4836fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } /* last_reading */ 4846fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4856fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (!data->valid || 4866fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) { 4876fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin /* Things that don't change often */ 4886fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin dev_dbg(&client->dev, "Reading config values\n"); 4896fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4906fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 0; i <= 3; ++i) { 4916fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_min[i] = 4926fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_IN_MIN(i)); 4936fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_max[i] = 4946fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_IN_MAX(i)); 4956fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->fan_min[i] = 4966fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_FAN_MIN(i)); 4976fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 4986fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 4996fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (!data->has_vid5) { 5006fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_min[4] = lm85_read_value(client, 5016fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin LM85_REG_IN_MIN(4)); 5026fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_max[4] = lm85_read_value(client, 5036fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin LM85_REG_IN_MAX(4)); 5046fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 5056fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5066fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (data->type == emc6d100) { 5076fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 5; i <= 7; ++i) { 5086fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_min[i] = lm85_read_value(client, 5096fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D100_REG_IN_MIN(i)); 5106fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->in_max[i] = lm85_read_value(client, 5116fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin EMC6D100_REG_IN_MAX(i)); 5126fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 5136fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 5146fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5156fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin for (i = 0; i <= 2; ++i) { 5166fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin int val; 5176fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5186fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_min[i] = 5196fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_TEMP_MIN(i)); 5206fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_max[i] = 5216fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_TEMP_MAX(i)); 5226fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5236fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->autofan[i].config = 5246fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_AFAN_CONFIG(i)); 5256fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i)); 5266fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->pwm_freq[i] = val & 0x07; 5276fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[i].range = val >> 4; 5286fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->autofan[i].min_pwm = 5296fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_AFAN_MINPWM(i)); 5306fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[i].limit = 5316fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_AFAN_LIMIT(i)); 5326fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[i].critical = 5336fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i)); 5346fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5356fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (IS_ADT7468_OFF64(data)) { 5366fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_min[i] -= 64; 5376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->temp_max[i] -= 64; 5386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[i].limit -= 64; 5396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[i].critical -= 64; 5406fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 5416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 5426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin if (data->type != emc6d103s) { 5446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); 5456fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->autofan[0].min_off = (i & 0x20) != 0; 5466fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->autofan[1].min_off = (i & 0x40) != 0; 5476fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->autofan[2].min_off = (i & 0x80) != 0; 5486fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5496fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin i = lm85_read_value(client, LM85_REG_AFAN_HYST1); 5506fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[0].hyst = i >> 4; 5516fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[1].hyst = i & 0x0f; 5526fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5536fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin i = lm85_read_value(client, LM85_REG_AFAN_HYST2); 5546fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->zone[2].hyst = i >> 4; 5556fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } 5566fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5576fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->last_config = jiffies; 5586fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin } /* last_config */ 5596fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5606fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin data->valid = 1; 5616fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5626fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin mutex_unlock(&data->update_lock); 5636fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin 5646fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin return data; 5656fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin} 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4 Fans */ 568b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_fan(struct device *dev, struct device_attribute *attr, 569b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 571b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 5731f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr])); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 575b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 576b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_fan_min(struct device *dev, struct device_attribute *attr, 577b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 579b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 5811f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[nr])); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 583b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 584b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, 585b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare const char *buf, size_t count) 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 587b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 588746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 589746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 59009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck unsigned long val; 59109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 59209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 59309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtoul(buf, 10, &val); 59409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 59509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5979a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->fan_min[nr] = FAN_TO_REG(val); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]); 6009a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_fan_offset(offset) \ 605b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ 606b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_fan, NULL, offset - 1); \ 607b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 608b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_fan_min, set_fan_min, offset - 1) 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(1); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(2); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(3); 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_fan_offset(4); 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* vid, vrm, alarms */ 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6171f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr, 6181f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare char *buf) 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 6219c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare int vid; 6229c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare 623de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck if (data->has_vid5) { 6249c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare /* 6-pin VID (VRM 10) */ 6259c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare vid = vid_from_reg(data->vid & 0x3f, data->vrm); 6269c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare } else { 6279c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare /* 5-pin VID (VRM 9) */ 6289c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare vid = vid_from_reg(data->vid & 0x1f, data->vrm); 6299c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare } 6309c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare 6319c516ef496c857aa4b1b41dc313010f11d39c496Jean Delvare return sprintf(buf, "%d\n", vid); 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL); 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6361f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_vrm_reg(struct device *dev, struct device_attribute *attr, 6371f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare char *buf) 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 63990d6619a916062cb75a176aacb318d108758b4a5Jean Delvare struct lm85_data *data = dev_get_drvdata(dev); 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sprintf(buf, "%ld\n", (long) data->vrm); 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6431f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr, 6441f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare const char *buf, size_t count) 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6468f74efe81d122c071410fd74f42879ef81439fa4Jean Delvare struct lm85_data *data = dev_get_drvdata(dev); 64709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck unsigned long val; 64809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 64909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 65009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtoul(buf, 10, &val); 65109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 65209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 65309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 6543248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck if (val > 255) 6553248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck return -EINVAL; 6563248c3b771ddd9d31695da17ba350eb6e1b80a53Guenter Roeck 65709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck data->vrm = val; 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg); 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_alarms_reg(struct device *dev, struct device_attribute 6641f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare *attr, char *buf) 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 66768188ba7de2db9999ff08a4544a78b2f10eb08bdJean Delvare return sprintf(buf, "%u\n", data->alarms); 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL); 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 672bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic ssize_t show_alarm(struct device *dev, struct device_attribute *attr, 673bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare char *buf) 674bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare{ 675bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 676bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare struct lm85_data *data = lm85_update_device(dev); 677bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); 678bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare} 679bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare 680bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); 681bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); 682bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); 683bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); 684bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8); 685bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 18); 686bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 16); 687bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, 17); 688bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4); 689bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_alarm, NULL, 14); 690bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5); 691bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 6); 692bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_alarm, NULL, 15); 693bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 10); 694bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 11); 695bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 12); 696bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvarestatic SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 13); 697bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* pwm */ 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 700b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm(struct device *dev, struct device_attribute *attr, 701b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 703b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 7051f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 707b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 708b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm(struct device *dev, struct device_attribute *attr, 709b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare const char *buf, size_t count) 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 711b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 712746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 713746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 71409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck unsigned long val; 71509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 71609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 71709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtoul(buf, 10, &val); 71809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 71909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7219a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->pwm[nr] = PWM_TO_REG(val); 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]); 7249a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 727b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 728b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_enable(struct device *dev, struct device_attribute 729b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare *attr, char *buf) 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 731b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 7334b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare int pwm_zone, enable; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pwm_zone = ZONE_FROM_REG(data->autofan[nr].config); 7364b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare switch (pwm_zone) { 7374b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare case -1: /* PWM is always at 100% */ 7384b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare enable = 0; 7394b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare break; 7404b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare case 0: /* PWM is always at 0% */ 7414b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare case -2: /* PWM responds to manual control */ 7424b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare enable = 1; 7434b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare break; 7444b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare default: /* PWM in automatic mode */ 7454b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare enable = 2; 7464b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare } 7474b4df95dccdd2c6a573c9dedefb747ed663c074dJean Delvare return sprintf(buf, "%d\n", enable); 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 750455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvarestatic ssize_t set_pwm_enable(struct device *dev, struct device_attribute 751455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare *attr, const char *buf, size_t count) 752455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare{ 753455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 754746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 755746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 756455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare u8 config; 75709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck unsigned long val; 75809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 75909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 76009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtoul(buf, 10, &val); 76109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 76209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 763455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare 764455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare switch (val) { 765455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare case 0: 766455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare config = 3; 767455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare break; 768455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare case 1: 769455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare config = 7; 770455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare break; 771455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare case 2: 77209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck /* 77309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * Here we have to choose arbitrarily one of the 5 possible 77409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * configurations; I go for the safest 77509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */ 776455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare config = 6; 777455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare break; 778455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare default: 779455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare return -EINVAL; 780455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare } 781455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare 782455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare mutex_lock(&data->update_lock); 783455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare data->autofan[nr].config = lm85_read_value(client, 784455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare LM85_REG_AFAN_CONFIG(nr)); 785455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare data->autofan[nr].config = (data->autofan[nr].config & ~0xe0) 786455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare | (config << 5); 787455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), 788455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare data->autofan[nr].config); 789455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare mutex_unlock(&data->update_lock); 790455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare return count; 791455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare} 792455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvare 79334e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic ssize_t show_pwm_freq(struct device *dev, 79434e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare struct device_attribute *attr, char *buf) 79534e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare{ 79634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare int nr = to_sensor_dev_attr(attr)->index; 79734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare struct lm85_data *data = lm85_update_device(dev); 798f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare int freq; 799f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare 800f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare if (IS_ADT7468_HFPWM(data)) 801f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare freq = 22500; 802f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare else 803f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare freq = FREQ_FROM_REG(data->freq_map, data->pwm_freq[nr]); 804f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare 805f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare return sprintf(buf, "%d\n", freq); 80634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare} 80734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare 80834e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic ssize_t set_pwm_freq(struct device *dev, 80934e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare struct device_attribute *attr, const char *buf, size_t count) 81034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare{ 81134e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare int nr = to_sensor_dev_attr(attr)->index; 812746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 813746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 81409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck unsigned long val; 81509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 81609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 81709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtoul(buf, 10, &val); 81809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 81909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 82034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare 82134e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare mutex_lock(&data->update_lock); 82209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck /* 82309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * The ADT7468 has a special high-frequency PWM output mode, 824f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare * where all PWM outputs are driven by a 22.5 kHz clock. 82509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * This might confuse the user, but there's not much we can do. 82609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */ 827f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare if (data->type == adt7468 && val >= 11300) { /* High freq. mode */ 828f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare data->cfg5 &= ~ADT7468_HFPWM; 829f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5); 830f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare } else { /* Low freq. mode */ 831f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare data->pwm_freq[nr] = FREQ_TO_REG(data->freq_map, val); 832f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), 833f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare (data->zone[nr].range << 4) 834f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare | data->pwm_freq[nr]); 835f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare if (data->type == adt7468) { 836f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare data->cfg5 |= ADT7468_HFPWM; 837f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare lm85_write_value(client, ADT7468_REG_CFG5, data->cfg5); 838f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare } 839f6c61cff8bcb58b8dfb645d4243a049908c02024Jean Delvare } 84034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare mutex_unlock(&data->update_lock); 84134e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare return count; 84234e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare} 84334e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_pwm_reg(offset) \ 845b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ 846b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_pwm, set_pwm, offset - 1); \ 847455f791ea3e33a274c098b4a8c2e35d4d1a6d518Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \ 84834e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare show_pwm_enable, set_pwm_enable, offset - 1); \ 84934e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_freq, S_IRUGO | S_IWUSR, \ 85034e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare show_pwm_freq, set_pwm_freq, offset - 1) 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_pwm_reg(1); 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_pwm_reg(2); 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_pwm_reg(3); 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Voltages */ 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 858b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_in(struct device *dev, struct device_attribute *attr, 859b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 861b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 8631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", INSEXT_FROM_REG(nr, data->in[nr], 8641f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare data->in_ext[nr])); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 866b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 8671f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvarestatic ssize_t show_in_min(struct device *dev, struct device_attribute *attr, 868b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 870b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 8721f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_min[nr])); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 874b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 875b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_in_min(struct device *dev, struct device_attribute *attr, 876b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare const char *buf, size_t count) 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 878b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 879746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 880746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 88109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 88209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 88309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 88409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 88509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 88609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8889a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_min[nr] = INS_TO_REG(nr, val); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]); 8919a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 894b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 895b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_in_max(struct device *dev, struct device_attribute *attr, 896b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 898b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 9001f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", INS_FROM_REG(nr, data->in_max[nr])); 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 902b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 903b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_in_max(struct device *dev, struct device_attribute *attr, 904b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare const char *buf, size_t count) 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 906b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 907746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 908746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 90909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 91009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 91109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 91209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 91309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 91409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9169a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->in_max[nr] = INS_TO_REG(nr, val); 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]); 9199a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 922b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_in_reg(offset) \ 924b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ 925b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_in, NULL, offset); \ 926b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ 927b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_in_min, set_in_min, offset); \ 928b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ 929b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_in_max, set_in_max, offset) 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(0); 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(1); 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(2); 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(3); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_in_reg(4); 9366b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvareshow_in_reg(5); 9376b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvareshow_in_reg(6); 9386b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvareshow_in_reg(7); 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Temps */ 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 942b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp(struct device *dev, struct device_attribute *attr, 943b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 945b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 9471f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMPEXT_FROM_REG(data->temp[nr], 9481f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare data->temp_ext[nr])); 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 950b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 951b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_min(struct device *dev, struct device_attribute *attr, 952b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 954b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 9561f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 958b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 959b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_min(struct device *dev, struct device_attribute *attr, 960b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare const char *buf, size_t count) 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 962b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 963746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 964746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 96509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 96609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 96709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 96809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 96909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 97009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 97279b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong if (IS_ADT7468_OFF64(data)) 97379b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong val += 64; 97479b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong 9759a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->temp_min[nr] = TEMP_TO_REG(val); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); 9789a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 981b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 982b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_max(struct device *dev, struct device_attribute *attr, 983b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare char *buf) 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 985b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 9871f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 989b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 990b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_max(struct device *dev, struct device_attribute *attr, 991b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare const char *buf, size_t count) 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 993b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 994746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 995746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 99609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 99709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 99809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 99909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 100009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 100109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 100379b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong if (IS_ADT7468_OFF64(data)) 100479b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong val += 64; 100579b92f2bab0dc5ac70e8391548f75ac3268426e4Darrick J. Wong 10069a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->temp_max[nr] = TEMP_TO_REG(val); 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); 10099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1012b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define show_temp_reg(offset) \ 1014b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ 1015b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_temp, NULL, offset - 1); \ 1016b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ 1017b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_temp_min, set_temp_min, offset - 1); \ 1018b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ 1019b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare show_temp_max, set_temp_max, offset - 1); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_temp_reg(1); 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_temp_reg(2); 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsshow_temp_reg(3); 10241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Automatic PWM control */ 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1028b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_auto_channels(struct device *dev, 1029b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1031b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 10331f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", ZONE_FROM_REG(data->autofan[nr].config)); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1035b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1036b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm_auto_channels(struct device *dev, 1037b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1039b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1040746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1041746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 104209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 104309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 104409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 104509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 104609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 104709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 10481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10499a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->autofan[nr].config = (data->autofan[nr].config & (~0xe0)) 10511f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare | ZONE_TO_REG(val); 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr), 10531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->autofan[nr].config); 10549a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1057b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1058b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_auto_pwm_min(struct device *dev, 1059b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1061b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 10631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", PWM_FROM_REG(data->autofan[nr].min_pwm)); 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1065b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1066b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm_auto_pwm_min(struct device *dev, 1067b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1069b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1070746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1071746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 107209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck unsigned long val; 107309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 107409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 107509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtoul(buf, 10, &val); 107609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 107709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10799a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->autofan[nr].min_pwm = PWM_TO_REG(val); 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr), 10821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->autofan[nr].min_pwm); 10839a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1086b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1087b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_pwm_auto_pwm_minctl(struct device *dev, 1088b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1090b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 10921f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", data->autofan[nr].min_off); 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1094b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1095b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_pwm_auto_pwm_minctl(struct device *dev, 1096b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1098b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1099746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1100746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 11017133e56f29030b13601d3399e20050053e560860Jean Delvare u8 tmp; 110209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 110309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 110409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 110509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 110609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 110709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 11081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 11101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->autofan[nr].min_off = val; 11117133e56f29030b13601d3399e20050053e560860Jean Delvare tmp = lm85_read_value(client, LM85_REG_AFAN_SPIKE1); 11127133e56f29030b13601d3399e20050053e560860Jean Delvare tmp &= ~(0x20 << nr); 11137133e56f29030b13601d3399e20050053e560860Jean Delvare if (data->autofan[nr].min_off) 11147133e56f29030b13601d3399e20050053e560860Jean Delvare tmp |= 0x20 << nr; 11157133e56f29030b13601d3399e20050053e560860Jean Delvare lm85_write_value(client, LM85_REG_AFAN_SPIKE1, tmp); 11169a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 11171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 11181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1119b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 11201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define pwm_auto(offset) \ 1121b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_auto_channels, \ 1122b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_pwm_auto_channels, \ 1123b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare set_pwm_auto_channels, offset - 1); \ 1124b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_min, \ 1125b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_pwm_auto_pwm_min, \ 1126b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare set_pwm_auto_pwm_min, offset - 1); \ 1127b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(pwm##offset##_auto_pwm_minctl, \ 1128b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_pwm_auto_pwm_minctl, \ 112934e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare set_pwm_auto_pwm_minctl, offset - 1) 1130b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 11311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspwm_auto(1); 11321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspwm_auto(2); 11331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldspwm_auto(3); 11341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Temperature settings for automatic PWM control */ 11361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1137b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_off(struct device *dev, 1138b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 11391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1140b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 11411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 11421f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) - 11431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds HYST_FROM_REG(data->zone[nr].hyst)); 11441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1145b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1146b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_off(struct device *dev, 1147b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 11481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1149b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1150746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1151746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 11521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int min; 115309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 115409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 115509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 115609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 115709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 115809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 11591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11609a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds min = TEMP_FROM_REG(data->zone[nr].limit); 11621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].hyst = HYST_TO_REG(min - val); 11631f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare if (nr == 0 || nr == 1) { 11641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_HYST1, 11651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (data->zone[0].hyst << 4) 11661f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare | data->zone[1].hyst); 11671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 11681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_HYST2, 11691f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare (data->zone[2].hyst << 4)); 11701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 11719a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 11721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 11731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1174b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1175b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_min(struct device *dev, 1176b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 11771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1178b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 11791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 11801f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit)); 11811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1182b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1183b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_min(struct device *dev, 1184b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 11851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1186b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1187746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1188746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 118909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 119009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 119109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 119209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 119309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 119409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 11951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11969a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].limit = TEMP_TO_REG(val); 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr), 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].limit); 12001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Update temp_auto_max and temp_auto_range */ 12021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].range = RANGE_TO_REG( 12031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TEMP_FROM_REG(data->zone[nr].max_desired) - 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds TEMP_FROM_REG(data->zone[nr].limit)); 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((data->zone[nr].range & 0x0f) << 4) 120734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare | (data->pwm_freq[nr] & 0x07)); 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12099a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 12101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 12111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1212b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1213b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_max(struct device *dev, 1214b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 12151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1216b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 12171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 12181f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].limit) + 12191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds RANGE_FROM_REG(data->zone[nr].range)); 12201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1221b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1222b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_max(struct device *dev, 1223b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 12241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1225b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1226746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1227746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 12281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int min; 122909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 123009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 123109770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 123209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 123309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 123409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12369a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 12371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds min = TEMP_FROM_REG(data->zone[nr].limit); 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].max_desired = TEMP_TO_REG(val); 12391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].range = RANGE_TO_REG( 12401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val - min); 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_RANGE(nr), 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((data->zone[nr].range & 0x0f) << 4) 124334e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare | (data->pwm_freq[nr] & 0x07)); 12449a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 12451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1247b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1248b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t show_temp_auto_temp_crit(struct device *dev, 1249b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare struct device_attribute *attr, char *buf) 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1251b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 12521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct lm85_data *data = lm85_update_device(dev); 12531f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->zone[nr].critical)); 12541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1255b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1256b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic ssize_t set_temp_auto_temp_crit(struct device *dev, 12571f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare struct device_attribute *attr, const char *buf, size_t count) 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1259b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare int nr = to_sensor_dev_attr(attr)->index; 1260746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct lm85_data *data = dev_get_drvdata(dev); 1261746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct i2c_client *client = data->client; 126209770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck long val; 126309770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck int err; 126409770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck 126509770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck err = kstrtol(buf, 10, &val); 126609770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck if (err) 126709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck return err; 12681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12699a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_lock(&data->update_lock); 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].critical = TEMP_TO_REG(val); 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr), 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds data->zone[nr].critical); 12739a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_unlock(&data->update_lock); 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return count; 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1276b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define temp_auto(offset) \ 1278b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_off, \ 1279b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_temp_auto_temp_off, \ 1280b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare set_temp_auto_temp_off, offset - 1); \ 1281b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_min, \ 1282b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_temp_auto_temp_min, \ 1283b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare set_temp_auto_temp_min, offset - 1); \ 1284b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_max, \ 1285b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_temp_auto_temp_max, \ 1286b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare set_temp_auto_temp_max, offset - 1); \ 1287b353a487b9d835da331edb443afedfd7977b3d76Jean Delvarestatic SENSOR_DEVICE_ATTR(temp##offset##_auto_temp_crit, \ 1288b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare S_IRUGO | S_IWUSR, show_temp_auto_temp_crit, \ 1289b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare set_temp_auto_temp_crit, offset - 1); 1290b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstemp_auto(1); 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstemp_auto(2); 12931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstemp_auto(3); 12941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12950501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffmanstatic struct attribute *lm85_attributes[] = { 1296b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan1_input.dev_attr.attr, 1297b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan2_input.dev_attr.attr, 1298b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan3_input.dev_attr.attr, 1299b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan4_input.dev_attr.attr, 1300b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan1_min.dev_attr.attr, 1301b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan2_min.dev_attr.attr, 1302b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan3_min.dev_attr.attr, 1303b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_fan4_min.dev_attr.attr, 1304bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_fan1_alarm.dev_attr.attr, 1305bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_fan2_alarm.dev_attr.attr, 1306bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_fan3_alarm.dev_attr.attr, 1307bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_fan4_alarm.dev_attr.attr, 1308b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1309b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm1.dev_attr.attr, 1310b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm2.dev_attr.attr, 1311b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm3.dev_attr.attr, 1312b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm1_enable.dev_attr.attr, 1313b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm2_enable.dev_attr.attr, 1314b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm3_enable.dev_attr.attr, 131534e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare &sensor_dev_attr_pwm1_freq.dev_attr.attr, 131634e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare &sensor_dev_attr_pwm2_freq.dev_attr.attr, 131734e7dc6ca4a663a1bb0a0a4e118426849dccd72dJean Delvare &sensor_dev_attr_pwm3_freq.dev_attr.attr, 1318b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1319b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in0_input.dev_attr.attr, 1320b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in1_input.dev_attr.attr, 1321b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in2_input.dev_attr.attr, 1322b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in3_input.dev_attr.attr, 1323b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in0_min.dev_attr.attr, 1324b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in1_min.dev_attr.attr, 1325b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in2_min.dev_attr.attr, 1326b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in3_min.dev_attr.attr, 1327b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in0_max.dev_attr.attr, 1328b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in1_max.dev_attr.attr, 1329b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in2_max.dev_attr.attr, 1330b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in3_max.dev_attr.attr, 1331bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in0_alarm.dev_attr.attr, 1332bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in1_alarm.dev_attr.attr, 1333bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in2_alarm.dev_attr.attr, 1334bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in3_alarm.dev_attr.attr, 1335b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1336b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp1_input.dev_attr.attr, 1337b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp2_input.dev_attr.attr, 1338b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp3_input.dev_attr.attr, 1339b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp1_min.dev_attr.attr, 1340b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp2_min.dev_attr.attr, 1341b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp3_min.dev_attr.attr, 1342b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp1_max.dev_attr.attr, 1343b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp2_max.dev_attr.attr, 1344b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp3_max.dev_attr.attr, 1345bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_temp1_alarm.dev_attr.attr, 1346bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_temp2_alarm.dev_attr.attr, 1347bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_temp3_alarm.dev_attr.attr, 1348bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_temp1_fault.dev_attr.attr, 1349bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_temp3_fault.dev_attr.attr, 1350b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1351b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm1_auto_channels.dev_attr.attr, 1352b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm2_auto_channels.dev_attr.attr, 1353b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm3_auto_channels.dev_attr.attr, 1354b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm1_auto_pwm_min.dev_attr.attr, 1355b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm2_auto_pwm_min.dev_attr.attr, 1356b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_pwm3_auto_pwm_min.dev_attr.attr, 1357b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 1358b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp1_auto_temp_min.dev_attr.attr, 1359b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp2_auto_temp_min.dev_attr.attr, 1360b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp3_auto_temp_min.dev_attr.attr, 1361b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp1_auto_temp_max.dev_attr.attr, 1362b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp2_auto_temp_max.dev_attr.attr, 1363b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp3_auto_temp_max.dev_attr.attr, 1364b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp1_auto_temp_crit.dev_attr.attr, 1365b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp2_auto_temp_crit.dev_attr.attr, 1366b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_temp3_auto_temp_crit.dev_attr.attr, 1367b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare 13680501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman &dev_attr_vrm.attr, 13690501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman &dev_attr_cpu0_vid.attr, 13700501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman &dev_attr_alarms.attr, 13710501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman NULL 13720501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman}; 13730501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman 13740501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffmanstatic const struct attribute_group lm85_group = { 13750501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman .attrs = lm85_attributes, 13760501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman}; 13770501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman 137806923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic struct attribute *lm85_attributes_minctl[] = { 137906923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, 138006923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, 138106923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, 13825f441e2256506a5878d276399e0a22a13942fe4bJean Delvare NULL 138306923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck}; 138406923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck 138506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic const struct attribute_group lm85_group_minctl = { 138606923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck .attrs = lm85_attributes_minctl, 138706923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck}; 138806923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck 138906923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic struct attribute *lm85_attributes_temp_off[] = { 139006923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, 139106923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, 139206923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, 13935f441e2256506a5878d276399e0a22a13942fe4bJean Delvare NULL 139406923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck}; 139506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck 139606923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeckstatic const struct attribute_group lm85_group_temp_off = { 139706923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck .attrs = lm85_attributes_temp_off, 139806923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck}; 139906923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck 14006b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic struct attribute *lm85_attributes_in4[] = { 1401b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in4_input.dev_attr.attr, 1402b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in4_min.dev_attr.attr, 1403b353a487b9d835da331edb443afedfd7977b3d76Jean Delvare &sensor_dev_attr_in4_max.dev_attr.attr, 1404bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in4_alarm.dev_attr.attr, 14050501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman NULL 14060501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman}; 14070501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman 14086b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic const struct attribute_group lm85_group_in4 = { 14096b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare .attrs = lm85_attributes_in4, 14106b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare}; 14116b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare 14126b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic struct attribute *lm85_attributes_in567[] = { 14136b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in5_input.dev_attr.attr, 14146b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in6_input.dev_attr.attr, 14156b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in7_input.dev_attr.attr, 14166b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in5_min.dev_attr.attr, 14176b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in6_min.dev_attr.attr, 14186b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in7_min.dev_attr.attr, 14196b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in5_max.dev_attr.attr, 14206b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in6_max.dev_attr.attr, 14216b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare &sensor_dev_attr_in7_max.dev_attr.attr, 1422bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in5_alarm.dev_attr.attr, 1423bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in6_alarm.dev_attr.attr, 1424bf76e9d3c42fae879feabe26a10bf8ebf27ab328Jean Delvare &sensor_dev_attr_in7_alarm.dev_attr.attr, 14256b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare NULL 14266b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare}; 14276b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare 14286b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvarestatic const struct attribute_group lm85_group_in567 = { 14296b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare .attrs = lm85_attributes_in567, 14300501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman}; 14310501a3816e5b778830fc2157a6d6bb11a965fc2cMark M. Hoffman 14325f44759470f7248f74947a39cba339009d62052cJean Delvarestatic void lm85_init_client(struct i2c_client *client) 14335f44759470f7248f74947a39cba339009d62052cJean Delvare{ 14345f44759470f7248f74947a39cba339009d62052cJean Delvare int value; 14355f44759470f7248f74947a39cba339009d62052cJean Delvare 14365f44759470f7248f74947a39cba339009d62052cJean Delvare /* Start monitoring if needed */ 14375f44759470f7248f74947a39cba339009d62052cJean Delvare value = lm85_read_value(client, LM85_REG_CONFIG); 14385f44759470f7248f74947a39cba339009d62052cJean Delvare if (!(value & 0x01)) { 14395f44759470f7248f74947a39cba339009d62052cJean Delvare dev_info(&client->dev, "Starting monitoring\n"); 14405f44759470f7248f74947a39cba339009d62052cJean Delvare lm85_write_value(client, LM85_REG_CONFIG, value | 0x01); 14415f44759470f7248f74947a39cba339009d62052cJean Delvare } 14425f44759470f7248f74947a39cba339009d62052cJean Delvare 14435f44759470f7248f74947a39cba339009d62052cJean Delvare /* Warn about unusual configuration bits */ 14445f44759470f7248f74947a39cba339009d62052cJean Delvare if (value & 0x02) 14455f44759470f7248f74947a39cba339009d62052cJean Delvare dev_warn(&client->dev, "Device configuration is locked\n"); 14465f44759470f7248f74947a39cba339009d62052cJean Delvare if (!(value & 0x04)) 14475f44759470f7248f74947a39cba339009d62052cJean Delvare dev_warn(&client->dev, "Device is not ready\n"); 14485f44759470f7248f74947a39cba339009d62052cJean Delvare} 14495f44759470f7248f74947a39cba339009d62052cJean Delvare 14505cfaf338134605ce8d9272b9c16605bc920d25beJean Delvarestatic int lm85_is_fake(struct i2c_client *client) 14515cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare{ 14525cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare /* 14535cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare * Differenciate between real LM96000 and Winbond WPCD377I. The latter 14545cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare * emulate the former except that it has no hardware monitoring function 14555cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare * so the readings are always 0. 14565cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare */ 14575cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare int i; 14585cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare u8 in_temp, fan; 14595cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare 14605cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare for (i = 0; i < 8; i++) { 14615cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare in_temp = i2c_smbus_read_byte_data(client, 0x20 + i); 14625cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare fan = i2c_smbus_read_byte_data(client, 0x28 + i); 14635cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare if (in_temp != 0x00 || fan != 0xff) 14645cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare return 0; 14655cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare } 14665cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare 14675cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare return 1; 14685cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare} 14695cfaf338134605ce8d9272b9c16605bc920d25beJean Delvare 147067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare/* Return 0 if detection is successful, -ENODEV otherwise */ 1471310ec79210d754afe51e2e4a983e846b60179abdJean Delvarestatic int lm85_detect(struct i2c_client *client, struct i2c_board_info *info) 14721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 147367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare struct i2c_adapter *adapter = client->adapter; 147467712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare int address = client->addr; 1475590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare const char *type_name = NULL; 1476d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare int company, verstep; 14771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1478e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 14791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* We need to be able to do byte I/O */ 148067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare return -ENODEV; 14811f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare } 14821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1483d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare /* Determine the chip type */ 1484d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare company = lm85_read_value(client, LM85_REG_COMPANY); 1485d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare verstep = lm85_read_value(client, LM85_REG_VERSTEP); 1486d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare 1487b55f375725ff85aada394da488802b0a3cc99e88Guenter Roeck dev_dbg(&adapter->dev, 1488b55f375725ff85aada394da488802b0a3cc99e88Guenter Roeck "Detecting device at 0x%02x with COMPANY: 0x%02x and VERSTEP: 0x%02x\n", 1489d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare address, company, verstep); 1490d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare 1491d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare if (company == LM85_COMPANY_NATIONAL) { 1492d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare switch (verstep) { 1493d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_LM85C: 1494d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "lm85c"; 1495d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1496d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_LM85B: 1497d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "lm85b"; 1498d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1499d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_LM96000_1: 1500d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_LM96000_2: 1501d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare /* Check for Winbond WPCD377I */ 1502d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare if (lm85_is_fake(client)) { 1503d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare dev_dbg(&adapter->dev, 1504d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare "Found Winbond WPCD377I, ignoring\n"); 1505d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare return -ENODEV; 150669fc1feba2d5856ff74dedb6ae9d8c490210825cJean Delvare } 1507590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare type_name = "lm85"; 1508d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1509d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare } 1510d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare } else if (company == LM85_COMPANY_ANALOG_DEV) { 1511d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare switch (verstep) { 1512d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_ADM1027: 1513d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "adm1027"; 1514d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1515d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_ADT7463: 1516d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_ADT7463C: 1517d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "adt7463"; 1518d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1519d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_ADT7468_1: 1520d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_ADT7468_2: 1521d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "adt7468"; 1522d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 15231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1524d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare } else if (company == LM85_COMPANY_SMSC) { 1525d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare switch (verstep) { 1526d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_EMC6D100_A0: 1527d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_EMC6D100_A1: 1528d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare /* Note: we can't tell a '100 from a '101 */ 1529d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "emc6d100"; 1530d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1531d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare case LM85_VERSTEP_EMC6D102: 1532d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare type_name = "emc6d102"; 1533d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare break; 1534f065a93e168299569078bc6f52128b57f602fff3Jan Beulich case LM85_VERSTEP_EMC6D103_A0: 1535f065a93e168299569078bc6f52128b57f602fff3Jan Beulich case LM85_VERSTEP_EMC6D103_A1: 1536f065a93e168299569078bc6f52128b57f602fff3Jan Beulich type_name = "emc6d103"; 1537f065a93e168299569078bc6f52128b57f602fff3Jan Beulich break; 1538f065a93e168299569078bc6f52128b57f602fff3Jan Beulich case LM85_VERSTEP_EMC6D103S: 1539f065a93e168299569078bc6f52128b57f602fff3Jan Beulich type_name = "emc6d103s"; 1540f065a93e168299569078bc6f52128b57f602fff3Jan Beulich break; 1541d42a2eb5ad9766fac96f27af93b1634e4ffde220Jean Delvare } 15421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 15431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1544590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare if (!type_name) 1545590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare return -ENODEV; 1546590e8534447ce9f2f5e5e64681764079530ee8c7Jean Delvare 154767712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare strlcpy(info->type, type_name, I2C_NAME_SIZE); 154867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare 154967712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare return 0; 155067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare} 15511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1552746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Linstatic int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id) 155367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare{ 1554746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct device *dev = &client->dev; 1555746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin struct device *hwmon_dev; 155667712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare struct lm85_data *data; 1557746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin int idx = 0; 155867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare 1559746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data = devm_kzalloc(dev, sizeof(struct lm85_data), GFP_KERNEL); 156067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare if (!data) 156167712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare return -ENOMEM; 156267712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare 1563746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data->client = client; 156467712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare data->type = id->driver_data; 15659a61bf6300533d3b64d7ff29adfec00e596de67dIngo Molnar mutex_init(&data->update_lock); 15661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 156767712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare /* Fill in the chip specific driver values */ 156867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare switch (data->type) { 156967712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare case adm1027: 157067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare case adt7463: 1571fa7a5797e57d2ed71f9a6fb44f0ae42c2d7b74b7Jean Delvare case adt7468: 157267712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare case emc6d100: 157367712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare case emc6d102: 1574f065a93e168299569078bc6f52128b57f602fff3Jan Beulich case emc6d103: 157506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck case emc6d103s: 157667712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare data->freq_map = adm1027_freq_map; 157767712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare break; 157867712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare default: 157967712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare data->freq_map = lm85_freq_map; 158067712d01929295112b55fedd0b3c13f7d5c34f98Jean Delvare } 15811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Set the VRM version */ 1583303760b44a7a142cb9f4c9df4609fb63bbda98dbJean Delvare data->vrm = vid_which_vrm(); 15841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Initialize the LM85 chip */ 1586e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare lm85_init_client(client); 15871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1588746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin /* sysfs hooks */ 1589746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data->groups[idx++] = &lm85_group; 15901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 159106923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck /* minctl and temp_off exist on all chips except emc6d103s */ 159206923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck if (data->type != emc6d103s) { 1593746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data->groups[idx++] = &lm85_group_minctl; 1594746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data->groups[idx++] = &lm85_group_temp_off; 159506923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck } 159606923f84422371a6fb10b3efcd05b80ab48715c0Guenter Roeck 159709770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck /* 159809770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * The ADT7463/68 have an optional VRM 10 mode where pin 21 is used 159909770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck * as a sixth digital VID input rather than an analog input. 160009770b261914166f326dcff5e43794a5f53e0f6aGuenter Roeck */ 1601de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck if (data->type == adt7463 || data->type == adt7468) { 1602de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck u8 vid = lm85_read_value(client, LM85_REG_VID); 1603de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck if (vid & 0x80) 1604de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck data->has_vid5 = true; 1605de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck } 1606de24880586b28f1dc4cf91f5db962f0083baab2aGuenter Roeck 1607746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin if (!data->has_vid5) 1608746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data->groups[idx++] = &lm85_group_in4; 16096b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare 16106b9aad2d8acf309f99213875dd94f2ec691fe820Jean Delvare /* The EMC6D100 has 3 additional voltage inputs */ 1611746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin if (data->type == emc6d100) 1612746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data->groups[idx++] = &lm85_group_in567; 16131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1614746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 1615746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin data, data->groups); 1616746f68841a530ea0b6fd8f2ec92815ff087b962cAxel Lin return PTR_ERR_OR_ZERO(hwmon_dev); 16171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 16181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16196fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic const struct i2c_device_id lm85_id[] = { 16206fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "adm1027", adm1027 }, 16216fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "adt7463", adt7463 }, 16226fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "adt7468", adt7468 }, 16236fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "lm85", lm85 }, 16246fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "lm85b", lm85 }, 16256fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "lm85c", lm85 }, 16266fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "emc6d100", emc6d100 }, 16276fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "emc6d101", emc6d100 }, 16286fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "emc6d102", emc6d102 }, 16296fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "emc6d103", emc6d103 }, 16306fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { "emc6d103s", emc6d103s }, 16316fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin { } 16326fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin}; 16336fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel LinMODULE_DEVICE_TABLE(i2c, lm85_id); 16341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16356fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Linstatic struct i2c_driver lm85_driver = { 16366fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .class = I2C_CLASS_HWMON, 16376fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .driver = { 16386fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .name = "lm85", 16396fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin }, 16406fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .probe = lm85_probe, 16416fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .id_table = lm85_id, 16426fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .detect = lm85_detect, 16436fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin .address_list = normal_i2c, 16446fd5dd58371fb3cad5aedf64e30bef3ca54b3d6cAxel Lin}; 16451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1646f0967eea80ec2a19a4fe1ad27e3ff1b22c79a3c7Axel Linmodule_i2c_driver(lm85_driver); 16471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 16491f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean DelvareMODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, " 16501f44809ac3d7a3fc977684dc3a95fa221f33fc15Jean Delvare "Margit Schubert-While <margitsw@t-online.de>, " 1651e89e22b23bceb3fbbcfb931ad17a564b7c1eaa55Jean Delvare "Justin Thiessen <jthiessen@penguincomputing.com>"); 16521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("LM85-B, LM85-C driver"); 1653