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)  * TWL6030 GPADC module driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2009-2013 Texas Instruments Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Nishant Kamat <nskamat@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Balaji T K <balajitk@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Graeme Gregory <gg@slimlogic.co.uk>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Girish S Ghongdemath <girishsg@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Ambresh K <ambresh@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Oleksandr Kozaruk <oleksandr.kozaruk@ti.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Based on twl4030-madc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * Copyright (C) 2008 Nokia Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  * Mikko Ylinen <mikko.k.ylinen@nokia.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/mfd/twl.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/sysfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define DRIVER_NAME		"twl6030_gpadc"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * twl6030 per TRM has 17 channels, and twl6032 has 19 channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * 2 test network channels are not used,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  * 2 die temperature channels are not used either, as it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * defined how to convert ADC value to temperature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define TWL6030_GPADC_USED_CHANNELS		13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define TWL6030_GPADC_MAX_CHANNELS		15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define TWL6032_GPADC_USED_CHANNELS		15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define TWL6032_GPADC_MAX_CHANNELS		19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define TWL6030_GPADC_NUM_TRIM_REGS		16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define TWL6030_GPADC_CTRL_P1			0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define TWL6032_GPADC_GPSELECT_ISB		0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define TWL6032_GPADC_CTRL_P1			0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define TWL6032_GPADC_GPCH0_LSB			0x0d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define TWL6032_GPADC_GPCH0_MSB			0x0e
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define TWL6030_GPADC_CTRL_P1_SP1		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define TWL6030_GPADC_GPCH0_LSB			(0x29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define TWL6030_GPADC_RT_SW1_EOC_MASK		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define TWL6030_GPADC_TRIM1			0xCD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define TWL6030_REG_TOGGLE1			0x90
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define TWL6030_GPADCS				BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define TWL6030_GPADCR				BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * struct twl6030_chnl_calib - channel calibration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * @gain:		slope coefficient for ideal curve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * @gain_error:		gain error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * @offset_error:	offset of the real curve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) struct twl6030_chnl_calib {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	s32 gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	s32 gain_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	s32 offset_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  * struct twl6030_ideal_code - GPADC calibration parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * GPADC is calibrated in two points: close to the beginning and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * to the and of the measurable input range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * @channel:	channel number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * @code1:	ideal code for the input at the beginning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * @code2:	ideal code for at the end of the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * @volt1:	voltage input at the beginning(low voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * @volt2:	voltage input at the end(high voltage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) struct twl6030_ideal_code {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	int channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	u16 code1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	u16 code2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	u16 volt1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	u16 volt2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) struct twl6030_gpadc_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * struct twl6030_gpadc_platform_data - platform specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * @nchannels:		number of GPADC channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * @iio_channels:	iio channels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  * @ideal:		pointer to calibration parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * @start_conversion:	pointer to ADC start conversion function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * @channel_to_reg:	pointer to ADC function to convert channel to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  *			register address for reading conversion result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * @calibrate:		pointer to calibration function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct twl6030_gpadc_platform_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	const int nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	const struct iio_chan_spec *iio_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	const struct twl6030_ideal_code *ideal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	int (*start_conversion)(int channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	u8 (*channel_to_reg)(int channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	int (*calibrate)(struct twl6030_gpadc_data *gpadc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * struct twl6030_gpadc_data - GPADC data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * @dev:		device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * @lock:		mutual exclusion lock for the structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * @irq_complete:	completion to signal end of conversion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * @twl6030_cal_tbl:	pointer to calibration data for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  *			channel with gain error and offset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * @pdata:		pointer to device specific data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct twl6030_gpadc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	struct device	*dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	struct mutex	lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	struct completion	irq_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct twl6030_chnl_calib	*twl6030_cal_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	const struct twl6030_gpadc_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * channels 11, 12, 13, 15 and 16 have no calibration data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * calibration offset is same for channels 1, 3, 4, 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  * The data is taken from GPADC_TRIM registers description.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * GPADC_TRIM registers keep difference between the code measured
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * at volt1 and volt2 input voltages and corresponding code1 and code2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static const struct twl6030_ideal_code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	twl6030_ideal[TWL6030_GPADC_USED_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	[0] = { /* ch 0, external, battery type, resistor value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		.channel = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		.code1 = 116,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		.code2 = 745,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		.volt1 = 141,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		.volt2 = 910,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	[1] = { /* ch 1, external, battery temperature, NTC resistor value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		.channel = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		.code1 = 82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		.code2 = 900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		.volt1 = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		.volt2 = 1100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	[2] = { /* ch 2, external, audio accessory/general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		.channel = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		.code1 = 55,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		.code2 = 818,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		.volt1 = 101,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		.volt2 = 1499,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	[3] = { /* ch 3, external, general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		.channel = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		.code1 = 82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		.code2 = 900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		.volt1 = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		.volt2 = 1100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	[4] = { /* ch 4, external, temperature measurement/general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 		.channel = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		.code1 = 82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		.code2 = 900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		.volt1 = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		.volt2 = 1100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	[5] = { /* ch 5, external, general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		.channel = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		.code1 = 82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		.code2 = 900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		.volt1 = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		.volt2 = 1100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	[6] = { /* ch 6, external, general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		.channel = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		.code1 = 82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		.code2 = 900,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		.volt1 = 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		.volt2 = 1100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	[7] = { /* ch 7, internal, main battery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		.channel = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		.code1 = 614,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		.code2 = 941,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		.volt1 = 3001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		.volt2 = 4599,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	[8] = { /* ch 8, internal, backup battery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		.channel = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		.code1 = 82,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		.code2 = 688,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		.volt1 = 501,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		.volt2 = 4203,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	[9] = { /* ch 9, internal, external charger input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		.channel = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		.code1 = 182,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		.code2 = 818,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		.volt1 = 2001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		.volt2 = 8996,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	[10] = { /* ch 10, internal, VBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		.channel = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		.code1 = 149,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		.code2 = 818,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		.volt1 = 1001,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		.volt2 = 5497,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	[11] = { /* ch 11, internal, VBUS charging current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		.channel = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		/* ch 12, internal, Die temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		/* ch 13, internal, Die temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	[12] = { /* ch 14, internal, USB ID line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		.channel = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		.code1 = 48,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		.code2 = 714,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		.volt1 = 323,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		.volt2 = 4800,
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static const struct twl6030_ideal_code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 			twl6032_ideal[TWL6032_GPADC_USED_CHANNELS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	[0] = { /* ch 0, external, battery type, resistor value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		.channel = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		.volt1 = 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		.volt2 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	[1] = { /* ch 1, external, battery temperature, NTC resistor value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		.channel = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		.volt1 = 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		.volt2 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	[2] = { /* ch 2, external, audio accessory/general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		.channel = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		.volt1 = 660,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		.volt2 = 1500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	[3] = { /* ch 3, external, temperature with external diode/general
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 								purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		.channel = 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		.volt1 = 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		.volt2 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	[4] = { /* ch 4, external, temperature measurement/general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		.channel = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		.volt1 = 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		.volt2 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	[5] = { /* ch 5, external, general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		.channel = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		.volt1 = 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		.volt2 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	[6] = { /* ch 6, external, general purpose */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		.channel = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		.volt1 = 440,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 		.volt2 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	[7] = { /* ch7, internal, system supply */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		.channel = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		.volt1 = 2200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		.volt2 = 5000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	[8] = { /* ch8, internal, backup battery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		.channel = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		.volt1 = 2200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		.volt2 = 5000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	[9] = { /* ch 9, internal, external charger input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		.channel = 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		.volt1 = 3960,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		.volt2 = 9000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	[10] = { /* ch10, internal, VBUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		.channel = 10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		.code1 = 150,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		.code2 = 751,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		.volt1 = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		.volt2 = 5000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	[11] = { /* ch 11, internal, VBUS DC-DC output current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		.channel = 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 		.volt1 = 660,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		.volt2 = 1500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		/* ch 12, internal, Die temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		/* ch 13, internal, Die temperature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	[12] = { /* ch 14, internal, USB ID line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		.channel = 14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		.volt1 = 2420,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		.volt2 = 5500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		/* ch 15, internal, test network */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		/* ch 16, internal, test network */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	[13] = { /* ch 17, internal, battery charging current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		.channel = 17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	[14] = { /* ch 18, internal, battery voltage */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		.channel = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		.code1 = 1441,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		.code2 = 3276,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		.volt1 = 2200,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		.volt2 = 5000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) static inline int twl6030_gpadc_write(u8 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	return twl_i2c_write_u8(TWL6030_MODULE_GPADC, val, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) static inline int twl6030_gpadc_read(u8 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	return twl_i2c_read(TWL6030_MODULE_GPADC, val, reg, 2);
^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) static int twl6030_gpadc_enable_irq(u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_LINE_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	ret = twl6030_interrupt_unmask(mask, REG_INT_MSK_STS_B);
^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 void twl6030_gpadc_disable_irq(u8 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	twl6030_interrupt_mask(mask, REG_INT_MSK_LINE_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	twl6030_interrupt_mask(mask, REG_INT_MSK_STS_B);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static irqreturn_t twl6030_gpadc_irq_handler(int irq, void *indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	complete(&gpadc->irq_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static int twl6030_start_conversion(int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	return twl6030_gpadc_write(TWL6030_GPADC_CTRL_P1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 					TWL6030_GPADC_CTRL_P1_SP1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) static int twl6032_start_conversion(int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	ret = twl6030_gpadc_write(TWL6032_GPADC_GPSELECT_ISB, channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	return twl6030_gpadc_write(TWL6032_GPADC_CTRL_P1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 						TWL6030_GPADC_CTRL_P1_SP1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static u8 twl6030_channel_to_reg(int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	return TWL6030_GPADC_GPCH0_LSB + 2 * channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static u8 twl6032_channel_to_reg(int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	 * for any prior chosen channel, when the conversion is ready
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	 * the result is avalable in GPCH0_LSB, GPCH0_MSB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	return TWL6032_GPADC_GPCH0_LSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static int twl6030_gpadc_lookup(const struct twl6030_ideal_code *ideal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		int channel, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		if (ideal[i].channel == channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) static int twl6030_channel_calibrated(const struct twl6030_gpadc_platform_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		*pdata, int channel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	const struct twl6030_ideal_code *ideal = pdata->ideal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	i = twl6030_gpadc_lookup(ideal, channel, pdata->nchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	/* not calibrated channels have 0 in all structure members */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	return pdata->ideal[i].code2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int twl6030_gpadc_make_correction(struct twl6030_gpadc_data *gpadc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		int channel, int raw_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	int corrected_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	corrected_code = ((raw_code * 1000) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		gpadc->twl6030_cal_tbl[i].offset_error) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		gpadc->twl6030_cal_tbl[i].gain_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	return corrected_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static int twl6030_gpadc_get_raw(struct twl6030_gpadc_data *gpadc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		int channel, int *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	u8 reg = gpadc->pdata->channel_to_reg(channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	__le16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	int raw_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	ret = twl6030_gpadc_read(reg, (u8 *)&val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		dev_dbg(gpadc->dev, "unable to read register 0x%X\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		return ret;
^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) 	raw_code = le16_to_cpu(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	dev_dbg(gpadc->dev, "GPADC raw code: %d", raw_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (twl6030_channel_calibrated(gpadc->pdata, channel))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		*res = twl6030_gpadc_make_correction(gpadc, channel, raw_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		*res = raw_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static int twl6030_gpadc_get_processed(struct twl6030_gpadc_data *gpadc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		int channel, int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	int corrected_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	int channel_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	ret = twl6030_gpadc_get_raw(gpadc, channel, &corrected_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	channel_value = corrected_code *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			gpadc->twl6030_cal_tbl[i].gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	/* Shift back into mV range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	channel_value /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	dev_dbg(gpadc->dev, "GPADC corrected code: %d", corrected_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	dev_dbg(gpadc->dev, "GPADC value: %d", channel_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	*val = channel_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static int twl6030_gpadc_read_raw(struct iio_dev *indio_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 			     const struct iio_chan_spec *chan,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 			     int *val, int *val2, long mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	struct twl6030_gpadc_data *gpadc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	mutex_lock(&gpadc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	ret = gpadc->pdata->start_conversion(chan->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		dev_err(gpadc->dev, "failed to start conversion\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	/* wait for conversion to complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	timeout = wait_for_completion_interruptible_timeout(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 				&gpadc->irq_complete, msecs_to_jiffies(5000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 		ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	} else if (timeout < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 		ret = -EINTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	switch (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	case IIO_CHAN_INFO_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		ret = twl6030_gpadc_get_raw(gpadc, chan->channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		ret = ret ? -EIO : IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	case IIO_CHAN_INFO_PROCESSED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		ret = twl6030_gpadc_get_processed(gpadc, chan->channel, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		ret = ret ? -EIO : IIO_VAL_INT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 	mutex_unlock(&gpadc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)  * The GPADC channels are calibrated using a two point calibration method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)  * The channels measured with two known values: volt1 and volt2, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)  * ideal corresponding output codes are known: code1, code2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)  * The difference(d1, d2) between ideal and measured codes stored in trim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)  * registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)  * The goal is to find offset and gain of the real curve for each calibrated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)  * channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)  * gain: k = 1 + ((d2 - d1) / (x2 - x1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)  * offset: b = d1 + (k - 1) * x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static void twl6030_calibrate_channel(struct twl6030_gpadc_data *gpadc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		int channel, int d1, int d2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	int b, k, gain, x1, x2, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	const struct twl6030_ideal_code *ideal = gpadc->pdata->ideal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	i = twl6030_gpadc_lookup(ideal, channel, gpadc->pdata->nchannels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	/* Gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	gain = ((ideal[i].volt2 - ideal[i].volt1) * 1000) /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		(ideal[i].code2 - ideal[i].code1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	x1 = ideal[i].code1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	x2 = ideal[i].code2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	/* k - real curve gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	k = 1000 + (((d2 - d1) * 1000) / (x2 - x1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	/* b - offset of the real curve gain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	b = (d1 * 1000) - (k - 1000) * x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	gpadc->twl6030_cal_tbl[i].gain = gain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	gpadc->twl6030_cal_tbl[i].gain_error = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	gpadc->twl6030_cal_tbl[i].offset_error = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	dev_dbg(gpadc->dev, "GPADC d1   for Chn: %d = %d\n", channel, d1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	dev_dbg(gpadc->dev, "GPADC d2   for Chn: %d = %d\n", channel, d2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	dev_dbg(gpadc->dev, "GPADC x1   for Chn: %d = %d\n", channel, x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	dev_dbg(gpadc->dev, "GPADC x2   for Chn: %d = %d\n", channel, x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	dev_dbg(gpadc->dev, "GPADC Gain for Chn: %d = %d\n", channel, gain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	dev_dbg(gpadc->dev, "GPADC k    for Chn: %d = %d\n", channel, k);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	dev_dbg(gpadc->dev, "GPADC b    for Chn: %d = %d\n", channel, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static inline int twl6030_gpadc_get_trim_offset(s8 d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	 * XXX NOTE!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	 * bit 0 - sign, bit 7 - reserved, 6..1 - trim value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	 * though, the documentation states that trim value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	 * is absolute value, the correct conversion results are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	 * obtained if the value is interpreted as 2's complement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	__u32 temp = ((d & 0x7f) >> 1) | ((d & 1) << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	return sign_extend32(temp, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static int twl6030_calibration(struct twl6030_gpadc_data *gpadc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	int chn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	s8 d1, d2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	 * for calibration two measurements have been performed at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	 * factory, for some channels, during the production test and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	 * have been stored in registers. This two stored values are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	 * used to correct the measurements. The values represent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	 * offsets for the given input from the output on ideal curve.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 		dev_err(gpadc->dev, "calibration failed\n");
^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) 	for (chn = 0; chn < TWL6030_GPADC_MAX_CHANNELS; chn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 		switch (chn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 			d1 = trim_regs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 			d2 = trim_regs[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 		case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 		case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 		case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 		case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) 		case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 			d1 = trim_regs[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 			d2 = trim_regs[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 		case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 			d1 = trim_regs[12];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 			d2 = trim_regs[13];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 		case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 			d1 = trim_regs[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 			d2 = trim_regs[7];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 		case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 			d1 = trim_regs[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 			d2 = trim_regs[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 		case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 			d1 = trim_regs[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 			d2 = trim_regs[9];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 			d1 = trim_regs[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 			d2 = trim_regs[11];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 		case 14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 			d1 = trim_regs[14];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 			d2 = trim_regs[15];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 			continue;
^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) 		d1 = twl6030_gpadc_get_trim_offset(d1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		d2 = twl6030_gpadc_get_trim_offset(d2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 		twl6030_calibrate_channel(gpadc, chn, d1, d2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int twl6032_get_trim_value(u8 *trim_regs, unsigned int reg0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 		unsigned int reg1, unsigned int mask0, unsigned int mask1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 		unsigned int shift0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 	val = (trim_regs[reg0] & mask0) << shift0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	val |= (trim_regs[reg1] & mask1) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 	if (trim_regs[reg1] & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		val = -val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) static int twl6032_calibration(struct twl6030_gpadc_data *gpadc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	int chn, d1 = 0, d2 = 0, temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 	u8 trim_regs[TWL6030_GPADC_NUM_TRIM_REGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 	ret = twl_i2c_read(TWL6030_MODULE_ID2, trim_regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 			TWL6030_GPADC_TRIM1, TWL6030_GPADC_NUM_TRIM_REGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 		dev_err(gpadc->dev, "calibration failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 	 * Loop to calculate the value needed for returning voltages from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	 * GPADC not values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 	 * gain is calculated to 3 decimal places fixed point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 	for (chn = 0; chn < TWL6032_GPADC_MAX_CHANNELS; chn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 		switch (chn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 		case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 		case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 		case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 		case 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 		case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 		case 11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		case 14:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 			d1 = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 			d2 = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 			temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 			d1 = temp + twl6032_get_trim_value(trim_regs, 7, 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 								0x18, 0x1E, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 			temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 			d2 = temp + twl6032_get_trim_value(trim_regs, 9, 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 								0x1F, 0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		case 9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 			temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 			d1 = temp + twl6032_get_trim_value(trim_regs, 13, 11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 								0x18, 0x1E, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 			temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 			d2 = temp + twl6032_get_trim_value(trim_regs, 15, 13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 								0x1F, 0x06, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 			d1 = twl6032_get_trim_value(trim_regs, 10, 8, 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 								0x0E, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 			d2 = twl6032_get_trim_value(trim_regs, 14, 12, 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 								0x0E, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		case 7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		case 18:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 			temp = twl6032_get_trim_value(trim_regs, 2, 0, 0x1f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 			d1 = (trim_regs[4] & 0x7E) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 			if (trim_regs[4] & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 				d1 = -d1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 			d1 += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 			temp = twl6032_get_trim_value(trim_regs, 3, 1, 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 								0x06, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 			d2 = (trim_regs[5] & 0xFE) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 			if (trim_regs[5] & 0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 				d2 = -d2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 			d2 += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 			/* No data for other channels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 			continue;
^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) 		twl6030_calibrate_channel(gpadc, chn, d1, d2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) #define TWL6030_GPADC_CHAN(chn, _type, chan_info) {	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 	.type = _type,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 	.channel = chn,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 	.info_mask_separate = BIT(chan_info),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 	.indexed = 1,					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) static const struct iio_chan_spec twl6030_gpadc_iio_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 	TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 	TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 	TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 	TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 	TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 	TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 	TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 	TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 	TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 	TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 	TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 	TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 	TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) static const struct iio_chan_spec twl6032_gpadc_iio_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) 	TWL6030_GPADC_CHAN(0, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 	TWL6030_GPADC_CHAN(1, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 	TWL6030_GPADC_CHAN(2, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 	TWL6030_GPADC_CHAN(3, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 	TWL6030_GPADC_CHAN(4, IIO_TEMP, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 	TWL6030_GPADC_CHAN(5, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 	TWL6030_GPADC_CHAN(6, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 	TWL6030_GPADC_CHAN(7, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 	TWL6030_GPADC_CHAN(8, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 	TWL6030_GPADC_CHAN(9, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 	TWL6030_GPADC_CHAN(10, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 	TWL6030_GPADC_CHAN(11, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 	TWL6030_GPADC_CHAN(14, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 	TWL6030_GPADC_CHAN(17, IIO_VOLTAGE, IIO_CHAN_INFO_RAW),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) 	TWL6030_GPADC_CHAN(18, IIO_VOLTAGE, IIO_CHAN_INFO_PROCESSED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static const struct iio_info twl6030_gpadc_iio_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 	.read_raw = &twl6030_gpadc_read_raw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static const struct twl6030_gpadc_platform_data twl6030_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 	.iio_channels = twl6030_gpadc_iio_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 	.nchannels = TWL6030_GPADC_USED_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 	.ideal = twl6030_ideal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 	.start_conversion = twl6030_start_conversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 	.channel_to_reg = twl6030_channel_to_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 	.calibrate = twl6030_calibration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static const struct twl6030_gpadc_platform_data twl6032_pdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 	.iio_channels = twl6032_gpadc_iio_channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 	.nchannels = TWL6032_GPADC_USED_CHANNELS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 	.ideal = twl6032_ideal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) 	.start_conversion = twl6032_start_conversion,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 	.channel_to_reg = twl6032_channel_to_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 	.calibrate = twl6032_calibration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) static const struct of_device_id of_twl6030_match_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 		.compatible = "ti,twl6030-gpadc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 		.data = &twl6030_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 		.compatible = "ti,twl6032-gpadc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) 		.data = &twl6032_pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 	{ /* end */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) MODULE_DEVICE_TABLE(of, of_twl6030_match_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) static int twl6030_gpadc_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	struct twl6030_gpadc_data *gpadc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 	const struct twl6030_gpadc_platform_data *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 	struct iio_dev *indio_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 	int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	match = of_match_device(of_twl6030_match_tbl, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	if (!match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 	pdata = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) 	indio_dev = devm_iio_device_alloc(dev, sizeof(*gpadc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) 	if (!indio_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) 	gpadc = iio_priv(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) 	gpadc->twl6030_cal_tbl = devm_kcalloc(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) 					pdata->nchannels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) 					sizeof(*gpadc->twl6030_cal_tbl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 					GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 	if (!gpadc->twl6030_cal_tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 	gpadc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 	gpadc->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 	platform_set_drvdata(pdev, indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 	mutex_init(&gpadc->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 	init_completion(&gpadc->irq_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 	ret = pdata->calibrate(gpadc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 		dev_err(&pdev->dev, "failed to read calibration registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 	irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 	if (irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		return irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 	ret = devm_request_threaded_irq(dev, irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 				twl6030_gpadc_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 				IRQF_ONESHOT, "twl6030_gpadc", indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	ret = twl6030_gpadc_enable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 		dev_err(&pdev->dev, "failed to enable GPADC interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) 					TWL6030_REG_TOGGLE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 	if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 		dev_err(&pdev->dev, "failed to enable GPADC module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) 		return ret;
^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) 	indio_dev->name = DRIVER_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) 	indio_dev->info = &twl6030_gpadc_iio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) 	indio_dev->modes = INDIO_DIRECT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	indio_dev->channels = pdata->iio_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	indio_dev->num_channels = pdata->nchannels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 	return iio_device_register(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int twl6030_gpadc_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 	twl6030_gpadc_disable_irq(TWL6030_GPADC_RT_SW1_EOC_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) 	iio_device_unregister(indio_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) 	return 0;
^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) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static int twl6030_gpadc_suspend(struct device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) 	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) 				TWL6030_REG_TOGGLE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) 		dev_err(pdev, "error resetting GPADC (%d)!\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static int twl6030_gpadc_resume(struct device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) 	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, TWL6030_GPADCS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) 				TWL6030_REG_TOGGLE1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) 		dev_err(pdev, "error setting GPADC (%d)!\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static SIMPLE_DEV_PM_OPS(twl6030_gpadc_pm_ops, twl6030_gpadc_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) 					twl6030_gpadc_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static struct platform_driver twl6030_gpadc_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) 	.probe		= twl6030_gpadc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) 	.remove		= twl6030_gpadc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) 	.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) 		.name	= DRIVER_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) 		.pm	= &twl6030_gpadc_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) 		.of_match_table = of_twl6030_match_tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) module_platform_driver(twl6030_gpadc_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) MODULE_ALIAS("platform:" DRIVER_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) MODULE_AUTHOR("Balaji T K <balajitk@ti.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) MODULE_AUTHOR("Oleksandr Kozaruk <oleksandr.kozaruk@ti.com");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) MODULE_DESCRIPTION("twl6030 ADC driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) MODULE_LICENSE("GPL");