106160327SDavide Rizzo /* 2*0f1deb4bSDavide Rizzo * Copyright (C) 2008, 2010 Davide Rizzo <elpa.rizzo@gmail.com> 306160327SDavide Rizzo * 4*0f1deb4bSDavide Rizzo * The LM95241 is a sensor chip made by National Semiconductors. 5*0f1deb4bSDavide Rizzo * It reports up to three temperatures (its own plus up to two external ones). 6*0f1deb4bSDavide Rizzo * Complete datasheet can be obtained from National's website at: 706160327SDavide Rizzo * http://www.national.com/ds.cgi/LM/LM95241.pdf 806160327SDavide Rizzo * 906160327SDavide Rizzo * This program is free software; you can redistribute it and/or modify 1006160327SDavide Rizzo * it under the terms of the GNU General Public License as published by 1106160327SDavide Rizzo * the Free Software Foundation; either version 2 of the License, or 1206160327SDavide Rizzo * (at your option) any later version. 1306160327SDavide Rizzo * 1406160327SDavide Rizzo * This program is distributed in the hope that it will be useful, 1506160327SDavide Rizzo * but WITHOUT ANY WARRANTY; without even the implied warranty of 1606160327SDavide Rizzo * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1706160327SDavide Rizzo * GNU General Public License for more details. 1806160327SDavide Rizzo * 1906160327SDavide Rizzo * You should have received a copy of the GNU General Public License 2006160327SDavide Rizzo * along with this program; if not, write to the Free Software 2106160327SDavide Rizzo * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 2206160327SDavide Rizzo */ 2306160327SDavide Rizzo 2406160327SDavide Rizzo #include <linux/module.h> 2506160327SDavide Rizzo #include <linux/init.h> 2606160327SDavide Rizzo #include <linux/slab.h> 2706160327SDavide Rizzo #include <linux/jiffies.h> 2806160327SDavide Rizzo #include <linux/i2c.h> 2906160327SDavide Rizzo #include <linux/hwmon.h> 3006160327SDavide Rizzo #include <linux/hwmon-sysfs.h> 3106160327SDavide Rizzo #include <linux/err.h> 3206160327SDavide Rizzo #include <linux/mutex.h> 3306160327SDavide Rizzo #include <linux/sysfs.h> 3406160327SDavide Rizzo 35*0f1deb4bSDavide Rizzo #define DEVNAME "lm95241" 36*0f1deb4bSDavide Rizzo 3706160327SDavide Rizzo static const unsigned short normal_i2c[] = { 3806160327SDavide Rizzo 0x19, 0x2a, 0x2b, I2C_CLIENT_END }; 3906160327SDavide Rizzo 4006160327SDavide Rizzo /* LM95241 registers */ 4106160327SDavide Rizzo #define LM95241_REG_R_MAN_ID 0xFE 4206160327SDavide Rizzo #define LM95241_REG_R_CHIP_ID 0xFF 4306160327SDavide Rizzo #define LM95241_REG_R_STATUS 0x02 4406160327SDavide Rizzo #define LM95241_REG_RW_CONFIG 0x03 4506160327SDavide Rizzo #define LM95241_REG_RW_REM_FILTER 0x06 4606160327SDavide Rizzo #define LM95241_REG_RW_TRUTHERM 0x07 4706160327SDavide Rizzo #define LM95241_REG_W_ONE_SHOT 0x0F 4806160327SDavide Rizzo #define LM95241_REG_R_LOCAL_TEMPH 0x10 4906160327SDavide Rizzo #define LM95241_REG_R_REMOTE1_TEMPH 0x11 5006160327SDavide Rizzo #define LM95241_REG_R_REMOTE2_TEMPH 0x12 5106160327SDavide Rizzo #define LM95241_REG_R_LOCAL_TEMPL 0x20 5206160327SDavide Rizzo #define LM95241_REG_R_REMOTE1_TEMPL 0x21 5306160327SDavide Rizzo #define LM95241_REG_R_REMOTE2_TEMPL 0x22 5406160327SDavide Rizzo #define LM95241_REG_RW_REMOTE_MODEL 0x30 5506160327SDavide Rizzo 5606160327SDavide Rizzo /* LM95241 specific bitfields */ 5706160327SDavide Rizzo #define CFG_STOP 0x40 5806160327SDavide Rizzo #define CFG_CR0076 0x00 5906160327SDavide Rizzo #define CFG_CR0182 0x10 6006160327SDavide Rizzo #define CFG_CR1000 0x20 6106160327SDavide Rizzo #define CFG_CR2700 0x30 6206160327SDavide Rizzo #define R1MS_SHIFT 0 6306160327SDavide Rizzo #define R2MS_SHIFT 2 6406160327SDavide Rizzo #define R1MS_MASK (0x01 << (R1MS_SHIFT)) 6506160327SDavide Rizzo #define R2MS_MASK (0x01 << (R2MS_SHIFT)) 6606160327SDavide Rizzo #define R1DF_SHIFT 1 6706160327SDavide Rizzo #define R2DF_SHIFT 2 6806160327SDavide Rizzo #define R1DF_MASK (0x01 << (R1DF_SHIFT)) 6906160327SDavide Rizzo #define R2DF_MASK (0x01 << (R2DF_SHIFT)) 7006160327SDavide Rizzo #define R1FE_MASK 0x01 7106160327SDavide Rizzo #define R2FE_MASK 0x05 7206160327SDavide Rizzo #define TT1_SHIFT 0 7306160327SDavide Rizzo #define TT2_SHIFT 4 7406160327SDavide Rizzo #define TT_OFF 0 7506160327SDavide Rizzo #define TT_ON 1 7606160327SDavide Rizzo #define TT_MASK 7 7706160327SDavide Rizzo #define MANUFACTURER_ID 0x01 7806160327SDavide Rizzo #define DEFAULT_REVISION 0xA4 7906160327SDavide Rizzo 80*0f1deb4bSDavide Rizzo static const u8 lm95241_reg_address[] = { 81*0f1deb4bSDavide Rizzo LM95241_REG_R_LOCAL_TEMPH, 82*0f1deb4bSDavide Rizzo LM95241_REG_R_LOCAL_TEMPL, 83*0f1deb4bSDavide Rizzo LM95241_REG_R_REMOTE1_TEMPH, 84*0f1deb4bSDavide Rizzo LM95241_REG_R_REMOTE1_TEMPL, 85*0f1deb4bSDavide Rizzo LM95241_REG_R_REMOTE2_TEMPH, 86*0f1deb4bSDavide Rizzo LM95241_REG_R_REMOTE2_TEMPL 87*0f1deb4bSDavide Rizzo }; 8806160327SDavide Rizzo 8906160327SDavide Rizzo /* Client data (each client gets its own) */ 9006160327SDavide Rizzo struct lm95241_data { 9106160327SDavide Rizzo struct device *hwmon_dev; 9206160327SDavide Rizzo struct mutex update_lock; 93bc482bf0SGuenter Roeck unsigned long last_updated, interval; /* in jiffies */ 9406160327SDavide Rizzo char valid; /* zero until following fields are valid */ 9506160327SDavide Rizzo /* registers values */ 96*0f1deb4bSDavide Rizzo u8 temp[ARRAY_SIZE(lm95241_reg_address)]; 9706160327SDavide Rizzo u8 config, model, trutherm; 9806160327SDavide Rizzo }; 9906160327SDavide Rizzo 100*0f1deb4bSDavide Rizzo /* Conversions */ 101*0f1deb4bSDavide Rizzo static int TempFromReg(u8 val_h, u8 val_l) 102*0f1deb4bSDavide Rizzo { 103*0f1deb4bSDavide Rizzo if (val_h & 0x80) 104*0f1deb4bSDavide Rizzo return val_h - 0x100; 105*0f1deb4bSDavide Rizzo return val_h * 1000 + val_l * 1000 / 256; 10606160327SDavide Rizzo } 107*0f1deb4bSDavide Rizzo 108*0f1deb4bSDavide Rizzo static struct lm95241_data *lm95241_update_device(struct device *dev) 109*0f1deb4bSDavide Rizzo { 110*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 111*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 112*0f1deb4bSDavide Rizzo 113*0f1deb4bSDavide Rizzo mutex_lock(&data->update_lock); 114*0f1deb4bSDavide Rizzo 115*0f1deb4bSDavide Rizzo if (time_after(jiffies, data->last_updated + data->interval) || 116*0f1deb4bSDavide Rizzo !data->valid) { 117*0f1deb4bSDavide Rizzo int i; 118*0f1deb4bSDavide Rizzo 119*0f1deb4bSDavide Rizzo dev_dbg(&client->dev, "Updating lm95241 data.\n"); 120*0f1deb4bSDavide Rizzo for (i = 0; i < ARRAY_SIZE(lm95241_reg_address); i++) 121*0f1deb4bSDavide Rizzo data->temp[i] 122*0f1deb4bSDavide Rizzo = i2c_smbus_read_byte_data(client, 123*0f1deb4bSDavide Rizzo lm95241_reg_address[i]); 124*0f1deb4bSDavide Rizzo data->last_updated = jiffies; 125*0f1deb4bSDavide Rizzo data->valid = 1; 126*0f1deb4bSDavide Rizzo } 127*0f1deb4bSDavide Rizzo 128*0f1deb4bSDavide Rizzo mutex_unlock(&data->update_lock); 129*0f1deb4bSDavide Rizzo 130*0f1deb4bSDavide Rizzo return data; 131*0f1deb4bSDavide Rizzo } 132*0f1deb4bSDavide Rizzo 133*0f1deb4bSDavide Rizzo /* Sysfs stuff */ 134*0f1deb4bSDavide Rizzo static ssize_t show_input(struct device *dev, struct device_attribute *attr, 135*0f1deb4bSDavide Rizzo char *buf) 136*0f1deb4bSDavide Rizzo { 137*0f1deb4bSDavide Rizzo struct lm95241_data *data = lm95241_update_device(dev); 138*0f1deb4bSDavide Rizzo 139*0f1deb4bSDavide Rizzo return snprintf(buf, PAGE_SIZE - 1, "%d\n", 140*0f1deb4bSDavide Rizzo TempFromReg(data->temp[to_sensor_dev_attr(attr)->index], 141*0f1deb4bSDavide Rizzo data->temp[to_sensor_dev_attr(attr)->index + 1])); 142*0f1deb4bSDavide Rizzo } 143*0f1deb4bSDavide Rizzo 144*0f1deb4bSDavide Rizzo static ssize_t show_type(struct device *dev, struct device_attribute *attr, 145*0f1deb4bSDavide Rizzo char *buf) 146*0f1deb4bSDavide Rizzo { 147*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 148*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 149*0f1deb4bSDavide Rizzo 150*0f1deb4bSDavide Rizzo return snprintf(buf, PAGE_SIZE - 1, 151*0f1deb4bSDavide Rizzo data->model & to_sensor_dev_attr(attr)->index ? "1\n" : "2\n"); 152*0f1deb4bSDavide Rizzo } 153*0f1deb4bSDavide Rizzo 154*0f1deb4bSDavide Rizzo static ssize_t set_type(struct device *dev, struct device_attribute *attr, 155*0f1deb4bSDavide Rizzo const char *buf, size_t count) 156*0f1deb4bSDavide Rizzo { 157*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 158*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 159*0f1deb4bSDavide Rizzo unsigned long val; 160*0f1deb4bSDavide Rizzo int shift; 161*0f1deb4bSDavide Rizzo u8 mask = to_sensor_dev_attr(attr)->index; 162*0f1deb4bSDavide Rizzo 163*0f1deb4bSDavide Rizzo if (strict_strtoul(buf, 10, &val) < 0) 164*0f1deb4bSDavide Rizzo return -EINVAL; 165*0f1deb4bSDavide Rizzo if (val != 1 && val != 2) 166*0f1deb4bSDavide Rizzo return -EINVAL; 167*0f1deb4bSDavide Rizzo 168*0f1deb4bSDavide Rizzo shift = mask == R1MS_MASK ? TT1_SHIFT : TT2_SHIFT; 169*0f1deb4bSDavide Rizzo 170*0f1deb4bSDavide Rizzo mutex_lock(&data->update_lock); 171*0f1deb4bSDavide Rizzo 172*0f1deb4bSDavide Rizzo data->trutherm &= ~(TT_MASK << shift); 173*0f1deb4bSDavide Rizzo if (val == 1) { 174*0f1deb4bSDavide Rizzo data->model |= mask; 175*0f1deb4bSDavide Rizzo data->trutherm |= (TT_ON << shift); 176*0f1deb4bSDavide Rizzo } else { 177*0f1deb4bSDavide Rizzo data->model &= ~mask; 178*0f1deb4bSDavide Rizzo data->trutherm |= (TT_OFF << shift); 179*0f1deb4bSDavide Rizzo } 180*0f1deb4bSDavide Rizzo data->valid = 0; 181*0f1deb4bSDavide Rizzo 182*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, 183*0f1deb4bSDavide Rizzo data->model); 184*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, 185*0f1deb4bSDavide Rizzo data->trutherm); 186*0f1deb4bSDavide Rizzo 187*0f1deb4bSDavide Rizzo mutex_unlock(&data->update_lock); 188*0f1deb4bSDavide Rizzo 189*0f1deb4bSDavide Rizzo return count; 190*0f1deb4bSDavide Rizzo } 191*0f1deb4bSDavide Rizzo 192*0f1deb4bSDavide Rizzo static ssize_t show_min(struct device *dev, struct device_attribute *attr, 193*0f1deb4bSDavide Rizzo char *buf) 194*0f1deb4bSDavide Rizzo { 195*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 196*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 197*0f1deb4bSDavide Rizzo 198*0f1deb4bSDavide Rizzo return snprintf(buf, PAGE_SIZE - 1, 199*0f1deb4bSDavide Rizzo data->config & to_sensor_dev_attr(attr)->index ? 200*0f1deb4bSDavide Rizzo "-127000\n" : "0\n"); 201*0f1deb4bSDavide Rizzo } 202*0f1deb4bSDavide Rizzo 203*0f1deb4bSDavide Rizzo static ssize_t set_min(struct device *dev, struct device_attribute *attr, 204*0f1deb4bSDavide Rizzo const char *buf, size_t count) 205*0f1deb4bSDavide Rizzo { 206*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 207*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 208*0f1deb4bSDavide Rizzo long val; 209*0f1deb4bSDavide Rizzo 210*0f1deb4bSDavide Rizzo if (strict_strtol(buf, 10, &val) < 0) 211*0f1deb4bSDavide Rizzo return -EINVAL; 212*0f1deb4bSDavide Rizzo if (val < -128000) 213*0f1deb4bSDavide Rizzo return -EINVAL; 214*0f1deb4bSDavide Rizzo 215*0f1deb4bSDavide Rizzo mutex_lock(&data->update_lock); 216*0f1deb4bSDavide Rizzo 217*0f1deb4bSDavide Rizzo if (val < 0) 218*0f1deb4bSDavide Rizzo data->config |= to_sensor_dev_attr(attr)->index; 219*0f1deb4bSDavide Rizzo else 220*0f1deb4bSDavide Rizzo data->config &= ~to_sensor_dev_attr(attr)->index; 221*0f1deb4bSDavide Rizzo data->valid = 0; 222*0f1deb4bSDavide Rizzo 223*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); 224*0f1deb4bSDavide Rizzo 225*0f1deb4bSDavide Rizzo mutex_unlock(&data->update_lock); 226*0f1deb4bSDavide Rizzo 227*0f1deb4bSDavide Rizzo return count; 228*0f1deb4bSDavide Rizzo } 229*0f1deb4bSDavide Rizzo 230*0f1deb4bSDavide Rizzo static ssize_t show_max(struct device *dev, struct device_attribute *attr, 231*0f1deb4bSDavide Rizzo char *buf) 232*0f1deb4bSDavide Rizzo { 233*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 234*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 235*0f1deb4bSDavide Rizzo 236*0f1deb4bSDavide Rizzo return snprintf(buf, PAGE_SIZE - 1, 237*0f1deb4bSDavide Rizzo data->config & to_sensor_dev_attr(attr)->index ? 238*0f1deb4bSDavide Rizzo "127000\n" : "255000\n"); 239*0f1deb4bSDavide Rizzo } 240*0f1deb4bSDavide Rizzo 241*0f1deb4bSDavide Rizzo static ssize_t set_max(struct device *dev, struct device_attribute *attr, 242*0f1deb4bSDavide Rizzo const char *buf, size_t count) 243*0f1deb4bSDavide Rizzo { 244*0f1deb4bSDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 245*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 246*0f1deb4bSDavide Rizzo long val; 247*0f1deb4bSDavide Rizzo 248*0f1deb4bSDavide Rizzo if (strict_strtol(buf, 10, &val) < 0) 249*0f1deb4bSDavide Rizzo return -EINVAL; 250*0f1deb4bSDavide Rizzo if (val >= 256000) 251*0f1deb4bSDavide Rizzo return -EINVAL; 252*0f1deb4bSDavide Rizzo 253*0f1deb4bSDavide Rizzo mutex_lock(&data->update_lock); 254*0f1deb4bSDavide Rizzo 255*0f1deb4bSDavide Rizzo if (val <= 127000) 256*0f1deb4bSDavide Rizzo data->config |= to_sensor_dev_attr(attr)->index; 257*0f1deb4bSDavide Rizzo else 258*0f1deb4bSDavide Rizzo data->config &= ~to_sensor_dev_attr(attr)->index; 259*0f1deb4bSDavide Rizzo data->valid = 0; 260*0f1deb4bSDavide Rizzo 261*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); 262*0f1deb4bSDavide Rizzo 263*0f1deb4bSDavide Rizzo mutex_unlock(&data->update_lock); 264*0f1deb4bSDavide Rizzo 265*0f1deb4bSDavide Rizzo return count; 266*0f1deb4bSDavide Rizzo } 26706160327SDavide Rizzo 268bc482bf0SGuenter Roeck static ssize_t show_interval(struct device *dev, struct device_attribute *attr, 26906160327SDavide Rizzo char *buf) 27006160327SDavide Rizzo { 27106160327SDavide Rizzo struct lm95241_data *data = lm95241_update_device(dev); 27206160327SDavide Rizzo 273*0f1deb4bSDavide Rizzo return snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->interval 274*0f1deb4bSDavide Rizzo / HZ); 27506160327SDavide Rizzo } 27606160327SDavide Rizzo 277bc482bf0SGuenter Roeck static ssize_t set_interval(struct device *dev, struct device_attribute *attr, 27806160327SDavide Rizzo const char *buf, size_t count) 27906160327SDavide Rizzo { 28006160327SDavide Rizzo struct i2c_client *client = to_i2c_client(dev); 28106160327SDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 28261ec2da5SJean Delvare unsigned long val; 28306160327SDavide Rizzo 28461ec2da5SJean Delvare if (strict_strtoul(buf, 10, &val) < 0) 28561ec2da5SJean Delvare return -EINVAL; 28661ec2da5SJean Delvare 28761ec2da5SJean Delvare data->interval = val * HZ / 1000; 28806160327SDavide Rizzo 28906160327SDavide Rizzo return count; 29006160327SDavide Rizzo } 29106160327SDavide Rizzo 292*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_input, NULL, 0); 293*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_input, NULL, 2); 294*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_input, NULL, 4); 295*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type, set_type, 296*0f1deb4bSDavide Rizzo R1MS_MASK); 297*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type, set_type, 298*0f1deb4bSDavide Rizzo R2MS_MASK); 299*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min, set_min, 300*0f1deb4bSDavide Rizzo R1DF_MASK); 301*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min, set_min, 302*0f1deb4bSDavide Rizzo R2DF_MASK); 303*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max, set_max, 304*0f1deb4bSDavide Rizzo R1DF_MASK); 305*0f1deb4bSDavide Rizzo static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max, set_max, 306*0f1deb4bSDavide Rizzo R2DF_MASK); 307bc482bf0SGuenter Roeck static DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, show_interval, 308bc482bf0SGuenter Roeck set_interval); 30906160327SDavide Rizzo 31006160327SDavide Rizzo static struct attribute *lm95241_attributes[] = { 311*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp1_input.dev_attr.attr, 312*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp2_input.dev_attr.attr, 313*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp3_input.dev_attr.attr, 314*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp2_type.dev_attr.attr, 315*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp3_type.dev_attr.attr, 316*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp2_min.dev_attr.attr, 317*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp3_min.dev_attr.attr, 318*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp2_max.dev_attr.attr, 319*0f1deb4bSDavide Rizzo &sensor_dev_attr_temp3_max.dev_attr.attr, 320bc482bf0SGuenter Roeck &dev_attr_update_interval.attr, 32106160327SDavide Rizzo NULL 32206160327SDavide Rizzo }; 32306160327SDavide Rizzo 32406160327SDavide Rizzo static const struct attribute_group lm95241_group = { 32506160327SDavide Rizzo .attrs = lm95241_attributes, 32606160327SDavide Rizzo }; 32706160327SDavide Rizzo 328797eaa4bSJean Delvare /* Return 0 if detection is successful, -ENODEV otherwise */ 329310ec792SJean Delvare static int lm95241_detect(struct i2c_client *new_client, 330797eaa4bSJean Delvare struct i2c_board_info *info) 33106160327SDavide Rizzo { 332797eaa4bSJean Delvare struct i2c_adapter *adapter = new_client->adapter; 333797eaa4bSJean Delvare int address = new_client->addr; 33452df6440SJean Delvare const char *name; 33506160327SDavide Rizzo 33606160327SDavide Rizzo if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 337797eaa4bSJean Delvare return -ENODEV; 33806160327SDavide Rizzo 33906160327SDavide Rizzo if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) 34006160327SDavide Rizzo == MANUFACTURER_ID) 34106160327SDavide Rizzo && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) 34206160327SDavide Rizzo >= DEFAULT_REVISION)) { 343*0f1deb4bSDavide Rizzo name = DEVNAME; 34452df6440SJean Delvare } else { 34552df6440SJean Delvare dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n", 34652df6440SJean Delvare address); 347797eaa4bSJean Delvare return -ENODEV; 34806160327SDavide Rizzo } 34906160327SDavide Rizzo 350797eaa4bSJean Delvare /* Fill the i2c board info */ 351797eaa4bSJean Delvare strlcpy(info->type, name, I2C_NAME_SIZE); 352797eaa4bSJean Delvare return 0; 353797eaa4bSJean Delvare } 35406160327SDavide Rizzo 355*0f1deb4bSDavide Rizzo static void lm95241_init_client(struct i2c_client *client) 356*0f1deb4bSDavide Rizzo { 357*0f1deb4bSDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 358*0f1deb4bSDavide Rizzo 359*0f1deb4bSDavide Rizzo data->interval = HZ; /* 1 sec default */ 360*0f1deb4bSDavide Rizzo data->valid = 0; 361*0f1deb4bSDavide Rizzo data->config = CFG_CR0076; 362*0f1deb4bSDavide Rizzo data->model = 0; 363*0f1deb4bSDavide Rizzo data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT); 364*0f1deb4bSDavide Rizzo 365*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, data->config); 366*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER, 367*0f1deb4bSDavide Rizzo R1FE_MASK | R2FE_MASK); 368*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, 369*0f1deb4bSDavide Rizzo data->trutherm); 370*0f1deb4bSDavide Rizzo i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, 371*0f1deb4bSDavide Rizzo data->model); 372*0f1deb4bSDavide Rizzo } 373*0f1deb4bSDavide Rizzo 374797eaa4bSJean Delvare static int lm95241_probe(struct i2c_client *new_client, 375797eaa4bSJean Delvare const struct i2c_device_id *id) 376797eaa4bSJean Delvare { 377797eaa4bSJean Delvare struct lm95241_data *data; 378797eaa4bSJean Delvare int err; 379797eaa4bSJean Delvare 380797eaa4bSJean Delvare data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL); 381797eaa4bSJean Delvare if (!data) { 382797eaa4bSJean Delvare err = -ENOMEM; 383797eaa4bSJean Delvare goto exit; 384797eaa4bSJean Delvare } 385797eaa4bSJean Delvare 386797eaa4bSJean Delvare i2c_set_clientdata(new_client, data); 38706160327SDavide Rizzo mutex_init(&data->update_lock); 38806160327SDavide Rizzo 38906160327SDavide Rizzo /* Initialize the LM95241 chip */ 39006160327SDavide Rizzo lm95241_init_client(new_client); 39106160327SDavide Rizzo 39206160327SDavide Rizzo /* Register sysfs hooks */ 39306160327SDavide Rizzo err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group); 39406160327SDavide Rizzo if (err) 395797eaa4bSJean Delvare goto exit_free; 39606160327SDavide Rizzo 39706160327SDavide Rizzo data->hwmon_dev = hwmon_device_register(&new_client->dev); 39806160327SDavide Rizzo if (IS_ERR(data->hwmon_dev)) { 39906160327SDavide Rizzo err = PTR_ERR(data->hwmon_dev); 40006160327SDavide Rizzo goto exit_remove_files; 40106160327SDavide Rizzo } 40206160327SDavide Rizzo 40306160327SDavide Rizzo return 0; 40406160327SDavide Rizzo 40506160327SDavide Rizzo exit_remove_files: 40606160327SDavide Rizzo sysfs_remove_group(&new_client->dev.kobj, &lm95241_group); 40706160327SDavide Rizzo exit_free: 40806160327SDavide Rizzo kfree(data); 40906160327SDavide Rizzo exit: 41006160327SDavide Rizzo return err; 41106160327SDavide Rizzo } 41206160327SDavide Rizzo 413797eaa4bSJean Delvare static int lm95241_remove(struct i2c_client *client) 41406160327SDavide Rizzo { 41506160327SDavide Rizzo struct lm95241_data *data = i2c_get_clientdata(client); 41606160327SDavide Rizzo 41706160327SDavide Rizzo hwmon_device_unregister(data->hwmon_dev); 41806160327SDavide Rizzo sysfs_remove_group(&client->dev.kobj, &lm95241_group); 41906160327SDavide Rizzo 42006160327SDavide Rizzo kfree(data); 42106160327SDavide Rizzo return 0; 42206160327SDavide Rizzo } 42306160327SDavide Rizzo 424797eaa4bSJean Delvare /* Driver data (common to all clients) */ 425797eaa4bSJean Delvare static const struct i2c_device_id lm95241_id[] = { 426*0f1deb4bSDavide Rizzo { DEVNAME, 0 }, 427797eaa4bSJean Delvare { } 428797eaa4bSJean Delvare }; 429797eaa4bSJean Delvare MODULE_DEVICE_TABLE(i2c, lm95241_id); 430797eaa4bSJean Delvare 431797eaa4bSJean Delvare static struct i2c_driver lm95241_driver = { 432797eaa4bSJean Delvare .class = I2C_CLASS_HWMON, 433797eaa4bSJean Delvare .driver = { 434*0f1deb4bSDavide Rizzo .name = DEVNAME, 435797eaa4bSJean Delvare }, 436797eaa4bSJean Delvare .probe = lm95241_probe, 437797eaa4bSJean Delvare .remove = lm95241_remove, 438797eaa4bSJean Delvare .id_table = lm95241_id, 439797eaa4bSJean Delvare .detect = lm95241_detect, 440c3813d6aSJean Delvare .address_list = normal_i2c, 441797eaa4bSJean Delvare }; 442797eaa4bSJean Delvare 44306160327SDavide Rizzo static int __init sensors_lm95241_init(void) 44406160327SDavide Rizzo { 44506160327SDavide Rizzo return i2c_add_driver(&lm95241_driver); 44606160327SDavide Rizzo } 44706160327SDavide Rizzo 44806160327SDavide Rizzo static void __exit sensors_lm95241_exit(void) 44906160327SDavide Rizzo { 45006160327SDavide Rizzo i2c_del_driver(&lm95241_driver); 45106160327SDavide Rizzo } 45206160327SDavide Rizzo 453*0f1deb4bSDavide Rizzo MODULE_AUTHOR("Davide Rizzo <elpa.rizzo@gmail.com>"); 45406160327SDavide Rizzo MODULE_DESCRIPTION("LM95241 sensor driver"); 45506160327SDavide Rizzo MODULE_LICENSE("GPL"); 45606160327SDavide Rizzo 45706160327SDavide Rizzo module_init(sensors_lm95241_init); 45806160327SDavide Rizzo module_exit(sensors_lm95241_exit); 459