brintos

brintos / linux-shallow public Read only

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