1*beb1b6bbSSteven King /* Texas Instruments TMP102 SMBUS temperature sensor driver 2*beb1b6bbSSteven King * 3*beb1b6bbSSteven King * Copyright 2010 Steven King <sfking@fdwdc.com> 4*beb1b6bbSSteven King * 5*beb1b6bbSSteven King * This program is free software; you can redistribute it and/or modify 6*beb1b6bbSSteven King * it under the terms of the GNU General Public License as published by 7*beb1b6bbSSteven King * the Free Software Foundation; either version 2 of the License, or 8*beb1b6bbSSteven King * (at your option) any later version. 9*beb1b6bbSSteven King * 10*beb1b6bbSSteven King * This program is distributed in the hope that it will be useful, 11*beb1b6bbSSteven King * but WITHOUT ANY WARRANTY; without even the implied warranty of 12*beb1b6bbSSteven King * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13*beb1b6bbSSteven King * GNU General Public License for more details. 14*beb1b6bbSSteven King * 15*beb1b6bbSSteven King * You should have received a copy of the GNU General Public License 16*beb1b6bbSSteven King * along with this program; if not, write to the Free Software 17*beb1b6bbSSteven King * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA 18*beb1b6bbSSteven King */ 19*beb1b6bbSSteven King 20*beb1b6bbSSteven King 21*beb1b6bbSSteven King 22*beb1b6bbSSteven King #include <linux/module.h> 23*beb1b6bbSSteven King #include <linux/init.h> 24*beb1b6bbSSteven King #include <linux/slab.h> 25*beb1b6bbSSteven King #include <linux/i2c.h> 26*beb1b6bbSSteven King #include <linux/hwmon.h> 27*beb1b6bbSSteven King #include <linux/hwmon-sysfs.h> 28*beb1b6bbSSteven King #include <linux/err.h> 29*beb1b6bbSSteven King #include <linux/mutex.h> 30*beb1b6bbSSteven King #include <linux/delay.h> 31*beb1b6bbSSteven King 32*beb1b6bbSSteven King #define DRIVER_NAME "tmp102" 33*beb1b6bbSSteven King 34*beb1b6bbSSteven King #define TMP102_TEMP_REG 0x00 35*beb1b6bbSSteven King #define TMP102_CONF_REG 0x01 36*beb1b6bbSSteven King /* note: these bit definitions are byte swapped */ 37*beb1b6bbSSteven King #define TMP102_CONF_SD 0x0100 38*beb1b6bbSSteven King #define TMP102_CONF_TM 0x0200 39*beb1b6bbSSteven King #define TMP102_CONF_POL 0x0400 40*beb1b6bbSSteven King #define TMP102_CONF_F0 0x0800 41*beb1b6bbSSteven King #define TMP102_CONF_F1 0x1000 42*beb1b6bbSSteven King #define TMP102_CONF_R0 0x2000 43*beb1b6bbSSteven King #define TMP102_CONF_R1 0x4000 44*beb1b6bbSSteven King #define TMP102_CONF_OS 0x8000 45*beb1b6bbSSteven King #define TMP102_CONF_EM 0x0010 46*beb1b6bbSSteven King #define TMP102_CONF_AL 0x0020 47*beb1b6bbSSteven King #define TMP102_CONF_CR0 0x0040 48*beb1b6bbSSteven King #define TMP102_CONF_CR1 0x0080 49*beb1b6bbSSteven King #define TMP102_TLOW_REG 0x02 50*beb1b6bbSSteven King #define TMP102_THIGH_REG 0x03 51*beb1b6bbSSteven King 52*beb1b6bbSSteven King struct tmp102 { 53*beb1b6bbSSteven King struct device *hwmon_dev; 54*beb1b6bbSSteven King struct mutex lock; 55*beb1b6bbSSteven King unsigned long last_update; 56*beb1b6bbSSteven King int temp[3]; 57*beb1b6bbSSteven King }; 58*beb1b6bbSSteven King 59*beb1b6bbSSteven King /* the TMP102 registers are big endian so we have to swab16 the values */ 60*beb1b6bbSSteven King static int tmp102_read_reg(struct i2c_client *client, u8 reg) 61*beb1b6bbSSteven King { 62*beb1b6bbSSteven King int result = i2c_smbus_read_word_data(client, reg); 63*beb1b6bbSSteven King return result < 0 ? result : swab16(result); 64*beb1b6bbSSteven King } 65*beb1b6bbSSteven King 66*beb1b6bbSSteven King static int tmp102_write_reg(struct i2c_client *client, u8 reg, u16 val) 67*beb1b6bbSSteven King { 68*beb1b6bbSSteven King return i2c_smbus_write_word_data(client, reg, swab16(val)); 69*beb1b6bbSSteven King } 70*beb1b6bbSSteven King 71*beb1b6bbSSteven King /* convert left adjusted 13bit TMP102 register value to miliCelsius */ 72*beb1b6bbSSteven King static int tmp102_reg_to_mC(s16 val) 73*beb1b6bbSSteven King { 74*beb1b6bbSSteven King return (val * 1000) / 128; 75*beb1b6bbSSteven King } 76*beb1b6bbSSteven King 77*beb1b6bbSSteven King /* convert miliCelsius to left adjusted 13bit TMP102 register value */ 78*beb1b6bbSSteven King static u16 tmp102_mC_to_reg(int val) 79*beb1b6bbSSteven King { 80*beb1b6bbSSteven King return (val * 128) / 1000; 81*beb1b6bbSSteven King } 82*beb1b6bbSSteven King 83*beb1b6bbSSteven King static const u8 tmp102_reg[] = { 84*beb1b6bbSSteven King TMP102_TEMP_REG, 85*beb1b6bbSSteven King TMP102_TLOW_REG, 86*beb1b6bbSSteven King TMP102_THIGH_REG, 87*beb1b6bbSSteven King }; 88*beb1b6bbSSteven King 89*beb1b6bbSSteven King static struct tmp102 *tmp102_update_device(struct i2c_client *client) 90*beb1b6bbSSteven King { 91*beb1b6bbSSteven King struct tmp102 *tmp102 = i2c_get_clientdata(client); 92*beb1b6bbSSteven King 93*beb1b6bbSSteven King mutex_lock(&tmp102->lock); 94*beb1b6bbSSteven King if (time_after(jiffies, tmp102->last_update + HZ / 4)) { 95*beb1b6bbSSteven King int i; 96*beb1b6bbSSteven King for (i = 0; i < ARRAY_SIZE(tmp102->temp); ++i) { 97*beb1b6bbSSteven King int status = tmp102_read_reg(client, tmp102_reg[i]); 98*beb1b6bbSSteven King if (status > -1) 99*beb1b6bbSSteven King tmp102->temp[i] = tmp102_reg_to_mC(status); 100*beb1b6bbSSteven King } 101*beb1b6bbSSteven King tmp102->last_update = jiffies; 102*beb1b6bbSSteven King } 103*beb1b6bbSSteven King mutex_unlock(&tmp102->lock); 104*beb1b6bbSSteven King return tmp102; 105*beb1b6bbSSteven King } 106*beb1b6bbSSteven King 107*beb1b6bbSSteven King static ssize_t tmp102_show_temp(struct device *dev, 108*beb1b6bbSSteven King struct device_attribute *attr, 109*beb1b6bbSSteven King char *buf) 110*beb1b6bbSSteven King { 111*beb1b6bbSSteven King struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); 112*beb1b6bbSSteven King struct tmp102 *tmp102 = tmp102_update_device(to_i2c_client(dev)); 113*beb1b6bbSSteven King 114*beb1b6bbSSteven King return sprintf(buf, "%d\n", tmp102->temp[sda->index]); 115*beb1b6bbSSteven King } 116*beb1b6bbSSteven King 117*beb1b6bbSSteven King static ssize_t tmp102_set_temp(struct device *dev, 118*beb1b6bbSSteven King struct device_attribute *attr, 119*beb1b6bbSSteven King const char *buf, size_t count) 120*beb1b6bbSSteven King { 121*beb1b6bbSSteven King struct sensor_device_attribute *sda = to_sensor_dev_attr(attr); 122*beb1b6bbSSteven King struct i2c_client *client = to_i2c_client(dev); 123*beb1b6bbSSteven King struct tmp102 *tmp102 = i2c_get_clientdata(client); 124*beb1b6bbSSteven King long val; 125*beb1b6bbSSteven King int status = 0; 126*beb1b6bbSSteven King 127*beb1b6bbSSteven King if ((strict_strtol(buf, 10, &val) < 0) || (abs(val) > 150000)) 128*beb1b6bbSSteven King return -EINVAL; 129*beb1b6bbSSteven King mutex_lock(&tmp102->lock); 130*beb1b6bbSSteven King if (tmp102->temp[sda->index] != val) { 131*beb1b6bbSSteven King tmp102->temp[sda->index] = val; 132*beb1b6bbSSteven King status = tmp102_write_reg(client, tmp102_reg[sda->index], 133*beb1b6bbSSteven King tmp102_mC_to_reg(val)); 134*beb1b6bbSSteven King } 135*beb1b6bbSSteven King mutex_unlock(&tmp102->lock); 136*beb1b6bbSSteven King return status ? : count; 137*beb1b6bbSSteven King } 138*beb1b6bbSSteven King 139*beb1b6bbSSteven King static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp102_show_temp, NULL , 0); 140*beb1b6bbSSteven King 141*beb1b6bbSSteven King static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO, tmp102_show_temp, 142*beb1b6bbSSteven King tmp102_set_temp, 1); 143*beb1b6bbSSteven King 144*beb1b6bbSSteven King static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp102_show_temp, 145*beb1b6bbSSteven King tmp102_set_temp, 2); 146*beb1b6bbSSteven King 147*beb1b6bbSSteven King static struct attribute *tmp102_attributes[] = { 148*beb1b6bbSSteven King &sensor_dev_attr_temp1_input.dev_attr.attr, 149*beb1b6bbSSteven King &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, 150*beb1b6bbSSteven King &sensor_dev_attr_temp1_max.dev_attr.attr, 151*beb1b6bbSSteven King NULL 152*beb1b6bbSSteven King }; 153*beb1b6bbSSteven King 154*beb1b6bbSSteven King static const struct attribute_group tmp102_attr_group = { 155*beb1b6bbSSteven King .attrs = tmp102_attributes, 156*beb1b6bbSSteven King }; 157*beb1b6bbSSteven King 158*beb1b6bbSSteven King #define TMP102_CONFIG (TMP102_CONF_TM | TMP102_CONF_EM | TMP102_CONF_CR1) 159*beb1b6bbSSteven King #define TMP102_CONFIG_RD_ONLY (TMP102_CONF_R0 | TMP102_CONF_R1 | TMP102_CONF_AL) 160*beb1b6bbSSteven King 161*beb1b6bbSSteven King static int __devinit tmp102_probe(struct i2c_client *client, 162*beb1b6bbSSteven King const struct i2c_device_id *id) 163*beb1b6bbSSteven King { 164*beb1b6bbSSteven King struct tmp102 *tmp102; 165*beb1b6bbSSteven King int status; 166*beb1b6bbSSteven King 167*beb1b6bbSSteven King if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA | 168*beb1b6bbSSteven King I2C_FUNC_SMBUS_WORD_DATA)) { 169*beb1b6bbSSteven King dev_dbg(&client->dev, "adapter doesnt support SMBUS\n"); 170*beb1b6bbSSteven King return -ENODEV; 171*beb1b6bbSSteven King } 172*beb1b6bbSSteven King 173*beb1b6bbSSteven King tmp102 = kzalloc(sizeof(*tmp102), GFP_KERNEL); 174*beb1b6bbSSteven King if (!tmp102) { 175*beb1b6bbSSteven King dev_dbg(&client->dev, "kzalloc failed\n"); 176*beb1b6bbSSteven King return -ENOMEM; 177*beb1b6bbSSteven King } 178*beb1b6bbSSteven King i2c_set_clientdata(client, tmp102); 179*beb1b6bbSSteven King 180*beb1b6bbSSteven King tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); 181*beb1b6bbSSteven King status = tmp102_read_reg(client, TMP102_CONF_REG); 182*beb1b6bbSSteven King if (status < 0) { 183*beb1b6bbSSteven King dev_dbg(&client->dev, "error reading config register\n"); 184*beb1b6bbSSteven King goto fail0; 185*beb1b6bbSSteven King } 186*beb1b6bbSSteven King status &= ~TMP102_CONFIG_RD_ONLY; 187*beb1b6bbSSteven King if (status != TMP102_CONFIG) { 188*beb1b6bbSSteven King dev_dbg(&client->dev, "could not verify config settings\n"); 189*beb1b6bbSSteven King status = -EIO; 190*beb1b6bbSSteven King goto fail0; 191*beb1b6bbSSteven King } 192*beb1b6bbSSteven King tmp102->last_update = jiffies - HZ; 193*beb1b6bbSSteven King mutex_init(&tmp102->lock); 194*beb1b6bbSSteven King 195*beb1b6bbSSteven King status = sysfs_create_group(&client->dev.kobj, &tmp102_attr_group); 196*beb1b6bbSSteven King if (status) { 197*beb1b6bbSSteven King dev_dbg(&client->dev, "could not create sysfs files\n"); 198*beb1b6bbSSteven King goto fail0; 199*beb1b6bbSSteven King } 200*beb1b6bbSSteven King tmp102->hwmon_dev = hwmon_device_register(&client->dev); 201*beb1b6bbSSteven King if (IS_ERR(tmp102->hwmon_dev)) { 202*beb1b6bbSSteven King dev_dbg(&client->dev, "unable to register hwmon device\n"); 203*beb1b6bbSSteven King status = PTR_ERR(tmp102->hwmon_dev); 204*beb1b6bbSSteven King goto fail1; 205*beb1b6bbSSteven King } 206*beb1b6bbSSteven King 207*beb1b6bbSSteven King dev_info(&client->dev, "initialized\n"); 208*beb1b6bbSSteven King 209*beb1b6bbSSteven King return 0; 210*beb1b6bbSSteven King fail1: 211*beb1b6bbSSteven King sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); 212*beb1b6bbSSteven King fail0: 213*beb1b6bbSSteven King i2c_set_clientdata(client, NULL); 214*beb1b6bbSSteven King kfree(tmp102); 215*beb1b6bbSSteven King 216*beb1b6bbSSteven King return 0; 217*beb1b6bbSSteven King } 218*beb1b6bbSSteven King 219*beb1b6bbSSteven King static int __devexit tmp102_remove(struct i2c_client *client) 220*beb1b6bbSSteven King { 221*beb1b6bbSSteven King struct tmp102 *tmp102 = i2c_get_clientdata(client); 222*beb1b6bbSSteven King 223*beb1b6bbSSteven King /* shutdown the chip */ 224*beb1b6bbSSteven King tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); 225*beb1b6bbSSteven King 226*beb1b6bbSSteven King hwmon_device_unregister(tmp102->hwmon_dev); 227*beb1b6bbSSteven King sysfs_remove_group(&client->dev.kobj, &tmp102_attr_group); 228*beb1b6bbSSteven King i2c_set_clientdata(client, NULL); 229*beb1b6bbSSteven King kfree(tmp102); 230*beb1b6bbSSteven King 231*beb1b6bbSSteven King return 0; 232*beb1b6bbSSteven King } 233*beb1b6bbSSteven King 234*beb1b6bbSSteven King #ifdef CONFIG_PM 235*beb1b6bbSSteven King static int tmp102_suspend(struct device *dev) 236*beb1b6bbSSteven King { 237*beb1b6bbSSteven King struct i2c_client *client = to_i2c_client(dev); 238*beb1b6bbSSteven King 239*beb1b6bbSSteven King tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONF_SD); 240*beb1b6bbSSteven King 241*beb1b6bbSSteven King return 0; 242*beb1b6bbSSteven King } 243*beb1b6bbSSteven King 244*beb1b6bbSSteven King static int tmp102_resume(struct device *dev) 245*beb1b6bbSSteven King { 246*beb1b6bbSSteven King struct i2c_client *client = to_i2c_client(dev); 247*beb1b6bbSSteven King 248*beb1b6bbSSteven King tmp102_write_reg(client, TMP102_CONF_REG, TMP102_CONFIG); 249*beb1b6bbSSteven King 250*beb1b6bbSSteven King return 0; 251*beb1b6bbSSteven King } 252*beb1b6bbSSteven King 253*beb1b6bbSSteven King static const struct dev_pm_ops tmp102_dev_pm_ops = { 254*beb1b6bbSSteven King .suspend = tmp102_suspend, 255*beb1b6bbSSteven King .resume = tmp102_resume, 256*beb1b6bbSSteven King }; 257*beb1b6bbSSteven King 258*beb1b6bbSSteven King #define TMP102_DEV_PM_OPS (&tmp102_dev_pm_ops) 259*beb1b6bbSSteven King #else 260*beb1b6bbSSteven King #define TMP102_DEV_PM_OPS NULL 261*beb1b6bbSSteven King #endif /* CONFIG_PM */ 262*beb1b6bbSSteven King 263*beb1b6bbSSteven King static const unsigned short normal_i2c[] = { 264*beb1b6bbSSteven King 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END 265*beb1b6bbSSteven King }; 266*beb1b6bbSSteven King 267*beb1b6bbSSteven King static const struct i2c_device_id tmp102_id[] = { 268*beb1b6bbSSteven King { DRIVER_NAME, 0 }, 269*beb1b6bbSSteven King { } 270*beb1b6bbSSteven King }; 271*beb1b6bbSSteven King 272*beb1b6bbSSteven King static struct i2c_driver tmp102_driver = { 273*beb1b6bbSSteven King .driver.name = DRIVER_NAME, 274*beb1b6bbSSteven King .driver.pm = TMP102_DEV_PM_OPS, 275*beb1b6bbSSteven King .class = I2C_CLASS_HWMON, 276*beb1b6bbSSteven King .probe = tmp102_probe, 277*beb1b6bbSSteven King .remove = __devexit_p(tmp102_remove), 278*beb1b6bbSSteven King .id_table = tmp102_id, 279*beb1b6bbSSteven King .address_list = normal_i2c, 280*beb1b6bbSSteven King }; 281*beb1b6bbSSteven King 282*beb1b6bbSSteven King static int __init tmp102_init(void) 283*beb1b6bbSSteven King { 284*beb1b6bbSSteven King return i2c_add_driver(&tmp102_driver); 285*beb1b6bbSSteven King } 286*beb1b6bbSSteven King module_init(tmp102_init); 287*beb1b6bbSSteven King 288*beb1b6bbSSteven King static void __exit tmp102_exit(void) 289*beb1b6bbSSteven King { 290*beb1b6bbSSteven King i2c_del_driver(&tmp102_driver); 291*beb1b6bbSSteven King } 292*beb1b6bbSSteven King module_exit(tmp102_exit); 293*beb1b6bbSSteven King 294*beb1b6bbSSteven King 295*beb1b6bbSSteven King MODULE_AUTHOR("Steven King <sfking@fdwdc.com>"); 296*beb1b6bbSSteven King MODULE_DESCRIPTION("Texas Instruments TMP102 temperature sensor driver"); 297*beb1b6bbSSteven King MODULE_LICENSE("GPL"); 298