cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ingenic-adc.c (24667B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ADC driver for the Ingenic JZ47xx SoCs
      4 * Copyright (c) 2019 Artur Rojek <contact@artur-rojek.eu>
      5 *
      6 * based on drivers/mfd/jz4740-adc.c
      7 */
      8
      9#include <dt-bindings/iio/adc/ingenic,adc.h>
     10#include <linux/clk.h>
     11#include <linux/iio/buffer.h>
     12#include <linux/iio/iio.h>
     13#include <linux/interrupt.h>
     14#include <linux/io.h>
     15#include <linux/iopoll.h>
     16#include <linux/kernel.h>
     17#include <linux/module.h>
     18#include <linux/mod_devicetable.h>
     19#include <linux/mutex.h>
     20#include <linux/platform_device.h>
     21
     22#define JZ_ADC_REG_ENABLE		0x00
     23#define JZ_ADC_REG_CFG			0x04
     24#define JZ_ADC_REG_CTRL			0x08
     25#define JZ_ADC_REG_STATUS		0x0c
     26#define JZ_ADC_REG_ADSAME		0x10
     27#define JZ_ADC_REG_ADWAIT		0x14
     28#define JZ_ADC_REG_ADTCH		0x18
     29#define JZ_ADC_REG_ADBDAT		0x1c
     30#define JZ_ADC_REG_ADSDAT		0x20
     31#define JZ_ADC_REG_ADCMD		0x24
     32#define JZ_ADC_REG_ADCLK		0x28
     33
     34#define JZ_ADC_REG_ENABLE_PD		BIT(7)
     35#define JZ_ADC_REG_CFG_AUX_MD		(BIT(0) | BIT(1))
     36#define JZ_ADC_REG_CFG_BAT_MD		BIT(4)
     37#define JZ_ADC_REG_CFG_SAMPLE_NUM(n)	((n) << 10)
     38#define JZ_ADC_REG_CFG_PULL_UP(n)	((n) << 16)
     39#define JZ_ADC_REG_CFG_CMD_SEL		BIT(22)
     40#define JZ_ADC_REG_CFG_VBAT_SEL		BIT(30)
     41#define JZ_ADC_REG_CFG_TOUCH_OPS_MASK	(BIT(31) | GENMASK(23, 10))
     42#define JZ_ADC_REG_ADCLK_CLKDIV_LSB	0
     43#define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB	16
     44#define JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB	8
     45#define JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB	16
     46
     47#define JZ_ADC_REG_ADCMD_YNADC		BIT(7)
     48#define JZ_ADC_REG_ADCMD_YPADC		BIT(8)
     49#define JZ_ADC_REG_ADCMD_XNADC		BIT(9)
     50#define JZ_ADC_REG_ADCMD_XPADC		BIT(10)
     51#define JZ_ADC_REG_ADCMD_VREFPYP	BIT(11)
     52#define JZ_ADC_REG_ADCMD_VREFPXP	BIT(12)
     53#define JZ_ADC_REG_ADCMD_VREFPXN	BIT(13)
     54#define JZ_ADC_REG_ADCMD_VREFPAUX	BIT(14)
     55#define JZ_ADC_REG_ADCMD_VREFPVDD33	BIT(15)
     56#define JZ_ADC_REG_ADCMD_VREFNYN	BIT(16)
     57#define JZ_ADC_REG_ADCMD_VREFNXP	BIT(17)
     58#define JZ_ADC_REG_ADCMD_VREFNXN	BIT(18)
     59#define JZ_ADC_REG_ADCMD_VREFAUX	BIT(19)
     60#define JZ_ADC_REG_ADCMD_YNGRU		BIT(20)
     61#define JZ_ADC_REG_ADCMD_XNGRU		BIT(21)
     62#define JZ_ADC_REG_ADCMD_XPGRU		BIT(22)
     63#define JZ_ADC_REG_ADCMD_YPSUP		BIT(23)
     64#define JZ_ADC_REG_ADCMD_XNSUP		BIT(24)
     65#define JZ_ADC_REG_ADCMD_XPSUP		BIT(25)
     66
     67#define JZ_ADC_AUX_VREF				3300
     68#define JZ_ADC_AUX_VREF_BITS			12
     69#define JZ_ADC_BATTERY_LOW_VREF			2500
     70#define JZ_ADC_BATTERY_LOW_VREF_BITS		12
     71#define JZ4725B_ADC_BATTERY_HIGH_VREF		7500
     72#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS	10
     73#define JZ4740_ADC_BATTERY_HIGH_VREF		(7500 * 0.986)
     74#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS	12
     75#define JZ4760_ADC_BATTERY_VREF			2500
     76#define JZ4770_ADC_BATTERY_VREF			1200
     77#define JZ4770_ADC_BATTERY_VREF_BITS		12
     78
     79#define JZ_ADC_IRQ_AUX			BIT(0)
     80#define JZ_ADC_IRQ_BATTERY		BIT(1)
     81#define JZ_ADC_IRQ_TOUCH		BIT(2)
     82#define JZ_ADC_IRQ_PEN_DOWN		BIT(3)
     83#define JZ_ADC_IRQ_PEN_UP		BIT(4)
     84#define JZ_ADC_IRQ_PEN_DOWN_SLEEP	BIT(5)
     85#define JZ_ADC_IRQ_SLEEP		BIT(7)
     86
     87struct ingenic_adc;
     88
     89struct ingenic_adc_soc_data {
     90	unsigned int battery_high_vref;
     91	unsigned int battery_high_vref_bits;
     92	const int *battery_raw_avail;
     93	size_t battery_raw_avail_size;
     94	const int *battery_scale_avail;
     95	size_t battery_scale_avail_size;
     96	unsigned int battery_vref_mode: 1;
     97	unsigned int has_aux_md: 1;
     98	const struct iio_chan_spec *channels;
     99	unsigned int num_channels;
    100	int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
    101};
    102
    103struct ingenic_adc {
    104	void __iomem *base;
    105	struct clk *clk;
    106	struct mutex lock;
    107	struct mutex aux_lock;
    108	const struct ingenic_adc_soc_data *soc_data;
    109	bool low_vref_mode;
    110};
    111
    112static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)
    113{
    114	struct ingenic_adc *adc = iio_priv(iio_dev);
    115
    116	mutex_lock(&adc->lock);
    117
    118	/* Init ADCMD */
    119	readl(adc->base + JZ_ADC_REG_ADCMD);
    120
    121	if (mask & 0x3) {
    122		/* Second channel (INGENIC_ADC_TOUCH_YP): sample YP vs. GND */
    123		writel(JZ_ADC_REG_ADCMD_XNGRU
    124		       | JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33
    125		       | JZ_ADC_REG_ADCMD_YPADC,
    126		       adc->base + JZ_ADC_REG_ADCMD);
    127
    128		/* First channel (INGENIC_ADC_TOUCH_XP): sample XP vs. GND */
    129		writel(JZ_ADC_REG_ADCMD_YNGRU
    130		       | JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33
    131		       | JZ_ADC_REG_ADCMD_XPADC,
    132		       adc->base + JZ_ADC_REG_ADCMD);
    133	}
    134
    135	if (mask & 0xc) {
    136		/* Fourth channel (INGENIC_ADC_TOUCH_YN): sample YN vs. GND */
    137		writel(JZ_ADC_REG_ADCMD_XNGRU
    138		       | JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33
    139		       | JZ_ADC_REG_ADCMD_YNADC,
    140		       adc->base + JZ_ADC_REG_ADCMD);
    141
    142		/* Third channel (INGENIC_ADC_TOUCH_XN): sample XN vs. GND */
    143		writel(JZ_ADC_REG_ADCMD_YNGRU
    144		       | JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33
    145		       | JZ_ADC_REG_ADCMD_XNADC,
    146		       adc->base + JZ_ADC_REG_ADCMD);
    147	}
    148
    149	if (mask & 0x30) {
    150		/* Sixth channel (INGENIC_ADC_TOUCH_YD): sample YP vs. YN */
    151		writel(JZ_ADC_REG_ADCMD_VREFNYN | JZ_ADC_REG_ADCMD_VREFPVDD33
    152		       | JZ_ADC_REG_ADCMD_YPADC,
    153		       adc->base + JZ_ADC_REG_ADCMD);
    154
    155		/* Fifth channel (INGENIC_ADC_TOUCH_XD): sample XP vs. XN */
    156		writel(JZ_ADC_REG_ADCMD_VREFNXN | JZ_ADC_REG_ADCMD_VREFPVDD33
    157		       | JZ_ADC_REG_ADCMD_XPADC,
    158		       adc->base + JZ_ADC_REG_ADCMD);
    159	}
    160
    161	/* We're done */
    162	writel(0, adc->base + JZ_ADC_REG_ADCMD);
    163
    164	mutex_unlock(&adc->lock);
    165}
    166
    167static void ingenic_adc_set_config(struct ingenic_adc *adc,
    168				   uint32_t mask,
    169				   uint32_t val)
    170{
    171	uint32_t cfg;
    172
    173	mutex_lock(&adc->lock);
    174
    175	cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
    176	cfg |= val;
    177	writel(cfg, adc->base + JZ_ADC_REG_CFG);
    178
    179	mutex_unlock(&adc->lock);
    180}
    181
    182static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,
    183					int engine,
    184					bool enabled)
    185{
    186	u8 val;
    187
    188	val = readb(adc->base + JZ_ADC_REG_ENABLE);
    189
    190	if (enabled)
    191		val |= BIT(engine);
    192	else
    193		val &= ~BIT(engine);
    194
    195	writeb(val, adc->base + JZ_ADC_REG_ENABLE);
    196}
    197
    198static void ingenic_adc_enable(struct ingenic_adc *adc,
    199			       int engine,
    200			       bool enabled)
    201{
    202	mutex_lock(&adc->lock);
    203	ingenic_adc_enable_unlocked(adc, engine, enabled);
    204	mutex_unlock(&adc->lock);
    205}
    206
    207static int ingenic_adc_capture(struct ingenic_adc *adc,
    208			       int engine)
    209{
    210	u32 cfg;
    211	u8 val;
    212	int ret;
    213
    214	/*
    215	 * Disable CMD_SEL temporarily, because it causes wrong VBAT readings,
    216	 * probably due to the switch of VREF. We must keep the lock here to
    217	 * avoid races with the buffer enable/disable functions.
    218	 */
    219	mutex_lock(&adc->lock);
    220	cfg = readl(adc->base + JZ_ADC_REG_CFG);
    221	writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base + JZ_ADC_REG_CFG);
    222
    223	ingenic_adc_enable_unlocked(adc, engine, true);
    224	ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,
    225				 !(val & BIT(engine)), 250, 1000);
    226	if (ret)
    227		ingenic_adc_enable_unlocked(adc, engine, false);
    228
    229	writel(cfg, adc->base + JZ_ADC_REG_CFG);
    230	mutex_unlock(&adc->lock);
    231
    232	return ret;
    233}
    234
    235static int ingenic_adc_write_raw(struct iio_dev *iio_dev,
    236				 struct iio_chan_spec const *chan,
    237				 int val,
    238				 int val2,
    239				 long m)
    240{
    241	struct ingenic_adc *adc = iio_priv(iio_dev);
    242	struct device *dev = iio_dev->dev.parent;
    243	int ret;
    244
    245	switch (m) {
    246	case IIO_CHAN_INFO_SCALE:
    247		switch (chan->channel) {
    248		case INGENIC_ADC_BATTERY:
    249			if (!adc->soc_data->battery_vref_mode)
    250				return -EINVAL;
    251
    252			ret = clk_enable(adc->clk);
    253			if (ret) {
    254				dev_err(dev, "Failed to enable clock: %d\n",
    255					ret);
    256				return ret;
    257			}
    258
    259			if (val > JZ_ADC_BATTERY_LOW_VREF) {
    260				ingenic_adc_set_config(adc,
    261						       JZ_ADC_REG_CFG_BAT_MD,
    262						       0);
    263				adc->low_vref_mode = false;
    264			} else {
    265				ingenic_adc_set_config(adc,
    266						       JZ_ADC_REG_CFG_BAT_MD,
    267						       JZ_ADC_REG_CFG_BAT_MD);
    268				adc->low_vref_mode = true;
    269			}
    270
    271			clk_disable(adc->clk);
    272
    273			return 0;
    274		default:
    275			return -EINVAL;
    276		}
    277	default:
    278		return -EINVAL;
    279	}
    280}
    281
    282static const int jz4725b_adc_battery_raw_avail[] = {
    283	0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
    284};
    285
    286static const int jz4725b_adc_battery_scale_avail[] = {
    287	JZ4725B_ADC_BATTERY_HIGH_VREF, JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
    288	JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
    289};
    290
    291static const int jz4740_adc_battery_raw_avail[] = {
    292	0, 1, (1 << JZ_ADC_BATTERY_LOW_VREF_BITS) - 1,
    293};
    294
    295static const int jz4740_adc_battery_scale_avail[] = {
    296	JZ4740_ADC_BATTERY_HIGH_VREF, JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
    297	JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
    298};
    299
    300static const int jz4760_adc_battery_scale_avail[] = {
    301	JZ4760_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
    302};
    303
    304static const int jz4770_adc_battery_raw_avail[] = {
    305	0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
    306};
    307
    308static const int jz4770_adc_battery_scale_avail[] = {
    309	JZ4770_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
    310};
    311
    312static int jz4725b_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
    313{
    314	struct clk *parent_clk;
    315	unsigned long parent_rate, rate;
    316	unsigned int div_main, div_10us;
    317
    318	parent_clk = clk_get_parent(adc->clk);
    319	if (!parent_clk) {
    320		dev_err(dev, "ADC clock has no parent\n");
    321		return -ENODEV;
    322	}
    323	parent_rate = clk_get_rate(parent_clk);
    324
    325	/*
    326	 * The JZ4725B ADC works at 500 kHz to 8 MHz.
    327	 * We pick the highest rate possible.
    328	 * In practice we typically get 6 MHz, half of the 12 MHz EXT clock.
    329	 */
    330	div_main = DIV_ROUND_UP(parent_rate, 8000000);
    331	div_main = clamp(div_main, 1u, 64u);
    332	rate = parent_rate / div_main;
    333	if (rate < 500000 || rate > 8000000) {
    334		dev_err(dev, "No valid divider for ADC main clock\n");
    335		return -EINVAL;
    336	}
    337
    338	/* We also need a divider that produces a 10us clock. */
    339	div_10us = DIV_ROUND_UP(rate, 100000);
    340
    341	writel(((div_10us - 1) << JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB) |
    342	       (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
    343	       adc->base + JZ_ADC_REG_ADCLK);
    344
    345	return 0;
    346}
    347
    348static int jz4770_adc_init_clk_div(struct device *dev, struct ingenic_adc *adc)
    349{
    350	struct clk *parent_clk;
    351	unsigned long parent_rate, rate;
    352	unsigned int div_main, div_ms, div_10us;
    353
    354	parent_clk = clk_get_parent(adc->clk);
    355	if (!parent_clk) {
    356		dev_err(dev, "ADC clock has no parent\n");
    357		return -ENODEV;
    358	}
    359	parent_rate = clk_get_rate(parent_clk);
    360
    361	/*
    362	 * The JZ4770 ADC works at 20 kHz to 200 kHz.
    363	 * We pick the highest rate possible.
    364	 */
    365	div_main = DIV_ROUND_UP(parent_rate, 200000);
    366	div_main = clamp(div_main, 1u, 256u);
    367	rate = parent_rate / div_main;
    368	if (rate < 20000 || rate > 200000) {
    369		dev_err(dev, "No valid divider for ADC main clock\n");
    370		return -EINVAL;
    371	}
    372
    373	/* We also need a divider that produces a 10us clock. */
    374	div_10us = DIV_ROUND_UP(rate, 10000);
    375	/* And another, which produces a 1ms clock. */
    376	div_ms = DIV_ROUND_UP(rate, 1000);
    377
    378	writel(((div_ms - 1) << JZ4770_ADC_REG_ADCLK_CLKDIVMS_LSB) |
    379	       ((div_10us - 1) << JZ4770_ADC_REG_ADCLK_CLKDIV10US_LSB) |
    380	       (div_main - 1) << JZ_ADC_REG_ADCLK_CLKDIV_LSB,
    381	       adc->base + JZ_ADC_REG_ADCLK);
    382
    383	return 0;
    384}
    385
    386static const struct iio_chan_spec jz4740_channels[] = {
    387	{
    388		.extend_name = "aux",
    389		.type = IIO_VOLTAGE,
    390		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    391				      BIT(IIO_CHAN_INFO_SCALE),
    392		.indexed = 1,
    393		.channel = INGENIC_ADC_AUX,
    394		.scan_index = -1,
    395	},
    396	{
    397		.extend_name = "battery",
    398		.type = IIO_VOLTAGE,
    399		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    400				      BIT(IIO_CHAN_INFO_SCALE),
    401		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
    402						BIT(IIO_CHAN_INFO_SCALE),
    403		.indexed = 1,
    404		.channel = INGENIC_ADC_BATTERY,
    405		.scan_index = -1,
    406	},
    407};
    408
    409static const struct iio_chan_spec jz4760_channels[] = {
    410	{
    411		.extend_name = "aux",
    412		.type = IIO_VOLTAGE,
    413		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    414				      BIT(IIO_CHAN_INFO_SCALE),
    415		.indexed = 1,
    416		.channel = INGENIC_ADC_AUX0,
    417		.scan_index = -1,
    418	},
    419	{
    420		.extend_name = "aux1",
    421		.type = IIO_VOLTAGE,
    422		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    423				      BIT(IIO_CHAN_INFO_SCALE),
    424		.indexed = 1,
    425		.channel = INGENIC_ADC_AUX,
    426		.scan_index = -1,
    427	},
    428	{
    429		.extend_name = "aux2",
    430		.type = IIO_VOLTAGE,
    431		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    432				      BIT(IIO_CHAN_INFO_SCALE),
    433		.indexed = 1,
    434		.channel = INGENIC_ADC_AUX2,
    435		.scan_index = -1,
    436	},
    437	{
    438		.extend_name = "battery",
    439		.type = IIO_VOLTAGE,
    440		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    441				      BIT(IIO_CHAN_INFO_SCALE),
    442		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
    443						BIT(IIO_CHAN_INFO_SCALE),
    444		.indexed = 1,
    445		.channel = INGENIC_ADC_BATTERY,
    446		.scan_index = -1,
    447	},
    448};
    449
    450static const struct iio_chan_spec jz4770_channels[] = {
    451	{
    452		.type = IIO_VOLTAGE,
    453		.indexed = 1,
    454		.channel = INGENIC_ADC_TOUCH_XP,
    455		.scan_index = 0,
    456		.scan_type = {
    457			.sign = 'u',
    458			.realbits = 12,
    459			.storagebits = 16,
    460		},
    461	},
    462	{
    463		.type = IIO_VOLTAGE,
    464		.indexed = 1,
    465		.channel = INGENIC_ADC_TOUCH_YP,
    466		.scan_index = 1,
    467		.scan_type = {
    468			.sign = 'u',
    469			.realbits = 12,
    470			.storagebits = 16,
    471		},
    472	},
    473	{
    474		.type = IIO_VOLTAGE,
    475		.indexed = 1,
    476		.channel = INGENIC_ADC_TOUCH_XN,
    477		.scan_index = 2,
    478		.scan_type = {
    479			.sign = 'u',
    480			.realbits = 12,
    481			.storagebits = 16,
    482		},
    483	},
    484	{
    485		.type = IIO_VOLTAGE,
    486		.indexed = 1,
    487		.channel = INGENIC_ADC_TOUCH_YN,
    488		.scan_index = 3,
    489		.scan_type = {
    490			.sign = 'u',
    491			.realbits = 12,
    492			.storagebits = 16,
    493		},
    494	},
    495	{
    496		.type = IIO_VOLTAGE,
    497		.indexed = 1,
    498		.channel = INGENIC_ADC_TOUCH_XD,
    499		.scan_index = 4,
    500		.scan_type = {
    501			.sign = 'u',
    502			.realbits = 12,
    503			.storagebits = 16,
    504		},
    505	},
    506	{
    507		.type = IIO_VOLTAGE,
    508		.indexed = 1,
    509		.channel = INGENIC_ADC_TOUCH_YD,
    510		.scan_index = 5,
    511		.scan_type = {
    512			.sign = 'u',
    513			.realbits = 12,
    514			.storagebits = 16,
    515		},
    516	},
    517	{
    518		.extend_name = "aux",
    519		.type = IIO_VOLTAGE,
    520		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    521				      BIT(IIO_CHAN_INFO_SCALE),
    522		.indexed = 1,
    523		.channel = INGENIC_ADC_AUX,
    524		.scan_index = -1,
    525	},
    526	{
    527		.extend_name = "battery",
    528		.type = IIO_VOLTAGE,
    529		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    530				      BIT(IIO_CHAN_INFO_SCALE),
    531		.info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
    532						BIT(IIO_CHAN_INFO_SCALE),
    533		.indexed = 1,
    534		.channel = INGENIC_ADC_BATTERY,
    535		.scan_index = -1,
    536	},
    537	{
    538		.extend_name = "aux2",
    539		.type = IIO_VOLTAGE,
    540		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    541				      BIT(IIO_CHAN_INFO_SCALE),
    542		.indexed = 1,
    543		.channel = INGENIC_ADC_AUX2,
    544		.scan_index = -1,
    545	},
    546};
    547
    548static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
    549	.battery_high_vref = JZ4725B_ADC_BATTERY_HIGH_VREF,
    550	.battery_high_vref_bits = JZ4725B_ADC_BATTERY_HIGH_VREF_BITS,
    551	.battery_raw_avail = jz4725b_adc_battery_raw_avail,
    552	.battery_raw_avail_size = ARRAY_SIZE(jz4725b_adc_battery_raw_avail),
    553	.battery_scale_avail = jz4725b_adc_battery_scale_avail,
    554	.battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
    555	.battery_vref_mode = true,
    556	.has_aux_md = false,
    557	.channels = jz4740_channels,
    558	.num_channels = ARRAY_SIZE(jz4740_channels),
    559	.init_clk_div = jz4725b_adc_init_clk_div,
    560};
    561
    562static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
    563	.battery_high_vref = JZ4740_ADC_BATTERY_HIGH_VREF,
    564	.battery_high_vref_bits = JZ4740_ADC_BATTERY_HIGH_VREF_BITS,
    565	.battery_raw_avail = jz4740_adc_battery_raw_avail,
    566	.battery_raw_avail_size = ARRAY_SIZE(jz4740_adc_battery_raw_avail),
    567	.battery_scale_avail = jz4740_adc_battery_scale_avail,
    568	.battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
    569	.battery_vref_mode = true,
    570	.has_aux_md = false,
    571	.channels = jz4740_channels,
    572	.num_channels = ARRAY_SIZE(jz4740_channels),
    573	.init_clk_div = NULL, /* no ADCLK register on JZ4740 */
    574};
    575
    576static const struct ingenic_adc_soc_data jz4760_adc_soc_data = {
    577	.battery_high_vref = JZ4760_ADC_BATTERY_VREF,
    578	.battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
    579	.battery_raw_avail = jz4770_adc_battery_raw_avail,
    580	.battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
    581	.battery_scale_avail = jz4760_adc_battery_scale_avail,
    582	.battery_scale_avail_size = ARRAY_SIZE(jz4760_adc_battery_scale_avail),
    583	.battery_vref_mode = false,
    584	.has_aux_md = true,
    585	.channels = jz4760_channels,
    586	.num_channels = ARRAY_SIZE(jz4760_channels),
    587	.init_clk_div = jz4770_adc_init_clk_div,
    588};
    589
    590static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
    591	.battery_high_vref = JZ4770_ADC_BATTERY_VREF,
    592	.battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
    593	.battery_raw_avail = jz4770_adc_battery_raw_avail,
    594	.battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
    595	.battery_scale_avail = jz4770_adc_battery_scale_avail,
    596	.battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
    597	.battery_vref_mode = false,
    598	.has_aux_md = true,
    599	.channels = jz4770_channels,
    600	.num_channels = ARRAY_SIZE(jz4770_channels),
    601	.init_clk_div = jz4770_adc_init_clk_div,
    602};
    603
    604static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
    605				  struct iio_chan_spec const *chan,
    606				  const int **vals,
    607				  int *type,
    608				  int *length,
    609				  long m)
    610{
    611	struct ingenic_adc *adc = iio_priv(iio_dev);
    612
    613	switch (m) {
    614	case IIO_CHAN_INFO_RAW:
    615		*type = IIO_VAL_INT;
    616		*length = adc->soc_data->battery_raw_avail_size;
    617		*vals = adc->soc_data->battery_raw_avail;
    618		return IIO_AVAIL_RANGE;
    619	case IIO_CHAN_INFO_SCALE:
    620		*type = IIO_VAL_FRACTIONAL_LOG2;
    621		*length = adc->soc_data->battery_scale_avail_size;
    622		*vals = adc->soc_data->battery_scale_avail;
    623		return IIO_AVAIL_LIST;
    624	default:
    625		return -EINVAL;
    626	}
    627}
    628
    629static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
    630					  struct iio_chan_spec const *chan,
    631					  int *val)
    632{
    633	int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
    634	struct ingenic_adc *adc = iio_priv(iio_dev);
    635
    636	ret = clk_enable(adc->clk);
    637	if (ret) {
    638		dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",
    639			ret);
    640		return ret;
    641	}
    642
    643	/* We cannot sample the aux channels in parallel. */
    644	mutex_lock(&adc->aux_lock);
    645	if (adc->soc_data->has_aux_md && engine == 0) {
    646		switch (chan->channel) {
    647		case INGENIC_ADC_AUX0:
    648			cmd = 0;
    649			break;
    650		case INGENIC_ADC_AUX:
    651			cmd = 1;
    652			break;
    653		case INGENIC_ADC_AUX2:
    654			cmd = 2;
    655			break;
    656		}
    657
    658		ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, cmd);
    659	}
    660
    661	ret = ingenic_adc_capture(adc, engine);
    662	if (ret)
    663		goto out;
    664
    665	switch (chan->channel) {
    666	case INGENIC_ADC_AUX0:
    667	case INGENIC_ADC_AUX:
    668	case INGENIC_ADC_AUX2:
    669		*val = readw(adc->base + JZ_ADC_REG_ADSDAT);
    670		break;
    671	case INGENIC_ADC_BATTERY:
    672		*val = readw(adc->base + JZ_ADC_REG_ADBDAT);
    673		break;
    674	}
    675
    676	ret = IIO_VAL_INT;
    677out:
    678	mutex_unlock(&adc->aux_lock);
    679	clk_disable(adc->clk);
    680
    681	return ret;
    682}
    683
    684static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
    685				struct iio_chan_spec const *chan,
    686				int *val,
    687				int *val2,
    688				long m)
    689{
    690	struct ingenic_adc *adc = iio_priv(iio_dev);
    691
    692	switch (m) {
    693	case IIO_CHAN_INFO_RAW:
    694		return ingenic_adc_read_chan_info_raw(iio_dev, chan, val);
    695	case IIO_CHAN_INFO_SCALE:
    696		switch (chan->channel) {
    697		case INGENIC_ADC_AUX0:
    698		case INGENIC_ADC_AUX:
    699		case INGENIC_ADC_AUX2:
    700			*val = JZ_ADC_AUX_VREF;
    701			*val2 = JZ_ADC_AUX_VREF_BITS;
    702			break;
    703		case INGENIC_ADC_BATTERY:
    704			if (adc->low_vref_mode) {
    705				*val = JZ_ADC_BATTERY_LOW_VREF;
    706				*val2 = JZ_ADC_BATTERY_LOW_VREF_BITS;
    707			} else {
    708				*val = adc->soc_data->battery_high_vref;
    709				*val2 = adc->soc_data->battery_high_vref_bits;
    710			}
    711			break;
    712		}
    713
    714		return IIO_VAL_FRACTIONAL_LOG2;
    715	default:
    716		return -EINVAL;
    717	}
    718}
    719
    720static int ingenic_adc_of_xlate(struct iio_dev *iio_dev,
    721				const struct of_phandle_args *iiospec)
    722{
    723	int i;
    724
    725	if (!iiospec->args_count)
    726		return -EINVAL;
    727
    728	for (i = 0; i < iio_dev->num_channels; ++i)
    729		if (iio_dev->channels[i].channel == iiospec->args[0])
    730			return i;
    731
    732	return -EINVAL;
    733}
    734
    735static void ingenic_adc_clk_cleanup(void *data)
    736{
    737	clk_unprepare(data);
    738}
    739
    740static const struct iio_info ingenic_adc_info = {
    741	.write_raw = ingenic_adc_write_raw,
    742	.read_raw = ingenic_adc_read_raw,
    743	.read_avail = ingenic_adc_read_avail,
    744	.of_xlate = ingenic_adc_of_xlate,
    745};
    746
    747static int ingenic_adc_buffer_enable(struct iio_dev *iio_dev)
    748{
    749	struct ingenic_adc *adc = iio_priv(iio_dev);
    750	int ret;
    751
    752	ret = clk_enable(adc->clk);
    753	if (ret) {
    754		dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",
    755			ret);
    756		return ret;
    757	}
    758
    759	/* It takes significant time for the touchscreen hw to stabilize. */
    760	msleep(50);
    761	ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_TOUCH_OPS_MASK,
    762			       JZ_ADC_REG_CFG_SAMPLE_NUM(4) |
    763			       JZ_ADC_REG_CFG_PULL_UP(4));
    764
    765	writew(80, adc->base + JZ_ADC_REG_ADWAIT);
    766	writew(2, adc->base + JZ_ADC_REG_ADSAME);
    767	writeb((u8)~JZ_ADC_IRQ_TOUCH, adc->base + JZ_ADC_REG_CTRL);
    768	writel(0, adc->base + JZ_ADC_REG_ADTCH);
    769
    770	ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_CMD_SEL,
    771			       JZ_ADC_REG_CFG_CMD_SEL);
    772	ingenic_adc_set_adcmd(iio_dev, iio_dev->active_scan_mask[0]);
    773
    774	ingenic_adc_enable(adc, 2, true);
    775
    776	return 0;
    777}
    778
    779static int ingenic_adc_buffer_disable(struct iio_dev *iio_dev)
    780{
    781	struct ingenic_adc *adc = iio_priv(iio_dev);
    782
    783	ingenic_adc_enable(adc, 2, false);
    784
    785	ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_CMD_SEL, 0);
    786
    787	writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
    788	writeb(0xff, adc->base + JZ_ADC_REG_STATUS);
    789	ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_TOUCH_OPS_MASK, 0);
    790	writew(0, adc->base + JZ_ADC_REG_ADSAME);
    791	writew(0, adc->base + JZ_ADC_REG_ADWAIT);
    792	clk_disable(adc->clk);
    793
    794	return 0;
    795}
    796
    797static const struct iio_buffer_setup_ops ingenic_buffer_setup_ops = {
    798	.postenable = &ingenic_adc_buffer_enable,
    799	.predisable = &ingenic_adc_buffer_disable
    800};
    801
    802static irqreturn_t ingenic_adc_irq(int irq, void *data)
    803{
    804	struct iio_dev *iio_dev = data;
    805	struct ingenic_adc *adc = iio_priv(iio_dev);
    806	unsigned long mask = iio_dev->active_scan_mask[0];
    807	unsigned int i;
    808	u32 tdat[3];
    809
    810	for (i = 0; i < ARRAY_SIZE(tdat); mask >>= 2, i++) {
    811		if (mask & 0x3)
    812			tdat[i] = readl(adc->base + JZ_ADC_REG_ADTCH);
    813		else
    814			tdat[i] = 0;
    815	}
    816
    817	iio_push_to_buffers(iio_dev, tdat);
    818	writeb(JZ_ADC_IRQ_TOUCH, adc->base + JZ_ADC_REG_STATUS);
    819
    820	return IRQ_HANDLED;
    821}
    822
    823static int ingenic_adc_probe(struct platform_device *pdev)
    824{
    825	struct device *dev = &pdev->dev;
    826	struct iio_dev *iio_dev;
    827	struct ingenic_adc *adc;
    828	const struct ingenic_adc_soc_data *soc_data;
    829	int irq, ret;
    830
    831	soc_data = device_get_match_data(dev);
    832	if (!soc_data)
    833		return -EINVAL;
    834
    835	iio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
    836	if (!iio_dev)
    837		return -ENOMEM;
    838
    839	adc = iio_priv(iio_dev);
    840	mutex_init(&adc->lock);
    841	mutex_init(&adc->aux_lock);
    842	adc->soc_data = soc_data;
    843
    844	irq = platform_get_irq(pdev, 0);
    845	if (irq < 0)
    846		return irq;
    847
    848	ret = devm_request_irq(dev, irq, ingenic_adc_irq, 0,
    849			       dev_name(dev), iio_dev);
    850	if (ret < 0) {
    851		dev_err(dev, "Failed to request irq: %d\n", ret);
    852		return ret;
    853	}
    854
    855	adc->base = devm_platform_ioremap_resource(pdev, 0);
    856	if (IS_ERR(adc->base))
    857		return PTR_ERR(adc->base);
    858
    859	adc->clk = devm_clk_get(dev, "adc");
    860	if (IS_ERR(adc->clk)) {
    861		dev_err(dev, "Unable to get clock\n");
    862		return PTR_ERR(adc->clk);
    863	}
    864
    865	ret = clk_prepare_enable(adc->clk);
    866	if (ret) {
    867		dev_err(dev, "Failed to enable clock\n");
    868		return ret;
    869	}
    870
    871	/* Set clock dividers. */
    872	if (soc_data->init_clk_div) {
    873		ret = soc_data->init_clk_div(dev, adc);
    874		if (ret) {
    875			clk_disable_unprepare(adc->clk);
    876			return ret;
    877		}
    878	}
    879
    880	/* Put hardware in a known passive state. */
    881	writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);
    882	writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
    883
    884	/* JZ4760B specific */
    885	if (device_property_present(dev, "ingenic,use-internal-divider"))
    886		ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL,
    887					    JZ_ADC_REG_CFG_VBAT_SEL);
    888	else
    889		ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL, 0);
    890
    891	usleep_range(2000, 3000); /* Must wait at least 2ms. */
    892	clk_disable(adc->clk);
    893
    894	ret = devm_add_action_or_reset(dev, ingenic_adc_clk_cleanup, adc->clk);
    895	if (ret) {
    896		dev_err(dev, "Unable to add action\n");
    897		return ret;
    898	}
    899
    900	iio_dev->name = "jz-adc";
    901	iio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
    902	iio_dev->setup_ops = &ingenic_buffer_setup_ops;
    903	iio_dev->channels = soc_data->channels;
    904	iio_dev->num_channels = soc_data->num_channels;
    905	iio_dev->info = &ingenic_adc_info;
    906
    907	ret = devm_iio_device_register(dev, iio_dev);
    908	if (ret)
    909		dev_err(dev, "Unable to register IIO device\n");
    910
    911	return ret;
    912}
    913
    914static const struct of_device_id ingenic_adc_of_match[] = {
    915	{ .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },
    916	{ .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },
    917	{ .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data, },
    918	{ .compatible = "ingenic,jz4760b-adc", .data = &jz4760_adc_soc_data, },
    919	{ .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, },
    920	{ },
    921};
    922MODULE_DEVICE_TABLE(of, ingenic_adc_of_match);
    923
    924static struct platform_driver ingenic_adc_driver = {
    925	.driver = {
    926		.name = "ingenic-adc",
    927		.of_match_table = ingenic_adc_of_match,
    928	},
    929	.probe = ingenic_adc_probe,
    930};
    931module_platform_driver(ingenic_adc_driver);
    932MODULE_LICENSE("GPL v2");