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)  * ltr501.c - Support for Lite-On LTR501 ambient light and proximity sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright 2014 Peter Meerwald <pmeerw@pmeerw.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * 7-bit I2C slave address 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  * TODO: IR LED characteristics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <linux/iio/trigger_consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/iio/triggered_buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define LTR501_DRV_NAME "ltr501"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define LTR501_ALS_CONTR 0x80 /* ALS operation mode, SW reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define LTR501_PS_CONTR 0x81 /* PS operation mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define LTR501_PS_MEAS_RATE 0x84 /* measurement rate*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define LTR501_ALS_MEAS_RATE 0x85 /* ALS integ time, measurement rate*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define LTR501_PART_ID 0x86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define LTR501_MANUFAC_ID 0x87
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define LTR501_ALS_DATA1 0x88 /* 16-bit, little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define LTR501_ALS_DATA1_UPPER 0x89 /* upper 8 bits of LTR501_ALS_DATA1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define LTR501_ALS_DATA0 0x8a /* 16-bit, little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define LTR501_ALS_DATA0_UPPER 0x8b /* upper 8 bits of LTR501_ALS_DATA0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define LTR501_ALS_PS_STATUS 0x8c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define LTR501_PS_DATA 0x8d /* 16-bit, little endian */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define LTR501_PS_DATA_UPPER 0x8e /* upper 8 bits of LTR501_PS_DATA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define LTR501_INTR 0x8f /* output mode, polarity, mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define LTR501_PS_THRESH_UP 0x90 /* 11 bit, ps upper threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define LTR501_PS_THRESH_LOW 0x92 /* 11 bit, ps lower threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define LTR501_ALS_THRESH_UP 0x97 /* 16 bit, ALS upper threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define LTR501_ALS_THRESH_LOW 0x99 /* 16 bit, ALS lower threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define LTR501_INTR_PRST 0x9e /* ps thresh, als thresh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define LTR501_MAX_REG 0x9f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define LTR501_ALS_CONTR_SW_RESET BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define LTR501_CONTR_PS_GAIN_MASK (BIT(3) | BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define LTR501_CONTR_PS_GAIN_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define LTR501_CONTR_ALS_GAIN_MASK BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define LTR501_CONTR_ACTIVE BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define LTR501_STATUS_ALS_INTR BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define LTR501_STATUS_ALS_RDY BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define LTR501_STATUS_PS_INTR BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define LTR501_STATUS_PS_RDY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define LTR501_PS_DATA_MASK 0x7ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define LTR501_PS_THRESH_MASK 0x7ff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define LTR501_ALS_THRESH_MASK 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define LTR501_ALS_DEF_PERIOD 500000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define LTR501_PS_DEF_PERIOD 100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define LTR501_REGMAP_NAME "ltr501_regmap"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define LTR501_LUX_CONV(vis_coeff, vis_data, ir_coeff, ir_data) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 			((vis_coeff * vis_data) - (ir_coeff * ir_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) static const int int_time_mapping[] = {100000, 50000, 200000, 400000};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) static const struct reg_field reg_field_it =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 				REG_FIELD(LTR501_ALS_MEAS_RATE, 3, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) static const struct reg_field reg_field_als_intr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 				REG_FIELD(LTR501_INTR, 1, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) static const struct reg_field reg_field_ps_intr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 				REG_FIELD(LTR501_INTR, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) static const struct reg_field reg_field_als_rate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 				REG_FIELD(LTR501_ALS_MEAS_RATE, 0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) static const struct reg_field reg_field_ps_rate =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 				REG_FIELD(LTR501_PS_MEAS_RATE, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) static const struct reg_field reg_field_als_prst =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 				REG_FIELD(LTR501_INTR_PRST, 0, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static const struct reg_field reg_field_ps_prst =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 				REG_FIELD(LTR501_INTR_PRST, 4, 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) struct ltr501_samp_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	int freq_val;  /* repetition frequency in micro HZ*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	int time_val; /* repetition rate in micro seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define LTR501_RESERVED_GAIN -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	ltr501 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	ltr559,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	ltr301,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) struct ltr501_gain {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	int scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	int uscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) static const struct ltr501_gain ltr501_als_gain_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	{1, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	{0, 5000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) static const struct ltr501_gain ltr559_als_gain_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	{1, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	{0, 500000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	{0, 250000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	{0, 125000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	{LTR501_RESERVED_GAIN, LTR501_RESERVED_GAIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	{LTR501_RESERVED_GAIN, LTR501_RESERVED_GAIN},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	{0, 20000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	{0, 10000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static const struct ltr501_gain ltr501_ps_gain_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	{1, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	{0, 250000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	{0, 125000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	{0, 62500},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) static const struct ltr501_gain ltr559_ps_gain_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	{0, 62500}, /* x16 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	{0, 31250}, /* x32 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	{0, 15625}, /* bits X1 are for x64 gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	{0, 15624},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) struct ltr501_chip_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	u8 partid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	const struct ltr501_gain *als_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	int als_gain_tbl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	const struct ltr501_gain *ps_gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	int ps_gain_tbl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	u8 als_mode_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	u8 als_gain_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	u8 als_gain_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	struct iio_chan_spec const *channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	const int no_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	const struct iio_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	const struct iio_info *info_no_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) struct ltr501_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	struct mutex lock_als, lock_ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	struct ltr501_chip_info *chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 	u8 als_contr, ps_contr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	int als_period, ps_period; /* period in micro seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	struct regmap_field *reg_it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	struct regmap_field *reg_als_intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	struct regmap_field *reg_ps_intr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	struct regmap_field *reg_als_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	struct regmap_field *reg_ps_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	struct regmap_field *reg_als_prst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	struct regmap_field *reg_ps_prst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) static const struct ltr501_samp_table ltr501_als_samp_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 			{20000000, 50000}, {10000000, 100000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			{5000000, 200000}, {2000000, 500000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 			{1000000, 1000000}, {500000, 2000000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 			{500000, 2000000}, {500000, 2000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) static const struct ltr501_samp_table ltr501_ps_samp_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			{20000000, 50000}, {14285714, 70000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 			{10000000, 100000}, {5000000, 200000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 			{2000000, 500000}, {1000000, 1000000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 			{500000, 2000000}, {500000, 2000000},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 			{500000, 2000000}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) static int ltr501_match_samp_freq(const struct ltr501_samp_table *tab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 					   int len, int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	int i, freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	freq = val * 1000000 + val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	for (i = 0; i < len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 		if (tab[i].freq_val == freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) static int ltr501_als_read_samp_freq(const struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 				     int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	ret = regmap_field_read(data->reg_als_rate, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	if (i < 0 || i >= ARRAY_SIZE(ltr501_als_samp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	*val = ltr501_als_samp_table[i].freq_val / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	*val2 = ltr501_als_samp_table[i].freq_val % 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) static int ltr501_ps_read_samp_freq(const struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 				    int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	ret = regmap_field_read(data->reg_ps_rate, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	if (i < 0 || i >= ARRAY_SIZE(ltr501_ps_samp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	*val = ltr501_ps_samp_table[i].freq_val / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	*val2 = ltr501_ps_samp_table[i].freq_val % 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) static int ltr501_als_write_samp_freq(struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 				      int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	i = ltr501_match_samp_freq(ltr501_als_samp_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 				   ARRAY_SIZE(ltr501_als_samp_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 				   val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	ret = regmap_field_write(data->reg_als_rate, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) static int ltr501_ps_write_samp_freq(struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 				     int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	i = ltr501_match_samp_freq(ltr501_ps_samp_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 				   ARRAY_SIZE(ltr501_ps_samp_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 				   val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	if (i < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	mutex_lock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	ret = regmap_field_write(data->reg_ps_rate, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	mutex_unlock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) static int ltr501_als_read_samp_period(const struct ltr501_data *data, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	ret = regmap_field_read(data->reg_als_rate, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	if (i < 0 || i >= ARRAY_SIZE(ltr501_als_samp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	*val = ltr501_als_samp_table[i].time_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) static int ltr501_ps_read_samp_period(const struct ltr501_data *data, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	ret = regmap_field_read(data->reg_ps_rate, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (i < 0 || i >= ARRAY_SIZE(ltr501_ps_samp_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	*val = ltr501_ps_samp_table[i].time_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	return IIO_VAL_INT;
^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) /* IR and visible spectrum coeff's are given in data sheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) static unsigned long ltr501_calculate_lux(u16 vis_data, u16 ir_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	unsigned long ratio, lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	if (vis_data == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	/* multiply numerator by 100 to avoid handling ratio < 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	ratio = DIV_ROUND_UP(ir_data * 100, ir_data + vis_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (ratio < 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		lux = LTR501_LUX_CONV(1774, vis_data, -1105, ir_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	else if (ratio >= 45 && ratio < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		lux = LTR501_LUX_CONV(3772, vis_data, 1336, ir_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	else if (ratio >= 64 && ratio < 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		lux = LTR501_LUX_CONV(1690, vis_data, 169, ir_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		lux = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	return lux / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) static int ltr501_drdy(const struct ltr501_data *data, u8 drdy_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	int tries = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	int ret, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	while (tries--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 		ret = regmap_read(data->regmap, LTR501_ALS_PS_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 		if ((status & drdy_mask) == drdy_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		msleep(25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	dev_err(&data->client->dev, "ltr501_drdy() failed, data not ready\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) static int ltr501_set_it_time(struct ltr501_data *data, int it)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	int ret, i, index = -1, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	for (i = 0; i < ARRAY_SIZE(int_time_mapping); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 		if (int_time_mapping[i] == it) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 			index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	/* Make sure integ time index is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	if (index < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	ret = regmap_read(data->regmap, LTR501_ALS_CONTR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	if (status & LTR501_CONTR_ALS_GAIN_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		 * 200 ms and 400 ms integ time can only be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		 * used in dynamic range 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		if (index > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 		/* 50 ms integ time can only be used in dynamic range 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		if (index == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	return regmap_field_write(data->reg_it, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) /* read int time in micro seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) static int ltr501_read_it_time(const struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 			       int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	int ret, index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	ret = regmap_field_read(data->reg_it, &index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	/* Make sure integ time index is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	if (index < 0 || index >= ARRAY_SIZE(int_time_mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	*val2 = int_time_mapping[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	*val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) static int ltr501_read_als(const struct ltr501_data *data, __le16 buf[2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	ret = ltr501_drdy(data, LTR501_STATUS_ALS_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	/* always read both ALS channels in given order */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	return regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 				buf, 2 * sizeof(__le16));
^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 ltr501_read_ps(const struct ltr501_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	__le16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	ret = ltr501_drdy(data, LTR501_STATUS_PS_RDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	ret = regmap_bulk_read(data->regmap, LTR501_PS_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 			       &status, sizeof(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	return le16_to_cpu(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) static int ltr501_read_intr_prst(const struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				 enum iio_chan_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				 int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	int ret, samp_period, prst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		ret = regmap_field_read(data->reg_als_prst, &prst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		ret = ltr501_als_read_samp_period(data, &samp_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		*val2 = samp_period * prst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		ret = regmap_field_read(data->reg_ps_prst, &prst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		ret = ltr501_ps_read_samp_period(data, &samp_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		*val2 = samp_period * prst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int ltr501_write_intr_prst(struct ltr501_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 				  enum iio_chan_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				  int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	int ret, samp_period, new_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	unsigned long period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	if (val < 0 || val2 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	/* period in microseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	period = ((val * 1000000) + val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		ret = ltr501_als_read_samp_period(data, &samp_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		/* period should be atleast equal to sampling period */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		if (period < samp_period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 		new_val = DIV_ROUND_UP(period, samp_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		if (new_val < 0 || new_val > 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 		mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		ret = regmap_field_write(data->reg_als_prst, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			data->als_period = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		ret = ltr501_ps_read_samp_period(data, &samp_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 		/* period should be atleast equal to rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		if (period < samp_period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		new_val = DIV_ROUND_UP(period, samp_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 		if (new_val < 0 || new_val > 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		mutex_lock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		ret = regmap_field_write(data->reg_ps_prst, new_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		mutex_unlock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			data->ps_period = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) static const struct iio_event_spec ltr501_als_event_spec[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		.dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		.dir = IIO_EV_DIR_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		.dir = IIO_EV_DIR_EITHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 				 BIT(IIO_EV_INFO_PERIOD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) static const struct iio_event_spec ltr501_pxs_event_spec[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		.dir = IIO_EV_DIR_RISING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 		.dir = IIO_EV_DIR_FALLING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	}, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		.dir = IIO_EV_DIR_EITHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 				 BIT(IIO_EV_INFO_PERIOD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) #define LTR501_INTENSITY_CHANNEL(_idx, _addr, _mod, _shared, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 				 _evspec, _evsize) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	.type = IIO_INTENSITY, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	.modified = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	.address = (_addr), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	.channel2 = (_mod), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	.info_mask_shared_by_type = (_shared), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	.scan_index = (_idx), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	.scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		.sign = 'u', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		.realbits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		.storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		.endianness = IIO_CPU, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	.event_spec = _evspec,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	.num_event_specs = _evsize,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) #define LTR501_LIGHT_CHANNEL() { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	.type = IIO_LIGHT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	.scan_index = -1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) static const struct iio_chan_spec ltr501_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	LTR501_LIGHT_CHANNEL(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	LTR501_INTENSITY_CHANNEL(0, LTR501_ALS_DATA0, IIO_MOD_LIGHT_BOTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 				 ltr501_als_event_spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 				 ARRAY_SIZE(ltr501_als_event_spec)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	LTR501_INTENSITY_CHANNEL(1, LTR501_ALS_DATA1, IIO_MOD_LIGHT_IR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 				 BIT(IIO_CHAN_INFO_SCALE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 				 BIT(IIO_CHAN_INFO_INT_TIME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 				 BIT(IIO_CHAN_INFO_SAMP_FREQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 				 NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 		.type = IIO_PROXIMITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		.address = LTR501_PS_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 			BIT(IIO_CHAN_INFO_SCALE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 		.scan_index = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		.scan_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 			.sign = 'u',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			.realbits = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 			.storagebits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 			.endianness = IIO_CPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		.event_spec = ltr501_pxs_event_spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 		.num_event_specs = ARRAY_SIZE(ltr501_pxs_event_spec),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	IIO_CHAN_SOFT_TIMESTAMP(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) static const struct iio_chan_spec ltr301_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	LTR501_LIGHT_CHANNEL(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	LTR501_INTENSITY_CHANNEL(0, LTR501_ALS_DATA0, IIO_MOD_LIGHT_BOTH, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 				 ltr501_als_event_spec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 				 ARRAY_SIZE(ltr501_als_event_spec)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	LTR501_INTENSITY_CHANNEL(1, LTR501_ALS_DATA1, IIO_MOD_LIGHT_IR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 				 BIT(IIO_CHAN_INFO_SCALE) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 				 BIT(IIO_CHAN_INFO_INT_TIME) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 				 BIT(IIO_CHAN_INFO_SAMP_FREQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 				 NULL, 0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	IIO_CHAN_SOFT_TIMESTAMP(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static int ltr501_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			   struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			   int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	__le16 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		case IIO_LIGHT:
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 			mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 			ret = ltr501_read_als(data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 			mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 			iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 			*val = ltr501_calculate_lux(le16_to_cpu(buf[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 						    le16_to_cpu(buf[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 			ret = ltr501_read_als(data, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 			mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			*val = le16_to_cpu(chan->address == LTR501_ALS_DATA1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 					   buf[0] : buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 			ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 			mutex_lock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 			ret = ltr501_read_ps(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 			mutex_unlock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			*val = ret & LTR501_PS_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 			i = (data->als_contr & data->chip_info->als_gain_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			     >> data->chip_info->als_gain_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			*val = data->chip_info->als_gain[i].scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			*val2 = data->chip_info->als_gain[i].uscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			i = (data->ps_contr & LTR501_CONTR_PS_GAIN_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 				LTR501_CONTR_PS_GAIN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			*val = data->chip_info->ps_gain[i].scale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			*val2 = data->chip_info->ps_gain[i].uscale;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			return IIO_VAL_INT_PLUS_MICRO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	case IIO_CHAN_INFO_INT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			return ltr501_read_it_time(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			return ltr501_als_read_samp_freq(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 			return ltr501_ps_read_samp_freq(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 			return -EINVAL;
^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) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) static int ltr501_get_gain_index(const struct ltr501_gain *gain, int size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				 int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		if (val == gain[i].scale && val2 == gain[i].uscale)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) static int ltr501_write_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			    struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			    int val, int val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	int i, ret, freq_val, freq_val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	struct ltr501_chip_info *info = data->chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	ret = iio_device_claim_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	case IIO_CHAN_INFO_SCALE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			i = ltr501_get_gain_index(info->als_gain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 						  info->als_gain_tbl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 						  val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 			if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 			data->als_contr &= ~info->als_gain_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 			data->als_contr |= i << info->als_gain_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 			ret = regmap_write(data->regmap, LTR501_ALS_CONTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 					   data->als_contr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 			i = ltr501_get_gain_index(info->ps_gain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 						  info->ps_gain_tbl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 						  val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 			if (i < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 			data->ps_contr &= ~LTR501_CONTR_PS_GAIN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			data->ps_contr |= i << LTR501_CONTR_PS_GAIN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 			ret = regmap_write(data->regmap, LTR501_PS_CONTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 					   data->ps_contr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	case IIO_CHAN_INFO_INT_TIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 			if (val != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 			mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 			ret = ltr501_set_it_time(data, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	case IIO_CHAN_INFO_SAMP_FREQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 			ret = ltr501_als_read_samp_freq(data, &freq_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 							&freq_val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 			ret = ltr501_als_write_samp_freq(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 			/* update persistence count when changing frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			ret = ltr501_write_intr_prst(data, chan->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 						     0, data->als_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 				ret = ltr501_als_write_samp_freq(data, freq_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 								 freq_val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 		case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 			ret = ltr501_ps_read_samp_freq(data, &freq_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 						       &freq_val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 			ret = ltr501_ps_write_samp_freq(data, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 			/* update persistence count when changing frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 			ret = ltr501_write_intr_prst(data, chan->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 						     0, data->ps_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 				ret = ltr501_ps_write_samp_freq(data, freq_val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 								freq_val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	iio_device_release_direct_mode(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) static int ltr501_read_thresh(const struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 			      const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 			      enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			      enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			      enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 			      int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	const struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	int ret, thresh_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 		case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 			ret = regmap_bulk_read(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 					       LTR501_ALS_THRESH_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 					       &thresh_data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 			*val = thresh_data & LTR501_ALS_THRESH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			ret = regmap_bulk_read(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 					       LTR501_ALS_THRESH_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 					       &thresh_data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			*val = thresh_data & LTR501_ALS_THRESH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			ret = regmap_bulk_read(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 					       LTR501_PS_THRESH_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 					       &thresh_data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			*val = thresh_data & LTR501_PS_THRESH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			ret = regmap_bulk_read(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 					       LTR501_PS_THRESH_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 					       &thresh_data, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 			*val = thresh_data & LTR501_PS_THRESH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 			return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		return -EINVAL;
^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) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) static int ltr501_write_thresh(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			       const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			       enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 			       enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 			       enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 			       int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 		if (val > LTR501_ALS_THRESH_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 		case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 			mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 			ret = regmap_bulk_write(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 						LTR501_ALS_THRESH_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 						&val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 			mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 			mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 			ret = regmap_bulk_write(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 						LTR501_ALS_THRESH_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 						&val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 			mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		if (val > LTR501_PS_THRESH_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		switch (dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 		case IIO_EV_DIR_RISING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 			mutex_lock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 			ret = regmap_bulk_write(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 						LTR501_PS_THRESH_UP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 						&val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 			mutex_unlock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		case IIO_EV_DIR_FALLING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 			mutex_lock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			ret = regmap_bulk_write(data->regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 						LTR501_PS_THRESH_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 						&val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 			mutex_unlock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	return -EINVAL;
^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 int ltr501_read_event(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			     const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 			     enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 			     enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 			     enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 			     int *val, int *val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	case IIO_EV_INFO_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		return ltr501_read_thresh(indio_dev, chan, type, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 					  info, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	case IIO_EV_INFO_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		ret = ltr501_read_intr_prst(iio_priv(indio_dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 					    chan->type, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		*val = *val2 / 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		*val2 = *val2 % 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int ltr501_write_event(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 			      const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 			      enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			      enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 			      enum iio_event_info info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 			      int val, int val2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	switch (info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	case IIO_EV_INFO_VALUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		if (val2 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		return ltr501_write_thresh(indio_dev, chan, type, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 					   info, val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	case IIO_EV_INFO_PERIOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		return ltr501_write_intr_prst(iio_priv(indio_dev), chan->type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 					      val, val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int ltr501_read_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 				    const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 				    enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 				    enum iio_event_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	int ret, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		ret = regmap_field_read(data->reg_als_intr, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		ret = regmap_field_read(data->reg_ps_intr, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static int ltr501_write_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 				     const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 				     enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 				     enum iio_event_direction dir, int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	/* only 1 and 0 are valid inputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	if (state != 1  && state != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	case IIO_INTENSITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 		mutex_lock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		ret = regmap_field_write(data->reg_als_intr, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		mutex_unlock(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	case IIO_PROXIMITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		mutex_lock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		ret = regmap_field_write(data->reg_ps_intr, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		mutex_unlock(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) static ssize_t ltr501_show_proximity_scale_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 						 struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 						 char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	struct ltr501_data *data = iio_priv(dev_to_iio_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	struct ltr501_chip_info *info = data->chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	ssize_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	for (i = 0; i < info->ps_gain_tbl_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		if (info->ps_gain[i].scale == LTR501_RESERVED_GAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 				 info->ps_gain[i].scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 				 info->ps_gain[i].uscale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	buf[len - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static ssize_t ltr501_show_intensity_scale_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 						 struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 						 char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	struct ltr501_data *data = iio_priv(dev_to_iio_dev(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	struct ltr501_chip_info *info = data->chip_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	ssize_t len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	for (i = 0; i < info->als_gain_tbl_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 		if (info->als_gain[i].scale == LTR501_RESERVED_GAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%06d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				 info->als_gain[i].scale,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 				 info->als_gain[i].uscale);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	buf[len - 1] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) static IIO_CONST_ATTR_INT_TIME_AVAIL("0.05 0.1 0.2 0.4");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("20 10 5 2 1 0.5");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static IIO_DEVICE_ATTR(in_proximity_scale_available, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		       ltr501_show_proximity_scale_avail, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) static IIO_DEVICE_ATTR(in_intensity_scale_available, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 		       ltr501_show_intensity_scale_avail, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) static struct attribute *ltr501_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	&iio_dev_attr_in_proximity_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	&iio_dev_attr_in_intensity_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	&iio_const_attr_integration_time_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static struct attribute *ltr301_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	&iio_dev_attr_in_intensity_scale_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	&iio_const_attr_integration_time_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static const struct attribute_group ltr501_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	.attrs = ltr501_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static const struct attribute_group ltr301_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	.attrs = ltr301_attributes,
^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 const struct iio_info ltr501_info_no_irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	.read_raw = ltr501_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	.write_raw = ltr501_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	.attrs = &ltr501_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) static const struct iio_info ltr501_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	.read_raw = ltr501_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	.write_raw = ltr501_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	.attrs = &ltr501_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 	.read_event_value	= &ltr501_read_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	.write_event_value	= &ltr501_write_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	.read_event_config	= &ltr501_read_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	.write_event_config	= &ltr501_write_event_config,
^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_info ltr301_info_no_irq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	.read_raw = ltr501_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	.write_raw = ltr501_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	.attrs = &ltr301_attribute_group,
^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) static const struct iio_info ltr301_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	.read_raw = ltr501_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	.write_raw = ltr501_write_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	.attrs = &ltr301_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	.read_event_value	= &ltr501_read_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	.write_event_value	= &ltr501_write_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	.read_event_config	= &ltr501_read_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	.write_event_config	= &ltr501_write_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) static struct ltr501_chip_info ltr501_chip_info_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	[ltr501] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		.partid = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 		.als_gain = ltr501_als_gain_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 		.als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		.ps_gain = ltr501_ps_gain_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		.ps_gain_tbl_size = ARRAY_SIZE(ltr501_ps_gain_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 		.als_mode_active = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 		.als_gain_mask = BIT(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		.als_gain_shift = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 		.info = &ltr501_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 		.info_no_irq = &ltr501_info_no_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		.channels = ltr501_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		.no_channels = ARRAY_SIZE(ltr501_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	[ltr559] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		.partid = 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		.als_gain = ltr559_als_gain_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 		.als_gain_tbl_size = ARRAY_SIZE(ltr559_als_gain_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 		.ps_gain = ltr559_ps_gain_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 		.ps_gain_tbl_size = ARRAY_SIZE(ltr559_ps_gain_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) 		.als_mode_active = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 		.als_gain_mask = BIT(2) | BIT(3) | BIT(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 		.als_gain_shift = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 		.info = &ltr501_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		.info_no_irq = &ltr501_info_no_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		.channels = ltr501_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 		.no_channels = ARRAY_SIZE(ltr501_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	[ltr301] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		.partid = 0x08,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 		.als_gain = ltr501_als_gain_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		.als_gain_tbl_size = ARRAY_SIZE(ltr501_als_gain_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		.als_mode_active = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 		.als_gain_mask = BIT(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		.als_gain_shift = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		.info = &ltr301_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 		.info_no_irq = &ltr301_info_no_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		.channels = ltr301_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		.no_channels = ARRAY_SIZE(ltr301_channels),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	},
^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 int ltr501_write_contr(struct ltr501_data *data, u8 als_val, u8 ps_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	ret = regmap_write(data->regmap, LTR501_ALS_CONTR, als_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	return regmap_write(data->regmap, LTR501_PS_CONTR, ps_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) static irqreturn_t ltr501_trigger_handler(int irq, void *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	struct iio_poll_func *pf = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	struct iio_dev *indio_dev = pf->indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 		u16 channels[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 		s64 ts __aligned(8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	} scan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	__le16 als_buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	u8 mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	int j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	int ret, psdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	memset(&scan, 0, sizeof(scan));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	/* figure out which data needs to be ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 	if (test_bit(0, indio_dev->active_scan_mask) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	    test_bit(1, indio_dev->active_scan_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 		mask |= LTR501_STATUS_ALS_RDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	if (test_bit(2, indio_dev->active_scan_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		mask |= LTR501_STATUS_PS_RDY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	ret = ltr501_drdy(data, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	if (mask & LTR501_STATUS_ALS_RDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		ret = regmap_bulk_read(data->regmap, LTR501_ALS_DATA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 				       als_buf, sizeof(als_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 		if (test_bit(0, indio_dev->active_scan_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 			scan.channels[j++] = le16_to_cpu(als_buf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 		if (test_bit(1, indio_dev->active_scan_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			scan.channels[j++] = le16_to_cpu(als_buf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	if (mask & LTR501_STATUS_PS_RDY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 		ret = regmap_bulk_read(data->regmap, LTR501_PS_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 				       &psdata, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		scan.channels[j++] = psdata & LTR501_PS_DATA_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	iio_push_to_buffers_with_timestamp(indio_dev, &scan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 					   iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	iio_trigger_notify_done(indio_dev->trig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) static irqreturn_t ltr501_interrupt_handler(int irq, void *private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	struct iio_dev *indio_dev = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	struct ltr501_data *data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	int ret, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	ret = regmap_read(data->regmap, LTR501_ALS_PS_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		dev_err(&data->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 			"irq read int reg failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	if (status & LTR501_STATUS_ALS_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 		iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 			       IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 						    IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 						    IIO_EV_DIR_EITHER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 			       iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	if (status & LTR501_STATUS_PS_INTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 		iio_push_event(indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 			       IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 						    IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 						    IIO_EV_DIR_EITHER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 			       iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static int ltr501_init(struct ltr501_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	int ret, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	ret = regmap_read(data->regmap, LTR501_ALS_CONTR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	data->als_contr = status | data->chip_info->als_mode_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	ret = regmap_read(data->regmap, LTR501_PS_CONTR, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	data->ps_contr = status | LTR501_CONTR_ACTIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	ret = ltr501_read_intr_prst(data, IIO_INTENSITY, &data->als_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	ret = ltr501_read_intr_prst(data, IIO_PROXIMITY, &data->ps_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	return ltr501_write_contr(data, data->als_contr, data->ps_contr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) static bool ltr501_is_volatile_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	switch (reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	case LTR501_ALS_DATA1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	case LTR501_ALS_DATA1_UPPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	case LTR501_ALS_DATA0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	case LTR501_ALS_DATA0_UPPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	case LTR501_ALS_PS_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	case LTR501_PS_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	case LTR501_PS_DATA_UPPER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) static const struct regmap_config ltr501_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 	.name =  LTR501_REGMAP_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 	.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 	.max_register = LTR501_MAX_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	.cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	.volatile_reg = ltr501_is_volatile_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) static int ltr501_powerdown(struct ltr501_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	return ltr501_write_contr(data, data->als_contr &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 				  ~data->chip_info->als_mode_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 				  data->ps_contr & ~LTR501_CONTR_ACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static const char *ltr501_match_acpi_device(struct device *dev, int *chip_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	const struct acpi_device_id *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) 	id = acpi_match_device(dev->driver->acpi_match_table, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 	if (!id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 	*chip_idx = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	return dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) static int ltr501_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 			const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	struct ltr501_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	int ret, partid, chip_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 	const char *name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	regmap = devm_regmap_init_i2c(client, &ltr501_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 		dev_err(&client->dev, "Regmap initialization failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 		return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	data = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	data->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	data->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	mutex_init(&data->lock_als);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	mutex_init(&data->lock_ps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	data->reg_it = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 					       reg_field_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	if (IS_ERR(data->reg_it)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 		dev_err(&client->dev, "Integ time reg field init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 		return PTR_ERR(data->reg_it);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	data->reg_als_intr = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 						     reg_field_als_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	if (IS_ERR(data->reg_als_intr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		dev_err(&client->dev, "ALS intr mode reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 		return PTR_ERR(data->reg_als_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	data->reg_ps_intr = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 						    reg_field_ps_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	if (IS_ERR(data->reg_ps_intr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		dev_err(&client->dev, "PS intr mode reg field init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		return PTR_ERR(data->reg_ps_intr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	data->reg_als_rate = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 						     reg_field_als_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	if (IS_ERR(data->reg_als_rate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 		dev_err(&client->dev, "ALS samp rate field init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 		return PTR_ERR(data->reg_als_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	data->reg_ps_rate = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 						    reg_field_ps_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	if (IS_ERR(data->reg_ps_rate)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 		dev_err(&client->dev, "PS samp rate field init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 		return PTR_ERR(data->reg_ps_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	data->reg_als_prst = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 						     reg_field_als_prst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	if (IS_ERR(data->reg_als_prst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		dev_err(&client->dev, "ALS prst reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		return PTR_ERR(data->reg_als_prst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	data->reg_ps_prst = devm_regmap_field_alloc(&client->dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 						    reg_field_ps_prst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	if (IS_ERR(data->reg_ps_prst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		dev_err(&client->dev, "PS prst reg field init failed.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		return PTR_ERR(data->reg_ps_prst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	ret = regmap_read(data->regmap, LTR501_PART_ID, &partid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	if (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		name = id->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 		chip_idx = id->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	} else  if (ACPI_HANDLE(&client->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		name = ltr501_match_acpi_device(&client->dev, &chip_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	data->chip_info = &ltr501_chip_info_tbl[chip_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	if ((partid >> 4) != data->chip_info->partid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 	indio_dev->info = data->chip_info->info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 	indio_dev->channels = data->chip_info->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	indio_dev->num_channels = data->chip_info->no_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	indio_dev->name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 	ret = ltr501_init(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	if (client->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 		ret = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 						NULL, ltr501_interrupt_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 						IRQF_TRIGGER_FALLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 						IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 						"ltr501_thresh_event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 						indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 			dev_err(&client->dev, "request irq (%d) failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 				client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 		indio_dev->info = data->chip_info->info_no_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 					 ltr501_trigger_handler, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 		goto powerdown_on_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 	ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 		goto error_unreg_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) error_unreg_buffer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) powerdown_on_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	ltr501_powerdown(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) static int ltr501_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	iio_triggered_buffer_cleanup(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 	ltr501_powerdown(iio_priv(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) static int ltr501_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	struct ltr501_data *data = iio_priv(i2c_get_clientdata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 					    to_i2c_client(dev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 	return ltr501_powerdown(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) static int ltr501_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 	struct ltr501_data *data = iio_priv(i2c_get_clientdata(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 					    to_i2c_client(dev)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	return ltr501_write_contr(data, data->als_contr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 		data->ps_contr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) static SIMPLE_DEV_PM_OPS(ltr501_pm_ops, ltr501_suspend, ltr501_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static const struct acpi_device_id ltr_acpi_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	{"LTER0501", ltr501},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	{"LTER0559", ltr559},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	{"LTER0301", ltr301},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) MODULE_DEVICE_TABLE(acpi, ltr_acpi_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) static const struct i2c_device_id ltr501_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	{ "ltr501", ltr501},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	{ "ltr559", ltr559},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	{ "ltr301", ltr301},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) MODULE_DEVICE_TABLE(i2c, ltr501_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static struct i2c_driver ltr501_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 		.name   = LTR501_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		.pm	= &ltr501_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 		.acpi_match_table = ACPI_PTR(ltr_acpi_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	.probe  = ltr501_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	.remove	= ltr501_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	.id_table = ltr501_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) module_i2c_driver(ltr501_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) MODULE_DESCRIPTION("Lite-On LTR501 ambient light and proximity sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) MODULE_LICENSE("GPL");