diff options
Diffstat (limited to 'drivers/hwmon/sht3x.c')
| -rw-r--r-- | drivers/hwmon/sht3x.c | 84 |
1 files changed, 55 insertions, 29 deletions
diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c index 79657910b79e..f36c0229328f 100644 --- a/drivers/hwmon/sht3x.c +++ b/drivers/hwmon/sht3x.c @@ -10,6 +10,7 @@ #include <asm/page.h> #include <linux/crc8.h> +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/hwmon.h> @@ -41,6 +42,7 @@ static const unsigned char sht3x_cmd_heater_off[] = { 0x30, 0x66 }; /* other commands */ static const unsigned char sht3x_cmd_read_status_reg[] = { 0xf3, 0x2d }; static const unsigned char sht3x_cmd_clear_status_reg[] = { 0x30, 0x41 }; +static const unsigned char sht3x_cmd_read_serial_number[] = { 0x37, 0x80 }; /* delays for single-shot mode i2c commands, both in us */ #define SHT3X_SINGLE_WAIT_TIME_HPM 15000 @@ -169,6 +171,7 @@ struct sht3x_data { u32 wait_time; /* in us*/ unsigned long last_update; /* last update in periodic mode*/ enum sht3x_repeatability repeatability; + u32 serial_number; /* * cached values for temperature and humidity and limits @@ -288,24 +291,26 @@ out: return data; } -static int temp1_input_read(struct device *dev) +static int temp1_input_read(struct device *dev, long *temp) { struct sht3x_data *data = sht3x_update_client(dev); if (IS_ERR(data)) return PTR_ERR(data); - return data->temperature; + *temp = data->temperature; + return 0; } -static int humidity1_input_read(struct device *dev) +static int humidity1_input_read(struct device *dev, long *humidity) { struct sht3x_data *data = sht3x_update_client(dev); if (IS_ERR(data)) return PTR_ERR(data); - return data->humidity; + *humidity = data->humidity; + return 0; } /* @@ -703,6 +708,7 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { enum sht3x_limits index; + int ret; switch (type) { case hwmon_chip: @@ -717,10 +723,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, case hwmon_temp: switch (attr) { case hwmon_temp_input: - *val = temp1_input_read(dev); - break; + return temp1_input_read(dev, val); case hwmon_temp_alarm: - *val = temp1_alarm_read(dev); + ret = temp1_alarm_read(dev); + if (ret < 0) + return ret; + *val = ret; break; case hwmon_temp_max: index = limit_max; @@ -745,10 +753,12 @@ static int sht3x_read(struct device *dev, enum hwmon_sensor_types type, case hwmon_humidity: switch (attr) { case hwmon_humidity_input: - *val = humidity1_input_read(dev); - break; + return humidity1_input_read(dev, val); case hwmon_humidity_alarm: - *val = humidity1_alarm_read(dev); + ret = humidity1_alarm_read(dev); + if (ret < 0) + return ret; + *val = ret; break; case hwmon_humidity_max: index = limit_max; @@ -831,6 +841,25 @@ static int sht3x_write(struct device *dev, enum hwmon_sensor_types type, } } +static void sht3x_serial_number_read(struct sht3x_data *data) +{ + int ret; + char buffer[SHT3X_RESPONSE_LENGTH]; + struct i2c_client *client = data->client; + + ret = sht3x_read_from_command(client, data, + sht3x_cmd_read_serial_number, + buffer, + SHT3X_RESPONSE_LENGTH, 0); + if (ret) + return; + + data->serial_number = (buffer[0] << 24) | (buffer[1] << 16) | + (buffer[3] << 8) | buffer[4]; + + debugfs_create_u32("serial_number", 0444, client->debugfs, &data->serial_number); +} + static const struct hwmon_ops sht3x_ops = { .is_visible = sht3x_is_visible, .read = sht3x_read, @@ -842,15 +871,6 @@ static const struct hwmon_chip_info sht3x_chip_info = { .info = sht3x_channel_info, }; -/* device ID table */ -static const struct i2c_device_id sht3x_ids[] = { - {"sht3x", sht3x}, - {"sts3x", sts3x}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, sht3x_ids); - static int sht3x_probe(struct i2c_client *client) { int ret; @@ -880,7 +900,7 @@ static int sht3x_probe(struct i2c_client *client) data->mode = 0; data->last_update = jiffies - msecs_to_jiffies(3000); data->client = client; - data->chip_id = i2c_match_id(sht3x_ids, client)->driver_data; + data->chip_id = (uintptr_t)i2c_get_match_data(client); crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL); sht3x_select_command(data); @@ -899,24 +919,30 @@ static int sht3x_probe(struct i2c_client *client) if (ret) return ret; - hwmon_dev = devm_hwmon_device_register_with_info(dev, - client->name, - data, - &sht3x_chip_info, - sht3x_groups); - + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, + &sht3x_chip_info, sht3x_groups); if (IS_ERR(hwmon_dev)) - dev_dbg(dev, "unable to register hwmon device\n"); + return PTR_ERR(hwmon_dev); + + sht3x_serial_number_read(data); - return PTR_ERR_OR_ZERO(hwmon_dev); + return 0; } +/* device ID table */ +static const struct i2c_device_id sht3x_ids[] = { + {"sht3x", sht3x}, + {"sts3x", sts3x}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, sht3x_ids); + static struct i2c_driver sht3x_i2c_driver = { .driver.name = "sht3x", .probe = sht3x_probe, .id_table = sht3x_ids, }; - module_i2c_driver(sht3x_i2c_driver); MODULE_AUTHOR("David Frey <david.frey@sensirion.com>"); |
