diff options
Diffstat (limited to 'drivers/hwmon/sht3x.c')
| -rw-r--r-- | drivers/hwmon/sht3x.c | 545 |
1 files changed, 357 insertions, 188 deletions
diff --git a/drivers/hwmon/sht3x.c b/drivers/hwmon/sht3x.c index 370b57dafab7..f36c0229328f 100644 --- a/drivers/hwmon/sht3x.c +++ b/drivers/hwmon/sht3x.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* Sensirion SHT3x-DIS humidity and temperature sensor driver. * The SHT3x comes in many different versions, this driver is for the * I2C version only. @@ -5,21 +6,11 @@ * Copyright (C) 2016 Sensirion AG, Switzerland * Author: David Frey <david.frey@sensirion.com> * Author: Pascal Sachs <pascal.sachs@sensirion.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * */ #include <asm/page.h> #include <linux/crc8.h> +#include <linux/debugfs.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/hwmon.h> @@ -30,15 +21,15 @@ #include <linux/module.h> #include <linux/slab.h> #include <linux/jiffies.h> -#include <linux/platform_data/sht3x.h> -/* commands (high precision mode) */ -static const unsigned char sht3x_cmd_measure_blocking_hpm[] = { 0x2c, 0x06 }; -static const unsigned char sht3x_cmd_measure_nonblocking_hpm[] = { 0x24, 0x00 }; +/* commands (high repeatability mode) */ +static const unsigned char sht3x_cmd_measure_single_hpm[] = { 0x24, 0x00 }; + +/* commands (medium repeatability mode) */ +static const unsigned char sht3x_cmd_measure_single_mpm[] = { 0x24, 0x0b }; -/* commands (low power mode) */ -static const unsigned char sht3x_cmd_measure_blocking_lpm[] = { 0x2c, 0x10 }; -static const unsigned char sht3x_cmd_measure_nonblocking_lpm[] = { 0x24, 0x16 }; +/* commands (low repeatability mode) */ +static const unsigned char sht3x_cmd_measure_single_lpm[] = { 0x24, 0x16 }; /* commands for periodic mode */ static const unsigned char sht3x_cmd_measure_periodic_mode[] = { 0xe0, 0x00 }; @@ -51,10 +42,12 @@ 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 non-blocking i2c commands, both in us */ -#define SHT3X_NONBLOCKING_WAIT_TIME_HPM 15000 -#define SHT3X_NONBLOCKING_WAIT_TIME_LPM 4000 +/* delays for single-shot mode i2c commands, both in us */ +#define SHT3X_SINGLE_WAIT_TIME_HPM 15000 +#define SHT3X_SINGLE_WAIT_TIME_MPM 6000 +#define SHT3X_SINGLE_WAIT_TIME_LPM 4000 #define SHT3X_WORD_LEN 2 #define SHT3X_CMD_LENGTH 2 @@ -79,9 +72,15 @@ enum sht3x_limits { limit_min_hyst, }; +enum sht3x_repeatability { + low_repeatability, + medium_repeatability, + high_repeatability, +}; + DECLARE_CRC8_TABLE(sht3x_crc8_table); -/* periodic measure commands (high precision mode) */ +/* periodic measure commands (high repeatability mode) */ static const char periodic_measure_commands_hpm[][SHT3X_CMD_LENGTH] = { /* 0.5 measurements per second */ {0x20, 0x32}, @@ -95,7 +94,21 @@ static const char periodic_measure_commands_hpm[][SHT3X_CMD_LENGTH] = { {0x27, 0x37}, }; -/* periodic measure commands (low power mode) */ +/* periodic measure commands (medium repeatability) */ +static const char periodic_measure_commands_mpm[][SHT3X_CMD_LENGTH] = { + /* 0.5 measurements per second */ + {0x20, 0x24}, + /* 1 measurements per second */ + {0x21, 0x26}, + /* 2 measurements per second */ + {0x22, 0x20}, + /* 4 measurements per second */ + {0x23, 0x22}, + /* 10 measurements per second */ + {0x27, 0x21}, +}; + +/* periodic measure commands (low repeatability mode) */ static const char periodic_measure_commands_lpm[][SHT3X_CMD_LENGTH] = { /* 0.5 measurements per second */ {0x20, 0x2f}, @@ -136,8 +149,20 @@ static const u16 mode_to_update_interval[] = { 100, }; +static const struct hwmon_channel_info * const sht3x_channel_info[] = { + HWMON_CHANNEL_INFO(chip, HWMON_C_UPDATE_INTERVAL), + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_MIN | + HWMON_T_MIN_HYST | HWMON_T_MAX | + HWMON_T_MAX_HYST | HWMON_T_ALARM), + HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT | HWMON_H_MIN | + HWMON_H_MIN_HYST | HWMON_H_MAX | + HWMON_H_MAX_HYST | HWMON_H_ALARM), + NULL, +}; + struct sht3x_data { struct i2c_client *client; + enum sht3x_chips chip_id; struct mutex i2c_lock; /* lock for sending i2c commands */ struct mutex data_lock; /* lock for updating driver data */ @@ -145,8 +170,8 @@ struct sht3x_data { const unsigned char *command; u32 wait_time; /* in us*/ unsigned long last_update; /* last update in periodic mode*/ - - struct sht3x_platform_data setup; + enum sht3x_repeatability repeatability; + u32 serial_number; /* * cached values for temperature and humidity and limits @@ -266,27 +291,26 @@ out: return data; } -/* sysfs attributes */ -static ssize_t temp1_input_show(struct device *dev, - struct device_attribute *attr, char *buf) +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 sprintf(buf, "%d\n", data->temperature); + *temp = data->temperature; + return 0; } -static ssize_t humidity1_input_show(struct device *dev, - struct device_attribute *attr, char *buf) +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 sprintf(buf, "%u\n", data->humidity); + *humidity = data->humidity; + return 0; } /* @@ -322,33 +346,24 @@ static int limits_update(struct sht3x_data *data) return ret; } -static ssize_t temp1_limit_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static int temp1_limit_read(struct device *dev, int index) { struct sht3x_data *data = dev_get_drvdata(dev); - u8 index = to_sensor_dev_attr(attr)->index; - int temperature_limit = data->temperature_limits[index]; - return scnprintf(buf, PAGE_SIZE, "%d\n", temperature_limit); + return data->temperature_limits[index]; } -static ssize_t humidity1_limit_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static int humidity1_limit_read(struct device *dev, int index) { struct sht3x_data *data = dev_get_drvdata(dev); - u8 index = to_sensor_dev_attr(attr)->index; - u32 humidity_limit = data->humidity_limits[index]; - return scnprintf(buf, PAGE_SIZE, "%u\n", humidity_limit); + return data->humidity_limits[index]; } /* - * limit_store must only be called with data_lock held + * limit_write must only be called with data_lock held */ -static size_t limit_store(struct device *dev, - size_t count, +static size_t limit_write(struct device *dev, u8 index, int temperature, u32 humidity) @@ -369,7 +384,7 @@ static size_t limit_store(struct device *dev, * ST = (T + 45) / 175 * 2^16 * SRH = RH / 100 * 2^16 * adapted for fixed point arithmetic and packed the same as - * in limit_show() + * in limit_read() */ raw = ((u32)(temperature + 45000) * 24543) >> (16 + 7); raw |= ((humidity * 42950) >> 16) & 0xfe00; @@ -390,50 +405,35 @@ static size_t limit_store(struct device *dev, data->temperature_limits[index] = temperature; data->humidity_limits[index] = humidity; - return count; + + return 0; } -static ssize_t temp1_limit_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) +static int temp1_limit_write(struct device *dev, int index, int val) { int temperature; int ret; struct sht3x_data *data = dev_get_drvdata(dev); - u8 index = to_sensor_dev_attr(attr)->index; - - ret = kstrtoint(buf, 0, &temperature); - if (ret) - return ret; - temperature = clamp_val(temperature, SHT3X_MIN_TEMPERATURE, + temperature = clamp_val(val, SHT3X_MIN_TEMPERATURE, SHT3X_MAX_TEMPERATURE); mutex_lock(&data->data_lock); - ret = limit_store(dev, count, index, temperature, + ret = limit_write(dev, index, temperature, data->humidity_limits[index]); mutex_unlock(&data->data_lock); return ret; } -static ssize_t humidity1_limit_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) +static int humidity1_limit_write(struct device *dev, int index, int val) { u32 humidity; int ret; struct sht3x_data *data = dev_get_drvdata(dev); - u8 index = to_sensor_dev_attr(attr)->index; - - ret = kstrtou32(buf, 0, &humidity); - if (ret) - return ret; - humidity = clamp_val(humidity, SHT3X_MIN_HUMIDITY, SHT3X_MAX_HUMIDITY); + humidity = clamp_val(val, SHT3X_MIN_HUMIDITY, SHT3X_MAX_HUMIDITY); mutex_lock(&data->data_lock); - ret = limit_store(dev, count, index, data->temperature_limits[index], + ret = limit_write(dev, index, data->temperature_limits[index], humidity); mutex_unlock(&data->data_lock); @@ -443,32 +443,27 @@ static ssize_t humidity1_limit_store(struct device *dev, static void sht3x_select_command(struct sht3x_data *data) { /* - * In blocking mode (clock stretching mode) the I2C bus - * is blocked for other traffic, thus the call to i2c_master_recv() - * will wait until the data is ready. For non blocking mode, we - * have to wait ourselves. + * For single-shot mode, only non blocking mode is support, + * we have to wait ourselves for result. */ if (data->mode > 0) { data->command = sht3x_cmd_measure_periodic_mode; data->wait_time = 0; - } else if (data->setup.blocking_io) { - data->command = data->setup.high_precision ? - sht3x_cmd_measure_blocking_hpm : - sht3x_cmd_measure_blocking_lpm; - data->wait_time = 0; } else { - if (data->setup.high_precision) { - data->command = sht3x_cmd_measure_nonblocking_hpm; - data->wait_time = SHT3X_NONBLOCKING_WAIT_TIME_HPM; + if (data->repeatability == high_repeatability) { + data->command = sht3x_cmd_measure_single_hpm; + data->wait_time = SHT3X_SINGLE_WAIT_TIME_HPM; + } else if (data->repeatability == medium_repeatability) { + data->command = sht3x_cmd_measure_single_mpm; + data->wait_time = SHT3X_SINGLE_WAIT_TIME_MPM; } else { - data->command = sht3x_cmd_measure_nonblocking_lpm; - data->wait_time = SHT3X_NONBLOCKING_WAIT_TIME_LPM; + data->command = sht3x_cmd_measure_single_lpm; + data->wait_time = SHT3X_SINGLE_WAIT_TIME_LPM; } } } static int status_register_read(struct device *dev, - struct device_attribute *attr, char *buffer, int length) { int ret; @@ -481,34 +476,30 @@ static int status_register_read(struct device *dev, return ret; } -static ssize_t temp1_alarm_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static int temp1_alarm_read(struct device *dev) { char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN]; int ret; - ret = status_register_read(dev, attr, buffer, + ret = status_register_read(dev, buffer, SHT3X_WORD_LEN + SHT3X_CRC8_LEN); if (ret) return ret; - return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x04)); + return !!(buffer[0] & 0x04); } -static ssize_t humidity1_alarm_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static int humidity1_alarm_read(struct device *dev) { char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN]; int ret; - ret = status_register_read(dev, attr, buffer, + ret = status_register_read(dev, buffer, SHT3X_WORD_LEN + SHT3X_CRC8_LEN); if (ret) return ret; - return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x08)); + return !!(buffer[0] & 0x08); } static ssize_t heater_enable_show(struct device *dev, @@ -518,12 +509,12 @@ static ssize_t heater_enable_show(struct device *dev, char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN]; int ret; - ret = status_register_read(dev, attr, buffer, + ret = status_register_read(dev, buffer, SHT3X_WORD_LEN + SHT3X_CRC8_LEN); if (ret) return ret; - return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x20)); + return sysfs_emit(buf, "%d\n", !!(buffer[0] & 0x20)); } static ssize_t heater_enable_store(struct device *dev, @@ -554,39 +545,28 @@ static ssize_t heater_enable_store(struct device *dev, return ret; } -static ssize_t update_interval_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static int update_interval_read(struct device *dev) { struct sht3x_data *data = dev_get_drvdata(dev); - return scnprintf(buf, PAGE_SIZE, "%u\n", - mode_to_update_interval[data->mode]); + return mode_to_update_interval[data->mode]; } -static ssize_t update_interval_store(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t count) +static int update_interval_write(struct device *dev, int val) { - u16 update_interval; u8 mode; int ret; const char *command; struct sht3x_data *data = dev_get_drvdata(dev); struct i2c_client *client = data->client; - ret = kstrtou16(buf, 0, &update_interval); - if (ret) - return ret; - - mode = get_mode_from_update_interval(update_interval); + mode = get_mode_from_update_interval(val); mutex_lock(&data->data_lock); /* mode did not change */ if (mode == data->mode) { mutex_unlock(&data->data_lock); - return count; + return 0; } mutex_lock(&data->i2c_lock); @@ -605,8 +585,10 @@ static ssize_t update_interval_store(struct device *dev, } if (mode > 0) { - if (data->setup.high_precision) + if (data->repeatability == high_repeatability) command = periodic_measure_commands_hpm[mode - 1]; + else if (data->repeatability == medium_repeatability) + command = periodic_measure_commands_mpm[mode - 1]; else command = periodic_measure_commands_lpm[mode - 1]; @@ -626,79 +608,276 @@ out: if (ret != SHT3X_CMD_LENGTH) return ret < 0 ? ret : -EIO; + return 0; +} + +static ssize_t repeatability_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct sht3x_data *data = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%d\n", data->repeatability); +} + +static ssize_t repeatability_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + int ret; + u8 val; + + struct sht3x_data *data = dev_get_drvdata(dev); + + ret = kstrtou8(buf, 0, &val); + if (ret) + return ret; + + if (val > 2) + return -EINVAL; + + data->repeatability = val; + return count; } -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, temp1_input_show, NULL, 0); -static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, humidity1_input_show, - NULL, 0); -static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, - temp1_limit_show, temp1_limit_store, - limit_max); -static SENSOR_DEVICE_ATTR(humidity1_max, S_IRUGO | S_IWUSR, - humidity1_limit_show, humidity1_limit_store, - limit_max); -static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, - temp1_limit_show, temp1_limit_store, - limit_max_hyst); -static SENSOR_DEVICE_ATTR(humidity1_max_hyst, S_IRUGO | S_IWUSR, - humidity1_limit_show, humidity1_limit_store, - limit_max_hyst); -static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, - temp1_limit_show, temp1_limit_store, - limit_min); -static SENSOR_DEVICE_ATTR(humidity1_min, S_IRUGO | S_IWUSR, - humidity1_limit_show, humidity1_limit_store, - limit_min); -static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO | S_IWUSR, - temp1_limit_show, temp1_limit_store, - limit_min_hyst); -static SENSOR_DEVICE_ATTR(humidity1_min_hyst, S_IRUGO | S_IWUSR, - humidity1_limit_show, humidity1_limit_store, - limit_min_hyst); -static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, temp1_alarm_show, NULL, 0); -static SENSOR_DEVICE_ATTR(humidity1_alarm, S_IRUGO, humidity1_alarm_show, - NULL, 0); -static SENSOR_DEVICE_ATTR(heater_enable, S_IRUGO | S_IWUSR, - heater_enable_show, heater_enable_store, 0); -static SENSOR_DEVICE_ATTR(update_interval, S_IRUGO | S_IWUSR, - update_interval_show, update_interval_store, 0); +static SENSOR_DEVICE_ATTR_RW(heater_enable, heater_enable, 0); +static SENSOR_DEVICE_ATTR_RW(repeatability, repeatability, 0); static struct attribute *sht3x_attrs[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - &sensor_dev_attr_humidity1_input.dev_attr.attr, - &sensor_dev_attr_temp1_max.dev_attr.attr, - &sensor_dev_attr_temp1_max_hyst.dev_attr.attr, - &sensor_dev_attr_humidity1_max.dev_attr.attr, - &sensor_dev_attr_humidity1_max_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_min.dev_attr.attr, - &sensor_dev_attr_temp1_min_hyst.dev_attr.attr, - &sensor_dev_attr_humidity1_min.dev_attr.attr, - &sensor_dev_attr_humidity1_min_hyst.dev_attr.attr, - &sensor_dev_attr_temp1_alarm.dev_attr.attr, - &sensor_dev_attr_humidity1_alarm.dev_attr.attr, &sensor_dev_attr_heater_enable.dev_attr.attr, - &sensor_dev_attr_update_interval.dev_attr.attr, + &sensor_dev_attr_repeatability.dev_attr.attr, NULL }; -static struct attribute *sts3x_attrs[] = { - &sensor_dev_attr_temp1_input.dev_attr.attr, - NULL +ATTRIBUTE_GROUPS(sht3x); + +static umode_t sht3x_is_visible(const void *data, enum hwmon_sensor_types type, + u32 attr, int channel) +{ + const struct sht3x_data *chip_data = data; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + return 0644; + default: + break; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + case hwmon_temp_alarm: + return 0444; + case hwmon_temp_max: + case hwmon_temp_max_hyst: + case hwmon_temp_min: + case hwmon_temp_min_hyst: + return 0644; + default: + break; + } + break; + case hwmon_humidity: + if (chip_data->chip_id == sts3x) + break; + switch (attr) { + case hwmon_humidity_input: + case hwmon_humidity_alarm: + return 0444; + case hwmon_humidity_max: + case hwmon_humidity_max_hyst: + case hwmon_humidity_min: + case hwmon_humidity_min_hyst: + return 0644; + default: + break; + } + break; + default: + break; + } + + return 0; +} + +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: + switch (attr) { + case hwmon_chip_update_interval: + *val = update_interval_read(dev); + break; + default: + return -EOPNOTSUPP; + } + break; + case hwmon_temp: + switch (attr) { + case hwmon_temp_input: + return temp1_input_read(dev, val); + case hwmon_temp_alarm: + ret = temp1_alarm_read(dev); + if (ret < 0) + return ret; + *val = ret; + break; + case hwmon_temp_max: + index = limit_max; + *val = temp1_limit_read(dev, index); + break; + case hwmon_temp_max_hyst: + index = limit_max_hyst; + *val = temp1_limit_read(dev, index); + break; + case hwmon_temp_min: + index = limit_min; + *val = temp1_limit_read(dev, index); + break; + case hwmon_temp_min_hyst: + index = limit_min_hyst; + *val = temp1_limit_read(dev, index); + break; + default: + return -EOPNOTSUPP; + } + break; + case hwmon_humidity: + switch (attr) { + case hwmon_humidity_input: + return humidity1_input_read(dev, val); + case hwmon_humidity_alarm: + ret = humidity1_alarm_read(dev); + if (ret < 0) + return ret; + *val = ret; + break; + case hwmon_humidity_max: + index = limit_max; + *val = humidity1_limit_read(dev, index); + break; + case hwmon_humidity_max_hyst: + index = limit_max_hyst; + *val = humidity1_limit_read(dev, index); + break; + case hwmon_humidity_min: + index = limit_min; + *val = humidity1_limit_read(dev, index); + break; + case hwmon_humidity_min_hyst: + index = limit_min_hyst; + *val = humidity1_limit_read(dev, index); + break; + default: + return -EOPNOTSUPP; + } + break; + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int sht3x_write(struct device *dev, enum hwmon_sensor_types type, + u32 attr, int channel, long val) +{ + enum sht3x_limits index; + + switch (type) { + case hwmon_chip: + switch (attr) { + case hwmon_chip_update_interval: + return update_interval_write(dev, val); + default: + return -EOPNOTSUPP; + } + case hwmon_temp: + switch (attr) { + case hwmon_temp_max: + index = limit_max; + break; + case hwmon_temp_max_hyst: + index = limit_max_hyst; + break; + case hwmon_temp_min: + index = limit_min; + break; + case hwmon_temp_min_hyst: + index = limit_min_hyst; + break; + default: + return -EOPNOTSUPP; + } + return temp1_limit_write(dev, index, val); + case hwmon_humidity: + switch (attr) { + case hwmon_humidity_max: + index = limit_max; + break; + case hwmon_humidity_max_hyst: + index = limit_max_hyst; + break; + case hwmon_humidity_min: + index = limit_min; + break; + case hwmon_humidity_min_hyst: + index = limit_min_hyst; + break; + default: + return -EOPNOTSUPP; + } + return humidity1_limit_write(dev, index, val); + default: + return -EOPNOTSUPP; + } +} + +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, + .write = sht3x_write, }; -ATTRIBUTE_GROUPS(sht3x); -ATTRIBUTE_GROUPS(sts3x); +static const struct hwmon_chip_info sht3x_chip_info = { + .ops = &sht3x_ops, + .info = sht3x_channel_info, +}; -static int sht3x_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int sht3x_probe(struct i2c_client *client) { int ret; struct sht3x_data *data; struct device *hwmon_dev; struct i2c_adapter *adap = client->adapter; struct device *dev = &client->dev; - const struct attribute_group **attribute_groups; /* * we require full i2c support since the sht3x uses multi-byte read and @@ -717,16 +896,13 @@ static int sht3x_probe(struct i2c_client *client, if (!data) return -ENOMEM; - data->setup.blocking_io = false; - data->setup.high_precision = true; + data->repeatability = high_repeatability; data->mode = 0; data->last_update = jiffies - msecs_to_jiffies(3000); data->client = client; + data->chip_id = (uintptr_t)i2c_get_match_data(client); crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL); - if (client->dev.platform_data) - data->setup = *(struct sht3x_platform_data *)dev->platform_data; - sht3x_select_command(data); mutex_init(&data->i2c_lock); @@ -743,20 +919,14 @@ static int sht3x_probe(struct i2c_client *client, if (ret) return ret; - if (id->driver_data == sts3x) - attribute_groups = sts3x_groups; - else - attribute_groups = sht3x_groups; - - hwmon_dev = devm_hwmon_device_register_with_groups(dev, - client->name, - data, - attribute_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 */ @@ -773,7 +943,6 @@ static struct i2c_driver sht3x_i2c_driver = { .probe = sht3x_probe, .id_table = sht3x_ids, }; - module_i2c_driver(sht3x_i2c_driver); MODULE_AUTHOR("David Frey <david.frey@sensirion.com>"); |
