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)  * palmas-adc.c -- TI PALMAS GPADC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2013, NVIDIA Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Author: Pradeep Goudagunta <pgoudagunta@nvidia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mfd/palmas.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/iio/iio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/iio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/iio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define MOD_NAME "palmas-gpadc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define PALMAS_ADC_CONVERSION_TIMEOUT	(msecs_to_jiffies(5000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define PALMAS_TO_BE_CALCULATED 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define PALMAS_GPADC_TRIMINVALID	-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct palmas_gpadc_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) /* calibration codes and regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	int x1;	/* lower ideal code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	int x2;	/* higher ideal code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	int v1;	/* expected lower volt reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	int v2;	/* expected higher volt reading */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	u8 trim1_reg;	/* register number for lower trim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	u8 trim2_reg;	/* register number for upper trim */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	int gain;	/* calculated from above (after reading trim regs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	int offset;	/* calculated from above (after reading trim regs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	int gain_error;	/* calculated from above (after reading trim regs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	bool is_uncalibrated;	/* if channel has calibration data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define PALMAS_ADC_INFO(_chan, _x1, _x2, _v1, _v2, _t1, _t2, _is_uncalibrated) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	[PALMAS_ADC_CH_##_chan] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		.x1 = _x1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		.x2 = _x2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		.v1 = _v1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		.v2 = _v2, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		.gain = PALMAS_TO_BE_CALCULATED, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		.offset = PALMAS_TO_BE_CALCULATED, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		.gain_error = PALMAS_TO_BE_CALCULATED, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		.trim1_reg = PALMAS_GPADC_TRIM##_t1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		.trim2_reg = PALMAS_GPADC_TRIM##_t2,  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		.is_uncalibrated = _is_uncalibrated \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static struct palmas_gpadc_info palmas_gpadc_info[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	PALMAS_ADC_INFO(IN0, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	PALMAS_ADC_INFO(IN1, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	PALMAS_ADC_INFO(IN2, 2064, 3112, 1260, 1900, 3, 4, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	PALMAS_ADC_INFO(IN3, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	PALMAS_ADC_INFO(IN4, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	PALMAS_ADC_INFO(IN5, 2064, 3112, 630, 950, 1, 2, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	PALMAS_ADC_INFO(IN6, 2064, 3112, 2520, 3800, 5, 6, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	PALMAS_ADC_INFO(IN7, 2064, 3112, 2520, 3800, 7, 8, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	PALMAS_ADC_INFO(IN8, 2064, 3112, 3150, 4750, 9, 10, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	PALMAS_ADC_INFO(IN9, 2064, 3112, 5670, 8550, 11, 12, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	PALMAS_ADC_INFO(IN10, 2064, 3112, 3465, 5225, 13, 14, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	PALMAS_ADC_INFO(IN11, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	PALMAS_ADC_INFO(IN12, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	PALMAS_ADC_INFO(IN13, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	PALMAS_ADC_INFO(IN14, 2064, 3112, 3645, 5225, 15, 16, false),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	PALMAS_ADC_INFO(IN15, 0, 0, 0, 0, INVALID, INVALID, true),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * struct palmas_gpadc - the palmas_gpadc structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * @ch0_current:	channel 0 current source setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  *			0: 0 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  *			1: 5 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  *			2: 15 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  *			3: 20 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  * @ch3_current:	channel 0 current source setting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  *			0: 0 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  *			1: 10 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *			2: 400 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  *			3: 800 uA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * @extended_delay:	enable the gpadc extended delay mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  * @auto_conversion_period:	define the auto_conversion_period
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * This is the palmas_gpadc structure to store run-time information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * and pointers for this driver instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) struct palmas_gpadc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	struct device			*dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	struct palmas			*palmas;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	u8				ch0_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	u8				ch3_current;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	bool				extended_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	int				irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	int				irq_auto_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	int				irq_auto_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct palmas_gpadc_info	*adc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	struct completion		conv_completion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	struct palmas_adc_wakeup_property wakeup1_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	struct palmas_adc_wakeup_property wakeup2_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	bool				wakeup1_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	bool				wakeup2_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	int				auto_conversion_period;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * GPADC lock issue in AUTO mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * Impact: In AUTO mode, GPADC conversion can be locked after disabling AUTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  *	   mode feature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * Details:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  *	When the AUTO mode is the only conversion mode enabled, if the AUTO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  *	mode feature is disabled with bit GPADC_AUTO_CTRL.  AUTO_CONV1_EN = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  *	or bit GPADC_AUTO_CTRL.  AUTO_CONV0_EN = 0 during a conversion, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *	conversion mechanism can be seen as locked meaning that all following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  *	conversion will give 0 as a result.  Bit GPADC_STATUS.GPADC_AVAILABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  *	will stay at 0 meaning that GPADC is busy.  An RT conversion can unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  *	the GPADC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * Workaround(s):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  *	To avoid the lock mechanism, the workaround to follow before any stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  *	conversion request is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *	Force the GPADC state machine to be ON by using the GPADC_CTRL1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  *		GPADC_FORCE bit = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *	Shutdown the GPADC AUTO conversion using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  *		GPADC_AUTO_CTRL.SHUTDOWN_CONV[01] = 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  *	After 100us, force the GPADC state machine to be OFF by using the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  *		GPADC_CTRL1.  GPADC_FORCE bit = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int palmas_disable_auto_conversion(struct palmas_gpadc *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 			PALMAS_GPADC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			PALMAS_GPADC_CTRL1_GPADC_FORCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			PALMAS_GPADC_CTRL1_GPADC_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			PALMAS_GPADC_AUTO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			PALMAS_GPADC_AUTO_CTRL_SHUTDOWN_CONV0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 			0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		dev_err(adc->dev, "AUTO_CTRL update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			PALMAS_GPADC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		dev_err(adc->dev, "GPADC_CTRL1 update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static irqreturn_t palmas_gpadc_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	struct palmas_gpadc *adc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	complete(&adc->conv_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static irqreturn_t palmas_gpadc_irq_auto(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	struct palmas_gpadc *adc = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	dev_dbg(adc->dev, "Threshold interrupt %d occurs\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	palmas_disable_auto_conversion(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static int palmas_gpadc_start_mask_interrupt(struct palmas_gpadc *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 						bool mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	if (!mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 					PALMAS_INT3_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 					PALMAS_INT3_MASK_GPADC_EOC_SW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		ret = palmas_update_bits(adc->palmas, PALMAS_INTERRUPT_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 					PALMAS_INT3_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 					PALMAS_INT3_MASK_GPADC_EOC_SW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 					PALMAS_INT3_MASK_GPADC_EOC_SW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		dev_err(adc->dev, "GPADC INT MASK update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return 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 palmas_gpadc_enable(struct palmas_gpadc *adc, int adc_chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 			       int enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	unsigned int mask, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		val = (adc->extended_delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 			<< PALMAS_GPADC_RT_CTRL_EXTEND_DELAY_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 					PALMAS_GPADC_RT_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 					PALMAS_GPADC_RT_CTRL_EXTEND_DELAY, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 			dev_err(adc->dev, "RT_CTRL update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		mask = (PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			PALMAS_GPADC_CTRL1_GPADC_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		val = (adc->ch0_current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 			<< PALMAS_GPADC_CTRL1_CURRENT_SRC_CH0_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		val |= (adc->ch3_current
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 			<< PALMAS_GPADC_CTRL1_CURRENT_SRC_CH3_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		val |= PALMAS_GPADC_CTRL1_GPADC_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 				PALMAS_GPADC_CTRL1, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 				"Failed to update current setting: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		mask = (PALMAS_GPADC_SW_SELECT_SW_CONV0_SEL_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		val = (adc_chan | PALMAS_GPADC_SW_SELECT_SW_CONV_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				PALMAS_GPADC_SW_SELECT, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			dev_err(adc->dev, "SW_SELECT update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 				PALMAS_GPADC_SW_SELECT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			dev_err(adc->dev, "SW_SELECT write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				PALMAS_GPADC_CTRL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 				PALMAS_GPADC_CTRL1_GPADC_FORCE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 			dev_err(adc->dev, "CTRL1 update failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int palmas_gpadc_read_prepare(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	ret = palmas_gpadc_enable(adc, adc_chan, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	return palmas_gpadc_start_mask_interrupt(adc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static void palmas_gpadc_read_done(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	palmas_gpadc_start_mask_interrupt(adc, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	palmas_gpadc_enable(adc, adc_chan, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int palmas_gpadc_calibrate(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	int d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	int d2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	int gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	int x1 =  adc->adc_info[adc_chan].x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	int x2 =  adc->adc_info[adc_chan].x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	int v1 = adc->adc_info[adc_chan].v1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	int v2 = adc->adc_info[adc_chan].v2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 				adc->adc_info[adc_chan].trim1_reg, &d1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		dev_err(adc->dev, "TRIM read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		goto scrub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	ret = palmas_read(adc->palmas, PALMAS_TRIM_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 				adc->adc_info[adc_chan].trim2_reg, &d2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		dev_err(adc->dev, "TRIM read failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		goto scrub;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	/* gain error calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	k = (1000 + (1000 * (d2 - d1)) / (x2 - x1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	/* gain calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	gain = ((v2 - v1) * 1000) / (x2 - x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	adc->adc_info[adc_chan].gain_error = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	adc->adc_info[adc_chan].gain = gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	/* offset Calculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	adc->adc_info[adc_chan].offset = (d1 * 1000) - ((k - 1000) * x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) scrub:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int palmas_gpadc_start_conversion(struct palmas_gpadc *adc, int adc_chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	init_completion(&adc->conv_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				PALMAS_GPADC_SW_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 				PALMAS_GPADC_SW_SELECT_SW_START_CONV0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 				PALMAS_GPADC_SW_SELECT_SW_START_CONV0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		dev_err(adc->dev, "SELECT_SW_START write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	ret = wait_for_completion_timeout(&adc->conv_completion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 				PALMAS_ADC_CONVERSION_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		dev_err(adc->dev, "conversion not completed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	ret = palmas_bulk_read(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 				PALMAS_GPADC_SW_CONV0_LSB, &val, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		dev_err(adc->dev, "SW_CONV0_LSB read failed: %d\n", ret);
^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) 	ret = val & 0xFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) static int palmas_gpadc_get_calibrated_code(struct palmas_gpadc *adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 						int adc_chan, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	if (!adc->adc_info[adc_chan].is_uncalibrated)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		val  = (val*1000 - adc->adc_info[adc_chan].offset) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 					adc->adc_info[adc_chan].gain_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	if (val < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		dev_err(adc->dev, "Mismatch with calibration\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	val = (val * adc->adc_info[adc_chan].gain) / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int palmas_gpadc_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	struct iio_chan_spec const *chan, int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	struct  palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	int adc_chan = chan->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if (adc_chan > PALMAS_ADC_CH_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	mutex_lock(&indio_dev->mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		ret = palmas_gpadc_read_prepare(adc, adc_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		ret = palmas_gpadc_start_conversion(adc, adc_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			"ADC start conversion failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		if (mask == IIO_CHAN_INFO_PROCESSED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 			ret = palmas_gpadc_get_calibrated_code(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 							adc, adc_chan, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		*val = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		ret = IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	mutex_unlock(&indio_dev->mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	palmas_gpadc_read_done(adc, adc_chan);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	mutex_unlock(&indio_dev->mlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static const struct iio_info palmas_gpadc_iio_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	.read_raw = palmas_gpadc_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) #define PALMAS_ADC_CHAN_IIO(chan, _type, chan_info)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) {							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	.datasheet_name = PALMAS_DATASHEET_NAME(chan),	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 	.type = _type,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 			BIT(chan_info),			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	.indexed = 1,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	.channel = PALMAS_ADC_CH_##chan,		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static const struct iio_chan_spec palmas_gpadc_iio_channel[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	PALMAS_ADC_CHAN_IIO(IN0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	PALMAS_ADC_CHAN_IIO(IN1, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	PALMAS_ADC_CHAN_IIO(IN2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	PALMAS_ADC_CHAN_IIO(IN3, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	PALMAS_ADC_CHAN_IIO(IN4, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	PALMAS_ADC_CHAN_IIO(IN5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	PALMAS_ADC_CHAN_IIO(IN6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	PALMAS_ADC_CHAN_IIO(IN7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	PALMAS_ADC_CHAN_IIO(IN8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	PALMAS_ADC_CHAN_IIO(IN9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	PALMAS_ADC_CHAN_IIO(IN10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	PALMAS_ADC_CHAN_IIO(IN11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	PALMAS_ADC_CHAN_IIO(IN12, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	PALMAS_ADC_CHAN_IIO(IN13, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	PALMAS_ADC_CHAN_IIO(IN14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	PALMAS_ADC_CHAN_IIO(IN15, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static int palmas_gpadc_get_adc_dt_data(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	struct palmas_gpadc_platform_data **gpadc_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	struct device_node *np = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	struct palmas_gpadc_platform_data *gp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	u32 pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	gp_data = devm_kzalloc(&pdev->dev, sizeof(*gp_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (!gp_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	ret = of_property_read_u32(np, "ti,channel0-current-microamp", &pval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		gp_data->ch0_current = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	ret = of_property_read_u32(np, "ti,channel3-current-microamp", &pval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		gp_data->ch3_current = pval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	gp_data->extended_delay = of_property_read_bool(np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 					"ti,enable-extended-delay");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	*gpadc_pdata = gp_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static int palmas_gpadc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	struct palmas_gpadc *adc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	struct palmas_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	struct palmas_gpadc_platform_data *gpadc_pdata = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	pdata = dev_get_platdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	if (pdata && pdata->gpadc_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		gpadc_pdata = pdata->gpadc_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	if (!gpadc_pdata && pdev->dev.of_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		ret = palmas_gpadc_get_adc_dt_data(pdev, &gpadc_pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (!gpadc_pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	if (!indio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		dev_err(&pdev->dev, "iio_device_alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	adc->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	adc->palmas = dev_get_drvdata(pdev->dev.parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	adc->adc_info = palmas_gpadc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	init_completion(&adc->conv_completion);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	dev_set_drvdata(&pdev->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	adc->auto_conversion_period = gpadc_pdata->auto_conversion_period_ms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	adc->irq = palmas_irq_get_virq(adc->palmas, PALMAS_GPADC_EOC_SW_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	if (adc->irq < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			"get virq failed: %d\n", adc->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		ret = adc->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	ret = request_threaded_irq(adc->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		palmas_gpadc_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		IRQF_ONESHOT, dev_name(adc->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			"request irq %d failed: %d\n", adc->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	if (gpadc_pdata->adc_wakeup1_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		memcpy(&adc->wakeup1_data, gpadc_pdata->adc_wakeup1_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 			sizeof(adc->wakeup1_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		adc->wakeup1_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		adc->irq_auto_0 =  platform_get_irq(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		ret = request_threaded_irq(adc->irq_auto_0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 				palmas_gpadc_irq_auto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 				IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 				"palmas-adc-auto-0", adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 			dev_err(adc->dev, "request auto0 irq %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 				adc->irq_auto_0, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			goto out_irq_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	if (gpadc_pdata->adc_wakeup2_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		memcpy(&adc->wakeup2_data, gpadc_pdata->adc_wakeup2_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 				sizeof(adc->wakeup2_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		adc->wakeup2_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		adc->irq_auto_1 =  platform_get_irq(pdev, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		ret = request_threaded_irq(adc->irq_auto_1, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 				palmas_gpadc_irq_auto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 				IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 				"palmas-adc-auto-1", adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			dev_err(adc->dev, "request auto1 irq %d failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 				adc->irq_auto_1, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			goto out_irq_auto0_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	/* set the current source 0 (value 0/5/15/20 uA => 0..3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	if (gpadc_pdata->ch0_current <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	else if (gpadc_pdata->ch0_current <= 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	else if (gpadc_pdata->ch0_current <= 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		adc->ch0_current = PALMAS_ADC_CH0_CURRENT_SRC_20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	/* set the current source 3 (value 0/10/400/800 uA => 0..3) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	if (gpadc_pdata->ch3_current <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	else if (gpadc_pdata->ch3_current <= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	else if (gpadc_pdata->ch3_current <= 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_400;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		adc->ch3_current = PALMAS_ADC_CH3_CURRENT_SRC_800;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	adc->extended_delay = gpadc_pdata->extended_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	indio_dev->name = MOD_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 	indio_dev->info = &palmas_gpadc_iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	indio_dev->channels = palmas_gpadc_iio_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	indio_dev->num_channels = ARRAY_SIZE(palmas_gpadc_iio_channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	ret = iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		dev_err(adc->dev, "iio_device_register() failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 		goto out_irq_auto1_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	device_set_wakeup_capable(&pdev->dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 	for (i = 0; i < PALMAS_ADC_CH_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 		if (!(adc->adc_info[i].is_uncalibrated))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 			palmas_gpadc_calibrate(adc, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	if (adc->wakeup1_enable || adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 		device_wakeup_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) out_irq_auto1_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	if (gpadc_pdata->adc_wakeup2_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 		free_irq(adc->irq_auto_1, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) out_irq_auto0_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	if (gpadc_pdata->adc_wakeup1_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 		free_irq(adc->irq_auto_0, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) out_irq_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	free_irq(adc->irq, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static int palmas_gpadc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	struct iio_dev *indio_dev = dev_to_iio_dev(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	if (adc->wakeup1_enable || adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 		device_wakeup_disable(&pdev->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) 	free_irq(adc->irq, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	if (adc->wakeup1_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		free_irq(adc->irq_auto_0, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 	if (adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 		free_irq(adc->irq_auto_1, adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) static int palmas_adc_wakeup_configure(struct palmas_gpadc *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	int adc_period, conv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 	int ch0 = 0, ch1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 	int thres;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 	adc_period = adc->auto_conversion_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	for (i = 0; i < 16; ++i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		if (((1000 * (1 << i)) / 32) >= adc_period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 	if (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 		i--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	adc_period = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 			PALMAS_GPADC_AUTO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			PALMAS_GPADC_AUTO_CTRL_COUNTER_CONV_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			adc_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	conv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 	if (adc->wakeup1_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		int polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		ch0 = adc->wakeup1_data.adc_channel_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 		conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 		if (adc->wakeup1_data.adc_high_threshold > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 			thres = adc->wakeup1_data.adc_high_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 			polarity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 			thres = adc->wakeup1_data.adc_low_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 			polarity = PALMAS_GPADC_THRES_CONV0_MSB_THRES_CONV0_POL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 				PALMAS_GPADC_THRES_CONV0_LSB, thres & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 			dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 				"THRES_CONV0_LSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 				PALMAS_GPADC_THRES_CONV0_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 				((thres >> 8) & 0xF) | polarity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 			dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 				"THRES_CONV0_MSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 	if (adc->wakeup2_enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		int polarity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 		ch1 = adc->wakeup2_data.adc_channel_number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		conv |= PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 		if (adc->wakeup2_data.adc_high_threshold > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 			thres = adc->wakeup2_data.adc_high_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 			polarity = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 			thres = adc->wakeup2_data.adc_low_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 			polarity = PALMAS_GPADC_THRES_CONV1_MSB_THRES_CONV1_POL;
^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) 		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 				PALMAS_GPADC_THRES_CONV1_LSB, thres & 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 			dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 				"THRES_CONV1_LSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 				PALMAS_GPADC_THRES_CONV1_MSB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 				((thres >> 8) & 0xF) | polarity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 		if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 			dev_err(adc->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 				"THRES_CONV1_MSB write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 			PALMAS_GPADC_AUTO_SELECT, (ch1 << 4) | ch0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	ret = palmas_update_bits(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 			PALMAS_GPADC_AUTO_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 			PALMAS_GPADC_AUTO_CTRL_AUTO_CONV1_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 			PALMAS_GPADC_AUTO_CTRL_AUTO_CONV0_EN, conv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		dev_err(adc->dev, "AUTO_CTRL write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static int palmas_adc_wakeup_reset(struct palmas_gpadc *adc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 	ret = palmas_write(adc->palmas, PALMAS_GPADC_BASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 			PALMAS_GPADC_AUTO_SELECT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		dev_err(adc->dev, "AUTO_SELECT write failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	ret = palmas_disable_auto_conversion(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		dev_err(adc->dev, "Disable auto conversion failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static int palmas_gpadc_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	int wakeup = adc->wakeup1_enable || adc->wakeup2_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	if (!device_may_wakeup(dev) || !wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 	ret = palmas_adc_wakeup_configure(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	if (adc->wakeup1_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 		enable_irq_wake(adc->irq_auto_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 	if (adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 		enable_irq_wake(adc->irq_auto_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static int palmas_gpadc_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 	struct palmas_gpadc *adc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	int wakeup = adc->wakeup1_enable || adc->wakeup2_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	if (!device_may_wakeup(dev) || !wakeup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	ret = palmas_adc_wakeup_reset(adc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	if (adc->wakeup1_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 		disable_irq_wake(adc->irq_auto_0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 	if (adc->wakeup2_enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 		disable_irq_wake(adc->irq_auto_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static const struct dev_pm_ops palmas_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	SET_SYSTEM_SLEEP_PM_OPS(palmas_gpadc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 				palmas_gpadc_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static const struct of_device_id of_palmas_gpadc_match_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	{ .compatible = "ti,palmas-gpadc", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	{ /* end */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) MODULE_DEVICE_TABLE(of, of_palmas_gpadc_match_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static struct platform_driver palmas_gpadc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 	.probe = palmas_gpadc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 	.remove = palmas_gpadc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 		.name = MOD_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 		.pm = &palmas_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 		.of_match_table = of_palmas_gpadc_match_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) module_platform_driver(palmas_gpadc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) MODULE_DESCRIPTION("palmas GPADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) MODULE_AUTHOR("Pradeep Goudagunta<pgoudagunta@nvidia.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) MODULE_ALIAS("platform:palmas-gpadc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) MODULE_LICENSE("GPL v2");