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)  * This file is part of the APDS990x sensor driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * Chip is combined proximity and ambient light sensor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/kernel.h>
^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/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/platform_data/apds990x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) /* Register map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #define APDS990X_ENABLE	 0x00 /* Enable of states and interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #define APDS990X_ATIME	 0x01 /* ALS ADC time  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define APDS990X_PTIME	 0x02 /* Proximity ADC time  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define APDS990X_WTIME	 0x03 /* Wait time  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define APDS990X_AILTL	 0x04 /* ALS interrupt low threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define APDS990X_AILTH	 0x05 /* ALS interrupt low threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define APDS990X_AIHTL	 0x06 /* ALS interrupt hi threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define APDS990X_AIHTH	 0x07 /* ALS interrupt hi threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define APDS990X_PILTL	 0x08 /* Proximity interrupt low threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define APDS990X_PILTH	 0x09 /* Proximity interrupt low threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define APDS990X_PIHTL	 0x0a /* Proximity interrupt hi threshold low byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define APDS990X_PIHTH	 0x0b /* Proximity interrupt hi threshold hi byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define APDS990X_PERS	 0x0c /* Interrupt persistence filters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define APDS990X_CONFIG	 0x0d /* Configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define APDS990X_PPCOUNT 0x0e /* Proximity pulse count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define APDS990X_CONTROL 0x0f /* Gain control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define APDS990X_REV	 0x11 /* Revision Number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define APDS990X_ID	 0x12 /* Device ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define APDS990X_STATUS	 0x13 /* Device status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define APDS990X_CDATAL	 0x14 /* Clear ADC low data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define APDS990X_CDATAH	 0x15 /* Clear ADC high data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define APDS990X_IRDATAL 0x16 /* IR ADC low data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define APDS990X_IRDATAH 0x17 /* IR ADC high data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define APDS990X_PDATAL	 0x18 /* Proximity ADC low data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define APDS990X_PDATAH	 0x19 /* Proximity ADC high data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) /* Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define APDS990X_MAX_AGAIN	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) /* Enable register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define APDS990X_EN_PIEN	(0x1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define APDS990X_EN_AIEN	(0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define APDS990X_EN_WEN		(0x1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define APDS990X_EN_PEN		(0x1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define APDS990X_EN_AEN		(0x1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define APDS990X_EN_PON		(0x1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define APDS990X_EN_DISABLE_ALL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) /* Status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define APDS990X_ST_PINT	(0x1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define APDS990X_ST_AINT	(0x1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) /* I2C access types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define APDS990x_CMD_TYPE_MASK	(0x03 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define APDS990x_CMD_TYPE_RB	(0x00 << 5) /* Repeated byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define APDS990x_CMD_TYPE_INC	(0x01 << 5) /* Auto increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define APDS990x_CMD_TYPE_SPE	(0x03 << 5) /* Special function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define APDS990x_ADDR_SHIFT	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define APDS990x_CMD		0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) /* Interrupt ack commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define APDS990X_INT_ACK_ALS	0x6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define APDS990X_INT_ACK_PS	0x5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define APDS990X_INT_ACK_BOTH	0x7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) /* ptime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define APDS990X_PTIME_DEFAULT	0xff /* Recommended conversion time 2.7ms*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) /* wtime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define APDS990X_WTIME_DEFAULT	0xee /* ~50ms wait time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define APDS990X_TIME_TO_ADC	1024 /* One timetick as ADC count value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) /* Persistence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define APDS990X_APERS_SHIFT	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define APDS990X_PPERS_SHIFT	4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) /* Supported ID:s */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define APDS990X_ID_0		0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define APDS990X_ID_4		0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define APDS990X_ID_29		0x29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) /* pgain and pdiode settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) #define APDS_PGAIN_1X	       0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) #define APDS_PDIODE_IR	       0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define APDS990X_LUX_OUTPUT_SCALE 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) /* Reverse chip factors for threshold calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) struct reverse_factors {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	u32 afactor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	int cf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	int irf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	int cf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	int irf2;
^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) struct apds990x_chip {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 	struct apds990x_platform_data	*pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	struct i2c_client		*client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	struct mutex			mutex; /* avoid parallel access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	struct regulator_bulk_data	regs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	wait_queue_head_t		wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	int	prox_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	bool	prox_continuous_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	bool	lux_wait_fresh_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	/* Chip parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	struct	apds990x_chip_factors	cf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	struct	reverse_factors		rcf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	u16	atime;		/* als integration time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	u16	arate;		/* als reporting rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	u16	a_max_result;	/* Max possible ADC value with current atime */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	u8	again_meas;	/* Gain used in last measurement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	u8	again_next;	/* Next calculated gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	u8	pgain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	u8	pdiode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	u8	pdrive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	u8	lux_persistence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	u8	prox_persistence;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	u32	lux_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	u32	lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	u16	lux_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	u16	lux_ir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	u16	lux_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	u32	lux_thres_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	u32	lux_thres_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	u32	prox_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	u16	prox_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	u16	prox_calib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	char	chipname[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	u8	revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) #define APDS_CALIB_SCALER		8192
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) #define APDS_LUX_NEUTRAL_CALIB_VALUE	(1 * APDS_CALIB_SCALER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) #define APDS_PROX_NEUTRAL_CALIB_VALUE	(1 * APDS_CALIB_SCALER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) #define APDS_PROX_DEF_THRES		600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) #define APDS_PROX_HYSTERESIS		50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) #define APDS_LUX_DEF_THRES_HI		101
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) #define APDS_LUX_DEF_THRES_LO		100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) #define APDS_DEFAULT_PROX_PERS		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) #define APDS_TIMEOUT			2000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) #define APDS_STARTUP_DELAY		25000 /* us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) #define APDS_RANGE			65535
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) #define APDS_PROX_RANGE			1023
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) #define APDS_LUX_GAIN_LO_LIMIT		100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) #define APDS_LUX_GAIN_LO_LIMIT_STRICT	25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) #define TIMESTEP			87 /* 2.7ms is about 87 / 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) #define TIME_STEP_SCALER		32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) #define APDS_LUX_AVERAGING_TIME		50 /* tolerates 50/60Hz ripple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) #define APDS_LUX_DEFAULT_RATE		200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static const u8 again[]	= {1, 8, 16, 120}; /* ALS gain steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) /* Following two tables must match i.e 10Hz rate means 1 as persistence value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) static const u16 arates_hz[] = {10, 5, 2, 1};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) static const u8 apersis[] = {1, 2, 4, 5};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) /* Regulators */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) static const char reg_vcc[] = "Vdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) static const char reg_vled[] = "Vled";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) static int apds990x_read_byte(struct apds990x_chip *chip, u8 reg, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	reg |= APDS990x_CMD | APDS990x_CMD_TYPE_RB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	ret = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	*data = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) static int apds990x_read_word(struct apds990x_chip *chip, u8 reg, u16 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	reg |= APDS990x_CMD | APDS990x_CMD_TYPE_INC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	ret = i2c_smbus_read_word_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	*data = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) static int apds990x_write_byte(struct apds990x_chip *chip, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	reg |= APDS990x_CMD | APDS990x_CMD_TYPE_RB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	ret = i2c_smbus_write_byte_data(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) static int apds990x_write_word(struct apds990x_chip *chip, u8 reg, u16 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	reg &= ~APDS990x_CMD_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	reg |= APDS990x_CMD | APDS990x_CMD_TYPE_INC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	ret = i2c_smbus_write_word_data(client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) static int apds990x_mode_on(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	/* ALS is mandatory, proximity optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	u8 reg = APDS990X_EN_AIEN | APDS990X_EN_PON | APDS990X_EN_AEN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		APDS990X_EN_WEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	if (chip->prox_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 		reg |= APDS990X_EN_PIEN | APDS990X_EN_PEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	return apds990x_write_byte(chip, APDS990X_ENABLE, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) static u16 apds990x_lux_to_threshold(struct apds990x_chip *chip, u32 lux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	u32 thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	u32 cpl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	u32 ir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	if (lux == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	else if (lux == APDS_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		return APDS_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	 * Reported LUX value is a combination of the IR and CLEAR channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	 * values. However, interrupt threshold is only for clear channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	 * This function approximates needed HW threshold value for a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	 * LUX value in the current lightning type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	 * IR level compared to visible light varies heavily depending on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	 * source of the light
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	 * Calculate threshold value for the next measurement period.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	 * Math: threshold = lux * cpl where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	 * cpl = atime * again / (glass_attenuation * device_factor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	 * (count-per-lux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	 * First remove calibration. Division by four is to avoid overflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	lux = lux * (APDS_CALIB_SCALER / 4) / (chip->lux_calib / 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	/* Multiplication by 64 is to increase accuracy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	cpl = ((u32)chip->atime * (u32)again[chip->again_next] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		APDS_PARAM_SCALE * 64) / (chip->cf.ga * chip->cf.df);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	thres = lux * cpl / 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	 * Convert IR light from the latest result to match with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	 * new gain step. This helps to adapt with the current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	 * source of light.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	ir = (u32)chip->lux_ir * (u32)again[chip->again_next] /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		(u32)again[chip->again_meas];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	 * Compensate count with IR light impact
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	 * IAC1 > IAC2 (see apds990x_get_lux for formulas)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (chip->lux_clear * APDS_PARAM_SCALE >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		chip->rcf.afactor * chip->lux_ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		thres = (chip->rcf.cf1 * thres + chip->rcf.irf1 * ir) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 		thres = (chip->rcf.cf2 * thres + chip->rcf.irf2 * ir) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 			APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	if (thres >= chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		thres = chip->a_max_result - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	return thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) static inline int apds990x_set_atime(struct apds990x_chip *chip, u32 time_ms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	u8 reg_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	chip->atime = time_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	/* Formula is specified in the data sheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	reg_value = 256 - ((time_ms * TIME_STEP_SCALER) / TIMESTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	/* Calculate max ADC value for given integration time */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	chip->a_max_result = (u16)(256 - reg_value) * APDS990X_TIME_TO_ADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	return apds990x_write_byte(chip, APDS990X_ATIME, reg_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) static int apds990x_refresh_pthres(struct apds990x_chip *chip, int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	int ret, lo, hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	/* If the chip is not in use, don't try to access it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	if (pm_runtime_suspended(&chip->client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	if (data < chip->prox_thres) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 		hi = chip->prox_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 		lo = chip->prox_thres - APDS_PROX_HYSTERESIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		if (chip->prox_continuous_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 			hi = chip->prox_thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 			hi = APDS_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	ret = apds990x_write_word(chip, APDS990X_PILTL, lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	ret |= apds990x_write_word(chip, APDS990X_PIHTL, hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) static int apds990x_refresh_athres(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	/* If the chip is not in use, don't try to access it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	if (pm_runtime_suspended(&chip->client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	ret = apds990x_write_word(chip, APDS990X_AILTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 			apds990x_lux_to_threshold(chip, chip->lux_thres_lo));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	ret |= apds990x_write_word(chip, APDS990X_AIHTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 			apds990x_lux_to_threshold(chip, chip->lux_thres_hi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) static void apds990x_force_a_refresh(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	/* This will force ALS interrupt after the next measurement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	apds990x_write_word(chip, APDS990X_AILTL, APDS_LUX_DEF_THRES_LO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	apds990x_write_word(chip, APDS990X_AIHTL, APDS_LUX_DEF_THRES_HI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) static void apds990x_force_p_refresh(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	/* This will force proximity interrupt after the next measurement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	apds990x_write_word(chip, APDS990X_PILTL, APDS_PROX_DEF_THRES - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	apds990x_write_word(chip, APDS990X_PIHTL, APDS_PROX_DEF_THRES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) static int apds990x_calc_again(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	int curr_again = chip->again_meas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	int next_again = chip->again_meas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	/* Calculate suitable als gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	if (chip->lux_clear == chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		next_again -= 2; /* ALS saturated. Decrease gain by 2 steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	else if (chip->lux_clear > chip->a_max_result / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		next_again--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		next_again += 2; /* Too dark. Increase gain by 2 steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	else if (chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		next_again++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	/* Limit gain to available range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	if (next_again < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		next_again = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	else if (next_again > APDS990X_MAX_AGAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 		next_again = APDS990X_MAX_AGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	/* Let's check can we trust the measured result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (chip->lux_clear == chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		/* Result can be totally garbage due to saturation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	else if (next_again != curr_again &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		chip->lux_clear < APDS_LUX_GAIN_LO_LIMIT_STRICT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		 * Gain is changed and measurement result is very small.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		 * Result can be totally garbage due to underflow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	chip->again_next = next_again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	apds990x_write_byte(chip, APDS990X_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 			(chip->pdrive << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 			(chip->pdiode << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 			(chip->pgain << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 			(chip->again_next << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	 * Error means bad result -> re-measurement is needed. The forced
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	 * refresh uses fastest possible persistence setting to get result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	 * as soon as possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		apds990x_force_a_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		apds990x_refresh_athres(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) /* Called always with mutex locked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) static int apds990x_get_lux(struct apds990x_chip *chip, int clear, int ir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	int iac, iac1, iac2; /* IR adjusted counts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	u32 lpc; /* Lux per count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	/* Formulas:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	 * iac1 = CF1 * CLEAR_CH - IRF1 * IR_CH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	 * iac2 = CF2 * CLEAR_CH - IRF2 * IR_CH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	iac1 = (chip->cf.cf1 * clear - chip->cf.irf1 * ir) / APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	iac2 = (chip->cf.cf2 * clear - chip->cf.irf2 * ir) / APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	iac = max(iac1, iac2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	iac = max(iac, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	lpc = APDS990X_LUX_OUTPUT_SCALE * (chip->cf.df * chip->cf.ga) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		(u32)(again[chip->again_meas] * (u32)chip->atime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	return (iac * lpc) / APDS_PARAM_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) static int apds990x_ack_int(struct apds990x_chip *chip, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	u8 reg = APDS990x_CMD | APDS990x_CMD_TYPE_SPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	switch (mode & (APDS990X_ST_AINT | APDS990X_ST_PINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	case APDS990X_ST_AINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 		reg |= APDS990X_INT_ACK_ALS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	case APDS990X_ST_PINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		reg |= APDS990X_INT_ACK_PS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		reg |= APDS990X_INT_ACK_BOTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	ret = i2c_smbus_read_byte_data(client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	return (int)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) static irqreturn_t apds990x_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	struct apds990x_chip *chip = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	u8 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	apds990x_read_byte(chip, APDS990X_STATUS, &status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	apds990x_ack_int(chip, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	if (!pm_runtime_suspended(&chip->client->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		if (status & APDS990X_ST_AINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 			apds990x_read_word(chip, APDS990X_CDATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 					&chip->lux_clear);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			apds990x_read_word(chip, APDS990X_IRDATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 					&chip->lux_ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			/* Store used gain for calculations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			chip->again_meas = chip->again_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 			chip->lux_raw = apds990x_get_lux(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 							chip->lux_clear,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 							chip->lux_ir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			if (apds990x_calc_again(chip) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 				/* Result is valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 				chip->lux = chip->lux_raw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 				chip->lux_wait_fresh_res = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 				wake_up(&chip->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 				sysfs_notify(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 					NULL, "lux0_input");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		if ((status & APDS990X_ST_PINT) && chip->prox_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 			u16 clr_ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 			apds990x_read_word(chip, APDS990X_CDATAL, &clr_ch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 			 * If ALS channel is saturated at min gain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			 * proximity gives false posivite values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			 * Just ignore them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 			if (chip->again_meas == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 				clr_ch == chip->a_max_result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 				chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 				apds990x_read_word(chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 						APDS990X_PDATAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 						&chip->prox_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 			apds990x_refresh_pthres(chip, chip->prox_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 			if (chip->prox_data < chip->prox_thres)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 				chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 			else if (!chip->prox_continuous_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 				chip->prox_data = APDS_PROX_RANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 			sysfs_notify(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 				NULL, "prox0_raw");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static int apds990x_configure(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	/* It is recommended to use disabled mode during these operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	/* conversion and wait times for different state machince states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	apds990x_write_byte(chip, APDS990X_PTIME, APDS990X_PTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	apds990x_write_byte(chip, APDS990X_WTIME, APDS990X_WTIME_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	apds990x_set_atime(chip, APDS_LUX_AVERAGING_TIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	apds990x_write_byte(chip, APDS990X_CONFIG, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	/* Persistence levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	apds990x_write_byte(chip, APDS990X_PERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 			(chip->lux_persistence << APDS990X_APERS_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 			(chip->prox_persistence << APDS990X_PPERS_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	apds990x_write_byte(chip, APDS990X_PPCOUNT, chip->pdata->ppcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	/* Start with relatively small gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	chip->again_meas = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	chip->again_next = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	apds990x_write_byte(chip, APDS990X_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 			(chip->pdrive << 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 			(chip->pdiode << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 			(chip->pgain << 2) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 			(chip->again_next << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) static int apds990x_detect(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	ret = apds990x_read_byte(chip, APDS990X_ID, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		dev_err(&client->dev, "ID read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	ret = apds990x_read_byte(chip, APDS990X_REV, &chip->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		dev_err(&client->dev, "REV read failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	switch (id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	case APDS990X_ID_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	case APDS990X_ID_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	case APDS990X_ID_29:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		snprintf(chip->chipname, sizeof(chip->chipname), "APDS-990x");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) static int apds990x_chip_on(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	int err	 = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 					chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	/* Refresh all configs in case of regulators were off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	apds990x_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	apds990x_mode_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) static int apds990x_chip_off(struct apds990x_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 	apds990x_write_byte(chip, APDS990X_ENABLE, APDS990X_EN_DISABLE_ALL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) static ssize_t apds990x_lux_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 				 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	u32 result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	if (pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	timeout = wait_event_interruptible_timeout(chip->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 						!chip->lux_wait_fresh_res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 						msecs_to_jiffies(APDS_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	if (!timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	result = (chip->lux * chip->lux_calib) / APDS_CALIB_SCALER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	if (result > (APDS_RANGE * APDS990X_LUX_OUTPUT_SCALE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		result = APDS_RANGE * APDS990X_LUX_OUTPUT_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	ret = sprintf(buf, "%d.%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		result / APDS990X_LUX_OUTPUT_SCALE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		result % APDS990X_LUX_OUTPUT_SCALE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) static DEVICE_ATTR(lux0_input, S_IRUGO, apds990x_lux_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) static ssize_t apds990x_lux_range_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 				 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	return sprintf(buf, "%u\n", APDS_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) static DEVICE_ATTR(lux0_sensor_range, S_IRUGO, apds990x_lux_range_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) static ssize_t apds990x_lux_calib_format_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 				 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	return sprintf(buf, "%u\n", APDS_CALIB_SCALER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) static DEVICE_ATTR(lux0_calibscale_default, S_IRUGO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		apds990x_lux_calib_format_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) static ssize_t apds990x_lux_calib_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 				 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	return sprintf(buf, "%u\n", chip->lux_calib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) static ssize_t apds990x_lux_calib_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	struct apds990x_chip *chip = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	chip->lux_calib = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) static DEVICE_ATTR(lux0_calibscale, S_IRUGO | S_IWUSR, apds990x_lux_calib_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		apds990x_lux_calib_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) static ssize_t apds990x_rate_avail(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	int pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	for (i = 0; i < ARRAY_SIZE(arates_hz); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 		pos += sprintf(buf + pos, "%d ", arates_hz[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	sprintf(buf + pos - 1, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	return pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) static ssize_t apds990x_rate_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	return sprintf(buf, "%d\n", chip->arate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) static int apds990x_set_arate(struct apds990x_chip *chip, int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	for (i = 0; i < ARRAY_SIZE(arates_hz); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		if (rate >= arates_hz[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	if (i == ARRAY_SIZE(arates_hz))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	/* Pick up corresponding persistence value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	chip->lux_persistence = apersis[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	chip->arate = arates_hz[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	/* If the chip is not in use, don't try to access it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	if (pm_runtime_suspended(&chip->client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	/* Persistence levels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	return apds990x_write_byte(chip, APDS990X_PERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 			(chip->lux_persistence << APDS990X_APERS_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			(chip->prox_persistence << APDS990X_PPERS_SHIFT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) static ssize_t apds990x_rate_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	ret = apds990x_set_arate(chip, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) static DEVICE_ATTR(lux0_rate_avail, S_IRUGO, apds990x_rate_avail, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) static DEVICE_ATTR(lux0_rate, S_IRUGO | S_IWUSR, apds990x_rate_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 						 apds990x_rate_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) static ssize_t apds990x_prox_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 				 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	if (pm_runtime_suspended(dev) || !chip->prox_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	ret = sprintf(buf, "%d\n", chip->prox_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) static DEVICE_ATTR(prox0_raw, S_IRUGO, apds990x_prox_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) static ssize_t apds990x_prox_range_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 				 struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	return sprintf(buf, "%u\n", APDS_PROX_RANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) static DEVICE_ATTR(prox0_sensor_range, S_IRUGO, apds990x_prox_range_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) static ssize_t apds990x_prox_enable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	return sprintf(buf, "%d\n", chip->prox_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) static ssize_t apds990x_prox_enable_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	if (!chip->prox_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		chip->prox_data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	if (value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 		chip->prox_en++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	else if (chip->prox_en > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 		chip->prox_en--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	if (!pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 		apds990x_mode_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) static DEVICE_ATTR(prox0_raw_en, S_IRUGO | S_IWUSR, apds990x_prox_enable_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 						   apds990x_prox_enable_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) static const char *reporting_modes[] = {"trigger", "periodic"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) static ssize_t apds990x_prox_reporting_mode_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		reporting_modes[!!chip->prox_continuous_mode]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) static ssize_t apds990x_prox_reporting_mode_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	ret = sysfs_match_string(reporting_modes, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	if (ret < 0)
^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) 	chip->prox_continuous_mode = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) static DEVICE_ATTR(prox0_reporting_mode, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 		apds990x_prox_reporting_mode_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 		apds990x_prox_reporting_mode_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) static ssize_t apds990x_prox_reporting_avail_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	return sprintf(buf, "%s %s\n", reporting_modes[0], reporting_modes[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) static DEVICE_ATTR(prox0_reporting_mode_avail, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		apds990x_prox_reporting_avail_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) static ssize_t apds990x_lux_thresh_above_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	return sprintf(buf, "%d\n", chip->lux_thres_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) static ssize_t apds990x_lux_thresh_below_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	return sprintf(buf, "%d\n", chip->lux_thres_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) static ssize_t apds990x_set_lux_thresh(struct apds990x_chip *chip, u32 *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 				const char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	unsigned long thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	ret = kstrtoul(buf, 0, &thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	if (thresh > APDS_RANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	*target = thresh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	 * Don't update values in HW if we are still waiting for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	 * first interrupt to come after device handle open call.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	if (!chip->lux_wait_fresh_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		apds990x_refresh_athres(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) static ssize_t apds990x_lux_thresh_above_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_hi, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) static ssize_t apds990x_lux_thresh_below_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	int ret = apds990x_set_lux_thresh(chip, &chip->lux_thres_lo, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) static DEVICE_ATTR(lux0_thresh_above_value, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 		apds990x_lux_thresh_above_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		apds990x_lux_thresh_above_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static DEVICE_ATTR(lux0_thresh_below_value, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 		apds990x_lux_thresh_below_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 		apds990x_lux_thresh_below_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) static ssize_t apds990x_prox_threshold_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	return sprintf(buf, "%d\n", chip->prox_thres);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) static ssize_t apds990x_prox_threshold_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	if ((value > APDS_RANGE) || (value == 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		(value < APDS_PROX_HYSTERESIS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	chip->prox_thres = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	apds990x_force_p_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	return len;
^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 DEVICE_ATTR(prox0_thresh_above_value, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 		apds990x_prox_threshold_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		apds990x_prox_threshold_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) static ssize_t apds990x_power_state_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	return sprintf(buf, "%d\n", !pm_runtime_suspended(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) static ssize_t apds990x_power_state_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 				  struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 				  const char *buf, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	ret = kstrtoul(buf, 0, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	if (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		mutex_lock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		chip->lux_wait_fresh_res = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 		apds990x_force_a_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		apds990x_force_p_refresh(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 		mutex_unlock(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		if (!pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 			pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 		apds990x_power_state_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 		apds990x_power_state_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) static ssize_t apds990x_chip_id_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 				   struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	struct apds990x_chip *chip =  dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	return sprintf(buf, "%s %d\n", chip->chipname, chip->revision);
^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 DEVICE_ATTR(chip_id, S_IRUGO, apds990x_chip_id_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static struct attribute *sysfs_attrs_ctrl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	&dev_attr_lux0_calibscale.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	&dev_attr_lux0_calibscale_default.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	&dev_attr_lux0_input.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	&dev_attr_lux0_sensor_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	&dev_attr_lux0_rate.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	&dev_attr_lux0_rate_avail.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	&dev_attr_lux0_thresh_above_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	&dev_attr_lux0_thresh_below_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	&dev_attr_prox0_raw_en.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	&dev_attr_prox0_raw.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	&dev_attr_prox0_sensor_range.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	&dev_attr_prox0_thresh_above_value.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	&dev_attr_prox0_reporting_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	&dev_attr_prox0_reporting_mode_avail.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	&dev_attr_chip_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	&dev_attr_power_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static const struct attribute_group apds990x_attribute_group[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	{.attrs = sysfs_attrs_ctrl },
^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 apds990x_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 				const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	struct apds990x_chip *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	chip = kzalloc(sizeof *chip, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	chip->client  = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	init_waitqueue_head(&chip->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	mutex_init(&chip->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	chip->pdata	= client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	if (chip->pdata == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		dev_err(&client->dev, "platform data is mandatory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	if (chip->pdata->cf.ga == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		/* set uncovered sensor default parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 		chip->cf.ga = 1966; /* 0.48 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		chip->cf.cf1 = 4096; /* 1.00 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		chip->cf.irf1 = 9134; /* 2.23 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 		chip->cf.cf2 = 2867; /* 0.70 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		chip->cf.irf2 = 5816; /* 1.42 * APDS_PARAM_SCALE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 		chip->cf.df = 52;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		chip->cf = chip->pdata->cf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	/* precalculate inverse chip factors for threshold control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	chip->rcf.afactor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		(chip->cf.irf1 - chip->cf.irf2) * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		(chip->cf.cf1 - chip->cf.cf2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	chip->rcf.cf1 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		chip->cf.cf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	chip->rcf.irf1 = chip->cf.irf1 * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 		chip->cf.cf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	chip->rcf.cf2 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		chip->cf.cf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	chip->rcf.irf2 = chip->cf.irf2 * APDS_PARAM_SCALE /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		chip->cf.cf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	/* Set something to start with */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	chip->lux_thres_hi = APDS_LUX_DEF_THRES_HI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	chip->lux_thres_lo = APDS_LUX_DEF_THRES_LO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	chip->lux_calib = APDS_LUX_NEUTRAL_CALIB_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	chip->prox_thres = APDS_PROX_DEF_THRES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	chip->pdrive = chip->pdata->pdrive;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	chip->pdiode = APDS_PDIODE_IR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	chip->pgain = APDS_PGAIN_1X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	chip->prox_calib = APDS_PROX_NEUTRAL_CALIB_VALUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	chip->prox_persistence = APDS_DEFAULT_PROX_PERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	chip->prox_continuous_mode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	chip->regs[0].supply = reg_vcc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	chip->regs[1].supply = reg_vled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	err = regulator_bulk_get(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 				 ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		dev_err(&client->dev, "Cannot get regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		goto fail1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		dev_err(&client->dev, "Cannot enable regulators\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 		goto fail2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	err = apds990x_detect(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		dev_err(&client->dev, "APDS990X not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 		goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	pm_runtime_set_active(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	apds990x_configure(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 	apds990x_set_arate(chip, APDS_LUX_DEFAULT_RATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 	apds990x_mode_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	if (chip->pdata->setup_resources) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		err = chip->pdata->setup_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 			goto fail3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		}
^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) 	err = sysfs_create_group(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 				apds990x_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		dev_err(&chip->client->dev, "Sysfs registration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		goto fail4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	err = request_threaded_irq(client->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 				apds990x_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 				IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 				"apds990x", chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		dev_err(&client->dev, "could not get IRQ %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 			client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		goto fail5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) fail5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	sysfs_remove_group(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 			&apds990x_attribute_group[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) fail4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	if (chip->pdata && chip->pdata->release_resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		chip->pdata->release_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) fail3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) fail2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) fail1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static int apds990x_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	free_irq(client->irq, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 	sysfs_remove_group(&chip->client->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			apds990x_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	if (chip->pdata && chip->pdata->release_resources)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		chip->pdata->release_resources();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	if (!pm_runtime_suspended(&client->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		apds990x_chip_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	pm_runtime_set_suspended(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	kfree(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static int apds990x_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	apds990x_chip_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static int apds990x_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 	 * If we were enabled at suspend time, it is expected
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	 * everything works nice and smoothly. Chip_on is enough
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	apds990x_chip_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static int apds990x_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	apds990x_chip_off(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) static int apds990x_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	struct apds990x_chip *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	apds990x_chip_on(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static const struct i2c_device_id apds990x_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	{"apds990x", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	{}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) MODULE_DEVICE_TABLE(i2c, apds990x_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) static const struct dev_pm_ops apds990x_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	SET_SYSTEM_SLEEP_PM_OPS(apds990x_suspend, apds990x_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	SET_RUNTIME_PM_OPS(apds990x_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 			apds990x_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 			NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static struct i2c_driver apds990x_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	.driver	 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 		.name	= "apds990x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 		.pm	= &apds990x_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	.probe	  = apds990x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	.remove	  = apds990x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	.id_table = apds990x_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) module_i2c_driver(apds990x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) MODULE_DESCRIPTION("APDS990X combined ALS and proximity sensor");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) MODULE_LICENSE("GPL v2");