1*1a539d37STomas Pop /* Sensirion SHTC1 humidity and temperature sensor driver 2*1a539d37STomas Pop * 3*1a539d37STomas Pop * Copyright (C) 2014 Sensirion AG, Switzerland 4*1a539d37STomas Pop * Author: Johannes Winkelmann <johannes.winkelmann@sensirion.com> 5*1a539d37STomas Pop * 6*1a539d37STomas Pop * This program is free software; you can redistribute it and/or modify 7*1a539d37STomas Pop * it under the terms of the GNU General Public License as published by 8*1a539d37STomas Pop * the Free Software Foundation; either version 2 of the License, or 9*1a539d37STomas Pop * (at your option) any later version. 10*1a539d37STomas Pop * 11*1a539d37STomas Pop * This program is distributed in the hope that it will be useful, 12*1a539d37STomas Pop * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*1a539d37STomas Pop * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*1a539d37STomas Pop * GNU General Public License for more details. 15*1a539d37STomas Pop * 16*1a539d37STomas Pop */ 17*1a539d37STomas Pop 18*1a539d37STomas Pop #include <linux/module.h> 19*1a539d37STomas Pop #include <linux/init.h> 20*1a539d37STomas Pop #include <linux/slab.h> 21*1a539d37STomas Pop #include <linux/i2c.h> 22*1a539d37STomas Pop #include <linux/hwmon.h> 23*1a539d37STomas Pop #include <linux/hwmon-sysfs.h> 24*1a539d37STomas Pop #include <linux/err.h> 25*1a539d37STomas Pop #include <linux/delay.h> 26*1a539d37STomas Pop #include <linux/platform_data/shtc1.h> 27*1a539d37STomas Pop 28*1a539d37STomas Pop /* commands (high precision mode) */ 29*1a539d37STomas Pop static const unsigned char shtc1_cmd_measure_blocking_hpm[] = { 0x7C, 0xA2 }; 30*1a539d37STomas Pop static const unsigned char shtc1_cmd_measure_nonblocking_hpm[] = { 0x78, 0x66 }; 31*1a539d37STomas Pop 32*1a539d37STomas Pop /* commands (low precision mode) */ 33*1a539d37STomas Pop static const unsigned char shtc1_cmd_measure_blocking_lpm[] = { 0x64, 0x58 }; 34*1a539d37STomas Pop static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c }; 35*1a539d37STomas Pop 36*1a539d37STomas Pop /* command for reading the ID register */ 37*1a539d37STomas Pop static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 }; 38*1a539d37STomas Pop 39*1a539d37STomas Pop /* constants for reading the ID register */ 40*1a539d37STomas Pop #define SHTC1_ID 0x07 41*1a539d37STomas Pop #define SHTC1_ID_REG_MASK 0x1f 42*1a539d37STomas Pop 43*1a539d37STomas Pop /* delays for non-blocking i2c commands, both in us */ 44*1a539d37STomas Pop #define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400 45*1a539d37STomas Pop #define SHTC1_NONBLOCKING_WAIT_TIME_LPM 1000 46*1a539d37STomas Pop 47*1a539d37STomas Pop #define SHTC1_CMD_LENGTH 2 48*1a539d37STomas Pop #define SHTC1_RESPONSE_LENGTH 6 49*1a539d37STomas Pop 50*1a539d37STomas Pop struct shtc1_data { 51*1a539d37STomas Pop struct i2c_client *client; 52*1a539d37STomas Pop struct mutex update_lock; 53*1a539d37STomas Pop bool valid; 54*1a539d37STomas Pop unsigned long last_updated; /* in jiffies */ 55*1a539d37STomas Pop 56*1a539d37STomas Pop const unsigned char *command; 57*1a539d37STomas Pop unsigned int nonblocking_wait_time; /* in us */ 58*1a539d37STomas Pop 59*1a539d37STomas Pop struct shtc1_platform_data setup; 60*1a539d37STomas Pop 61*1a539d37STomas Pop int temperature; /* 1000 * temperature in dgr C */ 62*1a539d37STomas Pop int humidity; /* 1000 * relative humidity in %RH */ 63*1a539d37STomas Pop }; 64*1a539d37STomas Pop 65*1a539d37STomas Pop static int shtc1_update_values(struct i2c_client *client, 66*1a539d37STomas Pop struct shtc1_data *data, 67*1a539d37STomas Pop char *buf, int bufsize) 68*1a539d37STomas Pop { 69*1a539d37STomas Pop int ret = i2c_master_send(client, data->command, SHTC1_CMD_LENGTH); 70*1a539d37STomas Pop if (ret != SHTC1_CMD_LENGTH) { 71*1a539d37STomas Pop dev_err(&client->dev, "failed to send command: %d\n", ret); 72*1a539d37STomas Pop return ret < 0 ? ret : -EIO; 73*1a539d37STomas Pop } 74*1a539d37STomas Pop 75*1a539d37STomas Pop /* 76*1a539d37STomas Pop * In blocking mode (clock stretching mode) the I2C bus 77*1a539d37STomas Pop * is blocked for other traffic, thus the call to i2c_master_recv() 78*1a539d37STomas Pop * will wait until the data is ready. For non blocking mode, we 79*1a539d37STomas Pop * have to wait ourselves. 80*1a539d37STomas Pop */ 81*1a539d37STomas Pop if (!data->setup.blocking_io) 82*1a539d37STomas Pop usleep_range(data->nonblocking_wait_time, 83*1a539d37STomas Pop data->nonblocking_wait_time + 1000); 84*1a539d37STomas Pop 85*1a539d37STomas Pop ret = i2c_master_recv(client, buf, bufsize); 86*1a539d37STomas Pop if (ret != bufsize) { 87*1a539d37STomas Pop dev_err(&client->dev, "failed to read values: %d\n", ret); 88*1a539d37STomas Pop return ret < 0 ? ret : -EIO; 89*1a539d37STomas Pop } 90*1a539d37STomas Pop 91*1a539d37STomas Pop return 0; 92*1a539d37STomas Pop } 93*1a539d37STomas Pop 94*1a539d37STomas Pop /* sysfs attributes */ 95*1a539d37STomas Pop static struct shtc1_data *shtc1_update_client(struct device *dev) 96*1a539d37STomas Pop { 97*1a539d37STomas Pop struct shtc1_data *data = dev_get_drvdata(dev); 98*1a539d37STomas Pop struct i2c_client *client = data->client; 99*1a539d37STomas Pop unsigned char buf[SHTC1_RESPONSE_LENGTH]; 100*1a539d37STomas Pop int val; 101*1a539d37STomas Pop int ret = 0; 102*1a539d37STomas Pop 103*1a539d37STomas Pop mutex_lock(&data->update_lock); 104*1a539d37STomas Pop 105*1a539d37STomas Pop if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) { 106*1a539d37STomas Pop ret = shtc1_update_values(client, data, buf, sizeof(buf)); 107*1a539d37STomas Pop if (ret) 108*1a539d37STomas Pop goto out; 109*1a539d37STomas Pop 110*1a539d37STomas Pop /* 111*1a539d37STomas Pop * From datasheet: 112*1a539d37STomas Pop * T = -45 + 175 * ST / 2^16 113*1a539d37STomas Pop * RH = 100 * SRH / 2^16 114*1a539d37STomas Pop * 115*1a539d37STomas Pop * Adapted for integer fixed point (3 digit) arithmetic. 116*1a539d37STomas Pop */ 117*1a539d37STomas Pop val = be16_to_cpup((__be16 *)buf); 118*1a539d37STomas Pop data->temperature = ((21875 * val) >> 13) - 45000; 119*1a539d37STomas Pop val = be16_to_cpup((__be16 *)(buf + 3)); 120*1a539d37STomas Pop data->humidity = ((12500 * val) >> 13); 121*1a539d37STomas Pop 122*1a539d37STomas Pop data->last_updated = jiffies; 123*1a539d37STomas Pop data->valid = true; 124*1a539d37STomas Pop } 125*1a539d37STomas Pop 126*1a539d37STomas Pop out: 127*1a539d37STomas Pop mutex_unlock(&data->update_lock); 128*1a539d37STomas Pop 129*1a539d37STomas Pop return ret == 0 ? data : ERR_PTR(ret); 130*1a539d37STomas Pop } 131*1a539d37STomas Pop 132*1a539d37STomas Pop static ssize_t temp1_input_show(struct device *dev, 133*1a539d37STomas Pop struct device_attribute *attr, 134*1a539d37STomas Pop char *buf) 135*1a539d37STomas Pop { 136*1a539d37STomas Pop struct shtc1_data *data = shtc1_update_client(dev); 137*1a539d37STomas Pop if (IS_ERR(data)) 138*1a539d37STomas Pop return PTR_ERR(data); 139*1a539d37STomas Pop 140*1a539d37STomas Pop return sprintf(buf, "%d\n", data->temperature); 141*1a539d37STomas Pop } 142*1a539d37STomas Pop 143*1a539d37STomas Pop static ssize_t humidity1_input_show(struct device *dev, 144*1a539d37STomas Pop struct device_attribute *attr, char *buf) 145*1a539d37STomas Pop { 146*1a539d37STomas Pop struct shtc1_data *data = shtc1_update_client(dev); 147*1a539d37STomas Pop if (IS_ERR(data)) 148*1a539d37STomas Pop return PTR_ERR(data); 149*1a539d37STomas Pop 150*1a539d37STomas Pop return sprintf(buf, "%d\n", data->humidity); 151*1a539d37STomas Pop } 152*1a539d37STomas Pop 153*1a539d37STomas Pop static DEVICE_ATTR_RO(temp1_input); 154*1a539d37STomas Pop static DEVICE_ATTR_RO(humidity1_input); 155*1a539d37STomas Pop 156*1a539d37STomas Pop static struct attribute *shtc1_attrs[] = { 157*1a539d37STomas Pop &dev_attr_temp1_input.attr, 158*1a539d37STomas Pop &dev_attr_humidity1_input.attr, 159*1a539d37STomas Pop NULL 160*1a539d37STomas Pop }; 161*1a539d37STomas Pop 162*1a539d37STomas Pop ATTRIBUTE_GROUPS(shtc1); 163*1a539d37STomas Pop 164*1a539d37STomas Pop static void shtc1_select_command(struct shtc1_data *data) 165*1a539d37STomas Pop { 166*1a539d37STomas Pop if (data->setup.high_precision) { 167*1a539d37STomas Pop data->command = data->setup.blocking_io ? 168*1a539d37STomas Pop shtc1_cmd_measure_blocking_hpm : 169*1a539d37STomas Pop shtc1_cmd_measure_nonblocking_hpm; 170*1a539d37STomas Pop data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM; 171*1a539d37STomas Pop 172*1a539d37STomas Pop } else { 173*1a539d37STomas Pop data->command = data->setup.blocking_io ? 174*1a539d37STomas Pop shtc1_cmd_measure_blocking_lpm : 175*1a539d37STomas Pop shtc1_cmd_measure_nonblocking_lpm; 176*1a539d37STomas Pop data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM; 177*1a539d37STomas Pop } 178*1a539d37STomas Pop } 179*1a539d37STomas Pop 180*1a539d37STomas Pop static int shtc1_probe(struct i2c_client *client, 181*1a539d37STomas Pop const struct i2c_device_id *id) 182*1a539d37STomas Pop { 183*1a539d37STomas Pop int ret; 184*1a539d37STomas Pop char id_reg[2]; 185*1a539d37STomas Pop struct shtc1_data *data; 186*1a539d37STomas Pop struct device *hwmon_dev; 187*1a539d37STomas Pop struct i2c_adapter *adap = client->adapter; 188*1a539d37STomas Pop struct device *dev = &client->dev; 189*1a539d37STomas Pop 190*1a539d37STomas Pop if (!i2c_check_functionality(adap, I2C_FUNC_I2C)) { 191*1a539d37STomas Pop dev_err(dev, "plain i2c transactions not supported\n"); 192*1a539d37STomas Pop return -ENODEV; 193*1a539d37STomas Pop } 194*1a539d37STomas Pop 195*1a539d37STomas Pop ret = i2c_master_send(client, shtc1_cmd_read_id_reg, SHTC1_CMD_LENGTH); 196*1a539d37STomas Pop if (ret != SHTC1_CMD_LENGTH) { 197*1a539d37STomas Pop dev_err(dev, "could not send read_id_reg command: %d\n", ret); 198*1a539d37STomas Pop return ret < 0 ? ret : -ENODEV; 199*1a539d37STomas Pop } 200*1a539d37STomas Pop ret = i2c_master_recv(client, id_reg, sizeof(id_reg)); 201*1a539d37STomas Pop if (ret != sizeof(id_reg)) { 202*1a539d37STomas Pop dev_err(dev, "could not read ID register: %d\n", ret); 203*1a539d37STomas Pop return -ENODEV; 204*1a539d37STomas Pop } 205*1a539d37STomas Pop if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) { 206*1a539d37STomas Pop dev_err(dev, "ID register doesn't match\n"); 207*1a539d37STomas Pop return -ENODEV; 208*1a539d37STomas Pop } 209*1a539d37STomas Pop 210*1a539d37STomas Pop data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 211*1a539d37STomas Pop if (!data) 212*1a539d37STomas Pop return -ENOMEM; 213*1a539d37STomas Pop 214*1a539d37STomas Pop data->setup.blocking_io = false; 215*1a539d37STomas Pop data->setup.high_precision = true; 216*1a539d37STomas Pop data->client = client; 217*1a539d37STomas Pop 218*1a539d37STomas Pop if (client->dev.platform_data) 219*1a539d37STomas Pop data->setup = *(struct shtc1_platform_data *)dev->platform_data; 220*1a539d37STomas Pop shtc1_select_command(data); 221*1a539d37STomas Pop mutex_init(&data->update_lock); 222*1a539d37STomas Pop 223*1a539d37STomas Pop hwmon_dev = devm_hwmon_device_register_with_groups(dev, 224*1a539d37STomas Pop client->name, 225*1a539d37STomas Pop data, 226*1a539d37STomas Pop shtc1_groups); 227*1a539d37STomas Pop if (IS_ERR(hwmon_dev)) 228*1a539d37STomas Pop dev_dbg(dev, "unable to register hwmon device\n"); 229*1a539d37STomas Pop 230*1a539d37STomas Pop return PTR_ERR_OR_ZERO(hwmon_dev); 231*1a539d37STomas Pop } 232*1a539d37STomas Pop 233*1a539d37STomas Pop /* device ID table */ 234*1a539d37STomas Pop static const struct i2c_device_id shtc1_id[] = { 235*1a539d37STomas Pop { "shtc1", 0 }, 236*1a539d37STomas Pop { "shtw1", 0 }, 237*1a539d37STomas Pop { } 238*1a539d37STomas Pop }; 239*1a539d37STomas Pop MODULE_DEVICE_TABLE(i2c, shtc1_id); 240*1a539d37STomas Pop 241*1a539d37STomas Pop static struct i2c_driver shtc1_i2c_driver = { 242*1a539d37STomas Pop .driver.name = "shtc1", 243*1a539d37STomas Pop .probe = shtc1_probe, 244*1a539d37STomas Pop .id_table = shtc1_id, 245*1a539d37STomas Pop }; 246*1a539d37STomas Pop 247*1a539d37STomas Pop module_i2c_driver(shtc1_i2c_driver); 248*1a539d37STomas Pop 249*1a539d37STomas Pop MODULE_AUTHOR("Johannes Winkelmann <johannes.winkelmann@sensirion.com>"); 250*1a539d37STomas Pop MODULE_DESCRIPTION("Sensirion SHTC1 humidity and temperature sensor driver"); 251*1a539d37STomas Pop MODULE_LICENSE("GPL"); 252