1*8d5d45fbSJean Delvare /* 2*8d5d45fbSJean Delvare adm1031.c - Part of lm_sensors, Linux kernel modules for hardware 3*8d5d45fbSJean Delvare monitoring 4*8d5d45fbSJean Delvare Based on lm75.c and lm85.c 5*8d5d45fbSJean Delvare Supports adm1030 / adm1031 6*8d5d45fbSJean Delvare Copyright (C) 2004 Alexandre d'Alton <alex@alexdalton.org> 7*8d5d45fbSJean Delvare Reworked by Jean Delvare <khali@linux-fr.org> 8*8d5d45fbSJean Delvare 9*8d5d45fbSJean Delvare This program is free software; you can redistribute it and/or modify 10*8d5d45fbSJean Delvare it under the terms of the GNU General Public License as published by 11*8d5d45fbSJean Delvare the Free Software Foundation; either version 2 of the License, or 12*8d5d45fbSJean Delvare (at your option) any later version. 13*8d5d45fbSJean Delvare 14*8d5d45fbSJean Delvare This program is distributed in the hope that it will be useful, 15*8d5d45fbSJean Delvare but WITHOUT ANY WARRANTY; without even the implied warranty of 16*8d5d45fbSJean Delvare MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17*8d5d45fbSJean Delvare GNU General Public License for more details. 18*8d5d45fbSJean Delvare 19*8d5d45fbSJean Delvare You should have received a copy of the GNU General Public License 20*8d5d45fbSJean Delvare along with this program; if not, write to the Free Software 21*8d5d45fbSJean Delvare Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22*8d5d45fbSJean Delvare */ 23*8d5d45fbSJean Delvare 24*8d5d45fbSJean Delvare #include <linux/module.h> 25*8d5d45fbSJean Delvare #include <linux/init.h> 26*8d5d45fbSJean Delvare #include <linux/slab.h> 27*8d5d45fbSJean Delvare #include <linux/jiffies.h> 28*8d5d45fbSJean Delvare #include <linux/i2c.h> 29*8d5d45fbSJean Delvare #include <linux/i2c-sensor.h> 30*8d5d45fbSJean Delvare 31*8d5d45fbSJean Delvare /* Following macros takes channel parameter starting from 0 to 2 */ 32*8d5d45fbSJean Delvare #define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr)) 33*8d5d45fbSJean Delvare #define ADM1031_REG_FAN_DIV(nr) (0x20 + (nr)) 34*8d5d45fbSJean Delvare #define ADM1031_REG_PWM (0x22) 35*8d5d45fbSJean Delvare #define ADM1031_REG_FAN_MIN(nr) (0x10 + (nr)) 36*8d5d45fbSJean Delvare 37*8d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MAX(nr) (0x14 + 4*(nr)) 38*8d5d45fbSJean Delvare #define ADM1031_REG_TEMP_MIN(nr) (0x15 + 4*(nr)) 39*8d5d45fbSJean Delvare #define ADM1031_REG_TEMP_CRIT(nr) (0x16 + 4*(nr)) 40*8d5d45fbSJean Delvare 41*8d5d45fbSJean Delvare #define ADM1031_REG_TEMP(nr) (0xa + (nr)) 42*8d5d45fbSJean Delvare #define ADM1031_REG_AUTO_TEMP(nr) (0x24 + (nr)) 43*8d5d45fbSJean Delvare 44*8d5d45fbSJean Delvare #define ADM1031_REG_STATUS(nr) (0x2 + (nr)) 45*8d5d45fbSJean Delvare 46*8d5d45fbSJean Delvare #define ADM1031_REG_CONF1 0x0 47*8d5d45fbSJean Delvare #define ADM1031_REG_CONF2 0x1 48*8d5d45fbSJean Delvare #define ADM1031_REG_EXT_TEMP 0x6 49*8d5d45fbSJean Delvare 50*8d5d45fbSJean Delvare #define ADM1031_CONF1_MONITOR_ENABLE 0x01 /* Monitoring enable */ 51*8d5d45fbSJean Delvare #define ADM1031_CONF1_PWM_INVERT 0x08 /* PWM Invert */ 52*8d5d45fbSJean Delvare #define ADM1031_CONF1_AUTO_MODE 0x80 /* Auto FAN */ 53*8d5d45fbSJean Delvare 54*8d5d45fbSJean Delvare #define ADM1031_CONF2_PWM1_ENABLE 0x01 55*8d5d45fbSJean Delvare #define ADM1031_CONF2_PWM2_ENABLE 0x02 56*8d5d45fbSJean Delvare #define ADM1031_CONF2_TACH1_ENABLE 0x04 57*8d5d45fbSJean Delvare #define ADM1031_CONF2_TACH2_ENABLE 0x08 58*8d5d45fbSJean Delvare #define ADM1031_CONF2_TEMP_ENABLE(chan) (0x10 << (chan)) 59*8d5d45fbSJean Delvare 60*8d5d45fbSJean Delvare /* Addresses to scan */ 61*8d5d45fbSJean Delvare static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; 62*8d5d45fbSJean Delvare static unsigned int normal_isa[] = { I2C_CLIENT_ISA_END }; 63*8d5d45fbSJean Delvare 64*8d5d45fbSJean Delvare /* Insmod parameters */ 65*8d5d45fbSJean Delvare SENSORS_INSMOD_2(adm1030, adm1031); 66*8d5d45fbSJean Delvare 67*8d5d45fbSJean Delvare typedef u8 auto_chan_table_t[8][2]; 68*8d5d45fbSJean Delvare 69*8d5d45fbSJean Delvare /* Each client has this additional data */ 70*8d5d45fbSJean Delvare struct adm1031_data { 71*8d5d45fbSJean Delvare struct i2c_client client; 72*8d5d45fbSJean Delvare struct semaphore update_lock; 73*8d5d45fbSJean Delvare int chip_type; 74*8d5d45fbSJean Delvare char valid; /* !=0 if following fields are valid */ 75*8d5d45fbSJean Delvare unsigned long last_updated; /* In jiffies */ 76*8d5d45fbSJean Delvare /* The chan_select_table contains the possible configurations for 77*8d5d45fbSJean Delvare * auto fan control. 78*8d5d45fbSJean Delvare */ 79*8d5d45fbSJean Delvare auto_chan_table_t *chan_select_table; 80*8d5d45fbSJean Delvare u16 alarm; 81*8d5d45fbSJean Delvare u8 conf1; 82*8d5d45fbSJean Delvare u8 conf2; 83*8d5d45fbSJean Delvare u8 fan[2]; 84*8d5d45fbSJean Delvare u8 fan_div[2]; 85*8d5d45fbSJean Delvare u8 fan_min[2]; 86*8d5d45fbSJean Delvare u8 pwm[2]; 87*8d5d45fbSJean Delvare u8 old_pwm[2]; 88*8d5d45fbSJean Delvare s8 temp[3]; 89*8d5d45fbSJean Delvare u8 ext_temp[3]; 90*8d5d45fbSJean Delvare u8 auto_temp[3]; 91*8d5d45fbSJean Delvare u8 auto_temp_min[3]; 92*8d5d45fbSJean Delvare u8 auto_temp_off[3]; 93*8d5d45fbSJean Delvare u8 auto_temp_max[3]; 94*8d5d45fbSJean Delvare s8 temp_min[3]; 95*8d5d45fbSJean Delvare s8 temp_max[3]; 96*8d5d45fbSJean Delvare s8 temp_crit[3]; 97*8d5d45fbSJean Delvare }; 98*8d5d45fbSJean Delvare 99*8d5d45fbSJean Delvare static int adm1031_attach_adapter(struct i2c_adapter *adapter); 100*8d5d45fbSJean Delvare static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind); 101*8d5d45fbSJean Delvare static void adm1031_init_client(struct i2c_client *client); 102*8d5d45fbSJean Delvare static int adm1031_detach_client(struct i2c_client *client); 103*8d5d45fbSJean Delvare static struct adm1031_data *adm1031_update_device(struct device *dev); 104*8d5d45fbSJean Delvare 105*8d5d45fbSJean Delvare /* This is the driver that will be inserted */ 106*8d5d45fbSJean Delvare static struct i2c_driver adm1031_driver = { 107*8d5d45fbSJean Delvare .owner = THIS_MODULE, 108*8d5d45fbSJean Delvare .name = "adm1031", 109*8d5d45fbSJean Delvare .flags = I2C_DF_NOTIFY, 110*8d5d45fbSJean Delvare .attach_adapter = adm1031_attach_adapter, 111*8d5d45fbSJean Delvare .detach_client = adm1031_detach_client, 112*8d5d45fbSJean Delvare }; 113*8d5d45fbSJean Delvare 114*8d5d45fbSJean Delvare static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg) 115*8d5d45fbSJean Delvare { 116*8d5d45fbSJean Delvare return i2c_smbus_read_byte_data(client, reg); 117*8d5d45fbSJean Delvare } 118*8d5d45fbSJean Delvare 119*8d5d45fbSJean Delvare static inline int 120*8d5d45fbSJean Delvare adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value) 121*8d5d45fbSJean Delvare { 122*8d5d45fbSJean Delvare return i2c_smbus_write_byte_data(client, reg, value); 123*8d5d45fbSJean Delvare } 124*8d5d45fbSJean Delvare 125*8d5d45fbSJean Delvare 126*8d5d45fbSJean Delvare #define TEMP_TO_REG(val) (((val) < 0 ? ((val - 500) / 1000) : \ 127*8d5d45fbSJean Delvare ((val + 500) / 1000))) 128*8d5d45fbSJean Delvare 129*8d5d45fbSJean Delvare #define TEMP_FROM_REG(val) ((val) * 1000) 130*8d5d45fbSJean Delvare 131*8d5d45fbSJean Delvare #define TEMP_FROM_REG_EXT(val, ext) (TEMP_FROM_REG(val) + (ext) * 125) 132*8d5d45fbSJean Delvare 133*8d5d45fbSJean Delvare #define FAN_FROM_REG(reg, div) ((reg) ? (11250 * 60) / ((reg) * (div)) : 0) 134*8d5d45fbSJean Delvare 135*8d5d45fbSJean Delvare static int FAN_TO_REG(int reg, int div) 136*8d5d45fbSJean Delvare { 137*8d5d45fbSJean Delvare int tmp; 138*8d5d45fbSJean Delvare tmp = FAN_FROM_REG(SENSORS_LIMIT(reg, 0, 65535), div); 139*8d5d45fbSJean Delvare return tmp > 255 ? 255 : tmp; 140*8d5d45fbSJean Delvare } 141*8d5d45fbSJean Delvare 142*8d5d45fbSJean Delvare #define FAN_DIV_FROM_REG(reg) (1<<(((reg)&0xc0)>>6)) 143*8d5d45fbSJean Delvare 144*8d5d45fbSJean Delvare #define PWM_TO_REG(val) (SENSORS_LIMIT((val), 0, 255) >> 4) 145*8d5d45fbSJean Delvare #define PWM_FROM_REG(val) ((val) << 4) 146*8d5d45fbSJean Delvare 147*8d5d45fbSJean Delvare #define FAN_CHAN_FROM_REG(reg) (((reg) >> 5) & 7) 148*8d5d45fbSJean Delvare #define FAN_CHAN_TO_REG(val, reg) \ 149*8d5d45fbSJean Delvare (((reg) & 0x1F) | (((val) << 5) & 0xe0)) 150*8d5d45fbSJean Delvare 151*8d5d45fbSJean Delvare #define AUTO_TEMP_MIN_TO_REG(val, reg) \ 152*8d5d45fbSJean Delvare ((((val)/500) & 0xf8)|((reg) & 0x7)) 153*8d5d45fbSJean Delvare #define AUTO_TEMP_RANGE_FROM_REG(reg) (5000 * (1<< ((reg)&0x7))) 154*8d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG(reg) (1000 * ((((reg) >> 3) & 0x1f) << 2)) 155*8d5d45fbSJean Delvare 156*8d5d45fbSJean Delvare #define AUTO_TEMP_MIN_FROM_REG_DEG(reg) ((((reg) >> 3) & 0x1f) << 2) 157*8d5d45fbSJean Delvare 158*8d5d45fbSJean Delvare #define AUTO_TEMP_OFF_FROM_REG(reg) \ 159*8d5d45fbSJean Delvare (AUTO_TEMP_MIN_FROM_REG(reg) - 5000) 160*8d5d45fbSJean Delvare 161*8d5d45fbSJean Delvare #define AUTO_TEMP_MAX_FROM_REG(reg) \ 162*8d5d45fbSJean Delvare (AUTO_TEMP_RANGE_FROM_REG(reg) + \ 163*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG(reg)) 164*8d5d45fbSJean Delvare 165*8d5d45fbSJean Delvare static int AUTO_TEMP_MAX_TO_REG(int val, int reg, int pwm) 166*8d5d45fbSJean Delvare { 167*8d5d45fbSJean Delvare int ret; 168*8d5d45fbSJean Delvare int range = val - AUTO_TEMP_MIN_FROM_REG(reg); 169*8d5d45fbSJean Delvare 170*8d5d45fbSJean Delvare range = ((val - AUTO_TEMP_MIN_FROM_REG(reg))*10)/(16 - pwm); 171*8d5d45fbSJean Delvare ret = ((reg & 0xf8) | 172*8d5d45fbSJean Delvare (range < 10000 ? 0 : 173*8d5d45fbSJean Delvare range < 20000 ? 1 : 174*8d5d45fbSJean Delvare range < 40000 ? 2 : range < 80000 ? 3 : 4)); 175*8d5d45fbSJean Delvare return ret; 176*8d5d45fbSJean Delvare } 177*8d5d45fbSJean Delvare 178*8d5d45fbSJean Delvare /* FAN auto control */ 179*8d5d45fbSJean Delvare #define GET_FAN_AUTO_BITFIELD(data, idx) \ 180*8d5d45fbSJean Delvare (*(data)->chan_select_table)[FAN_CHAN_FROM_REG((data)->conf1)][idx%2] 181*8d5d45fbSJean Delvare 182*8d5d45fbSJean Delvare /* The tables below contains the possible values for the auto fan 183*8d5d45fbSJean Delvare * control bitfields. the index in the table is the register value. 184*8d5d45fbSJean Delvare * MSb is the auto fan control enable bit, so the four first entries 185*8d5d45fbSJean Delvare * in the table disables auto fan control when both bitfields are zero. 186*8d5d45fbSJean Delvare */ 187*8d5d45fbSJean Delvare static auto_chan_table_t auto_channel_select_table_adm1031 = { 188*8d5d45fbSJean Delvare {0, 0}, {0, 0}, {0, 0}, {0, 0}, 189*8d5d45fbSJean Delvare {2 /*0b010 */ , 4 /*0b100 */ }, 190*8d5d45fbSJean Delvare {2 /*0b010 */ , 2 /*0b010 */ }, 191*8d5d45fbSJean Delvare {4 /*0b100 */ , 4 /*0b100 */ }, 192*8d5d45fbSJean Delvare {7 /*0b111 */ , 7 /*0b111 */ }, 193*8d5d45fbSJean Delvare }; 194*8d5d45fbSJean Delvare 195*8d5d45fbSJean Delvare static auto_chan_table_t auto_channel_select_table_adm1030 = { 196*8d5d45fbSJean Delvare {0, 0}, {0, 0}, {0, 0}, {0, 0}, 197*8d5d45fbSJean Delvare {2 /*0b10 */ , 0}, 198*8d5d45fbSJean Delvare {0xff /*invalid */ , 0}, 199*8d5d45fbSJean Delvare {0xff /*invalid */ , 0}, 200*8d5d45fbSJean Delvare {3 /*0b11 */ , 0}, 201*8d5d45fbSJean Delvare }; 202*8d5d45fbSJean Delvare 203*8d5d45fbSJean Delvare /* That function checks if a bitfield is valid and returns the other bitfield 204*8d5d45fbSJean Delvare * nearest match if no exact match where found. 205*8d5d45fbSJean Delvare */ 206*8d5d45fbSJean Delvare static int 207*8d5d45fbSJean Delvare get_fan_auto_nearest(struct adm1031_data *data, 208*8d5d45fbSJean Delvare int chan, u8 val, u8 reg, u8 * new_reg) 209*8d5d45fbSJean Delvare { 210*8d5d45fbSJean Delvare int i; 211*8d5d45fbSJean Delvare int first_match = -1, exact_match = -1; 212*8d5d45fbSJean Delvare u8 other_reg_val = 213*8d5d45fbSJean Delvare (*data->chan_select_table)[FAN_CHAN_FROM_REG(reg)][chan ? 0 : 1]; 214*8d5d45fbSJean Delvare 215*8d5d45fbSJean Delvare if (val == 0) { 216*8d5d45fbSJean Delvare *new_reg = 0; 217*8d5d45fbSJean Delvare return 0; 218*8d5d45fbSJean Delvare } 219*8d5d45fbSJean Delvare 220*8d5d45fbSJean Delvare for (i = 0; i < 8; i++) { 221*8d5d45fbSJean Delvare if ((val == (*data->chan_select_table)[i][chan]) && 222*8d5d45fbSJean Delvare ((*data->chan_select_table)[i][chan ? 0 : 1] == 223*8d5d45fbSJean Delvare other_reg_val)) { 224*8d5d45fbSJean Delvare /* We found an exact match */ 225*8d5d45fbSJean Delvare exact_match = i; 226*8d5d45fbSJean Delvare break; 227*8d5d45fbSJean Delvare } else if (val == (*data->chan_select_table)[i][chan] && 228*8d5d45fbSJean Delvare first_match == -1) { 229*8d5d45fbSJean Delvare /* Save the first match in case of an exact match has not been 230*8d5d45fbSJean Delvare * found 231*8d5d45fbSJean Delvare */ 232*8d5d45fbSJean Delvare first_match = i; 233*8d5d45fbSJean Delvare } 234*8d5d45fbSJean Delvare } 235*8d5d45fbSJean Delvare 236*8d5d45fbSJean Delvare if (exact_match >= 0) { 237*8d5d45fbSJean Delvare *new_reg = exact_match; 238*8d5d45fbSJean Delvare } else if (first_match >= 0) { 239*8d5d45fbSJean Delvare *new_reg = first_match; 240*8d5d45fbSJean Delvare } else { 241*8d5d45fbSJean Delvare return -EINVAL; 242*8d5d45fbSJean Delvare } 243*8d5d45fbSJean Delvare return 0; 244*8d5d45fbSJean Delvare } 245*8d5d45fbSJean Delvare 246*8d5d45fbSJean Delvare static ssize_t show_fan_auto_channel(struct device *dev, char *buf, int nr) 247*8d5d45fbSJean Delvare { 248*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 249*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", GET_FAN_AUTO_BITFIELD(data, nr)); 250*8d5d45fbSJean Delvare } 251*8d5d45fbSJean Delvare 252*8d5d45fbSJean Delvare static ssize_t 253*8d5d45fbSJean Delvare set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr) 254*8d5d45fbSJean Delvare { 255*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 256*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 257*8d5d45fbSJean Delvare int val = simple_strtol(buf, NULL, 10); 258*8d5d45fbSJean Delvare u8 reg; 259*8d5d45fbSJean Delvare int ret; 260*8d5d45fbSJean Delvare u8 old_fan_mode; 261*8d5d45fbSJean Delvare 262*8d5d45fbSJean Delvare old_fan_mode = data->conf1; 263*8d5d45fbSJean Delvare 264*8d5d45fbSJean Delvare down(&data->update_lock); 265*8d5d45fbSJean Delvare 266*8d5d45fbSJean Delvare if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, ®))) { 267*8d5d45fbSJean Delvare up(&data->update_lock); 268*8d5d45fbSJean Delvare return ret; 269*8d5d45fbSJean Delvare } 270*8d5d45fbSJean Delvare if (((data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1)) & ADM1031_CONF1_AUTO_MODE) ^ 271*8d5d45fbSJean Delvare (old_fan_mode & ADM1031_CONF1_AUTO_MODE)) { 272*8d5d45fbSJean Delvare if (data->conf1 & ADM1031_CONF1_AUTO_MODE){ 273*8d5d45fbSJean Delvare /* Switch to Auto Fan Mode 274*8d5d45fbSJean Delvare * Save PWM registers 275*8d5d45fbSJean Delvare * Set PWM registers to 33% Both */ 276*8d5d45fbSJean Delvare data->old_pwm[0] = data->pwm[0]; 277*8d5d45fbSJean Delvare data->old_pwm[1] = data->pwm[1]; 278*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_PWM, 0x55); 279*8d5d45fbSJean Delvare } else { 280*8d5d45fbSJean Delvare /* Switch to Manual Mode */ 281*8d5d45fbSJean Delvare data->pwm[0] = data->old_pwm[0]; 282*8d5d45fbSJean Delvare data->pwm[1] = data->old_pwm[1]; 283*8d5d45fbSJean Delvare /* Restore PWM registers */ 284*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_PWM, 285*8d5d45fbSJean Delvare data->pwm[0] | (data->pwm[1] << 4)); 286*8d5d45fbSJean Delvare } 287*8d5d45fbSJean Delvare } 288*8d5d45fbSJean Delvare data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1); 289*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1); 290*8d5d45fbSJean Delvare up(&data->update_lock); 291*8d5d45fbSJean Delvare return count; 292*8d5d45fbSJean Delvare } 293*8d5d45fbSJean Delvare 294*8d5d45fbSJean Delvare #define fan_auto_channel_offset(offset) \ 295*8d5d45fbSJean Delvare static ssize_t show_fan_auto_channel_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 296*8d5d45fbSJean Delvare { \ 297*8d5d45fbSJean Delvare return show_fan_auto_channel(dev, buf, offset - 1); \ 298*8d5d45fbSJean Delvare } \ 299*8d5d45fbSJean Delvare static ssize_t set_fan_auto_channel_##offset (struct device *dev, struct device_attribute *attr, \ 300*8d5d45fbSJean Delvare const char *buf, size_t count) \ 301*8d5d45fbSJean Delvare { \ 302*8d5d45fbSJean Delvare return set_fan_auto_channel(dev, buf, count, offset - 1); \ 303*8d5d45fbSJean Delvare } \ 304*8d5d45fbSJean Delvare static DEVICE_ATTR(auto_fan##offset##_channel, S_IRUGO | S_IWUSR, \ 305*8d5d45fbSJean Delvare show_fan_auto_channel_##offset, \ 306*8d5d45fbSJean Delvare set_fan_auto_channel_##offset) 307*8d5d45fbSJean Delvare 308*8d5d45fbSJean Delvare fan_auto_channel_offset(1); 309*8d5d45fbSJean Delvare fan_auto_channel_offset(2); 310*8d5d45fbSJean Delvare 311*8d5d45fbSJean Delvare /* Auto Temps */ 312*8d5d45fbSJean Delvare static ssize_t show_auto_temp_off(struct device *dev, char *buf, int nr) 313*8d5d45fbSJean Delvare { 314*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 315*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", 316*8d5d45fbSJean Delvare AUTO_TEMP_OFF_FROM_REG(data->auto_temp[nr])); 317*8d5d45fbSJean Delvare } 318*8d5d45fbSJean Delvare static ssize_t show_auto_temp_min(struct device *dev, char *buf, int nr) 319*8d5d45fbSJean Delvare { 320*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 321*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", 322*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG(data->auto_temp[nr])); 323*8d5d45fbSJean Delvare } 324*8d5d45fbSJean Delvare static ssize_t 325*8d5d45fbSJean Delvare set_auto_temp_min(struct device *dev, const char *buf, size_t count, int nr) 326*8d5d45fbSJean Delvare { 327*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 328*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 329*8d5d45fbSJean Delvare int val = simple_strtol(buf, NULL, 10); 330*8d5d45fbSJean Delvare 331*8d5d45fbSJean Delvare down(&data->update_lock); 332*8d5d45fbSJean Delvare data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]); 333*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), 334*8d5d45fbSJean Delvare data->auto_temp[nr]); 335*8d5d45fbSJean Delvare up(&data->update_lock); 336*8d5d45fbSJean Delvare return count; 337*8d5d45fbSJean Delvare } 338*8d5d45fbSJean Delvare static ssize_t show_auto_temp_max(struct device *dev, char *buf, int nr) 339*8d5d45fbSJean Delvare { 340*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 341*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", 342*8d5d45fbSJean Delvare AUTO_TEMP_MAX_FROM_REG(data->auto_temp[nr])); 343*8d5d45fbSJean Delvare } 344*8d5d45fbSJean Delvare static ssize_t 345*8d5d45fbSJean Delvare set_auto_temp_max(struct device *dev, const char *buf, size_t count, int nr) 346*8d5d45fbSJean Delvare { 347*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 348*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 349*8d5d45fbSJean Delvare int val = simple_strtol(buf, NULL, 10); 350*8d5d45fbSJean Delvare 351*8d5d45fbSJean Delvare down(&data->update_lock); 352*8d5d45fbSJean Delvare data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]); 353*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr), 354*8d5d45fbSJean Delvare data->temp_max[nr]); 355*8d5d45fbSJean Delvare up(&data->update_lock); 356*8d5d45fbSJean Delvare return count; 357*8d5d45fbSJean Delvare } 358*8d5d45fbSJean Delvare 359*8d5d45fbSJean Delvare #define auto_temp_reg(offset) \ 360*8d5d45fbSJean Delvare static ssize_t show_auto_temp_##offset##_off (struct device *dev, struct device_attribute *attr, char *buf) \ 361*8d5d45fbSJean Delvare { \ 362*8d5d45fbSJean Delvare return show_auto_temp_off(dev, buf, offset - 1); \ 363*8d5d45fbSJean Delvare } \ 364*8d5d45fbSJean Delvare static ssize_t show_auto_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ 365*8d5d45fbSJean Delvare { \ 366*8d5d45fbSJean Delvare return show_auto_temp_min(dev, buf, offset - 1); \ 367*8d5d45fbSJean Delvare } \ 368*8d5d45fbSJean Delvare static ssize_t show_auto_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ 369*8d5d45fbSJean Delvare { \ 370*8d5d45fbSJean Delvare return show_auto_temp_max(dev, buf, offset - 1); \ 371*8d5d45fbSJean Delvare } \ 372*8d5d45fbSJean Delvare static ssize_t set_auto_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \ 373*8d5d45fbSJean Delvare const char *buf, size_t count) \ 374*8d5d45fbSJean Delvare { \ 375*8d5d45fbSJean Delvare return set_auto_temp_min(dev, buf, count, offset - 1); \ 376*8d5d45fbSJean Delvare } \ 377*8d5d45fbSJean Delvare static ssize_t set_auto_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \ 378*8d5d45fbSJean Delvare const char *buf, size_t count) \ 379*8d5d45fbSJean Delvare { \ 380*8d5d45fbSJean Delvare return set_auto_temp_max(dev, buf, count, offset - 1); \ 381*8d5d45fbSJean Delvare } \ 382*8d5d45fbSJean Delvare static DEVICE_ATTR(auto_temp##offset##_off, S_IRUGO, \ 383*8d5d45fbSJean Delvare show_auto_temp_##offset##_off, NULL); \ 384*8d5d45fbSJean Delvare static DEVICE_ATTR(auto_temp##offset##_min, S_IRUGO | S_IWUSR, \ 385*8d5d45fbSJean Delvare show_auto_temp_##offset##_min, set_auto_temp_##offset##_min);\ 386*8d5d45fbSJean Delvare static DEVICE_ATTR(auto_temp##offset##_max, S_IRUGO | S_IWUSR, \ 387*8d5d45fbSJean Delvare show_auto_temp_##offset##_max, set_auto_temp_##offset##_max) 388*8d5d45fbSJean Delvare 389*8d5d45fbSJean Delvare auto_temp_reg(1); 390*8d5d45fbSJean Delvare auto_temp_reg(2); 391*8d5d45fbSJean Delvare auto_temp_reg(3); 392*8d5d45fbSJean Delvare 393*8d5d45fbSJean Delvare /* pwm */ 394*8d5d45fbSJean Delvare static ssize_t show_pwm(struct device *dev, char *buf, int nr) 395*8d5d45fbSJean Delvare { 396*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 397*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); 398*8d5d45fbSJean Delvare } 399*8d5d45fbSJean Delvare static ssize_t 400*8d5d45fbSJean Delvare set_pwm(struct device *dev, const char *buf, size_t count, int nr) 401*8d5d45fbSJean Delvare { 402*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 403*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 404*8d5d45fbSJean Delvare int val = simple_strtol(buf, NULL, 10); 405*8d5d45fbSJean Delvare int reg; 406*8d5d45fbSJean Delvare 407*8d5d45fbSJean Delvare down(&data->update_lock); 408*8d5d45fbSJean Delvare if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) && 409*8d5d45fbSJean Delvare (((val>>4) & 0xf) != 5)) { 410*8d5d45fbSJean Delvare /* In automatic mode, the only PWM accepted is 33% */ 411*8d5d45fbSJean Delvare up(&data->update_lock); 412*8d5d45fbSJean Delvare return -EINVAL; 413*8d5d45fbSJean Delvare } 414*8d5d45fbSJean Delvare data->pwm[nr] = PWM_TO_REG(val); 415*8d5d45fbSJean Delvare reg = adm1031_read_value(client, ADM1031_REG_PWM); 416*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_PWM, 417*8d5d45fbSJean Delvare nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf) 418*8d5d45fbSJean Delvare : (data->pwm[nr] & 0xf) | (reg & 0xf0)); 419*8d5d45fbSJean Delvare up(&data->update_lock); 420*8d5d45fbSJean Delvare return count; 421*8d5d45fbSJean Delvare } 422*8d5d45fbSJean Delvare 423*8d5d45fbSJean Delvare #define pwm_reg(offset) \ 424*8d5d45fbSJean Delvare static ssize_t show_pwm_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 425*8d5d45fbSJean Delvare { \ 426*8d5d45fbSJean Delvare return show_pwm(dev, buf, offset - 1); \ 427*8d5d45fbSJean Delvare } \ 428*8d5d45fbSJean Delvare static ssize_t set_pwm_##offset (struct device *dev, struct device_attribute *attr, \ 429*8d5d45fbSJean Delvare const char *buf, size_t count) \ 430*8d5d45fbSJean Delvare { \ 431*8d5d45fbSJean Delvare return set_pwm(dev, buf, count, offset - 1); \ 432*8d5d45fbSJean Delvare } \ 433*8d5d45fbSJean Delvare static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \ 434*8d5d45fbSJean Delvare show_pwm_##offset, set_pwm_##offset) 435*8d5d45fbSJean Delvare 436*8d5d45fbSJean Delvare pwm_reg(1); 437*8d5d45fbSJean Delvare pwm_reg(2); 438*8d5d45fbSJean Delvare 439*8d5d45fbSJean Delvare /* Fans */ 440*8d5d45fbSJean Delvare 441*8d5d45fbSJean Delvare /* 442*8d5d45fbSJean Delvare * That function checks the cases where the fan reading is not 443*8d5d45fbSJean Delvare * relevant. It is used to provide 0 as fan reading when the fan is 444*8d5d45fbSJean Delvare * not supposed to run 445*8d5d45fbSJean Delvare */ 446*8d5d45fbSJean Delvare static int trust_fan_readings(struct adm1031_data *data, int chan) 447*8d5d45fbSJean Delvare { 448*8d5d45fbSJean Delvare int res = 0; 449*8d5d45fbSJean Delvare 450*8d5d45fbSJean Delvare if (data->conf1 & ADM1031_CONF1_AUTO_MODE) { 451*8d5d45fbSJean Delvare switch (data->conf1 & 0x60) { 452*8d5d45fbSJean Delvare case 0x00: /* remote temp1 controls fan1 remote temp2 controls fan2 */ 453*8d5d45fbSJean Delvare res = data->temp[chan+1] >= 454*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[chan+1]); 455*8d5d45fbSJean Delvare break; 456*8d5d45fbSJean Delvare case 0x20: /* remote temp1 controls both fans */ 457*8d5d45fbSJean Delvare res = 458*8d5d45fbSJean Delvare data->temp[1] >= 459*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]); 460*8d5d45fbSJean Delvare break; 461*8d5d45fbSJean Delvare case 0x40: /* remote temp2 controls both fans */ 462*8d5d45fbSJean Delvare res = 463*8d5d45fbSJean Delvare data->temp[2] >= 464*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2]); 465*8d5d45fbSJean Delvare break; 466*8d5d45fbSJean Delvare case 0x60: /* max controls both fans */ 467*8d5d45fbSJean Delvare res = 468*8d5d45fbSJean Delvare data->temp[0] >= 469*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[0]) 470*8d5d45fbSJean Delvare || data->temp[1] >= 471*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[1]) 472*8d5d45fbSJean Delvare || (data->chip_type == adm1031 473*8d5d45fbSJean Delvare && data->temp[2] >= 474*8d5d45fbSJean Delvare AUTO_TEMP_MIN_FROM_REG_DEG(data->auto_temp[2])); 475*8d5d45fbSJean Delvare break; 476*8d5d45fbSJean Delvare } 477*8d5d45fbSJean Delvare } else { 478*8d5d45fbSJean Delvare res = data->pwm[chan] > 0; 479*8d5d45fbSJean Delvare } 480*8d5d45fbSJean Delvare return res; 481*8d5d45fbSJean Delvare } 482*8d5d45fbSJean Delvare 483*8d5d45fbSJean Delvare 484*8d5d45fbSJean Delvare static ssize_t show_fan(struct device *dev, char *buf, int nr) 485*8d5d45fbSJean Delvare { 486*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 487*8d5d45fbSJean Delvare int value; 488*8d5d45fbSJean Delvare 489*8d5d45fbSJean Delvare value = trust_fan_readings(data, nr) ? FAN_FROM_REG(data->fan[nr], 490*8d5d45fbSJean Delvare FAN_DIV_FROM_REG(data->fan_div[nr])) : 0; 491*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", value); 492*8d5d45fbSJean Delvare } 493*8d5d45fbSJean Delvare 494*8d5d45fbSJean Delvare static ssize_t show_fan_div(struct device *dev, char *buf, int nr) 495*8d5d45fbSJean Delvare { 496*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 497*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", FAN_DIV_FROM_REG(data->fan_div[nr])); 498*8d5d45fbSJean Delvare } 499*8d5d45fbSJean Delvare static ssize_t show_fan_min(struct device *dev, char *buf, int nr) 500*8d5d45fbSJean Delvare { 501*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 502*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", 503*8d5d45fbSJean Delvare FAN_FROM_REG(data->fan_min[nr], 504*8d5d45fbSJean Delvare FAN_DIV_FROM_REG(data->fan_div[nr]))); 505*8d5d45fbSJean Delvare } 506*8d5d45fbSJean Delvare static ssize_t 507*8d5d45fbSJean Delvare set_fan_min(struct device *dev, const char *buf, size_t count, int nr) 508*8d5d45fbSJean Delvare { 509*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 510*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 511*8d5d45fbSJean Delvare int val = simple_strtol(buf, NULL, 10); 512*8d5d45fbSJean Delvare 513*8d5d45fbSJean Delvare down(&data->update_lock); 514*8d5d45fbSJean Delvare if (val) { 515*8d5d45fbSJean Delvare data->fan_min[nr] = 516*8d5d45fbSJean Delvare FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr])); 517*8d5d45fbSJean Delvare } else { 518*8d5d45fbSJean Delvare data->fan_min[nr] = 0xff; 519*8d5d45fbSJean Delvare } 520*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]); 521*8d5d45fbSJean Delvare up(&data->update_lock); 522*8d5d45fbSJean Delvare return count; 523*8d5d45fbSJean Delvare } 524*8d5d45fbSJean Delvare static ssize_t 525*8d5d45fbSJean Delvare set_fan_div(struct device *dev, const char *buf, size_t count, int nr) 526*8d5d45fbSJean Delvare { 527*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 528*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 529*8d5d45fbSJean Delvare int val = simple_strtol(buf, NULL, 10); 530*8d5d45fbSJean Delvare u8 tmp; 531*8d5d45fbSJean Delvare int old_div; 532*8d5d45fbSJean Delvare int new_min; 533*8d5d45fbSJean Delvare 534*8d5d45fbSJean Delvare tmp = val == 8 ? 0xc0 : 535*8d5d45fbSJean Delvare val == 4 ? 0x80 : 536*8d5d45fbSJean Delvare val == 2 ? 0x40 : 537*8d5d45fbSJean Delvare val == 1 ? 0x00 : 538*8d5d45fbSJean Delvare 0xff; 539*8d5d45fbSJean Delvare if (tmp == 0xff) 540*8d5d45fbSJean Delvare return -EINVAL; 541*8d5d45fbSJean Delvare 542*8d5d45fbSJean Delvare down(&data->update_lock); 543*8d5d45fbSJean Delvare old_div = FAN_DIV_FROM_REG(data->fan_div[nr]); 544*8d5d45fbSJean Delvare data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]); 545*8d5d45fbSJean Delvare new_min = data->fan_min[nr] * old_div / 546*8d5d45fbSJean Delvare FAN_DIV_FROM_REG(data->fan_div[nr]); 547*8d5d45fbSJean Delvare data->fan_min[nr] = new_min > 0xff ? 0xff : new_min; 548*8d5d45fbSJean Delvare data->fan[nr] = data->fan[nr] * old_div / 549*8d5d45fbSJean Delvare FAN_DIV_FROM_REG(data->fan_div[nr]); 550*8d5d45fbSJean Delvare 551*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_FAN_DIV(nr), 552*8d5d45fbSJean Delvare data->fan_div[nr]); 553*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), 554*8d5d45fbSJean Delvare data->fan_min[nr]); 555*8d5d45fbSJean Delvare up(&data->update_lock); 556*8d5d45fbSJean Delvare return count; 557*8d5d45fbSJean Delvare } 558*8d5d45fbSJean Delvare 559*8d5d45fbSJean Delvare #define fan_offset(offset) \ 560*8d5d45fbSJean Delvare static ssize_t show_fan_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 561*8d5d45fbSJean Delvare { \ 562*8d5d45fbSJean Delvare return show_fan(dev, buf, offset - 1); \ 563*8d5d45fbSJean Delvare } \ 564*8d5d45fbSJean Delvare static ssize_t show_fan_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ 565*8d5d45fbSJean Delvare { \ 566*8d5d45fbSJean Delvare return show_fan_min(dev, buf, offset - 1); \ 567*8d5d45fbSJean Delvare } \ 568*8d5d45fbSJean Delvare static ssize_t show_fan_##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \ 569*8d5d45fbSJean Delvare { \ 570*8d5d45fbSJean Delvare return show_fan_div(dev, buf, offset - 1); \ 571*8d5d45fbSJean Delvare } \ 572*8d5d45fbSJean Delvare static ssize_t set_fan_##offset##_min (struct device *dev, struct device_attribute *attr, \ 573*8d5d45fbSJean Delvare const char *buf, size_t count) \ 574*8d5d45fbSJean Delvare { \ 575*8d5d45fbSJean Delvare return set_fan_min(dev, buf, count, offset - 1); \ 576*8d5d45fbSJean Delvare } \ 577*8d5d45fbSJean Delvare static ssize_t set_fan_##offset##_div (struct device *dev, struct device_attribute *attr, \ 578*8d5d45fbSJean Delvare const char *buf, size_t count) \ 579*8d5d45fbSJean Delvare { \ 580*8d5d45fbSJean Delvare return set_fan_div(dev, buf, count, offset - 1); \ 581*8d5d45fbSJean Delvare } \ 582*8d5d45fbSJean Delvare static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, \ 583*8d5d45fbSJean Delvare NULL); \ 584*8d5d45fbSJean Delvare static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ 585*8d5d45fbSJean Delvare show_fan_##offset##_min, set_fan_##offset##_min); \ 586*8d5d45fbSJean Delvare static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ 587*8d5d45fbSJean Delvare show_fan_##offset##_div, set_fan_##offset##_div); \ 588*8d5d45fbSJean Delvare static DEVICE_ATTR(auto_fan##offset##_min_pwm, S_IRUGO | S_IWUSR, \ 589*8d5d45fbSJean Delvare show_pwm_##offset, set_pwm_##offset) 590*8d5d45fbSJean Delvare 591*8d5d45fbSJean Delvare fan_offset(1); 592*8d5d45fbSJean Delvare fan_offset(2); 593*8d5d45fbSJean Delvare 594*8d5d45fbSJean Delvare 595*8d5d45fbSJean Delvare /* Temps */ 596*8d5d45fbSJean Delvare static ssize_t show_temp(struct device *dev, char *buf, int nr) 597*8d5d45fbSJean Delvare { 598*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 599*8d5d45fbSJean Delvare int ext; 600*8d5d45fbSJean Delvare ext = nr == 0 ? 601*8d5d45fbSJean Delvare ((data->ext_temp[nr] >> 6) & 0x3) * 2 : 602*8d5d45fbSJean Delvare (((data->ext_temp[nr] >> ((nr - 1) * 3)) & 7)); 603*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG_EXT(data->temp[nr], ext)); 604*8d5d45fbSJean Delvare } 605*8d5d45fbSJean Delvare static ssize_t show_temp_min(struct device *dev, char *buf, int nr) 606*8d5d45fbSJean Delvare { 607*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 608*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_min[nr])); 609*8d5d45fbSJean Delvare } 610*8d5d45fbSJean Delvare static ssize_t show_temp_max(struct device *dev, char *buf, int nr) 611*8d5d45fbSJean Delvare { 612*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 613*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[nr])); 614*8d5d45fbSJean Delvare } 615*8d5d45fbSJean Delvare static ssize_t show_temp_crit(struct device *dev, char *buf, int nr) 616*8d5d45fbSJean Delvare { 617*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 618*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_crit[nr])); 619*8d5d45fbSJean Delvare } 620*8d5d45fbSJean Delvare static ssize_t 621*8d5d45fbSJean Delvare set_temp_min(struct device *dev, const char *buf, size_t count, int nr) 622*8d5d45fbSJean Delvare { 623*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 624*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 625*8d5d45fbSJean Delvare int val; 626*8d5d45fbSJean Delvare 627*8d5d45fbSJean Delvare val = simple_strtol(buf, NULL, 10); 628*8d5d45fbSJean Delvare val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); 629*8d5d45fbSJean Delvare down(&data->update_lock); 630*8d5d45fbSJean Delvare data->temp_min[nr] = TEMP_TO_REG(val); 631*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr), 632*8d5d45fbSJean Delvare data->temp_min[nr]); 633*8d5d45fbSJean Delvare up(&data->update_lock); 634*8d5d45fbSJean Delvare return count; 635*8d5d45fbSJean Delvare } 636*8d5d45fbSJean Delvare static ssize_t 637*8d5d45fbSJean Delvare set_temp_max(struct device *dev, const char *buf, size_t count, int nr) 638*8d5d45fbSJean Delvare { 639*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 640*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 641*8d5d45fbSJean Delvare int val; 642*8d5d45fbSJean Delvare 643*8d5d45fbSJean Delvare val = simple_strtol(buf, NULL, 10); 644*8d5d45fbSJean Delvare val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); 645*8d5d45fbSJean Delvare down(&data->update_lock); 646*8d5d45fbSJean Delvare data->temp_max[nr] = TEMP_TO_REG(val); 647*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr), 648*8d5d45fbSJean Delvare data->temp_max[nr]); 649*8d5d45fbSJean Delvare up(&data->update_lock); 650*8d5d45fbSJean Delvare return count; 651*8d5d45fbSJean Delvare } 652*8d5d45fbSJean Delvare static ssize_t 653*8d5d45fbSJean Delvare set_temp_crit(struct device *dev, const char *buf, size_t count, int nr) 654*8d5d45fbSJean Delvare { 655*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 656*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 657*8d5d45fbSJean Delvare int val; 658*8d5d45fbSJean Delvare 659*8d5d45fbSJean Delvare val = simple_strtol(buf, NULL, 10); 660*8d5d45fbSJean Delvare val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875); 661*8d5d45fbSJean Delvare down(&data->update_lock); 662*8d5d45fbSJean Delvare data->temp_crit[nr] = TEMP_TO_REG(val); 663*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr), 664*8d5d45fbSJean Delvare data->temp_crit[nr]); 665*8d5d45fbSJean Delvare up(&data->update_lock); 666*8d5d45fbSJean Delvare return count; 667*8d5d45fbSJean Delvare } 668*8d5d45fbSJean Delvare 669*8d5d45fbSJean Delvare #define temp_reg(offset) \ 670*8d5d45fbSJean Delvare static ssize_t show_temp_##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 671*8d5d45fbSJean Delvare { \ 672*8d5d45fbSJean Delvare return show_temp(dev, buf, offset - 1); \ 673*8d5d45fbSJean Delvare } \ 674*8d5d45fbSJean Delvare static ssize_t show_temp_##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ 675*8d5d45fbSJean Delvare { \ 676*8d5d45fbSJean Delvare return show_temp_min(dev, buf, offset - 1); \ 677*8d5d45fbSJean Delvare } \ 678*8d5d45fbSJean Delvare static ssize_t show_temp_##offset##_max (struct device *dev, struct device_attribute *attr, char *buf) \ 679*8d5d45fbSJean Delvare { \ 680*8d5d45fbSJean Delvare return show_temp_max(dev, buf, offset - 1); \ 681*8d5d45fbSJean Delvare } \ 682*8d5d45fbSJean Delvare static ssize_t show_temp_##offset##_crit (struct device *dev, struct device_attribute *attr, char *buf) \ 683*8d5d45fbSJean Delvare { \ 684*8d5d45fbSJean Delvare return show_temp_crit(dev, buf, offset - 1); \ 685*8d5d45fbSJean Delvare } \ 686*8d5d45fbSJean Delvare static ssize_t set_temp_##offset##_min (struct device *dev, struct device_attribute *attr, \ 687*8d5d45fbSJean Delvare const char *buf, size_t count) \ 688*8d5d45fbSJean Delvare { \ 689*8d5d45fbSJean Delvare return set_temp_min(dev, buf, count, offset - 1); \ 690*8d5d45fbSJean Delvare } \ 691*8d5d45fbSJean Delvare static ssize_t set_temp_##offset##_max (struct device *dev, struct device_attribute *attr, \ 692*8d5d45fbSJean Delvare const char *buf, size_t count) \ 693*8d5d45fbSJean Delvare { \ 694*8d5d45fbSJean Delvare return set_temp_max(dev, buf, count, offset - 1); \ 695*8d5d45fbSJean Delvare } \ 696*8d5d45fbSJean Delvare static ssize_t set_temp_##offset##_crit (struct device *dev, struct device_attribute *attr, \ 697*8d5d45fbSJean Delvare const char *buf, size_t count) \ 698*8d5d45fbSJean Delvare { \ 699*8d5d45fbSJean Delvare return set_temp_crit(dev, buf, count, offset - 1); \ 700*8d5d45fbSJean Delvare } \ 701*8d5d45fbSJean Delvare static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, \ 702*8d5d45fbSJean Delvare NULL); \ 703*8d5d45fbSJean Delvare static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ 704*8d5d45fbSJean Delvare show_temp_##offset##_min, set_temp_##offset##_min); \ 705*8d5d45fbSJean Delvare static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ 706*8d5d45fbSJean Delvare show_temp_##offset##_max, set_temp_##offset##_max); \ 707*8d5d45fbSJean Delvare static DEVICE_ATTR(temp##offset##_crit, S_IRUGO | S_IWUSR, \ 708*8d5d45fbSJean Delvare show_temp_##offset##_crit, set_temp_##offset##_crit) 709*8d5d45fbSJean Delvare 710*8d5d45fbSJean Delvare temp_reg(1); 711*8d5d45fbSJean Delvare temp_reg(2); 712*8d5d45fbSJean Delvare temp_reg(3); 713*8d5d45fbSJean Delvare 714*8d5d45fbSJean Delvare /* Alarms */ 715*8d5d45fbSJean Delvare static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf) 716*8d5d45fbSJean Delvare { 717*8d5d45fbSJean Delvare struct adm1031_data *data = adm1031_update_device(dev); 718*8d5d45fbSJean Delvare return sprintf(buf, "%d\n", data->alarm); 719*8d5d45fbSJean Delvare } 720*8d5d45fbSJean Delvare 721*8d5d45fbSJean Delvare static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); 722*8d5d45fbSJean Delvare 723*8d5d45fbSJean Delvare 724*8d5d45fbSJean Delvare static int adm1031_attach_adapter(struct i2c_adapter *adapter) 725*8d5d45fbSJean Delvare { 726*8d5d45fbSJean Delvare if (!(adapter->class & I2C_CLASS_HWMON)) 727*8d5d45fbSJean Delvare return 0; 728*8d5d45fbSJean Delvare return i2c_detect(adapter, &addr_data, adm1031_detect); 729*8d5d45fbSJean Delvare } 730*8d5d45fbSJean Delvare 731*8d5d45fbSJean Delvare /* This function is called by i2c_detect */ 732*8d5d45fbSJean Delvare static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) 733*8d5d45fbSJean Delvare { 734*8d5d45fbSJean Delvare struct i2c_client *new_client; 735*8d5d45fbSJean Delvare struct adm1031_data *data; 736*8d5d45fbSJean Delvare int err = 0; 737*8d5d45fbSJean Delvare const char *name = ""; 738*8d5d45fbSJean Delvare 739*8d5d45fbSJean Delvare if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 740*8d5d45fbSJean Delvare goto exit; 741*8d5d45fbSJean Delvare 742*8d5d45fbSJean Delvare if (!(data = kmalloc(sizeof(struct adm1031_data), GFP_KERNEL))) { 743*8d5d45fbSJean Delvare err = -ENOMEM; 744*8d5d45fbSJean Delvare goto exit; 745*8d5d45fbSJean Delvare } 746*8d5d45fbSJean Delvare memset(data, 0, sizeof(struct adm1031_data)); 747*8d5d45fbSJean Delvare 748*8d5d45fbSJean Delvare new_client = &data->client; 749*8d5d45fbSJean Delvare i2c_set_clientdata(new_client, data); 750*8d5d45fbSJean Delvare new_client->addr = address; 751*8d5d45fbSJean Delvare new_client->adapter = adapter; 752*8d5d45fbSJean Delvare new_client->driver = &adm1031_driver; 753*8d5d45fbSJean Delvare new_client->flags = 0; 754*8d5d45fbSJean Delvare 755*8d5d45fbSJean Delvare if (kind < 0) { 756*8d5d45fbSJean Delvare int id, co; 757*8d5d45fbSJean Delvare id = i2c_smbus_read_byte_data(new_client, 0x3d); 758*8d5d45fbSJean Delvare co = i2c_smbus_read_byte_data(new_client, 0x3e); 759*8d5d45fbSJean Delvare 760*8d5d45fbSJean Delvare if (!((id == 0x31 || id == 0x30) && co == 0x41)) 761*8d5d45fbSJean Delvare goto exit_free; 762*8d5d45fbSJean Delvare kind = (id == 0x30) ? adm1030 : adm1031; 763*8d5d45fbSJean Delvare } 764*8d5d45fbSJean Delvare 765*8d5d45fbSJean Delvare if (kind <= 0) 766*8d5d45fbSJean Delvare kind = adm1031; 767*8d5d45fbSJean Delvare 768*8d5d45fbSJean Delvare /* Given the detected chip type, set the chip name and the 769*8d5d45fbSJean Delvare * auto fan control helper table. */ 770*8d5d45fbSJean Delvare if (kind == adm1030) { 771*8d5d45fbSJean Delvare name = "adm1030"; 772*8d5d45fbSJean Delvare data->chan_select_table = &auto_channel_select_table_adm1030; 773*8d5d45fbSJean Delvare } else if (kind == adm1031) { 774*8d5d45fbSJean Delvare name = "adm1031"; 775*8d5d45fbSJean Delvare data->chan_select_table = &auto_channel_select_table_adm1031; 776*8d5d45fbSJean Delvare } 777*8d5d45fbSJean Delvare data->chip_type = kind; 778*8d5d45fbSJean Delvare 779*8d5d45fbSJean Delvare strlcpy(new_client->name, name, I2C_NAME_SIZE); 780*8d5d45fbSJean Delvare data->valid = 0; 781*8d5d45fbSJean Delvare init_MUTEX(&data->update_lock); 782*8d5d45fbSJean Delvare 783*8d5d45fbSJean Delvare /* Tell the I2C layer a new client has arrived */ 784*8d5d45fbSJean Delvare if ((err = i2c_attach_client(new_client))) 785*8d5d45fbSJean Delvare goto exit_free; 786*8d5d45fbSJean Delvare 787*8d5d45fbSJean Delvare /* Initialize the ADM1031 chip */ 788*8d5d45fbSJean Delvare adm1031_init_client(new_client); 789*8d5d45fbSJean Delvare 790*8d5d45fbSJean Delvare /* Register sysfs hooks */ 791*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_fan1_input); 792*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_fan1_div); 793*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_fan1_min); 794*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_pwm1); 795*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_fan1_channel); 796*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp1_input); 797*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp1_min); 798*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp1_max); 799*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp1_crit); 800*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp2_input); 801*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp2_min); 802*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp2_max); 803*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp2_crit); 804*8d5d45fbSJean Delvare 805*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp1_off); 806*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp1_min); 807*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp1_max); 808*8d5d45fbSJean Delvare 809*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp2_off); 810*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp2_min); 811*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp2_max); 812*8d5d45fbSJean Delvare 813*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_fan1_min_pwm); 814*8d5d45fbSJean Delvare 815*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_alarms); 816*8d5d45fbSJean Delvare 817*8d5d45fbSJean Delvare if (kind == adm1031) { 818*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_fan2_input); 819*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_fan2_div); 820*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_fan2_min); 821*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_pwm2); 822*8d5d45fbSJean Delvare device_create_file(&new_client->dev, 823*8d5d45fbSJean Delvare &dev_attr_auto_fan2_channel); 824*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp3_input); 825*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp3_min); 826*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp3_max); 827*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_temp3_crit); 828*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp3_off); 829*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp3_min); 830*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_temp3_max); 831*8d5d45fbSJean Delvare device_create_file(&new_client->dev, &dev_attr_auto_fan2_min_pwm); 832*8d5d45fbSJean Delvare } 833*8d5d45fbSJean Delvare 834*8d5d45fbSJean Delvare return 0; 835*8d5d45fbSJean Delvare 836*8d5d45fbSJean Delvare exit_free: 837*8d5d45fbSJean Delvare kfree(new_client); 838*8d5d45fbSJean Delvare exit: 839*8d5d45fbSJean Delvare return err; 840*8d5d45fbSJean Delvare } 841*8d5d45fbSJean Delvare 842*8d5d45fbSJean Delvare static int adm1031_detach_client(struct i2c_client *client) 843*8d5d45fbSJean Delvare { 844*8d5d45fbSJean Delvare int ret; 845*8d5d45fbSJean Delvare if ((ret = i2c_detach_client(client)) != 0) { 846*8d5d45fbSJean Delvare return ret; 847*8d5d45fbSJean Delvare } 848*8d5d45fbSJean Delvare kfree(client); 849*8d5d45fbSJean Delvare return 0; 850*8d5d45fbSJean Delvare } 851*8d5d45fbSJean Delvare 852*8d5d45fbSJean Delvare static void adm1031_init_client(struct i2c_client *client) 853*8d5d45fbSJean Delvare { 854*8d5d45fbSJean Delvare unsigned int read_val; 855*8d5d45fbSJean Delvare unsigned int mask; 856*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 857*8d5d45fbSJean Delvare 858*8d5d45fbSJean Delvare mask = (ADM1031_CONF2_PWM1_ENABLE | ADM1031_CONF2_TACH1_ENABLE); 859*8d5d45fbSJean Delvare if (data->chip_type == adm1031) { 860*8d5d45fbSJean Delvare mask |= (ADM1031_CONF2_PWM2_ENABLE | 861*8d5d45fbSJean Delvare ADM1031_CONF2_TACH2_ENABLE); 862*8d5d45fbSJean Delvare } 863*8d5d45fbSJean Delvare /* Initialize the ADM1031 chip (enables fan speed reading ) */ 864*8d5d45fbSJean Delvare read_val = adm1031_read_value(client, ADM1031_REG_CONF2); 865*8d5d45fbSJean Delvare if ((read_val | mask) != read_val) { 866*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_CONF2, read_val | mask); 867*8d5d45fbSJean Delvare } 868*8d5d45fbSJean Delvare 869*8d5d45fbSJean Delvare read_val = adm1031_read_value(client, ADM1031_REG_CONF1); 870*8d5d45fbSJean Delvare if ((read_val | ADM1031_CONF1_MONITOR_ENABLE) != read_val) { 871*8d5d45fbSJean Delvare adm1031_write_value(client, ADM1031_REG_CONF1, read_val | 872*8d5d45fbSJean Delvare ADM1031_CONF1_MONITOR_ENABLE); 873*8d5d45fbSJean Delvare } 874*8d5d45fbSJean Delvare 875*8d5d45fbSJean Delvare } 876*8d5d45fbSJean Delvare 877*8d5d45fbSJean Delvare static struct adm1031_data *adm1031_update_device(struct device *dev) 878*8d5d45fbSJean Delvare { 879*8d5d45fbSJean Delvare struct i2c_client *client = to_i2c_client(dev); 880*8d5d45fbSJean Delvare struct adm1031_data *data = i2c_get_clientdata(client); 881*8d5d45fbSJean Delvare int chan; 882*8d5d45fbSJean Delvare 883*8d5d45fbSJean Delvare down(&data->update_lock); 884*8d5d45fbSJean Delvare 885*8d5d45fbSJean Delvare if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 886*8d5d45fbSJean Delvare || !data->valid) { 887*8d5d45fbSJean Delvare 888*8d5d45fbSJean Delvare dev_dbg(&client->dev, "Starting adm1031 update\n"); 889*8d5d45fbSJean Delvare for (chan = 0; 890*8d5d45fbSJean Delvare chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) { 891*8d5d45fbSJean Delvare u8 oldh, newh; 892*8d5d45fbSJean Delvare 893*8d5d45fbSJean Delvare oldh = 894*8d5d45fbSJean Delvare adm1031_read_value(client, ADM1031_REG_TEMP(chan)); 895*8d5d45fbSJean Delvare data->ext_temp[chan] = 896*8d5d45fbSJean Delvare adm1031_read_value(client, ADM1031_REG_EXT_TEMP); 897*8d5d45fbSJean Delvare newh = 898*8d5d45fbSJean Delvare adm1031_read_value(client, ADM1031_REG_TEMP(chan)); 899*8d5d45fbSJean Delvare if (newh != oldh) { 900*8d5d45fbSJean Delvare data->ext_temp[chan] = 901*8d5d45fbSJean Delvare adm1031_read_value(client, 902*8d5d45fbSJean Delvare ADM1031_REG_EXT_TEMP); 903*8d5d45fbSJean Delvare #ifdef DEBUG 904*8d5d45fbSJean Delvare oldh = 905*8d5d45fbSJean Delvare adm1031_read_value(client, 906*8d5d45fbSJean Delvare ADM1031_REG_TEMP(chan)); 907*8d5d45fbSJean Delvare 908*8d5d45fbSJean Delvare /* oldh is actually newer */ 909*8d5d45fbSJean Delvare if (newh != oldh) 910*8d5d45fbSJean Delvare dev_warn(&client->dev, 911*8d5d45fbSJean Delvare "Remote temperature may be " 912*8d5d45fbSJean Delvare "wrong.\n"); 913*8d5d45fbSJean Delvare #endif 914*8d5d45fbSJean Delvare } 915*8d5d45fbSJean Delvare data->temp[chan] = newh; 916*8d5d45fbSJean Delvare 917*8d5d45fbSJean Delvare data->temp_min[chan] = 918*8d5d45fbSJean Delvare adm1031_read_value(client, 919*8d5d45fbSJean Delvare ADM1031_REG_TEMP_MIN(chan)); 920*8d5d45fbSJean Delvare data->temp_max[chan] = 921*8d5d45fbSJean Delvare adm1031_read_value(client, 922*8d5d45fbSJean Delvare ADM1031_REG_TEMP_MAX(chan)); 923*8d5d45fbSJean Delvare data->temp_crit[chan] = 924*8d5d45fbSJean Delvare adm1031_read_value(client, 925*8d5d45fbSJean Delvare ADM1031_REG_TEMP_CRIT(chan)); 926*8d5d45fbSJean Delvare data->auto_temp[chan] = 927*8d5d45fbSJean Delvare adm1031_read_value(client, 928*8d5d45fbSJean Delvare ADM1031_REG_AUTO_TEMP(chan)); 929*8d5d45fbSJean Delvare 930*8d5d45fbSJean Delvare } 931*8d5d45fbSJean Delvare 932*8d5d45fbSJean Delvare data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1); 933*8d5d45fbSJean Delvare data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2); 934*8d5d45fbSJean Delvare 935*8d5d45fbSJean Delvare data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0)) 936*8d5d45fbSJean Delvare | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) 937*8d5d45fbSJean Delvare << 8); 938*8d5d45fbSJean Delvare if (data->chip_type == adm1030) { 939*8d5d45fbSJean Delvare data->alarm &= 0xc0ff; 940*8d5d45fbSJean Delvare } 941*8d5d45fbSJean Delvare 942*8d5d45fbSJean Delvare for (chan=0; chan<(data->chip_type == adm1030 ? 1 : 2); chan++) { 943*8d5d45fbSJean Delvare data->fan_div[chan] = 944*8d5d45fbSJean Delvare adm1031_read_value(client, ADM1031_REG_FAN_DIV(chan)); 945*8d5d45fbSJean Delvare data->fan_min[chan] = 946*8d5d45fbSJean Delvare adm1031_read_value(client, ADM1031_REG_FAN_MIN(chan)); 947*8d5d45fbSJean Delvare data->fan[chan] = 948*8d5d45fbSJean Delvare adm1031_read_value(client, ADM1031_REG_FAN_SPEED(chan)); 949*8d5d45fbSJean Delvare data->pwm[chan] = 950*8d5d45fbSJean Delvare 0xf & (adm1031_read_value(client, ADM1031_REG_PWM) >> 951*8d5d45fbSJean Delvare (4*chan)); 952*8d5d45fbSJean Delvare } 953*8d5d45fbSJean Delvare data->last_updated = jiffies; 954*8d5d45fbSJean Delvare data->valid = 1; 955*8d5d45fbSJean Delvare } 956*8d5d45fbSJean Delvare 957*8d5d45fbSJean Delvare up(&data->update_lock); 958*8d5d45fbSJean Delvare 959*8d5d45fbSJean Delvare return data; 960*8d5d45fbSJean Delvare } 961*8d5d45fbSJean Delvare 962*8d5d45fbSJean Delvare static int __init sensors_adm1031_init(void) 963*8d5d45fbSJean Delvare { 964*8d5d45fbSJean Delvare return i2c_add_driver(&adm1031_driver); 965*8d5d45fbSJean Delvare } 966*8d5d45fbSJean Delvare 967*8d5d45fbSJean Delvare static void __exit sensors_adm1031_exit(void) 968*8d5d45fbSJean Delvare { 969*8d5d45fbSJean Delvare i2c_del_driver(&adm1031_driver); 970*8d5d45fbSJean Delvare } 971*8d5d45fbSJean Delvare 972*8d5d45fbSJean Delvare MODULE_AUTHOR("Alexandre d'Alton <alex@alexdalton.org>"); 973*8d5d45fbSJean Delvare MODULE_DESCRIPTION("ADM1031/ADM1030 driver"); 974*8d5d45fbSJean Delvare MODULE_LICENSE("GPL"); 975*8d5d45fbSJean Delvare 976*8d5d45fbSJean Delvare module_init(sensors_adm1031_init); 977*8d5d45fbSJean Delvare module_exit(sensors_adm1031_exit); 978