^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Sensirion SHT3x-DIS humidity and temperature sensor driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * The SHT3x comes in many different versions, this driver is for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * I2C version only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2016 Sensirion AG, Switzerland
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: David Frey <david.frey@sensirion.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author: Pascal Sachs <pascal.sachs@sensirion.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/crc8.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/hwmon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/hwmon-sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/platform_data/sht3x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /* commands (high precision mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static const unsigned char sht3x_cmd_measure_blocking_hpm[] = { 0x2c, 0x06 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static const unsigned char sht3x_cmd_measure_nonblocking_hpm[] = { 0x24, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* commands (low power mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static const unsigned char sht3x_cmd_measure_blocking_lpm[] = { 0x2c, 0x10 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static const unsigned char sht3x_cmd_measure_nonblocking_lpm[] = { 0x24, 0x16 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /* commands for periodic mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static const unsigned char sht3x_cmd_measure_periodic_mode[] = { 0xe0, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static const unsigned char sht3x_cmd_break[] = { 0x30, 0x93 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* commands for heater control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static const unsigned char sht3x_cmd_heater_on[] = { 0x30, 0x6d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static const unsigned char sht3x_cmd_heater_off[] = { 0x30, 0x66 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* other commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const unsigned char sht3x_cmd_read_status_reg[] = { 0xf3, 0x2d };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static const unsigned char sht3x_cmd_clear_status_reg[] = { 0x30, 0x41 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* delays for non-blocking i2c commands, both in us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SHT3X_NONBLOCKING_WAIT_TIME_HPM 15000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SHT3X_NONBLOCKING_WAIT_TIME_LPM 4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SHT3X_WORD_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SHT3X_CMD_LENGTH 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SHT3X_CRC8_LEN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define SHT3X_RESPONSE_LENGTH 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define SHT3X_CRC8_POLYNOMIAL 0x31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SHT3X_CRC8_INIT 0xFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SHT3X_MIN_TEMPERATURE -45000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SHT3X_MAX_TEMPERATURE 130000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define SHT3X_MIN_HUMIDITY 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SHT3X_MAX_HUMIDITY 100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) enum sht3x_chips {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) sht3x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) sts3x,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) enum sht3x_limits {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) limit_max = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) limit_max_hyst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) limit_min,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) limit_min_hyst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) DECLARE_CRC8_TABLE(sht3x_crc8_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* periodic measure commands (high precision mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static const char periodic_measure_commands_hpm[][SHT3X_CMD_LENGTH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /* 0.5 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) {0x20, 0x32},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* 1 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {0x21, 0x30},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* 2 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {0x22, 0x36},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) /* 4 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {0x23, 0x34},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* 10 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {0x27, 0x37},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* periodic measure commands (low power mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static const char periodic_measure_commands_lpm[][SHT3X_CMD_LENGTH] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /* 0.5 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {0x20, 0x2f},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /* 1 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {0x21, 0x2d},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* 2 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {0x22, 0x2b},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* 4 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {0x23, 0x29},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* 10 measurements per second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) {0x27, 0x2a},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct sht3x_limit_commands {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) const char read_command[SHT3X_CMD_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const char write_command[SHT3X_CMD_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static const struct sht3x_limit_commands limit_commands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* temp1_max, humidity1_max */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) [limit_max] = { {0xe1, 0x1f}, {0x61, 0x1d} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* temp_1_max_hyst, humidity1_max_hyst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) [limit_max_hyst] = { {0xe1, 0x14}, {0x61, 0x16} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* temp1_min, humidity1_min */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) [limit_min] = { {0xe1, 0x02}, {0x61, 0x00} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* temp_1_min_hyst, humidity1_min_hyst */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) [limit_min_hyst] = { {0xe1, 0x09}, {0x61, 0x0B} },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define SHT3X_NUM_LIMIT_CMD ARRAY_SIZE(limit_commands)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static const u16 mode_to_update_interval[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 2000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 250,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct sht3x_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct mutex i2c_lock; /* lock for sending i2c commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct mutex data_lock; /* lock for updating driver data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) const unsigned char *command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 wait_time; /* in us*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) unsigned long last_update; /* last update in periodic mode*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct sht3x_platform_data setup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * cached values for temperature and humidity and limits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * the limits arrays have the following order:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * max, max_hyst, min, min_hyst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int temperature_limits[SHT3X_NUM_LIMIT_CMD];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u32 humidity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u32 humidity_limits[SHT3X_NUM_LIMIT_CMD];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static u8 get_mode_from_update_interval(u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) size_t index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u8 number_of_modes = ARRAY_SIZE(mode_to_update_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (value == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* find next faster update interval */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) for (index = 1; index < number_of_modes; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (mode_to_update_interval[index] <= value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return number_of_modes - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int sht3x_read_from_command(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct sht3x_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) const char *command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) char *buf, int length, u32 wait_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mutex_lock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ret = i2c_master_send(client, command, SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ret != SHT3X_CMD_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) ret = ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (wait_time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) usleep_range(wait_time, wait_time + 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret = i2c_master_recv(client, buf, length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (ret != length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) ret = ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mutex_unlock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int sht3x_extract_temperature(u16 raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * From datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * T = -45 + 175 * ST / 2^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * Adapted for integer fixed point (3 digit) arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return ((21875 * (int)raw) >> 13) - 45000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static u32 sht3x_extract_humidity(u16 raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * From datasheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * RH = 100 * SRH / 2^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * Adapted for integer fixed point (3 digit) arithmetic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return (12500 * (u32)raw) >> 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static struct sht3x_data *sht3x_update_client(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u16 interval_ms = mode_to_update_interval[data->mode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned long interval_jiffies = msecs_to_jiffies(interval_ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned char buf[SHT3X_RESPONSE_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) mutex_lock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Only update cached readings once per update interval in periodic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * mode. In single shot mode the sensor measures values on demand, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * every time the sysfs interface is called, a measurement is triggered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * In periodic mode however, the measurement process is handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * internally by the sensor and reading out sensor values only makes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * sense if a new reading is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (time_after(jiffies, data->last_update + interval_jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = sht3x_read_from_command(client, data, data->command, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sizeof(buf), data->wait_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) val = be16_to_cpup((__be16 *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) data->temperature = sht3x_extract_temperature(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) val = be16_to_cpup((__be16 *)(buf + 3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) data->humidity = sht3x_extract_humidity(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) data->last_update = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) mutex_unlock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) return data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* sysfs attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static ssize_t temp1_input_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct sht3x_data *data = sht3x_update_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return sprintf(buf, "%d\n", data->temperature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static ssize_t humidity1_input_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct sht3x_data *data = sht3x_update_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (IS_ERR(data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return PTR_ERR(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return sprintf(buf, "%u\n", data->humidity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) * limits_update must only be called from probe or with data_lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static int limits_update(struct sht3x_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) u8 index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) u32 humidity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) u16 raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) char buffer[SHT3X_RESPONSE_LENGTH];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const struct sht3x_limit_commands *commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) for (index = 0; index < SHT3X_NUM_LIMIT_CMD; index++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) commands = &limit_commands[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = sht3x_read_from_command(client, data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) commands->read_command, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) SHT3X_RESPONSE_LENGTH, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) raw = be16_to_cpup((__be16 *)buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) temperature = sht3x_extract_temperature((raw & 0x01ff) << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) humidity = sht3x_extract_humidity(raw & 0xfe00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) data->temperature_limits[index] = temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) data->humidity_limits[index] = humidity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static ssize_t temp1_limit_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u8 index = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) int temperature_limit = data->temperature_limits[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return scnprintf(buf, PAGE_SIZE, "%d\n", temperature_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static ssize_t humidity1_limit_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u8 index = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) u32 humidity_limit = data->humidity_limits[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return scnprintf(buf, PAGE_SIZE, "%u\n", humidity_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * limit_store must only be called with data_lock held
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static size_t limit_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) u8 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int temperature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u32 humidity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) char buffer[SHT3X_CMD_LENGTH + SHT3X_WORD_LEN + SHT3X_CRC8_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) char *position = buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) u16 raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) const struct sht3x_limit_commands *commands;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) commands = &limit_commands[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) memcpy(position, commands->write_command, SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) position += SHT3X_CMD_LENGTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * ST = (T + 45) / 175 * 2^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * SRH = RH / 100 * 2^16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * adapted for fixed point arithmetic and packed the same as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * in limit_show()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) raw = ((u32)(temperature + 45000) * 24543) >> (16 + 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) raw |= ((humidity * 42950) >> 16) & 0xfe00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *((__be16 *)position) = cpu_to_be16(raw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) position += SHT3X_WORD_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) *position = crc8(sht3x_crc8_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) position - SHT3X_WORD_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) SHT3X_WORD_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) SHT3X_CRC8_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) mutex_lock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) ret = i2c_master_send(client, buffer, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) mutex_unlock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (ret != sizeof(buffer))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) data->temperature_limits[index] = temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) data->humidity_limits[index] = humidity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static ssize_t temp1_limit_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) int temperature;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) u8 index = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) ret = kstrtoint(buf, 0, &temperature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) temperature = clamp_val(temperature, SHT3X_MIN_TEMPERATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) SHT3X_MAX_TEMPERATURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) mutex_lock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) ret = limit_store(dev, count, index, temperature,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) data->humidity_limits[index]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) mutex_unlock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static ssize_t humidity1_limit_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) u32 humidity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) u8 index = to_sensor_dev_attr(attr)->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ret = kstrtou32(buf, 0, &humidity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) humidity = clamp_val(humidity, SHT3X_MIN_HUMIDITY, SHT3X_MAX_HUMIDITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) mutex_lock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret = limit_store(dev, count, index, data->temperature_limits[index],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) humidity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mutex_unlock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) static void sht3x_select_command(struct sht3x_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) * In blocking mode (clock stretching mode) the I2C bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) * is blocked for other traffic, thus the call to i2c_master_recv()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * will wait until the data is ready. For non blocking mode, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * have to wait ourselves.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (data->mode > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) data->command = sht3x_cmd_measure_periodic_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) data->wait_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) } else if (data->setup.blocking_io) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) data->command = data->setup.high_precision ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) sht3x_cmd_measure_blocking_hpm :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) sht3x_cmd_measure_blocking_lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) data->wait_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) if (data->setup.high_precision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) data->command = sht3x_cmd_measure_nonblocking_hpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) data->wait_time = SHT3X_NONBLOCKING_WAIT_TIME_HPM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) data->command = sht3x_cmd_measure_nonblocking_lpm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) data->wait_time = SHT3X_NONBLOCKING_WAIT_TIME_LPM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int status_register_read(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) char *buffer, int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ret = sht3x_read_from_command(client, data, sht3x_cmd_read_status_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) buffer, length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static ssize_t temp1_alarm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ret = status_register_read(dev, attr, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) SHT3X_WORD_LEN + SHT3X_CRC8_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x04));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static ssize_t humidity1_alarm_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = status_register_read(dev, attr, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) SHT3X_WORD_LEN + SHT3X_CRC8_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x08));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static ssize_t heater_enable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) char buffer[SHT3X_WORD_LEN + SHT3X_CRC8_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) ret = status_register_read(dev, attr, buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) SHT3X_WORD_LEN + SHT3X_CRC8_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return scnprintf(buf, PAGE_SIZE, "%d\n", !!(buffer[0] & 0x20));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static ssize_t heater_enable_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) bool status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) ret = kstrtobool(buf, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) mutex_lock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ret = i2c_master_send(client, (char *)&sht3x_cmd_heater_on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret = i2c_master_send(client, (char *)&sht3x_cmd_heater_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) mutex_unlock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static ssize_t update_interval_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return scnprintf(buf, PAGE_SIZE, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) mode_to_update_interval[data->mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static ssize_t update_interval_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) u16 update_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) const char *command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct sht3x_data *data = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ret = kstrtou16(buf, 0, &update_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) mode = get_mode_from_update_interval(update_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) mutex_lock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /* mode did not change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (mode == data->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) mutex_unlock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) mutex_lock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) * Abort periodic measure mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) * To do any changes to the configuration while in periodic mode, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) * have to send a break command to the sensor, which then falls back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * to single shot (mode = 0).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (data->mode > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) ret = i2c_master_send(client, sht3x_cmd_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (ret != SHT3X_CMD_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) data->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (mode > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (data->setup.high_precision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) command = periodic_measure_commands_hpm[mode - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) command = periodic_measure_commands_lpm[mode - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* select mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ret = i2c_master_send(client, command, SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (ret != SHT3X_CMD_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* select mode and command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) data->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) sht3x_select_command(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) mutex_unlock(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) mutex_unlock(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (ret != SHT3X_CMD_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static SENSOR_DEVICE_ATTR_RO(temp1_input, temp1_input, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) static SENSOR_DEVICE_ATTR_RO(humidity1_input, humidity1_input, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) static SENSOR_DEVICE_ATTR_RW(temp1_max, temp1_limit, limit_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static SENSOR_DEVICE_ATTR_RW(humidity1_max, humidity1_limit, limit_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static SENSOR_DEVICE_ATTR_RW(temp1_max_hyst, temp1_limit, limit_max_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static SENSOR_DEVICE_ATTR_RW(humidity1_max_hyst, humidity1_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) limit_max_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static SENSOR_DEVICE_ATTR_RW(temp1_min, temp1_limit, limit_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static SENSOR_DEVICE_ATTR_RW(humidity1_min, humidity1_limit, limit_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static SENSOR_DEVICE_ATTR_RW(temp1_min_hyst, temp1_limit, limit_min_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static SENSOR_DEVICE_ATTR_RW(humidity1_min_hyst, humidity1_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) limit_min_hyst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static SENSOR_DEVICE_ATTR_RO(temp1_alarm, temp1_alarm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static SENSOR_DEVICE_ATTR_RO(humidity1_alarm, humidity1_alarm, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static SENSOR_DEVICE_ATTR_RW(heater_enable, heater_enable, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static SENSOR_DEVICE_ATTR_RW(update_interval, update_interval, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static struct attribute *sht3x_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) &sensor_dev_attr_humidity1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) &sensor_dev_attr_temp1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) &sensor_dev_attr_humidity1_max.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) &sensor_dev_attr_humidity1_max_hyst.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) &sensor_dev_attr_temp1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) &sensor_dev_attr_temp1_min_hyst.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) &sensor_dev_attr_humidity1_min.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) &sensor_dev_attr_humidity1_min_hyst.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) &sensor_dev_attr_temp1_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &sensor_dev_attr_humidity1_alarm.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) &sensor_dev_attr_heater_enable.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) &sensor_dev_attr_update_interval.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static struct attribute *sts3x_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) &sensor_dev_attr_temp1_input.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ATTRIBUTE_GROUPS(sht3x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) ATTRIBUTE_GROUPS(sts3x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static const struct i2c_device_id sht3x_ids[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) static int sht3x_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) struct sht3x_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct device *hwmon_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct i2c_adapter *adap = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) const struct attribute_group **attribute_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * we require full i2c support since the sht3x uses multi-byte read and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * writes as well as multi-byte commands which are not supported by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * the smbus protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (!i2c_check_functionality(adap, I2C_FUNC_I2C))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) ret = i2c_master_send(client, sht3x_cmd_clear_status_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) SHT3X_CMD_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (ret != SHT3X_CMD_LENGTH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) return ret < 0 ? ret : -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) data->setup.blocking_io = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) data->setup.high_precision = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) data->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) data->last_update = jiffies - msecs_to_jiffies(3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) crc8_populate_msb(sht3x_crc8_table, SHT3X_CRC8_POLYNOMIAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (client->dev.platform_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) data->setup = *(struct sht3x_platform_data *)dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) sht3x_select_command(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) mutex_init(&data->i2c_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) mutex_init(&data->data_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * An attempt to read limits register too early
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * causes a NACK response from the chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * Waiting for an empirical delay of 500 us solves the issue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) usleep_range(500, 600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) ret = limits_update(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (i2c_match_id(sht3x_ids, client)->driver_data == sts3x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) attribute_groups = sts3x_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) attribute_groups = sht3x_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) hwmon_dev = devm_hwmon_device_register_with_groups(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) client->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) attribute_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (IS_ERR(hwmon_dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) dev_dbg(dev, "unable to register hwmon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return PTR_ERR_OR_ZERO(hwmon_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) /* device ID table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static const struct i2c_device_id sht3x_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {"sht3x", sht3x},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) {"sts3x", sts3x},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) MODULE_DEVICE_TABLE(i2c, sht3x_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) static struct i2c_driver sht3x_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .driver.name = "sht3x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .probe_new = sht3x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .id_table = sht3x_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) module_i2c_driver(sht3x_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) MODULE_AUTHOR("David Frey <david.frey@sensirion.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) MODULE_AUTHOR("Pascal Sachs <pascal.sachs@sensirion.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) MODULE_DESCRIPTION("Sensirion SHT3x humidity and temperature sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) MODULE_LICENSE("GPL");