mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 06:02:05 +00:00
hwmon: (shtc1) add support for the SHTC3 sensor
Add support for the Sensirion SHTC3 humidity and temperature sensor to the shtc1 module. Signed-off-by: Dan Robertson <dan@dlrobertson.com> Link: https://lore.kernel.org/r/20190905014554.21658-2-dan@dlrobertson.com Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
parent
fdc7d8e829
commit
ffd96868ac
@ -19,7 +19,17 @@ Supported chips:
|
||||
|
||||
Addresses scanned: none
|
||||
|
||||
Datasheet: Not publicly available
|
||||
Datasheet: http://www.sensirion.com/file/datasheet_shtw1
|
||||
|
||||
|
||||
|
||||
* Sensirion SHTC3
|
||||
|
||||
Prefix: 'shtc3'
|
||||
|
||||
Addresses scanned: none
|
||||
|
||||
Datasheet: http://www.sensirion.com/file/datasheet_shtc3
|
||||
|
||||
|
||||
|
||||
@ -30,10 +40,9 @@ Author:
|
||||
Description
|
||||
-----------
|
||||
|
||||
This driver implements support for the Sensirion SHTC1 chip, a humidity and
|
||||
temperature sensor. Temperature is measured in degrees celsius, relative
|
||||
humidity is expressed as a percentage. Driver can be used as well for SHTW1
|
||||
chip, which has the same electrical interface.
|
||||
This driver implements support for the Sensirion SHTC1, SHTW1, and SHTC3
|
||||
chips, a humidity and temperature sensor. Temperature is measured in degrees
|
||||
celsius, relative humidity is expressed as a percentage.
|
||||
|
||||
The device communicates with the I2C protocol. All sensors are set to I2C
|
||||
address 0x70. See Documentation/i2c/instantiating-devices for methods to
|
||||
|
@ -1392,8 +1392,8 @@ config SENSORS_SHTC1
|
||||
tristate "Sensiron humidity and temperature sensors. SHTC1 and compat."
|
||||
depends on I2C
|
||||
help
|
||||
If you say yes here you get support for the Sensiron SHTC1 and SHTW1
|
||||
humidity and temperature sensors.
|
||||
If you say yes here you get support for the Sensiron SHTC1, SHTW1,
|
||||
and SHTC3 humidity and temperature sensors.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called shtc1.
|
||||
|
@ -24,19 +24,33 @@ static const unsigned char shtc1_cmd_measure_blocking_lpm[] = { 0x64, 0x58 };
|
||||
static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
|
||||
|
||||
/* command for reading the ID register */
|
||||
static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 };
|
||||
static const unsigned char shtc1_cmd_read_id_reg[] = { 0xef, 0xc8 };
|
||||
|
||||
/* constants for reading the ID register */
|
||||
#define SHTC1_ID 0x07
|
||||
#define SHTC1_ID_REG_MASK 0x3f
|
||||
/*
|
||||
* constants for reading the ID register
|
||||
* SHTC1: 0x0007 with mask 0x003f
|
||||
* SHTW1: 0x0007 with mask 0x003f
|
||||
* SHTC3: 0x0807 with mask 0x083f
|
||||
*/
|
||||
#define SHTC3_ID 0x0807
|
||||
#define SHTC3_ID_MASK 0x083f
|
||||
#define SHTC1_ID 0x0007
|
||||
#define SHTC1_ID_MASK 0x003f
|
||||
|
||||
/* delays for non-blocking i2c commands, both in us */
|
||||
#define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400
|
||||
#define SHTC1_NONBLOCKING_WAIT_TIME_LPM 1000
|
||||
#define SHTC3_NONBLOCKING_WAIT_TIME_HPM 12100
|
||||
#define SHTC3_NONBLOCKING_WAIT_TIME_LPM 800
|
||||
|
||||
#define SHTC1_CMD_LENGTH 2
|
||||
#define SHTC1_RESPONSE_LENGTH 6
|
||||
|
||||
enum shtcx_chips {
|
||||
shtc1,
|
||||
shtc3,
|
||||
};
|
||||
|
||||
struct shtc1_data {
|
||||
struct i2c_client *client;
|
||||
struct mutex update_lock;
|
||||
@ -47,6 +61,7 @@ struct shtc1_data {
|
||||
unsigned int nonblocking_wait_time; /* in us */
|
||||
|
||||
struct shtc1_platform_data setup;
|
||||
enum shtcx_chips chip;
|
||||
|
||||
int temperature; /* 1000 * temperature in dgr C */
|
||||
int humidity; /* 1000 * relative humidity in %RH */
|
||||
@ -157,13 +172,16 @@ static void shtc1_select_command(struct shtc1_data *data)
|
||||
data->command = data->setup.blocking_io ?
|
||||
shtc1_cmd_measure_blocking_hpm :
|
||||
shtc1_cmd_measure_nonblocking_hpm;
|
||||
data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM;
|
||||
|
||||
data->nonblocking_wait_time = (data->chip == shtc1) ?
|
||||
SHTC1_NONBLOCKING_WAIT_TIME_HPM :
|
||||
SHTC3_NONBLOCKING_WAIT_TIME_HPM;
|
||||
} else {
|
||||
data->command = data->setup.blocking_io ?
|
||||
shtc1_cmd_measure_blocking_lpm :
|
||||
shtc1_cmd_measure_nonblocking_lpm;
|
||||
data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM;
|
||||
data->nonblocking_wait_time = (data->chip == shtc1) ?
|
||||
SHTC1_NONBLOCKING_WAIT_TIME_LPM :
|
||||
SHTC3_NONBLOCKING_WAIT_TIME_LPM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,9 +189,11 @@ static int shtc1_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
int ret;
|
||||
char id_reg[2];
|
||||
u16 id_reg;
|
||||
char id_reg_buf[2];
|
||||
struct shtc1_data *data;
|
||||
struct device *hwmon_dev;
|
||||
enum shtcx_chips chip = id->driver_data;
|
||||
struct i2c_adapter *adap = client->adapter;
|
||||
struct device *dev = &client->dev;
|
||||
|
||||
@ -187,13 +207,20 @@ static int shtc1_probe(struct i2c_client *client,
|
||||
dev_err(dev, "could not send read_id_reg command: %d\n", ret);
|
||||
return ret < 0 ? ret : -ENODEV;
|
||||
}
|
||||
ret = i2c_master_recv(client, id_reg, sizeof(id_reg));
|
||||
if (ret != sizeof(id_reg)) {
|
||||
ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
|
||||
if (ret != sizeof(id_reg_buf)) {
|
||||
dev_err(dev, "could not read ID register: %d\n", ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) {
|
||||
dev_err(dev, "ID register doesn't match\n");
|
||||
|
||||
id_reg = be16_to_cpup((__be16 *)id_reg_buf);
|
||||
if (chip == shtc3) {
|
||||
if ((id_reg & SHTC3_ID_MASK) != SHTC3_ID) {
|
||||
dev_err(dev, "SHTC3 ID register does not match\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
} else if ((id_reg & SHTC1_ID_MASK) != SHTC1_ID) {
|
||||
dev_err(dev, "SHTC1 ID register does not match\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
@ -204,6 +231,7 @@ static int shtc1_probe(struct i2c_client *client,
|
||||
data->setup.blocking_io = false;
|
||||
data->setup.high_precision = true;
|
||||
data->client = client;
|
||||
data->chip = chip;
|
||||
|
||||
if (client->dev.platform_data)
|
||||
data->setup = *(struct shtc1_platform_data *)dev->platform_data;
|
||||
@ -222,8 +250,9 @@ static int shtc1_probe(struct i2c_client *client,
|
||||
|
||||
/* device ID table */
|
||||
static const struct i2c_device_id shtc1_id[] = {
|
||||
{ "shtc1", 0 },
|
||||
{ "shtw1", 0 },
|
||||
{ "shtc1", shtc1 },
|
||||
{ "shtw1", shtc1 },
|
||||
{ "shtc3", shtc3 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, shtc1_id);
|
||||
|
Loading…
Reference in New Issue
Block a user