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)  * These are the two Sharp GP2AP002 variants supported by this driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * GP2AP002A00F Ambient Light and Proximity Sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * GP2AP002S00F Proximity Sensor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2020 Linaro Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Author: Linus Walleij <linus.walleij@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Based partly on the code in Sony Ericssons GP2AP00200F driver by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Courtney Cavin and Oskar Andero in drivers/input/misc/gp2ap002a00f.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Based partly on a Samsung misc driver submitted by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Donggeun Kim & Minkyu Kang in 2011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * https://lore.kernel.org/lkml/1315556546-7445-1-git-send-email-dg77.kim@samsung.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * Based partly on a submission by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Jonathan Bakker and Paweł Chmiel in january 2019:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * https://lore.kernel.org/linux-input/20190125175045.22576-1-pawel.mikolaj.chmiel@gmail.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * Based partly on code from the Samsung GT-S7710 by <mjchen@sta.samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * Based partly on the code in LG Electronics GP2AP00200F driver by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Kenobi Lee <sungyoung.lee@lge.com> and EunYoung Cho <ey.cho@lge.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/iio/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/iio/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/iio/consumer.h> /* To get our ADC channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/iio/types.h> /* To deal with our ADC channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/math64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define GP2AP002_PROX_CHANNEL 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define GP2AP002_ALS_CHANNEL 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) /* ------------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) /* ADDRESS SYMBOL             DATA                                 Init R/W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) /*                   D7    D6    D5    D4    D3    D2    D1    D0           */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) /* ------------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) /*    0      PROX     X     X     X     X     X     X     X    VO  H'00   R */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) /*    1      GAIN     X     X     X     X  LED0     X     X     X  H'00   W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /*    2       HYS  HYSD HYSC1 HYSC0     X HYSF3 HYSF2 HYSF1 HYSF0  H'00   W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) /*    3     CYCLE     X     X CYCL2 CYCL1 CYCL0  OSC2     X     X  H'00   W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /*    4     OPMOD     X     X     X   ASD     X     X  VCON   SSD  H'00   W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) /*    6       CON     X     X     X OCON1 OCON0     X     X     X  H'00   W */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) /* ------------------------------------------------------------------------ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /* VO   :Proximity sensing result(0: no detection, 1: detection)            */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) /* LED0 :Select switch for LED driver's On-registence(0:2x higher, 1:normal)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) /* HYSD/HYSF :Adjusts the receiver sensitivity                              */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) /* OSC  :Select switch internal clocl frequency hoppling(0:effective)       */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) /* CYCL :Determine the detection cycle(typically 8ms, up to 128x)           */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) /* SSD  :Software Shutdown function(0:shutdown, 1:operating)                */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) /* VCON :VOUT output method control(0:normal, 1:interrupt)                  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) /* ASD  :Select switch for analog sleep function(0:ineffective, 1:effective)*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) /* OCON :Select switch for enabling/disabling VOUT (00:enable, 11:disable)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define GP2AP002_PROX				0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define GP2AP002_GAIN				0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define GP2AP002_HYS				0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define GP2AP002_CYCLE				0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define GP2AP002_OPMOD				0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define GP2AP002_CON				0x06
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define GP2AP002_PROX_VO_DETECT			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /* Setting this bit to 0 means 2x higher LED resistance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define GP2AP002_GAIN_LED_NORMAL		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  * These bits adjusts the proximity sensitivity, determining characteristics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * of the detection distance and its hysteresis.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define GP2AP002_HYS_HYSD_SHIFT		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define GP2AP002_HYS_HYSD_MASK		BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) #define GP2AP002_HYS_HYSC_SHIFT		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define GP2AP002_HYS_HYSC_MASK		GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define GP2AP002_HYS_HYSF_SHIFT		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define GP2AP002_HYS_HYSF_MASK		GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) #define GP2AP002_HYS_MASK		(GP2AP002_HYS_HYSD_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 					 GP2AP002_HYS_HYSC_MASK | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 					 GP2AP002_HYS_HYSF_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * These values determine the detection cycle response time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * 0: 8ms, 1: 16ms, 2: 32ms, 3: 64ms, 4: 128ms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * 5: 256ms, 6: 512ms, 7: 1024ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define GP2AP002_CYCLE_CYCL_SHIFT	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define GP2AP002_CYCLE_CYCL_MASK	GENMASK(5, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * Select switch for internal clock frequency hopping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  *	0: effective,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  *	1: ineffective
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define GP2AP002_CYCLE_OSC_EFFECTIVE	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define GP2AP002_CYCLE_OSC_INEFFECTIVE	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define GP2AP002_CYCLE_OSC_MASK		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Analog sleep effective */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define GP2AP002_OPMOD_ASD		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* Enable chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define GP2AP002_OPMOD_SSD_OPERATING	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) /* IRQ mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define GP2AP002_OPMOD_VCON_IRQ		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define GP2AP002_OPMOD_MASK		(BIT(0) | BIT(1) | BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * Select switch for enabling/disabling Vout pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * 0: enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * 2: force to go Low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  * 3: force to go High
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define GP2AP002_CON_OCON_SHIFT		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define GP2AP002_CON_OCON_ENABLE	(0x0 << GP2AP002_CON_OCON_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define GP2AP002_CON_OCON_LOW		(0x2 << GP2AP002_CON_OCON_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define GP2AP002_CON_OCON_HIGH		(0x3 << GP2AP002_CON_OCON_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define GP2AP002_CON_OCON_MASK		(0x3 << GP2AP002_CON_OCON_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  * struct gp2ap002 - GP2AP002 state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * @map: regmap pointer for the i2c regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * @dev: pointer to parent device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * @vdd: regulator controlling VDD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * @vio: regulator controlling VIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * @alsout: IIO ADC channel to convert the ALSOUT signal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * @hys_far: hysteresis control from device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * @hys_close: hysteresis control from device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * @is_gp2ap002s00f: this is the GP2AP002F variant of the chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * @irq: the IRQ line used by this device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * @enabled: we cannot read the status of the hardware so we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * keep track of whether the event is enabled using this state variable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct gp2ap002 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct regmap *map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct regulator *vdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct regulator *vio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct iio_channel *alsout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	u8 hys_far;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	u8 hys_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	bool is_gp2ap002s00f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	bool enabled;
^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) static irqreturn_t gp2ap002_prox_irq(int irq, void *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	struct iio_dev *indio_dev = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	u64 ev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (!gp2ap002->enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		goto err_retrig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	ret = regmap_read(gp2ap002->map, GP2AP002_PROX, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		dev_err(gp2ap002->dev, "error reading proximity\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		goto err_retrig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if (val & GP2AP002_PROX_VO_DETECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		/* Close */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		dev_dbg(gp2ap002->dev, "close\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		ret = regmap_write(gp2ap002->map, GP2AP002_HYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 				   gp2ap002->hys_far);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			dev_err(gp2ap002->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 				"error setting up proximity hysteresis\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, GP2AP002_PROX_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 					IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		/* Far */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		dev_dbg(gp2ap002->dev, "far\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		ret = regmap_write(gp2ap002->map, GP2AP002_HYS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 				   gp2ap002->hys_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			dev_err(gp2ap002->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 				"error setting up proximity hysteresis\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		ev = IIO_UNMOD_EVENT_CODE(IIO_PROXIMITY, GP2AP002_PROX_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 					IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	iio_push_event(indio_dev, ev, iio_get_time_ns(indio_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	 * After changing hysteresis, we need to wait for one detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	 * cycle to see if anything changed, or we will just trigger the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	 * previous interrupt again. A detection cycle depends on the CYCLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	 * register, we are hard-coding ~8 ms in probe() so wait some more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	 * than this, 20-30 ms.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	usleep_range(20000, 30000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) err_retrig:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	ret = regmap_write(gp2ap002->map, GP2AP002_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			   GP2AP002_CON_OCON_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		dev_err(gp2ap002->dev, "error setting up VOUT control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^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)  * This array maps current and lux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * Ambient light sensing range is 3 to 55000 lux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * This mapping is based on the following formula.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  * illuminance = 10 ^ (current[mA] / 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * When the ADC measures 0, return 0 lux.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static const u16 gp2ap002_illuminance_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	0, 1, 1, 2, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 25, 32, 40, 50, 63, 79,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	100, 126, 158, 200, 251, 316, 398, 501, 631, 794, 1000, 1259, 1585,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	1995, 2512, 3162, 3981, 5012, 6310, 7943, 10000, 12589, 15849, 19953,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	25119, 31623, 39811, 50119,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static int gp2ap002_get_lux(struct gp2ap002 *gp2ap002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	int ret, res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	u16 lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	ret = iio_read_channel_processed(gp2ap002->alsout, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	dev_dbg(gp2ap002->dev, "read %d mA from ADC\n", res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	/* ensure we don't under/overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	res = clamp(res, 0, (int)ARRAY_SIZE(gp2ap002_illuminance_table) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	lux = gp2ap002_illuminance_table[res];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	return (int)lux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int gp2ap002_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 			   struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 			   int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	pm_runtime_get_sync(gp2ap002->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		switch (chan->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		case IIO_LIGHT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 			ret = gp2ap002_get_lux(gp2ap002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			*val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	pm_runtime_mark_last_busy(gp2ap002->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	pm_runtime_put_autosuspend(gp2ap002->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static int gp2ap002_init(struct gp2ap002 *gp2ap002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	/* Set up the IR LED resistance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	ret = regmap_write(gp2ap002->map, GP2AP002_GAIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			   GP2AP002_GAIN_LED_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		dev_err(gp2ap002->dev, "error setting up LED gain\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	ret = regmap_write(gp2ap002->map, GP2AP002_HYS, gp2ap002->hys_far);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		dev_err(gp2ap002->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 			"error setting up proximity hysteresis\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	/* Disable internal frequency hopping */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	ret = regmap_write(gp2ap002->map, GP2AP002_CYCLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 			   GP2AP002_CYCLE_OSC_INEFFECTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		dev_err(gp2ap002->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 			"error setting up internal frequency hopping\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	/* Enable chip and IRQ, disable analog sleep */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			   GP2AP002_OPMOD_SSD_OPERATING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 			   GP2AP002_OPMOD_VCON_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		dev_err(gp2ap002->dev, "error setting up operation mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	/* Interrupt on VOUT enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	ret = regmap_write(gp2ap002->map, GP2AP002_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			   GP2AP002_CON_OCON_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		dev_err(gp2ap002->dev, "error setting up VOUT control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) static int gp2ap002_read_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 				      const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 				      enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 				      enum iio_event_direction dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	 * We just keep track of this internally, as it is not possible to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	 * query the hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return gp2ap002->enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int gp2ap002_write_event_config(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 				       const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				       enum iio_event_type type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 				       enum iio_event_direction dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 				       int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		 * This will bring the regulators up (unless they are on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		 * already) and reintialize the sensor by using runtime_pm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		 * callbacks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		pm_runtime_get_sync(gp2ap002->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		gp2ap002->enabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		pm_runtime_mark_last_busy(gp2ap002->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		pm_runtime_put_autosuspend(gp2ap002->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 		gp2ap002->enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static const struct iio_info gp2ap002_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	.read_raw = gp2ap002_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	.read_event_config = gp2ap002_read_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	.write_event_config = gp2ap002_write_event_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static const struct iio_event_spec gp2ap002_events[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		.type = IIO_EV_TYPE_THRESH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		.dir = IIO_EV_DIR_EITHER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static const struct iio_chan_spec gp2ap002_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		.type = IIO_PROXIMITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		.event_spec = gp2ap002_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		.num_event_specs = ARRAY_SIZE(gp2ap002_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		.type = IIO_LIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 		.channel = GP2AP002_ALS_CHANNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  * We need a special regmap because this hardware expects to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * write single bytes to registers but read a 16bit word on some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * variants and discard the lower 8 bits so combine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  * i2c_smbus_read_word_data() with i2c_smbus_write_byte_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  * selectively like this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static int gp2ap002_regmap_i2c_read(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 				    unsigned int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	ret = i2c_smbus_read_word_data(i2c, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	*val = (ret >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static int gp2ap002_regmap_i2c_write(void *context, unsigned int reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 				     unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	struct device *dev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	struct i2c_client *i2c = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	return i2c_smbus_write_byte_data(i2c, reg, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) static struct regmap_bus gp2ap002_regmap_bus = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	.reg_read = gp2ap002_regmap_i2c_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	.reg_write = gp2ap002_regmap_i2c_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int gp2ap002_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			  const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	struct gp2ap002 *gp2ap002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	enum iio_chan_type ch_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	static const struct regmap_config config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		.reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		.val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		.max_register = GP2AP002_CON,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	int num_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	const char *compat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	indio_dev = devm_iio_device_alloc(dev, sizeof(*gp2ap002));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	i2c_set_clientdata(client, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	gp2ap002->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	 * Check the device compatible like this makes it possible to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	 * ACPI PRP0001 for registering the sensor using device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	 * properties.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	ret = device_property_read_string(dev, "compatible", &compat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		dev_err(dev, "cannot check compatible\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	gp2ap002->is_gp2ap002s00f = !strcmp(compat, "sharp,gp2ap002s00f");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	regmap = devm_regmap_init(dev, &gp2ap002_regmap_bus, dev, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		dev_err(dev, "Failed to register i2c regmap %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			(int)PTR_ERR(regmap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		return PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	gp2ap002->map = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	 * The hysteresis settings are coded into the device tree as values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	 * to be written into the hysteresis register. The datasheet defines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	 * modes "A", "B1" and "B2" with fixed values to be use but vendor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	 * code trees for actual devices are tweaking these values and refer to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	 * modes named things like "B1.5". To be able to support any devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	 * we allow passing an arbitrary hysteresis setting for "near" and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	 * "far".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	/* Check the device tree for the IR LED hysteresis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	ret = device_property_read_u8(dev, "sharp,proximity-far-hysteresis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 				      &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		dev_err(dev, "failed to obtain proximity far setting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	dev_dbg(dev, "proximity far setting %02x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	gp2ap002->hys_far = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	ret = device_property_read_u8(dev, "sharp,proximity-close-hysteresis",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 				      &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		dev_err(dev, "failed to obtain proximity close setting\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	dev_dbg(dev, "proximity close setting %02x\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	gp2ap002->hys_close = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	/* The GP2AP002A00F has a light sensor too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (!gp2ap002->is_gp2ap002s00f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		gp2ap002->alsout = devm_iio_channel_get(dev, "alsout");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 		if (IS_ERR(gp2ap002->alsout)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 			if (PTR_ERR(gp2ap002->alsout) == -ENODEV) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 				dev_err(dev, "no ADC, deferring...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 				return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 			dev_err(dev, "failed to get ALSOUT ADC channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 			return PTR_ERR(gp2ap002->alsout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		ret = iio_get_channel_type(gp2ap002->alsout, &ch_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		if (ch_type != IIO_CURRENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 			dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 				"wrong type of IIO channel specified for ALSOUT\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	gp2ap002->vdd = devm_regulator_get(dev, "vdd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	if (IS_ERR(gp2ap002->vdd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		dev_err(dev, "failed to get VDD regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		return PTR_ERR(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	gp2ap002->vio = devm_regulator_get(dev, "vio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	if (IS_ERR(gp2ap002->vio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		dev_err(dev, "failed to get VIO regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		return PTR_ERR(gp2ap002->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	/* Operating voltage 2.4V .. 3.6V according to datasheet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 	ret = regulator_set_voltage(gp2ap002->vdd, 2400000, 3600000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		dev_err(dev, "failed to sett VDD voltage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	/* VIO should be between 1.65V and VDD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	ret = regulator_get_voltage(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		dev_err(dev, "failed to get VDD voltage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	ret = regulator_set_voltage(gp2ap002->vio, 1650000, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		dev_err(dev, "failed to set VIO voltage\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	ret = regulator_enable(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		dev_err(dev, "failed to enable VDD regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	ret = regulator_enable(gp2ap002->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		dev_err(dev, "failed to enable VIO regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		goto out_disable_vdd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	 * Initialize the device and signal to runtime PM that now we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	 * definitely up and using power.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	ret = gp2ap002_init(gp2ap002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		dev_err(dev, "initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		goto out_disable_vio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	pm_runtime_get_noresume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	gp2ap002->enabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	ret = devm_request_threaded_irq(dev, client->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 					gp2ap002_prox_irq, IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 					"gp2ap002", indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		dev_err(dev, "unable to request IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		goto out_put_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	gp2ap002->irq = client->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	 * As the device takes 20 ms + regulator delay to come up with a fresh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	 * measurement after power-on, do not shut it down unnecessarily.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	 * Set autosuspend to a one second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	pm_runtime_set_autosuspend_delay(dev, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	pm_runtime_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	indio_dev->info = &gp2ap002_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	indio_dev->name = "gp2ap002";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	indio_dev->channels = gp2ap002_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	/* Skip light channel for the proximity-only sensor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	num_chan = ARRAY_SIZE(gp2ap002_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	if (gp2ap002->is_gp2ap002s00f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 		num_chan--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	indio_dev->num_channels = num_chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 		goto out_disable_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	dev_dbg(dev, "Sharp GP2AP002 probed successfully\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) out_put_pm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	pm_runtime_put_noidle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) out_disable_pm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) out_disable_vio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	regulator_disable(gp2ap002->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) out_disable_vdd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	regulator_disable(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static int gp2ap002_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	pm_runtime_put_noidle(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 	pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	regulator_disable(gp2ap002->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	regulator_disable(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) static int __maybe_unused gp2ap002_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	/* Deactivate the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	disable_irq(gp2ap002->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	/* Disable chip and IRQ, everything off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	ret = regmap_write(gp2ap002->map, GP2AP002_OPMOD, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 		dev_err(gp2ap002->dev, "error setting up operation mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		return ret;
^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) 	 * As these regulators may be shared, at least we are now in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	 * sleep even if the regulators aren't really turned off.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	regulator_disable(gp2ap002->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	regulator_disable(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) static int __maybe_unused gp2ap002_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	struct gp2ap002 *gp2ap002 = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	ret = regulator_enable(gp2ap002->vdd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		dev_err(dev, "failed to enable VDD regulator in resume path\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	ret = regulator_enable(gp2ap002->vio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		dev_err(dev, "failed to enable VIO regulator in resume path\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	ret = gp2ap002_init(gp2ap002);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		dev_err(dev, "re-initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	/* Re-activate the IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 	enable_irq(gp2ap002->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static const struct dev_pm_ops gp2ap002_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 				pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	SET_RUNTIME_PM_OPS(gp2ap002_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 			   gp2ap002_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static const struct i2c_device_id gp2ap002_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	{ "gp2ap002", 0 },
^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) MODULE_DEVICE_TABLE(i2c, gp2ap002_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static const struct of_device_id gp2ap002_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	{ .compatible = "sharp,gp2ap002a00f" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	{ .compatible = "sharp,gp2ap002s00f" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) MODULE_DEVICE_TABLE(of, gp2ap002_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) static struct i2c_driver gp2ap002_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		.name = "gp2ap002",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		.of_match_table = gp2ap002_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		.pm = &gp2ap002_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	.probe = gp2ap002_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 	.remove = gp2ap002_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 	.id_table = gp2ap002_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) module_i2c_driver(gp2ap002_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) MODULE_DESCRIPTION("GP2AP002 ambient light and proximity sensor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) MODULE_LICENSE("GPL v2");