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
|
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
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
This driver implements support for the Sensirion SHTC1 chip, a humidity and
|
This driver implements support for the Sensirion SHTC1, SHTW1, and SHTC3
|
||||||
temperature sensor. Temperature is measured in degrees celsius, relative
|
chips, a humidity and temperature sensor. Temperature is measured in degrees
|
||||||
humidity is expressed as a percentage. Driver can be used as well for SHTW1
|
celsius, relative humidity is expressed as a percentage.
|
||||||
chip, which has the same electrical interface.
|
|
||||||
|
|
||||||
The device communicates with the I2C protocol. All sensors are set to I2C
|
The device communicates with the I2C protocol. All sensors are set to I2C
|
||||||
address 0x70. See Documentation/i2c/instantiating-devices for methods to
|
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."
|
tristate "Sensiron humidity and temperature sensors. SHTC1 and compat."
|
||||||
depends on I2C
|
depends on I2C
|
||||||
help
|
help
|
||||||
If you say yes here you get support for the Sensiron SHTC1 and SHTW1
|
If you say yes here you get support for the Sensiron SHTC1, SHTW1,
|
||||||
humidity and temperature sensors.
|
and SHTC3 humidity and temperature sensors.
|
||||||
|
|
||||||
This driver can also be built as a module. If so, the module
|
This driver can also be built as a module. If so, the module
|
||||||
will be called shtc1.
|
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 };
|
static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
|
||||||
|
|
||||||
/* command for reading the ID register */
|
/* 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
|
* constants for reading the ID register
|
||||||
#define SHTC1_ID_REG_MASK 0x3f
|
* 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 */
|
/* delays for non-blocking i2c commands, both in us */
|
||||||
#define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400
|
#define SHTC1_NONBLOCKING_WAIT_TIME_HPM 14400
|
||||||
#define SHTC1_NONBLOCKING_WAIT_TIME_LPM 1000
|
#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_CMD_LENGTH 2
|
||||||
#define SHTC1_RESPONSE_LENGTH 6
|
#define SHTC1_RESPONSE_LENGTH 6
|
||||||
|
|
||||||
|
enum shtcx_chips {
|
||||||
|
shtc1,
|
||||||
|
shtc3,
|
||||||
|
};
|
||||||
|
|
||||||
struct shtc1_data {
|
struct shtc1_data {
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
struct mutex update_lock;
|
struct mutex update_lock;
|
||||||
|
@ -47,6 +61,7 @@ struct shtc1_data {
|
||||||
unsigned int nonblocking_wait_time; /* in us */
|
unsigned int nonblocking_wait_time; /* in us */
|
||||||
|
|
||||||
struct shtc1_platform_data setup;
|
struct shtc1_platform_data setup;
|
||||||
|
enum shtcx_chips chip;
|
||||||
|
|
||||||
int temperature; /* 1000 * temperature in dgr C */
|
int temperature; /* 1000 * temperature in dgr C */
|
||||||
int humidity; /* 1000 * relative humidity in %RH */
|
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 ?
|
data->command = data->setup.blocking_io ?
|
||||||
shtc1_cmd_measure_blocking_hpm :
|
shtc1_cmd_measure_blocking_hpm :
|
||||||
shtc1_cmd_measure_nonblocking_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 {
|
} else {
|
||||||
data->command = data->setup.blocking_io ?
|
data->command = data->setup.blocking_io ?
|
||||||
shtc1_cmd_measure_blocking_lpm :
|
shtc1_cmd_measure_blocking_lpm :
|
||||||
shtc1_cmd_measure_nonblocking_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)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char id_reg[2];
|
u16 id_reg;
|
||||||
|
char id_reg_buf[2];
|
||||||
struct shtc1_data *data;
|
struct shtc1_data *data;
|
||||||
struct device *hwmon_dev;
|
struct device *hwmon_dev;
|
||||||
|
enum shtcx_chips chip = id->driver_data;
|
||||||
struct i2c_adapter *adap = client->adapter;
|
struct i2c_adapter *adap = client->adapter;
|
||||||
struct device *dev = &client->dev;
|
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);
|
dev_err(dev, "could not send read_id_reg command: %d\n", ret);
|
||||||
return ret < 0 ? ret : -ENODEV;
|
return ret < 0 ? ret : -ENODEV;
|
||||||
}
|
}
|
||||||
ret = i2c_master_recv(client, id_reg, sizeof(id_reg));
|
ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
|
||||||
if (ret != sizeof(id_reg)) {
|
if (ret != sizeof(id_reg_buf)) {
|
||||||
dev_err(dev, "could not read ID register: %d\n", ret);
|
dev_err(dev, "could not read ID register: %d\n", ret);
|
||||||
return -ENODEV;
|
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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,6 +231,7 @@ static int shtc1_probe(struct i2c_client *client,
|
||||||
data->setup.blocking_io = false;
|
data->setup.blocking_io = false;
|
||||||
data->setup.high_precision = true;
|
data->setup.high_precision = true;
|
||||||
data->client = client;
|
data->client = client;
|
||||||
|
data->chip = chip;
|
||||||
|
|
||||||
if (client->dev.platform_data)
|
if (client->dev.platform_data)
|
||||||
data->setup = *(struct shtc1_platform_data *)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 */
|
/* device ID table */
|
||||||
static const struct i2c_device_id shtc1_id[] = {
|
static const struct i2c_device_id shtc1_id[] = {
|
||||||
{ "shtc1", 0 },
|
{ "shtc1", shtc1 },
|
||||||
{ "shtw1", 0 },
|
{ "shtw1", shtc1 },
|
||||||
|
{ "shtc3", shtc3 },
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(i2c, shtc1_id);
|
MODULE_DEVICE_TABLE(i2c, shtc1_id);
|
||||||
|
|
Loading…
Reference in New Issue