Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");