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)  * Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Rewritten for Linux IIO framework with some code based on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * earlier driver found in the Motorola Linux kernel:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  * Copyright (C) 2009-2010 Motorola, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <linux/iio/buffer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <linux/iio/driver.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/kfifo_buf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #include <linux/mfd/motorola-cpcap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) /* Register CPCAP_REG_ADCC1 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define CPCAP_BIT_ADEN_AUTO_CLR		BIT(15)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define CPCAP_BIT_CAL_MODE		BIT(14) /* Set with BIT_RAND0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define CPCAP_BIT_ADC_CLK_SEL1		BIT(13)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define CPCAP_BIT_ADC_CLK_SEL0		BIT(12)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define CPCAP_BIT_ATOX			BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define CPCAP_BIT_ATO3			BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define CPCAP_BIT_ATO2			BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define CPCAP_BIT_ATO1			BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define CPCAP_BIT_ATO0			BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define CPCAP_BIT_ADA2			BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define CPCAP_BIT_ADA1			BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define CPCAP_BIT_ADA0			BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define CPCAP_BIT_AD_SEL1		BIT(3)	/* Set for bank1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define CPCAP_BIT_RAND1			BIT(2)	/* Set for channel 16 & 17 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define CPCAP_BIT_RAND0			BIT(1)	/* Set with CAL_MODE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define CPCAP_BIT_ADEN			BIT(0)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define CPCAP_REG_ADCC1_DEFAULTS	(CPCAP_BIT_ADEN_AUTO_CLR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 					 CPCAP_BIT_ADC_CLK_SEL0 |  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 					 CPCAP_BIT_RAND1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) /* Register CPCAP_REG_ADCC2 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define CPCAP_BIT_CAL_FACTOR_ENABLE	BIT(15)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define CPCAP_BIT_BATDETB_EN		BIT(14)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define CPCAP_BIT_ADTRIG_ONESHOT	BIT(13)	/* Set for !TIMING_IMM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define CPCAP_BIT_ASC			BIT(12)	/* Set for TIMING_IMM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) #define CPCAP_BIT_ATOX_PS_FACTOR	BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define CPCAP_BIT_ADC_PS_FACTOR1	BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define CPCAP_BIT_ADC_PS_FACTOR0	BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define CPCAP_BIT_AD4_SELECT		BIT(8)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define CPCAP_BIT_ADC_BUSY		BIT(7)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define CPCAP_BIT_THERMBIAS_EN		BIT(6)	/* Bias for AD0_BATTDETB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define CPCAP_BIT_ADTRIG_DIS		BIT(5)	/* Disable interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define CPCAP_BIT_LIADC			BIT(4)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define CPCAP_BIT_TS_REFEN		BIT(3)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define CPCAP_BIT_TS_M2			BIT(2)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define CPCAP_BIT_TS_M1			BIT(1)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define CPCAP_BIT_TS_M0			BIT(0)	/* Currently unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define CPCAP_REG_ADCC2_DEFAULTS	(CPCAP_BIT_AD4_SELECT | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 					 CPCAP_BIT_ADTRIG_DIS | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 					 CPCAP_BIT_LIADC | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 					 CPCAP_BIT_TS_M2 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 					 CPCAP_BIT_TS_M1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define CPCAP_MAX_TEMP_LVL		27
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define CPCAP_FOUR_POINT_TWO_ADC	801
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define ST_ADC_CAL_CHRGI_HIGH_THRESHOLD	530
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define ST_ADC_CAL_CHRGI_LOW_THRESHOLD	494
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) #define ST_ADC_CAL_BATTI_HIGH_THRESHOLD	530
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define ST_ADC_CAL_BATTI_LOW_THRESHOLD	494
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define ST_ADC_CALIBRATE_DIFF_THRESHOLD	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define CPCAP_ADC_MAX_RETRIES		5	/* Calibration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * struct cpcap_adc_ato - timing settings for cpcap adc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88)  * Unfortunately no cpcap documentation available, please document when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89)  * using these.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) struct cpcap_adc_ato {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	unsigned short ato_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	unsigned short atox_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	unsigned short adc_ps_factor_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	unsigned short atox_ps_factor_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	unsigned short ato_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	unsigned short atox_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	unsigned short adc_ps_factor_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	unsigned short atox_ps_factor_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  * struct cpcap-adc - cpcap adc device driver data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  * @reg: cpcap regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * @dev: struct device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  * @vendor: cpcap vendor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * @irq: interrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  * @lock: mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  * @ato: request timings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110)  * @wq_data_avail: work queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111)  * @done: work done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) struct cpcap_adc {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	struct regmap *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	u16 vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	struct mutex lock;	/* ADC register access lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	const struct cpcap_adc_ato *ato;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	wait_queue_head_t wq_data_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	bool done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125)  * enum cpcap_adc_channel - cpcap adc channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) enum cpcap_adc_channel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	/* Bank0 channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	CPCAP_ADC_AD0,		/* Battery temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	CPCAP_ADC_BATTP,	/* Battery voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	CPCAP_ADC_VBUS,		/* USB VBUS voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	CPCAP_ADC_AD3,		/* Die temperature when charging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	CPCAP_ADC_BPLUS_AD4,	/* Another battery or system voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	CPCAP_ADC_CHG_ISENSE,	/* Calibrated charge current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	CPCAP_ADC_BATTI,	/* Calibrated system current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	CPCAP_ADC_USB_ID,	/* USB OTG ID, unused on droid 4? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	/* Bank1 channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	CPCAP_ADC_AD8,		/* Seems unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 	CPCAP_ADC_AD9,		/* Seems unused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 	CPCAP_ADC_LICELL,	/* Maybe system voltage? Always 3V */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	CPCAP_ADC_HV_BATTP,	/* Another battery detection? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	CPCAP_ADC_TSX1_AD12,	/* Seems unused, for touchscreen? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	CPCAP_ADC_TSX2_AD13,	/* Seems unused, for touchscreen? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	CPCAP_ADC_TSY1_AD14,	/* Seems unused, for touchscreen? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	CPCAP_ADC_TSY2_AD15,	/* Seems unused, for touchscreen? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	/* Remuxed channels using bank0 entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	CPCAP_ADC_BATTP_PI16,	/* Alternative mux mode for BATTP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	CPCAP_ADC_BATTI_PI17,	/* Alternative mux mode for BATTI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	CPCAP_ADC_CHANNEL_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * enum cpcap_adc_timing - cpcap adc timing options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  * CPCAP_ADC_TIMING_IMM seems to be immediate with no timings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * Please document when using.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) enum cpcap_adc_timing {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	CPCAP_ADC_TIMING_IMM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	CPCAP_ADC_TIMING_IN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	CPCAP_ADC_TIMING_OUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168)  * struct cpcap_adc_phasing_tbl - cpcap phasing table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169)  * @offset: offset in the phasing table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170)  * @multiplier: multiplier in the phasing table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171)  * @divider: divider in the phasing table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172)  * @min: minimum value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173)  * @max: maximum value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) struct cpcap_adc_phasing_tbl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	short offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	unsigned short multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	unsigned short divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	short min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	short max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184)  * struct cpcap_adc_conversion_tbl - cpcap conversion table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185)  * @conv_type: conversion type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186)  * @align_offset: align offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187)  * @conv_offset: conversion offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188)  * @cal_offset: calibration offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189)  * @multiplier: conversion multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190)  * @divider: conversion divider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) struct cpcap_adc_conversion_tbl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	enum iio_chan_info_enum conv_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	int align_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	int conv_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	int cal_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	int multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 	int divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202)  * struct cpcap_adc_request - cpcap adc request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203)  * @channel: request channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  * @phase_tbl: channel phasing table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  * @conv_tbl: channel conversion table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  * @bank_index: channel index within the bank
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207)  * @timing: timing settings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208)  * @result: result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) struct cpcap_adc_request {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	const struct cpcap_adc_phasing_tbl *phase_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	const struct cpcap_adc_conversion_tbl *conv_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	int bank_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 	enum cpcap_adc_timing timing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) /* Phasing table for channels. Note that channels 16 & 17 use BATTP and BATTI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) static const struct cpcap_adc_phasing_tbl bank_phasing[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	/* Bank0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	[CPCAP_ADC_AD0] =          {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	[CPCAP_ADC_BATTP] =        {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	[CPCAP_ADC_VBUS] =         {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	[CPCAP_ADC_AD3] =          {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	[CPCAP_ADC_BPLUS_AD4] =    {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	[CPCAP_ADC_CHG_ISENSE] =   {0, 0x80, 0x80, -512,  511},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	[CPCAP_ADC_BATTI] =        {0, 0x80, 0x80, -512,  511},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	[CPCAP_ADC_USB_ID] =       {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	/* Bank1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	[CPCAP_ADC_AD8] =          {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	[CPCAP_ADC_AD9] =          {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	[CPCAP_ADC_LICELL] =       {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	[CPCAP_ADC_HV_BATTP] =     {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	[CPCAP_ADC_TSX1_AD12] =    {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	[CPCAP_ADC_TSX2_AD13] =    {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	[CPCAP_ADC_TSY1_AD14] =    {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	[CPCAP_ADC_TSY2_AD15] =    {0, 0x80, 0x80,    0, 1023},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243)  * Conversion table for channels. Updated during init based on calibration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244)  * Here too channels 16 & 17 use BATTP and BATTI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) static struct cpcap_adc_conversion_tbl bank_conversion[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	/* Bank0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	[CPCAP_ADC_AD0] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	[CPCAP_ADC_BATTP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		IIO_CHAN_INFO_PROCESSED,    0, 2400, 0,  2300, 1023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	[CPCAP_ADC_VBUS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		IIO_CHAN_INFO_PROCESSED,    0,    0, 0, 10000, 1023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	[CPCAP_ADC_AD3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	[CPCAP_ADC_BPLUS_AD4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 		IIO_CHAN_INFO_PROCESSED,    0, 2400, 0,  2300, 1023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	[CPCAP_ADC_CHG_ISENSE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		IIO_CHAN_INFO_PROCESSED, -512,    2, 0,  5000, 1023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	[CPCAP_ADC_BATTI] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		IIO_CHAN_INFO_PROCESSED, -512,    2, 0,  5000, 1023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	[CPCAP_ADC_USB_ID] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^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) 	/* Bank1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	[CPCAP_ADC_AD8] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	[CPCAP_ADC_AD9] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	[CPCAP_ADC_LICELL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		IIO_CHAN_INFO_PROCESSED,    0,    0, 0,  3400, 1023,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	[CPCAP_ADC_HV_BATTP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	[CPCAP_ADC_TSX1_AD12] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	[CPCAP_ADC_TSX2_AD13] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	[CPCAP_ADC_TSY1_AD14] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	[CPCAP_ADC_TSY2_AD15] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		IIO_CHAN_INFO_RAW,          0,    0, 0,     1,    1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301)  * Temperature lookup table of register values to milliCelcius.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302)  * REVISIT: Check the duplicate 0x3ff entry in a freezer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) static const int temp_map[CPCAP_MAX_TEMP_LVL][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	{ 0x03ff, -40000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	{ 0x03ff, -35000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	{ 0x03ef, -30000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	{ 0x03b2, -25000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	{ 0x036c, -20000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	{ 0x0320, -15000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	{ 0x02d0, -10000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	{ 0x027f, -5000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	{ 0x022f, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	{ 0x01e4, 5000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	{ 0x019f, 10000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	{ 0x0161, 15000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	{ 0x012b, 20000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	{ 0x00fc, 25000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	{ 0x00d4, 30000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 	{ 0x00b2, 35000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	{ 0x0095, 40000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	{ 0x007d, 45000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 	{ 0x0069, 50000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	{ 0x0059, 55000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	{ 0x004b, 60000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	{ 0x003f, 65000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	{ 0x0036, 70000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 	{ 0x002e, 75000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	{ 0x0027, 80000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	{ 0x0022, 85000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	{ 0x001d, 90000 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) #define CPCAP_CHAN(_type, _index, _address, _datasheet_name) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	.type = (_type), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	.address = (_address), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	.indexed = 1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	.channel = (_index), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 			      BIT(IIO_CHAN_INFO_PROCESSED), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	.scan_index = (_index), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	.scan_type = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 		.sign = 'u', \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 		.realbits = 10, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		.storagebits = 16, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		.endianness = IIO_CPU, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	}, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	.datasheet_name = (_datasheet_name), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) }
^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)  * The datasheet names are from Motorola mapphone Linux kernel except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353)  * for the last two which might be uncalibrated charge voltage and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354)  * current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) static const struct iio_chan_spec cpcap_adc_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	/* Bank0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	CPCAP_CHAN(IIO_TEMP,    0, CPCAP_REG_ADCD0,  "battdetb"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	CPCAP_CHAN(IIO_VOLTAGE, 1, CPCAP_REG_ADCD1,  "battp"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	CPCAP_CHAN(IIO_VOLTAGE, 2, CPCAP_REG_ADCD2,  "vbus"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	CPCAP_CHAN(IIO_TEMP,    3, CPCAP_REG_ADCD3,  "ad3"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	CPCAP_CHAN(IIO_VOLTAGE, 4, CPCAP_REG_ADCD4,  "ad4"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	CPCAP_CHAN(IIO_CURRENT, 5, CPCAP_REG_ADCD5,  "chg_isense"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	CPCAP_CHAN(IIO_CURRENT, 6, CPCAP_REG_ADCD6,  "batti"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	CPCAP_CHAN(IIO_VOLTAGE, 7, CPCAP_REG_ADCD7,  "usb_id"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	/* Bank1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	CPCAP_CHAN(IIO_CURRENT, 8, CPCAP_REG_ADCD0,  "ad8"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	CPCAP_CHAN(IIO_VOLTAGE, 9, CPCAP_REG_ADCD1,  "ad9"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	CPCAP_CHAN(IIO_VOLTAGE, 10, CPCAP_REG_ADCD2, "licell"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	CPCAP_CHAN(IIO_VOLTAGE, 11, CPCAP_REG_ADCD3, "hv_battp"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	CPCAP_CHAN(IIO_VOLTAGE, 12, CPCAP_REG_ADCD4, "tsx1_ad12"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	CPCAP_CHAN(IIO_VOLTAGE, 13, CPCAP_REG_ADCD5, "tsx2_ad13"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	CPCAP_CHAN(IIO_VOLTAGE, 14, CPCAP_REG_ADCD6, "tsy1_ad14"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	CPCAP_CHAN(IIO_VOLTAGE, 15, CPCAP_REG_ADCD7, "tsy2_ad15"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	/* There are two registers with multiplexed functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	CPCAP_CHAN(IIO_VOLTAGE, 16, CPCAP_REG_ADCD0, "chg_vsense"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	CPCAP_CHAN(IIO_CURRENT, 17, CPCAP_REG_ADCD1, "batti2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) static irqreturn_t cpcap_adc_irq_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	struct iio_dev *indio_dev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	struct cpcap_adc *ddata = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 				   CPCAP_BIT_ADTRIG_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 				   CPCAP_BIT_ADTRIG_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	ddata->done = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	wake_up_interruptible(&ddata->wq_data_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) /* ADC calibration functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) static void cpcap_adc_setup_calibrate(struct cpcap_adc *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 				      enum cpcap_adc_channel chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	unsigned int value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	unsigned long timeout = jiffies + msecs_to_jiffies(3000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	if ((chan != CPCAP_ADC_CHG_ISENSE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	    (chan != CPCAP_ADC_BATTI))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	value |= CPCAP_BIT_CAL_MODE | CPCAP_BIT_RAND0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	value |= ((chan << 4) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		  (CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 | CPCAP_BIT_ADA0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 				   CPCAP_BIT_CAL_MODE | CPCAP_BIT_ATOX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 				   CPCAP_BIT_ATO3 | CPCAP_BIT_ATO2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 				   CPCAP_BIT_ATO1 | CPCAP_BIT_ATO0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				   CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 				   CPCAP_BIT_ADA0 | CPCAP_BIT_AD_SEL1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 				   CPCAP_BIT_RAND1 | CPCAP_BIT_RAND0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				   value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				   CPCAP_BIT_ATOX_PS_FACTOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 				   CPCAP_BIT_ADC_PS_FACTOR1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 				   CPCAP_BIT_ADC_PS_FACTOR0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 				   0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 				   CPCAP_BIT_ADTRIG_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 				   CPCAP_BIT_ADTRIG_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 				   CPCAP_BIT_ASC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				   CPCAP_BIT_ASC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		schedule_timeout_uninterruptible(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		error = regmap_read(ddata->reg, CPCAP_REG_ADCC2, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	} while ((value & CPCAP_BIT_ASC) && time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	if (value & CPCAP_BIT_ASC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		dev_err(ddata->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 			"Timeout waiting for calibration to complete\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 				   CPCAP_BIT_CAL_MODE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) static int cpcap_adc_calibrate_one(struct cpcap_adc *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 				   int channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 				   u16 calibration_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 				   int lower_threshold,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 				   int upper_threshold)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	unsigned int calibration_data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	unsigned short cal_data_diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	int i, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	for (i = 0; i < CPCAP_ADC_MAX_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		calibration_data[0]  = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		calibration_data[1]  = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		cal_data_diff = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		cpcap_adc_setup_calibrate(ddata, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 		error = regmap_read(ddata->reg, calibration_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 				    &calibration_data[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		cpcap_adc_setup_calibrate(ddata, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 		error = regmap_read(ddata->reg, calibration_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				    &calibration_data[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		if (calibration_data[0] > calibration_data[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			cal_data_diff =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 				calibration_data[0] - calibration_data[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 			cal_data_diff =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 				calibration_data[1] - calibration_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		if (((calibration_data[1] >= lower_threshold) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		     (calibration_data[1] <= upper_threshold) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 		     (cal_data_diff <= ST_ADC_CALIBRATE_DIFF_THRESHOLD)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		    (ddata->vendor == CPCAP_VENDOR_TI)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 			bank_conversion[channel].cal_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 				((short)calibration_data[1] * -1) + 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			dev_dbg(ddata->dev, "ch%i calibration complete: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 				channel, bank_conversion[channel].cal_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) static int cpcap_adc_calibrate(struct cpcap_adc *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	error = cpcap_adc_calibrate_one(ddata, CPCAP_ADC_CHG_ISENSE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 					CPCAP_REG_ADCAL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 					ST_ADC_CAL_CHRGI_LOW_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 					ST_ADC_CAL_CHRGI_HIGH_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	error = cpcap_adc_calibrate_one(ddata, CPCAP_ADC_BATTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 					CPCAP_REG_ADCAL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 					ST_ADC_CAL_BATTI_LOW_THRESHOLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 					ST_ADC_CAL_BATTI_HIGH_THRESHOLD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) /* ADC setup, read and scale functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) static void cpcap_adc_setup_bank(struct cpcap_adc *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 				 struct cpcap_adc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	const struct cpcap_adc_ato *ato = ddata->ato;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	unsigned short value1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	unsigned short value2 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	if (!ato)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	switch (req->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	case CPCAP_ADC_AD0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		value2 |= CPCAP_BIT_THERMBIAS_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 					   CPCAP_BIT_THERMBIAS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 					   value2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 		usleep_range(800, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 		value1 |= CPCAP_BIT_AD_SEL1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	case CPCAP_ADC_BATTP_PI16 ... CPCAP_ADC_BATTI_PI17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 		value1 |= CPCAP_BIT_RAND1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	switch (req->timing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	case CPCAP_ADC_TIMING_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 		value1 |= ato->ato_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 		value1 |= ato->atox_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 		value2 |= ato->adc_ps_factor_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 		value2 |= ato->atox_ps_factor_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	case CPCAP_ADC_TIMING_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 		value1 |= ato->ato_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		value1 |= ato->atox_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 		value2 |= ato->adc_ps_factor_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		value2 |= ato->atox_ps_factor_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	case CPCAP_ADC_TIMING_IMM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 				   CPCAP_BIT_CAL_MODE | CPCAP_BIT_ATOX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 				   CPCAP_BIT_ATO3 | CPCAP_BIT_ATO2 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 				   CPCAP_BIT_ATO1 | CPCAP_BIT_ATO0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 				   CPCAP_BIT_ADA2 | CPCAP_BIT_ADA1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 				   CPCAP_BIT_ADA0 | CPCAP_BIT_AD_SEL1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 				   CPCAP_BIT_RAND1 | CPCAP_BIT_RAND0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 				   value1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 				   CPCAP_BIT_ATOX_PS_FACTOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 				   CPCAP_BIT_ADC_PS_FACTOR1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 				   CPCAP_BIT_ADC_PS_FACTOR0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 				   CPCAP_BIT_THERMBIAS_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 				   value2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	if (req->timing == CPCAP_ADC_TIMING_IMM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 					   CPCAP_BIT_ADTRIG_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 					   CPCAP_BIT_ADTRIG_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 					   CPCAP_BIT_ASC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 					   CPCAP_BIT_ASC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 					   CPCAP_BIT_ADTRIG_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 					   CPCAP_BIT_ADTRIG_ONESHOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 		error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 					   CPCAP_BIT_ADTRIG_DIS, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	}
^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 cpcap_adc_start_bank(struct cpcap_adc *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 				struct cpcap_adc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	int i, error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	req->timing = CPCAP_ADC_TIMING_IMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	ddata->done = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	for (i = 0; i < CPCAP_ADC_MAX_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		cpcap_adc_setup_bank(ddata, req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		error = wait_event_interruptible_timeout(ddata->wq_data_avail,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 							 ddata->done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 							 msecs_to_jiffies(50));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		if (error > 0)
^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) 		if (error == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			error = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static int cpcap_adc_stop_bank(struct cpcap_adc *ddata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	error = regmap_update_bits(ddata->reg, CPCAP_REG_ADCC1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 				   0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 				   CPCAP_REG_ADCC1_DEFAULTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	return regmap_update_bits(ddata->reg, CPCAP_REG_ADCC2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 				  0xffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				  CPCAP_REG_ADCC2_DEFAULTS);
^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) static void cpcap_adc_phase(struct cpcap_adc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	const struct cpcap_adc_phasing_tbl *phase_tbl = req->phase_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	int index = req->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	/* Remuxed channels 16 and 17 use BATTP and BATTI entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	switch (req->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	case CPCAP_ADC_BATTP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	case CPCAP_ADC_BATTP_PI16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		index = req->bank_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		req->result -= phase_tbl[index].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 		req->result -= CPCAP_FOUR_POINT_TWO_ADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		req->result *= phase_tbl[index].multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		if (phase_tbl[index].divider == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		req->result /= phase_tbl[index].divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		req->result += CPCAP_FOUR_POINT_TWO_ADC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	case CPCAP_ADC_BATTI_PI17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		index = req->bank_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		req->result += conv_tbl[index].cal_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		req->result += conv_tbl[index].align_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		req->result *= phase_tbl[index].multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 		if (phase_tbl[index].divider == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		req->result /= phase_tbl[index].divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		req->result += phase_tbl[index].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	if (req->result < phase_tbl[index].min)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		req->result = phase_tbl[index].min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	else if (req->result > phase_tbl[index].max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 		req->result = phase_tbl[index].max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) /* Looks up temperatures in a table and calculates averages if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) static int cpcap_adc_table_to_millicelcius(unsigned short value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	int i, result = 0, alpha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	if (value <= temp_map[CPCAP_MAX_TEMP_LVL - 1][0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		return temp_map[CPCAP_MAX_TEMP_LVL - 1][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	if (value >= temp_map[0][0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		return temp_map[0][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 	for (i = 0; i < CPCAP_MAX_TEMP_LVL - 1; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		if ((value <= temp_map[i][0]) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		    (value >= temp_map[i + 1][0])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			if (value == temp_map[i][0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 				result = temp_map[i][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 			} else if (value == temp_map[i + 1][0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 				result = temp_map[i + 1][1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 				alpha = ((value - temp_map[i][0]) * 1000) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 					(temp_map[i + 1][0] - temp_map[i][0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 				result = temp_map[i][1] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 					((alpha * (temp_map[i + 1][1] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 						 temp_map[i][1])) / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) static void cpcap_adc_convert(struct cpcap_adc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	const struct cpcap_adc_conversion_tbl *conv_tbl = req->conv_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	int index = req->channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	/* Remuxed channels 16 and 17 use BATTP and BATTI entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	switch (req->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	case CPCAP_ADC_BATTP_PI16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 		index = CPCAP_ADC_BATTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	case CPCAP_ADC_BATTI_PI17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		index = CPCAP_ADC_BATTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	/* No conversion for raw channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	if (conv_tbl[index].conv_type == IIO_CHAN_INFO_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	/* Temperatures use a lookup table instead of conversion table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	if ((req->channel == CPCAP_ADC_AD0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	    (req->channel == CPCAP_ADC_AD3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		req->result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 			cpcap_adc_table_to_millicelcius(req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	/* All processed channels use a conversion table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	req->result *= conv_tbl[index].multiplier;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	if (conv_tbl[index].divider == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	req->result /= conv_tbl[index].divider;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	req->result += conv_tbl[index].conv_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783)  * REVISIT: Check if timed sampling can use multiple channels at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784)  * same time. If not, replace channel_mask with just channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) static int cpcap_adc_read_bank_scaled(struct cpcap_adc *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 				      struct cpcap_adc_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	int calibration_data, error, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (ddata->vendor == CPCAP_VENDOR_TI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		error = regmap_read(ddata->reg, CPCAP_REG_ADCAL1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 				    &calibration_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		bank_conversion[CPCAP_ADC_CHG_ISENSE].cal_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 			((short)calibration_data * -1) + 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		error = regmap_read(ddata->reg, CPCAP_REG_ADCAL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 				    &calibration_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		bank_conversion[CPCAP_ADC_BATTI].cal_offset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 			((short)calibration_data * -1) + 512;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	addr = CPCAP_REG_ADCD0 + req->bank_index * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	error = regmap_read(ddata->reg, addr, &req->result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	req->result &= 0x3ff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	cpcap_adc_phase(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	cpcap_adc_convert(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) static int cpcap_adc_init_request(struct cpcap_adc_request *req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 				  int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	req->channel = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	req->phase_tbl = bank_phasing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	req->conv_tbl = bank_conversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	switch (channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	case CPCAP_ADC_AD0 ... CPCAP_ADC_USB_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 		req->bank_index = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	case CPCAP_ADC_AD8 ... CPCAP_ADC_TSY2_AD15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 		req->bank_index = channel - 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	case CPCAP_ADC_BATTP_PI16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		req->bank_index = CPCAP_ADC_BATTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	case CPCAP_ADC_BATTI_PI17:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		req->bank_index = CPCAP_ADC_BATTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) static int cpcap_adc_read_st_die_temp(struct cpcap_adc *ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 				      int addr, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	error = regmap_read(ddata->reg, addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	*val -= 282;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	*val *= 114;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	*val += 25000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) static int cpcap_adc_read(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			  struct iio_chan_spec const *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			  int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	struct cpcap_adc *ddata = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	struct cpcap_adc_request req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	error = cpcap_adc_init_request(&req, chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		mutex_lock(&ddata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		error = cpcap_adc_start_bank(ddata, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		error = regmap_read(ddata->reg, chan->address, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		error = cpcap_adc_stop_bank(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		mutex_unlock(&ddata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 		mutex_lock(&ddata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		error = cpcap_adc_start_bank(ddata, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		if ((ddata->vendor == CPCAP_VENDOR_ST) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		    (chan->channel == CPCAP_ADC_AD3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			error = cpcap_adc_read_st_die_temp(ddata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 							   chan->address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 							   &req.result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 				goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 			error = cpcap_adc_read_bank_scaled(ddata, &req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 				goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		error = cpcap_adc_stop_bank(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 		mutex_unlock(&ddata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		*val = req.result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	return IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	mutex_unlock(&ddata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	dev_err(ddata->dev, "error reading ADC: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) static const struct iio_info cpcap_adc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	.read_raw = &cpcap_adc_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930)  * Configuration for Motorola mapphone series such as droid 4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931)  * Copied from the Motorola mapphone kernel tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) static const struct cpcap_adc_ato mapphone_adc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	.ato_in = 0x0480,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	.atox_in = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	.adc_ps_factor_in = 0x0200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	.atox_ps_factor_in = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	.ato_out = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	.atox_out = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	.adc_ps_factor_out = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	.atox_ps_factor_out = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) static const struct of_device_id cpcap_adc_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 		.compatible = "motorola,cpcap-adc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		.compatible = "motorola,mapphone-cpcap-adc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 		.data = &mapphone_adc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	{ /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) MODULE_DEVICE_TABLE(of, cpcap_adc_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) static int cpcap_adc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	struct cpcap_adc *ddata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*ddata));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (!indio_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		dev_err(&pdev->dev, "failed to allocate iio device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	ddata = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	ddata->ato = device_get_match_data(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	if (!ddata->ato)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	ddata->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	mutex_init(&ddata->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	init_waitqueue_head(&ddata->wq_data_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	indio_dev->channels = cpcap_adc_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	indio_dev->num_channels = ARRAY_SIZE(cpcap_adc_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	indio_dev->name = dev_name(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	indio_dev->info = &cpcap_adc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	if (!ddata->reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	error = cpcap_get_vendor(ddata->dev, ddata->reg, &ddata->vendor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	platform_set_drvdata(pdev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	ddata->irq = platform_get_irq_byname(pdev, "adcdone");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	if (ddata->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	error = devm_request_threaded_irq(&pdev->dev, ddata->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 					  cpcap_adc_irq_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 					  IRQF_TRIGGER_NONE | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 					  "cpcap-adc", indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		dev_err(&pdev->dev, "could not get irq: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	error = cpcap_adc_calibrate(ddata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	dev_info(&pdev->dev, "CPCAP ADC device probed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	return devm_iio_device_register(&pdev->dev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static struct platform_driver cpcap_adc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 		.name = "cpcap_adc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		.of_match_table = cpcap_adc_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	.probe = cpcap_adc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) module_platform_driver(cpcap_adc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) MODULE_ALIAS("platform:cpcap_adc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) MODULE_DESCRIPTION("CPCAP ADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) MODULE_AUTHOR("Tony Lindgren <tony@atomide.com");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) MODULE_LICENSE("GPL v2");