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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * si1145.c - Support for Silabs SI1132 and SI1141/2/3/5/6/7 combined ambient
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * light, UV index and proximity sensors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright 2014-16 Peter Meerwald-Stadler <pmeerw@pmeerw.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Copyright 2016 Crestez Dan Leonard <leonard.crestez@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * SI1132 (7-bit I2C slave address 0x60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  * SI1141/2/3 (7-bit I2C slave address 0x5a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11)  * SI1145/6/6 (7-bit I2C slave address 0x60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/iio/trigger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/util_macros.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define SI1145_REG_PART_ID		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define SI1145_REG_REV_ID		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define SI1145_REG_SEQ_ID		0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define SI1145_REG_INT_CFG		0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define SI1145_REG_IRQ_ENABLE		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define SI1145_REG_IRQ_MODE		0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define SI1145_REG_HW_KEY		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define SI1145_REG_MEAS_RATE		0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define SI1145_REG_PS_LED21		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define SI1145_REG_PS_LED3		0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define SI1145_REG_UCOEF1		0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define SI1145_REG_UCOEF2		0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define SI1145_REG_UCOEF3		0x15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define SI1145_REG_UCOEF4		0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define SI1145_REG_PARAM_WR		0x17
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define SI1145_REG_COMMAND		0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define SI1145_REG_RESPONSE		0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define SI1145_REG_IRQ_STATUS		0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define SI1145_REG_ALSVIS_DATA		0x22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define SI1145_REG_ALSIR_DATA		0x24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define SI1145_REG_PS1_DATA		0x26
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define SI1145_REG_PS2_DATA		0x28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define SI1145_REG_PS3_DATA		0x2a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define SI1145_REG_AUX_DATA		0x2c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define SI1145_REG_PARAM_RD		0x2e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define SI1145_REG_CHIP_STAT		0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define SI1145_UCOEF1_DEFAULT		0x7b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define SI1145_UCOEF2_DEFAULT		0x6b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define SI1145_UCOEF3_DEFAULT		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define SI1145_UCOEF4_DEFAULT		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) /* Helper to figure out PS_LED register / shift per channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define SI1145_PS_LED_REG(ch) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 	(((ch) == 2) ? SI1145_REG_PS_LED3 : SI1145_REG_PS_LED21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define SI1145_PS_LED_SHIFT(ch) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	(((ch) == 1) ? 4 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) /* Parameter offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define SI1145_PARAM_CHLIST		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define SI1145_PARAM_PSLED12_SELECT	0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define SI1145_PARAM_PSLED3_SELECT	0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define SI1145_PARAM_PS_ENCODING	0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define SI1145_PARAM_ALS_ENCODING	0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define SI1145_PARAM_PS1_ADC_MUX	0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define SI1145_PARAM_PS2_ADC_MUX	0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define SI1145_PARAM_PS3_ADC_MUX	0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define SI1145_PARAM_PS_ADC_COUNTER	0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define SI1145_PARAM_PS_ADC_GAIN	0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define SI1145_PARAM_PS_ADC_MISC	0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define SI1145_PARAM_ALS_ADC_MUX	0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define SI1145_PARAM_ALSIR_ADC_MUX	0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define SI1145_PARAM_AUX_ADC_MUX	0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) #define SI1145_PARAM_ALSVIS_ADC_COUNTER	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define SI1145_PARAM_ALSVIS_ADC_GAIN	0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define SI1145_PARAM_ALSVIS_ADC_MISC	0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) #define SI1145_PARAM_LED_RECOVERY	0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define SI1145_PARAM_ALSIR_ADC_COUNTER	0x1d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define SI1145_PARAM_ALSIR_ADC_GAIN	0x1e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define SI1145_PARAM_ALSIR_ADC_MISC	0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define SI1145_PARAM_ADC_OFFSET		0x1a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) /* Channel enable masks for CHLIST parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define SI1145_CHLIST_EN_PS1		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define SI1145_CHLIST_EN_PS2		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define SI1145_CHLIST_EN_PS3		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define SI1145_CHLIST_EN_ALSVIS		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define SI1145_CHLIST_EN_ALSIR		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define SI1145_CHLIST_EN_AUX		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define SI1145_CHLIST_EN_UV		BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) /* Proximity measurement mode for ADC_MISC parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define SI1145_PS_ADC_MODE_NORMAL	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) /* Signal range mask for ADC_MISC parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define SI1145_ADC_MISC_RANGE		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) /* Commands for REG_COMMAND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define SI1145_CMD_NOP			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) #define SI1145_CMD_RESET		0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) #define SI1145_CMD_PS_FORCE		0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) #define SI1145_CMD_ALS_FORCE		0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define SI1145_CMD_PSALS_FORCE		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define SI1145_CMD_PS_PAUSE		0x09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define SI1145_CMD_ALS_PAUSE		0x0a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #define SI1145_CMD_PSALS_PAUSE		0x0b
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define SI1145_CMD_PS_AUTO		0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define SI1145_CMD_ALS_AUTO		0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define SI1145_CMD_PSALS_AUTO		0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define SI1145_CMD_PARAM_QUERY		0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define SI1145_CMD_PARAM_SET		0xa0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) #define SI1145_RSP_INVALID_SETTING	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) #define SI1145_RSP_COUNTER_MASK		0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) /* Minimum sleep after each command to ensure it's received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define SI1145_COMMAND_MINSLEEP_MS	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) /* Return -ETIMEDOUT after this long */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define SI1145_COMMAND_TIMEOUT_MS	25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) /* Interrupt configuration masks for INT_CFG register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define SI1145_INT_CFG_OE		BIT(0) /* enable interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) #define SI1145_INT_CFG_MODE		BIT(1) /* auto reset interrupt pin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) /* Interrupt enable masks for IRQ_ENABLE register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define SI1145_MASK_ALL_IE		(BIT(4) | BIT(3) | BIT(2) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define SI1145_MUX_TEMP			0x65
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define SI1145_MUX_VDD			0x75
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) /* Proximity LED current; see Table 2 in datasheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define SI1145_LED_CURRENT_45mA		0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	SI1132,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	SI1141,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	SI1142,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	SI1143,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	SI1145,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	SI1146,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	SI1147,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) struct si1145_part_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	u8 part;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	const struct iio_info *iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	const struct iio_chan_spec *channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	unsigned int num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	unsigned int num_leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	bool uncompressed_meas_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  * struct si1145_data - si1145 chip state data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)  * @client:	I2C client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  * @lock:	mutex to protect shared state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  * @cmdlock:	Low-level mutex to protect command execution only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  * @rsp_seq:	Next expected response number or -1 if counter reset required
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * @scan_mask:	Saved scan mask to avoid duplicate set_chlist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  * @autonomous: If automatic measurements are active (for buffer support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * @part_info:	Part information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * @trig:	Pointer to iio trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * @meas_rate:	Value of MEAS_RATE register. Only set in HW in auto mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * @buffer:	Used to pack data read from sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) struct si1145_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	struct mutex cmdlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	int rsp_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	const struct si1145_part_info *part_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	unsigned long scan_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	bool autonomous;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	struct iio_trigger *trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	int meas_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	 * Ensure timestamp will be naturally aligned if present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	 * Maximum buffer size (may be only partly used if not all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	 * channels are enabled):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	 *   6*2 bytes channels data + 4 bytes alignment +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	 *   8 bytes timestamp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	u8 buffer[24] __aligned(8);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194)  * __si1145_command_reset() - Send CMD_NOP and wait for response 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  * Does not modify data->rsp_seq
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  * Return: 0 on success and -errno on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) static int __si1145_command_reset(struct si1145_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	struct device *dev = &data->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	unsigned long stop_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 						      SI1145_CMD_NOP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	msleep(SI1145_COMMAND_MINSLEEP_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 					       SI1145_REG_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		if (ret <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		if (time_after(jiffies, stop_jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 			dev_warn(dev, "timeout on reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 			return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 		msleep(SI1145_COMMAND_MINSLEEP_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  * si1145_command() - Execute a command and poll the response register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  * All conversion overflows are reported as -EOVERFLOW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)  * INVALID_SETTING is reported as -EINVAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  * Timeouts are reported as -ETIMEDOUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)  * Return: 0 on success or -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static int si1145_command(struct si1145_data *data, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	struct device *dev = &data->client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	unsigned long stop_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	mutex_lock(&data->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	if (data->rsp_seq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		ret = __si1145_command_reset(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			dev_err(dev, "failed to reset command counter, ret=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 				ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		data->rsp_seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		dev_warn(dev, "failed to write command, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	/* Sleep a little to ensure the command is received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	msleep(SI1145_COMMAND_MINSLEEP_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 					       SI1145_REG_RESPONSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			dev_warn(dev, "failed to read response, ret=%d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			break;
^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) 		if ((ret & ~SI1145_RSP_COUNTER_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			if (ret == data->rsp_seq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 				if (time_after(jiffies, stop_jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 					dev_warn(dev, "timeout on command %#02hhx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 						 cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 					ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 				msleep(SI1145_COMMAND_MINSLEEP_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 			if (ret == ((data->rsp_seq + 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 				SI1145_RSP_COUNTER_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 				data->rsp_seq = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 				ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			dev_warn(dev, "unexpected response counter %d instead of %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 				 ret, (data->rsp_seq + 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 					SI1145_RSP_COUNTER_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 			if (ret == SI1145_RSP_INVALID_SETTING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 				dev_warn(dev, "INVALID_SETTING error on command %#02hhx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 					 cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 				/* All overflows are treated identically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 				dev_dbg(dev, "overflow, ret=%d, cmd=%#02hhx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 					ret, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 				ret = -EOVERFLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		/* Force a counter reset next time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 		data->rsp_seq = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	mutex_unlock(&data->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) static int si1145_param_update(struct si1145_data *data, u8 op, u8 param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 			       u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		SI1145_REG_PARAM_WR, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	return si1145_command(data, op | (param & 0x1F));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) static int si1145_param_set(struct si1145_data *data, u8 param, u8 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	return si1145_param_update(data, SI1145_CMD_PARAM_SET, param, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) /* Set param. Returns negative errno or current value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) static int si1145_param_query(struct si1145_data *data, u8 param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	ret = si1145_command(data, SI1145_CMD_PARAM_QUERY | (param & 0x1F));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	return i2c_smbus_read_byte_data(data->client, SI1145_REG_PARAM_RD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) /* Expand 8 bit compressed value to 16 bit, see Silabs AN498 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) static u16 si1145_uncompress(u8 x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	u16 result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	u8 exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	if (x < 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	exponent = (x & 0xf0) >> 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	result = 0x10 | (x & 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	if (exponent >= 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 		return result << (exponent - 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	return result >> (4 - exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) /* Compress 16 bit value to 8 bit, see Silabs AN498 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) static u8 si1145_compress(u16 x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	u32 exponent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	u32 significand = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	u32 tmp = x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	if (x == 0x0000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		return 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	if (x == 0x0001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 		return 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 		tmp >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 		exponent += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 		if (tmp == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	if (exponent < 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 		significand = x << (4 - exponent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		return (exponent << 4) | (significand & 0xF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	significand = x >> (exponent - 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	if (significand & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		significand += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		if (significand & 0x0040) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 			exponent += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 			significand >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	return (exponent << 4) | ((significand >> 1) & 0xF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) /* Write meas_rate in hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) static int si1145_set_meas_rate(struct si1145_data *data, int interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	if (data->part_info->uncompressed_meas_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		return i2c_smbus_write_word_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 			SI1145_REG_MEAS_RATE, interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		return i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			SI1145_REG_MEAS_RATE, interval);
^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 int si1145_read_samp_freq(struct si1145_data *data, int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	*val = 32000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	if (data->part_info->uncompressed_meas_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		*val2 = data->meas_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		*val2 = si1145_uncompress(data->meas_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return IIO_VAL_FRACTIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) /* Set the samp freq in driver private data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) static int si1145_store_samp_freq(struct si1145_data *data, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	int meas_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	if (val <= 0 || val > 32000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	meas_rate = 32000 / val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	if (data->autonomous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 		ret = si1145_set_meas_rate(data, meas_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	if (data->part_info->uncompressed_meas_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		data->meas_rate = meas_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		data->meas_rate = si1145_compress(meas_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) static irqreturn_t si1145_trigger_handler(int irq, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	struct iio_poll_func *pf = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	int i, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	u8 irq_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	if (!data->autonomous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 		ret = si1145_command(data, SI1145_CMD_PSALS_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		if (ret < 0 && ret != -EOVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		irq_status = ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 				SI1145_REG_IRQ_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		if (!(irq_status & SI1145_MASK_ALL_IE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	for_each_set_bit(i, indio_dev->active_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 		indio_dev->masklength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		int run = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		while (i + run < indio_dev->masklength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			if (!test_bit(i + run, indio_dev->active_scan_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			if (indio_dev->channels[i + run].address !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 				indio_dev->channels[i].address + 2 * run)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 			run++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		ret = i2c_smbus_read_i2c_block_data_or_emulated(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 				data->client, indio_dev->channels[i].address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				sizeof(u16) * run, &data->buffer[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		j += run * sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		i += run - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	if (data->autonomous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 				SI1145_REG_IRQ_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 				irq_status & SI1145_MASK_ALL_IE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) static int si1145_set_chlist(struct iio_dev *indio_dev, unsigned long scan_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	u8 reg = 0, mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	/* channel list already set, no need to reprogram */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	if (data->scan_mask == scan_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	for_each_set_bit(i, &scan_mask, indio_dev->masklength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		switch (indio_dev->channels[i].address) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		case SI1145_REG_ALSVIS_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 			reg |= SI1145_CHLIST_EN_ALSVIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 		case SI1145_REG_ALSIR_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 			reg |= SI1145_CHLIST_EN_ALSIR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		case SI1145_REG_PS1_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 			reg |= SI1145_CHLIST_EN_PS1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		case SI1145_REG_PS2_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			reg |= SI1145_CHLIST_EN_PS2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		case SI1145_REG_PS3_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 			reg |= SI1145_CHLIST_EN_PS3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		case SI1145_REG_AUX_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 			switch (indio_dev->channels[i].type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 			case IIO_UVINDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 				reg |= SI1145_CHLIST_EN_UV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 				reg |= SI1145_CHLIST_EN_AUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 				if (indio_dev->channels[i].type == IIO_TEMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 					mux = SI1145_MUX_TEMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 					mux = SI1145_MUX_VDD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 				ret = si1145_param_set(data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 					SI1145_PARAM_AUX_ADC_MUX, mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 				if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 					return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	data->scan_mask = scan_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	ret = si1145_param_set(data, SI1145_PARAM_CHLIST, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static int si1145_measure(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 			  struct iio_chan_spec const *chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	ret = si1145_set_chlist(indio_dev, BIT(chan->scan_index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	if (ret < 0)
^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) 	cmd = (chan->type == IIO_PROXIMITY) ? SI1145_CMD_PS_FORCE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		SI1145_CMD_ALS_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	ret = si1145_command(data, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	if (ret < 0 && ret != -EOVERFLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	return i2c_smbus_read_word_data(data->client, chan->address);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583)  * Conversion between iio scale and ADC_GAIN values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584)  * These could be further adjusted but proximity/intensity are dimensionless
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) static const int si1145_proximity_scale_available[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	128, 64, 32, 16, 8, 4};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) static const int si1145_intensity_scale_available[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	128, 64, 32, 16, 8, 4, 2, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) static IIO_CONST_ATTR(in_proximity_scale_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	"128 64 32 16 8 4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) static IIO_CONST_ATTR(in_intensity_scale_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	"128 64 32 16 8 4 2 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) static IIO_CONST_ATTR(in_intensity_ir_scale_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	"128 64 32 16 8 4 2 1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) static int si1145_scale_from_adcgain(int regval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	return 128 >> regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) static int si1145_proximity_adcgain_from_scale(int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	val = find_closest_descending(val, si1145_proximity_scale_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 				ARRAY_SIZE(si1145_proximity_scale_available));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	if (val < 0 || val > 5 || val2 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) static int si1145_intensity_adcgain_from_scale(int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	val = find_closest_descending(val, si1145_intensity_scale_available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 				ARRAY_SIZE(si1145_intensity_scale_available));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	if (val < 0 || val > 7 || val2 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	return val;
^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 int si1145_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 				struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 				int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		case IIO_VOLTAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		case IIO_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		case IIO_UVINDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 			ret = si1145_measure(indio_dev, chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			*val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		case IIO_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				SI1145_PS_LED_REG(chan->channel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 			*val = (ret >> SI1145_PS_LED_SHIFT(chan->channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 				& 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			reg = SI1145_PARAM_PS_ADC_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			if (chan->channel2 == IIO_MOD_LIGHT_IR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				reg = SI1145_PARAM_ALSIR_ADC_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 				reg = SI1145_PARAM_ALSVIS_ADC_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		case IIO_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			*val = 28;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			*val2 = 571429;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		case IIO_UVINDEX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			*val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			*val2 = 10000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		ret = si1145_param_query(data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		*val = si1145_scale_from_adcgain(ret & 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	case IIO_CHAN_INFO_OFFSET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		case IIO_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 			 * -ADC offset - ADC counts @ 25°C -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			 *   35 * ADC counts / °C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			*val = -256 - 11136 + 25 * 35;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 			 * All ADC measurements have are by default offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			 * by -256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			 * See AN498 5.6.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 			ret = si1145_param_query(data, SI1145_PARAM_ADC_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			*val = -si1145_uncompress(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		return si1145_read_samp_freq(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) static int si1145_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 			       struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			       int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	u8 reg1, reg2, shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 			val = si1145_proximity_adcgain_from_scale(val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 			if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 				return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			reg1 = SI1145_PARAM_PS_ADC_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			reg2 = SI1145_PARAM_PS_ADC_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			val = si1145_intensity_adcgain_from_scale(val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 				return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 			if (chan->channel2 == IIO_MOD_LIGHT_IR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 				reg1 = SI1145_PARAM_ALSIR_ADC_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 				reg2 = SI1145_PARAM_ALSIR_ADC_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 				reg1 = SI1145_PARAM_ALSVIS_ADC_GAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 				reg2 = SI1145_PARAM_ALSVIS_ADC_COUNTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		ret = si1145_param_set(data, reg1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 		/* Set recovery period to one's complement of gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		ret = si1145_param_set(data, reg2, (~val & 0x07) << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		if (chan->type != IIO_CURRENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		if (val < 0 || val > 15 || val2 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		reg1 = SI1145_PS_LED_REG(chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		shift = SI1145_PS_LED_SHIFT(chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 		ret = i2c_smbus_read_byte_data(data->client, reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		ret = i2c_smbus_write_byte_data(data->client, reg1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 			(ret & ~(0x0f << shift)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			((val & 0x0f) << shift));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		return si1145_store_samp_freq(data, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) #define SI1145_ST { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	.sign = 'u', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	.realbits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	.storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	.endianness = IIO_LE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) #define SI1145_INTENSITY_CHANNEL(_si) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	.type = IIO_INTENSITY, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 			      BIT(IIO_CHAN_INFO_OFFSET) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 			      BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	.scan_type = SI1145_ST, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	.scan_index = _si, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	.address = SI1145_REG_ALSVIS_DATA, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) #define SI1145_INTENSITY_IR_CHANNEL(_si) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 	.type = IIO_INTENSITY, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			      BIT(IIO_CHAN_INFO_OFFSET) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 			      BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	.modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	.channel2 = IIO_MOD_LIGHT_IR, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	.scan_type = SI1145_ST, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	.scan_index = _si, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	.address = SI1145_REG_ALSIR_DATA, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) #define SI1145_TEMP_CHANNEL(_si) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	.type = IIO_TEMP, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			      BIT(IIO_CHAN_INFO_OFFSET) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			      BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	.scan_type = SI1145_ST, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	.scan_index = _si, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	.address = SI1145_REG_AUX_DATA, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) #define SI1145_UV_CHANNEL(_si) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	.type = IIO_UVINDEX, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 			      BIT(IIO_CHAN_INFO_SCALE), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	.scan_type = SI1145_ST, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	.scan_index = _si, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	.address = SI1145_REG_AUX_DATA, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) #define SI1145_PROXIMITY_CHANNEL(_si, _ch) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	.type = IIO_PROXIMITY, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	.indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	.channel = _ch, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 				    BIT(IIO_CHAN_INFO_OFFSET), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	.scan_type = SI1145_ST, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	.scan_index = _si, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	.address = SI1145_REG_PS1_DATA + _ch * 2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) #define SI1145_VOLTAGE_CHANNEL(_si) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	.type = IIO_VOLTAGE, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	.scan_type = SI1145_ST, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	.scan_index = _si, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	.address = SI1145_REG_AUX_DATA, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) #define SI1145_CURRENT_CHANNEL(_ch) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	.type = IIO_CURRENT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	.indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	.channel = _ch, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	.output = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	.scan_index = -1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) static const struct iio_chan_spec si1132_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	SI1145_TEMP_CHANNEL(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	SI1145_VOLTAGE_CHANNEL(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	SI1145_UV_CHANNEL(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	IIO_CHAN_SOFT_TIMESTAMP(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) static const struct iio_chan_spec si1141_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 	SI1145_PROXIMITY_CHANNEL(2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	SI1145_TEMP_CHANNEL(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	SI1145_VOLTAGE_CHANNEL(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	IIO_CHAN_SOFT_TIMESTAMP(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	SI1145_CURRENT_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) static const struct iio_chan_spec si1142_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	SI1145_PROXIMITY_CHANNEL(2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	SI1145_PROXIMITY_CHANNEL(3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	SI1145_TEMP_CHANNEL(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	SI1145_VOLTAGE_CHANNEL(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	IIO_CHAN_SOFT_TIMESTAMP(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	SI1145_CURRENT_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	SI1145_CURRENT_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) static const struct iio_chan_spec si1143_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	SI1145_PROXIMITY_CHANNEL(2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	SI1145_PROXIMITY_CHANNEL(3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	SI1145_PROXIMITY_CHANNEL(4, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	SI1145_TEMP_CHANNEL(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	SI1145_VOLTAGE_CHANNEL(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	IIO_CHAN_SOFT_TIMESTAMP(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	SI1145_CURRENT_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	SI1145_CURRENT_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	SI1145_CURRENT_CHANNEL(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) static const struct iio_chan_spec si1145_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	SI1145_PROXIMITY_CHANNEL(2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	SI1145_TEMP_CHANNEL(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	SI1145_VOLTAGE_CHANNEL(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	SI1145_UV_CHANNEL(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	IIO_CHAN_SOFT_TIMESTAMP(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	SI1145_CURRENT_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) static const struct iio_chan_spec si1146_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	SI1145_TEMP_CHANNEL(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	SI1145_VOLTAGE_CHANNEL(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	SI1145_UV_CHANNEL(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	SI1145_PROXIMITY_CHANNEL(5, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	SI1145_PROXIMITY_CHANNEL(6, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	IIO_CHAN_SOFT_TIMESTAMP(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	SI1145_CURRENT_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	SI1145_CURRENT_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) static const struct iio_chan_spec si1147_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	SI1145_INTENSITY_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	SI1145_INTENSITY_IR_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	SI1145_PROXIMITY_CHANNEL(2, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	SI1145_PROXIMITY_CHANNEL(3, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	SI1145_PROXIMITY_CHANNEL(4, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	SI1145_TEMP_CHANNEL(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	SI1145_VOLTAGE_CHANNEL(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	SI1145_UV_CHANNEL(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	IIO_CHAN_SOFT_TIMESTAMP(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	SI1145_CURRENT_CHANNEL(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	SI1145_CURRENT_CHANNEL(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	SI1145_CURRENT_CHANNEL(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) static struct attribute *si1132_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	&iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) static struct attribute *si114x_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	&iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	&iio_const_attr_in_proximity_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) static const struct attribute_group si1132_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	.attrs = si1132_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) static const struct attribute_group si114x_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	.attrs = si114x_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) static const struct iio_info si1132_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	.read_raw = si1145_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	.write_raw = si1145_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	.attrs = &si1132_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) static const struct iio_info si114x_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	.read_raw = si1145_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	.write_raw = si1145_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	.attrs = &si114x_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) #define SI1145_PART(id, iio_info, chans, leds, uncompressed_meas_rate) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	{id, iio_info, chans, ARRAY_SIZE(chans), leds, uncompressed_meas_rate}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static const struct si1145_part_info si1145_part_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	[SI1132] = SI1145_PART(0x32, &si1132_info, si1132_channels, 0, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	[SI1141] = SI1145_PART(0x41, &si114x_info, si1141_channels, 1, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	[SI1142] = SI1145_PART(0x42, &si114x_info, si1142_channels, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	[SI1143] = SI1145_PART(0x43, &si114x_info, si1143_channels, 3, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	[SI1145] = SI1145_PART(0x45, &si114x_info, si1145_channels, 1, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	[SI1146] = SI1145_PART(0x46, &si114x_info, si1146_channels, 2, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	[SI1147] = SI1145_PART(0x47, &si114x_info, si1147_channels, 3, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) static int si1145_initialize(struct si1145_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	ret = i2c_smbus_write_byte_data(client, SI1145_REG_COMMAND,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 					SI1145_CMD_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	msleep(SI1145_COMMAND_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	/* Hardware key, magic value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	ret = i2c_smbus_write_byte_data(client, SI1145_REG_HW_KEY, 0x17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	msleep(SI1145_COMMAND_TIMEOUT_MS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	/* Turn off autonomous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	ret = si1145_set_meas_rate(data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	/* Initialize sampling freq to 10 Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	ret = si1145_store_samp_freq(data, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	/* Set LED currents to 45 mA; have 4 bits, see Table 2 in datasheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	switch (data->part_info->num_leds) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		ret = i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 						SI1145_REG_PS_LED3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 						SI1145_LED_CURRENT_45mA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		ret = i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 						SI1145_REG_PS_LED21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 						(SI1145_LED_CURRENT_45mA << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 						SI1145_LED_CURRENT_45mA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		ret = i2c_smbus_write_byte_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 						SI1145_REG_PS_LED21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 						SI1145_LED_CURRENT_45mA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	/* Set normal proximity measurement mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 			       SI1145_PS_ADC_MODE_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_GAIN, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	/* ADC_COUNTER should be one complement of ADC_GAIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_COUNTER, 0x06 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	/* Set ALS visible measurement mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			       SI1145_ADC_MISC_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_GAIN, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 			       0x04 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	/* Set ALS IR measurement mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 			       SI1145_ADC_MISC_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_GAIN, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_COUNTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 			       0x06 << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	 * Initialize UCOEF to default values in datasheet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	 * These registers are normally zero on reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	if (data->part_info == &si1145_part_info[SI1132] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		data->part_info == &si1145_part_info[SI1145] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		data->part_info == &si1145_part_info[SI1146] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 		data->part_info == &si1145_part_info[SI1147]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 						SI1145_REG_UCOEF1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 						SI1145_UCOEF1_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 				SI1145_REG_UCOEF2, SI1145_UCOEF2_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 				SI1145_REG_UCOEF3, SI1145_UCOEF3_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 				SI1145_REG_UCOEF4, SI1145_UCOEF4_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  * Program the channels we want to measure with CMD_PSALS_AUTO. No need for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)  * _postdisable as we stop with CMD_PSALS_PAUSE; single measurement (direct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)  * mode reprograms the channels list anyway...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static int si1145_buffer_preenable(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	ret = si1145_set_chlist(indio_dev, *indio_dev->active_scan_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) static bool si1145_validate_scan_mask(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 			       const unsigned long *scan_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	unsigned int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	/* Check that at most one AUX channel is enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	for_each_set_bit(i, scan_mask, data->part_info->num_channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		if (indio_dev->channels[i].address == SI1145_REG_AUX_DATA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	return count <= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) static const struct iio_buffer_setup_ops si1145_buffer_setup_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	.preenable = si1145_buffer_preenable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	.validate_scan_mask = si1145_validate_scan_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)  * si1145_trigger_set_state() - Set trigger state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)  * When not using triggers interrupts are disabled and measurement rate is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)  * set to zero in order to minimize power consumption.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static int si1145_trigger_set_state(struct iio_trigger *trig, bool state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	int err = 0, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	mutex_lock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		data->autonomous = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		err = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 				SI1145_REG_INT_CFG, SI1145_INT_CFG_OE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 			goto disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		err = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 				SI1145_REG_IRQ_ENABLE, SI1145_MASK_ALL_IE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 			goto disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		err = si1145_set_meas_rate(data, data->meas_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 			goto disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		err = si1145_command(data, SI1145_CMD_PSALS_AUTO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			goto disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		/* Disable as much as possible skipping errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		ret = si1145_command(data, SI1145_CMD_PSALS_PAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		if (ret < 0 && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 			err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		ret = si1145_set_meas_rate(data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		if (ret < 0 && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 			err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 						SI1145_REG_IRQ_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		if (ret < 0 && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 			err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		ret = i2c_smbus_write_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 						SI1145_REG_INT_CFG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		if (ret < 0 && !err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 			err = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		data->autonomous = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	mutex_unlock(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) static const struct iio_trigger_ops si1145_trigger_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	.set_trigger_state = si1145_trigger_set_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) static int si1145_probe_trigger(struct iio_dev *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	struct si1145_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	struct i2c_client *client = data->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	struct iio_trigger *trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	trig = devm_iio_trigger_alloc(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 			"%s-dev%d", indio_dev->name, indio_dev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	if (!trig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	trig->dev.parent = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	trig->ops = &si1145_trigger_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	iio_trigger_set_drvdata(trig, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	ret = devm_request_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 			  iio_trigger_generic_data_rdy_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			  IRQF_TRIGGER_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 			  "si1145_irq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 			  trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 		dev_err(&client->dev, "irq request failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	ret = devm_iio_trigger_register(&client->dev, trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	data->trig = trig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	indio_dev->trig = iio_trigger_get(data->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static int si1145_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	struct si1145_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	u8 part_id, rev_id, seq_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	data->part_info = &si1145_part_info[id->driver_data];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	part_id = ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 						 SI1145_REG_PART_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	rev_id = ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 						SI1145_REG_REV_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	seq_id = ret = i2c_smbus_read_byte_data(data->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 						SI1145_REG_SEQ_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	dev_info(&client->dev, "device ID part %#02hhx rev %#02hhx seq %#02hhx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 			part_id, rev_id, seq_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	if (part_id != data->part_info->part) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 		dev_err(&client->dev, "part ID mismatch got %#02hhx, expected %#02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 				part_id, data->part_info->part);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	indio_dev->name = id->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	indio_dev->channels = data->part_info->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	indio_dev->num_channels = data->part_info->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	indio_dev->info = data->part_info->iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	mutex_init(&data->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	mutex_init(&data->cmdlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	ret = si1145_initialize(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	ret = devm_iio_triggered_buffer_setup(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 		indio_dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 		si1145_trigger_handler, &si1145_buffer_setup_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	if (client->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		ret = si1145_probe_trigger(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		dev_info(&client->dev, "no irq, using polling\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	return devm_iio_device_register(&client->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) static const struct i2c_device_id si1145_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	{ "si1132", SI1132 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	{ "si1141", SI1141 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	{ "si1142", SI1142 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	{ "si1143", SI1143 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	{ "si1145", SI1145 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	{ "si1146", SI1146 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	{ "si1147", SI1147 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) MODULE_DEVICE_TABLE(i2c, si1145_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static struct i2c_driver si1145_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 		.name   = "si1145",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	.probe  = si1145_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	.id_table = si1145_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) module_i2c_driver(si1145_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) MODULE_DESCRIPTION("Silabs SI1132 and SI1141/2/3/5/6/7 proximity, ambient light and UV index sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) MODULE_LICENSE("GPL");