brintos

brintos / linux-shallow public Read only

0
0
Text · 23.4 KiB · 5afd2fe Raw
988 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Freescale Vybrid vf610 ADC driver4 *5 * Copyright 2013 Freescale Semiconductor, Inc.6 */7 8#include <linux/mod_devicetable.h>9#include <linux/module.h>10#include <linux/mutex.h>11#include <linux/property.h>12#include <linux/platform_device.h>13#include <linux/interrupt.h>14#include <linux/delay.h>15#include <linux/kernel.h>16#include <linux/slab.h>17#include <linux/io.h>18#include <linux/clk.h>19#include <linux/completion.h>20#include <linux/regulator/consumer.h>21#include <linux/err.h>22 23#include <linux/iio/iio.h>24#include <linux/iio/buffer.h>25#include <linux/iio/sysfs.h>26#include <linux/iio/trigger.h>27#include <linux/iio/trigger_consumer.h>28#include <linux/iio/triggered_buffer.h>29 30/* This will be the driver name the kernel reports */31#define DRIVER_NAME "vf610-adc"32 33/* Vybrid/IMX ADC registers */34#define VF610_REG_ADC_HC0		0x0035#define VF610_REG_ADC_HC1		0x0436#define VF610_REG_ADC_HS		0x0837#define VF610_REG_ADC_R0		0x0c38#define VF610_REG_ADC_R1		0x1039#define VF610_REG_ADC_CFG		0x1440#define VF610_REG_ADC_GC		0x1841#define VF610_REG_ADC_GS		0x1c42#define VF610_REG_ADC_CV		0x2043#define VF610_REG_ADC_OFS		0x2444#define VF610_REG_ADC_CAL		0x2845#define VF610_REG_ADC_PCTL		0x3046 47/* Configuration register field define */48#define VF610_ADC_MODE_BIT8		0x0049#define VF610_ADC_MODE_BIT10		0x0450#define VF610_ADC_MODE_BIT12		0x0851#define VF610_ADC_MODE_MASK		0x0c52#define VF610_ADC_BUSCLK2_SEL		0x0153#define VF610_ADC_ALTCLK_SEL		0x0254#define VF610_ADC_ADACK_SEL		0x0355#define VF610_ADC_ADCCLK_MASK		0x0356#define VF610_ADC_CLK_DIV2		0x2057#define VF610_ADC_CLK_DIV4		0x4058#define VF610_ADC_CLK_DIV8		0x6059#define VF610_ADC_CLK_MASK		0x6060#define VF610_ADC_ADLSMP_LONG		0x1061#define VF610_ADC_ADSTS_SHORT   0x10062#define VF610_ADC_ADSTS_NORMAL  0x20063#define VF610_ADC_ADSTS_LONG    0x30064#define VF610_ADC_ADSTS_MASK		0x30065#define VF610_ADC_ADLPC_EN		0x8066#define VF610_ADC_ADHSC_EN		0x40067#define VF610_ADC_REFSEL_VALT		0x80068#define VF610_ADC_REFSEL_VBG		0x100069#define VF610_ADC_ADTRG_HARD		0x200070#define VF610_ADC_AVGS_8		0x400071#define VF610_ADC_AVGS_16		0x800072#define VF610_ADC_AVGS_32		0xC00073#define VF610_ADC_AVGS_MASK		0xC00074#define VF610_ADC_OVWREN		0x1000075 76/* General control register field define */77#define VF610_ADC_ADACKEN		0x178#define VF610_ADC_DMAEN			0x279#define VF610_ADC_ACREN			0x480#define VF610_ADC_ACFGT			0x881#define VF610_ADC_ACFE			0x1082#define VF610_ADC_AVGEN			0x2083#define VF610_ADC_ADCON			0x4084#define VF610_ADC_CAL			0x8085 86/* Other field define */87#define VF610_ADC_ADCHC(x)		((x) & 0x1F)88#define VF610_ADC_AIEN			(0x1 << 7)89#define VF610_ADC_CONV_DISABLE		0x1F90#define VF610_ADC_HS_COCO0		0x191#define VF610_ADC_CALF			0x292#define VF610_ADC_TIMEOUT		msecs_to_jiffies(100)93 94#define DEFAULT_SAMPLE_TIME		100095 96/* V at 25°C of 696 mV */97#define VF610_VTEMP25_3V0		95098/* V at 25°C of 699 mV */99#define VF610_VTEMP25_3V3		867100/* Typical sensor slope coefficient at all temperatures */101#define VF610_TEMP_SLOPE_COEFF		1840102 103enum clk_sel {104	VF610_ADCIOC_BUSCLK_SET,105	VF610_ADCIOC_ALTCLK_SET,106	VF610_ADCIOC_ADACK_SET,107};108 109enum vol_ref {110	VF610_ADCIOC_VR_VREF_SET,111	VF610_ADCIOC_VR_VALT_SET,112	VF610_ADCIOC_VR_VBG_SET,113};114 115enum average_sel {116	VF610_ADC_SAMPLE_1,117	VF610_ADC_SAMPLE_4,118	VF610_ADC_SAMPLE_8,119	VF610_ADC_SAMPLE_16,120	VF610_ADC_SAMPLE_32,121};122 123enum conversion_mode_sel {124	VF610_ADC_CONV_NORMAL,125	VF610_ADC_CONV_HIGH_SPEED,126	VF610_ADC_CONV_LOW_POWER,127};128 129enum lst_adder_sel {130	VF610_ADCK_CYCLES_3,131	VF610_ADCK_CYCLES_5,132	VF610_ADCK_CYCLES_7,133	VF610_ADCK_CYCLES_9,134	VF610_ADCK_CYCLES_13,135	VF610_ADCK_CYCLES_17,136	VF610_ADCK_CYCLES_21,137	VF610_ADCK_CYCLES_25,138};139 140struct vf610_adc_feature {141	enum clk_sel	clk_sel;142	enum vol_ref	vol_ref;143	enum conversion_mode_sel conv_mode;144 145	int	clk_div;146	int     sample_rate;147	int	res_mode;148	u32 lst_adder_index;149	u32 default_sample_time;150 151	bool	calibration;152	bool	ovwren;153};154 155struct vf610_adc {156	struct device *dev;157	void __iomem *regs;158	struct clk *clk;159 160	/* lock to protect against multiple access to the device */161	struct mutex lock;162 163	u32 vref_uv;164	u32 value;165	struct regulator *vref;166 167	u32 max_adck_rate[3];168	struct vf610_adc_feature adc_feature;169 170	u32 sample_freq_avail[5];171 172	struct completion completion;173	/* Ensure the timestamp is naturally aligned */174	struct {175		u16 chan;176		s64 timestamp __aligned(8);177	} scan;178};179 180static const u32 vf610_hw_avgs[] = { 1, 4, 8, 16, 32 };181static const u32 vf610_lst_adder[] = { 3, 5, 7, 9, 13, 17, 21, 25 };182 183static inline void vf610_adc_calculate_rates(struct vf610_adc *info)184{185	struct vf610_adc_feature *adc_feature = &info->adc_feature;186	unsigned long adck_rate, ipg_rate = clk_get_rate(info->clk);187	u32 adck_period, lst_addr_min;188	int divisor, i;189 190	adck_rate = info->max_adck_rate[adc_feature->conv_mode];191 192	if (adck_rate) {193		/* calculate clk divider which is within specification */194		divisor = ipg_rate / adck_rate;195		adc_feature->clk_div = 1 << fls(divisor + 1);196	} else {197		/* fall-back value using a safe divisor */198		adc_feature->clk_div = 8;199	}200 201	adck_rate = ipg_rate / adc_feature->clk_div;202 203	/*204	 * Determine the long sample time adder value to be used based205	 * on the default minimum sample time provided.206	 */207	adck_period = NSEC_PER_SEC / adck_rate;208	lst_addr_min = adc_feature->default_sample_time / adck_period;209	for (i = 0; i < ARRAY_SIZE(vf610_lst_adder); i++) {210		if (vf610_lst_adder[i] > lst_addr_min) {211			adc_feature->lst_adder_index = i;212			break;213		}214	}215 216	/*217	 * Calculate ADC sample frequencies218	 * Sample time unit is ADCK cycles. ADCK clk source is ipg clock,219	 * which is the same as bus clock.220	 *221	 * ADC conversion time = SFCAdder + AverageNum x (BCT + LSTAdder)222	 * SFCAdder: fixed to 6 ADCK cycles223	 * AverageNum: 1, 4, 8, 16, 32 samples for hardware average.224	 * BCT (Base Conversion Time): fixed to 25 ADCK cycles for 12 bit mode225	 * LSTAdder(Long Sample Time): 3, 5, 7, 9, 13, 17, 21, 25 ADCK cycles226	 */227	for (i = 0; i < ARRAY_SIZE(vf610_hw_avgs); i++)228		info->sample_freq_avail[i] =229			adck_rate / (6 + vf610_hw_avgs[i] *230			 (25 + vf610_lst_adder[adc_feature->lst_adder_index]));231}232 233static inline void vf610_adc_cfg_init(struct vf610_adc *info)234{235	struct vf610_adc_feature *adc_feature = &info->adc_feature;236 237	/* set default Configuration for ADC controller */238	adc_feature->clk_sel = VF610_ADCIOC_BUSCLK_SET;239	adc_feature->vol_ref = VF610_ADCIOC_VR_VREF_SET;240 241	adc_feature->calibration = true;242	adc_feature->ovwren = true;243 244	adc_feature->res_mode = 12;245	adc_feature->sample_rate = 1;246 247	adc_feature->conv_mode = VF610_ADC_CONV_LOW_POWER;248 249	vf610_adc_calculate_rates(info);250}251 252static void vf610_adc_cfg_post_set(struct vf610_adc *info)253{254	struct vf610_adc_feature *adc_feature = &info->adc_feature;255	int cfg_data = 0;256	int gc_data = 0;257 258	switch (adc_feature->clk_sel) {259	case VF610_ADCIOC_ALTCLK_SET:260		cfg_data |= VF610_ADC_ALTCLK_SEL;261		break;262	case VF610_ADCIOC_ADACK_SET:263		cfg_data |= VF610_ADC_ADACK_SEL;264		break;265	default:266		break;267	}268 269	/* low power set for calibration */270	cfg_data |= VF610_ADC_ADLPC_EN;271 272	/* enable high speed for calibration */273	cfg_data |= VF610_ADC_ADHSC_EN;274 275	/* voltage reference */276	switch (adc_feature->vol_ref) {277	case VF610_ADCIOC_VR_VREF_SET:278		break;279	case VF610_ADCIOC_VR_VALT_SET:280		cfg_data |= VF610_ADC_REFSEL_VALT;281		break;282	case VF610_ADCIOC_VR_VBG_SET:283		cfg_data |= VF610_ADC_REFSEL_VBG;284		break;285	default:286		dev_err(info->dev, "error voltage reference\n");287	}288 289	/* data overwrite enable */290	if (adc_feature->ovwren)291		cfg_data |= VF610_ADC_OVWREN;292 293	writel(cfg_data, info->regs + VF610_REG_ADC_CFG);294	writel(gc_data, info->regs + VF610_REG_ADC_GC);295}296 297static void vf610_adc_calibration(struct vf610_adc *info)298{299	int adc_gc, hc_cfg;300 301	if (!info->adc_feature.calibration)302		return;303 304	/* enable calibration interrupt */305	hc_cfg = VF610_ADC_AIEN | VF610_ADC_CONV_DISABLE;306	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);307 308	adc_gc = readl(info->regs + VF610_REG_ADC_GC);309	writel(adc_gc | VF610_ADC_CAL, info->regs + VF610_REG_ADC_GC);310 311	if (!wait_for_completion_timeout(&info->completion, VF610_ADC_TIMEOUT))312		dev_err(info->dev, "Timeout for adc calibration\n");313 314	adc_gc = readl(info->regs + VF610_REG_ADC_GS);315	if (adc_gc & VF610_ADC_CALF)316		dev_err(info->dev, "ADC calibration failed\n");317 318	info->adc_feature.calibration = false;319}320 321static void vf610_adc_cfg_set(struct vf610_adc *info)322{323	struct vf610_adc_feature *adc_feature = &(info->adc_feature);324	int cfg_data;325 326	cfg_data = readl(info->regs + VF610_REG_ADC_CFG);327 328	cfg_data &= ~VF610_ADC_ADLPC_EN;329	if (adc_feature->conv_mode == VF610_ADC_CONV_LOW_POWER)330		cfg_data |= VF610_ADC_ADLPC_EN;331 332	cfg_data &= ~VF610_ADC_ADHSC_EN;333	if (adc_feature->conv_mode == VF610_ADC_CONV_HIGH_SPEED)334		cfg_data |= VF610_ADC_ADHSC_EN;335 336	writel(cfg_data, info->regs + VF610_REG_ADC_CFG);337}338 339static void vf610_adc_sample_set(struct vf610_adc *info)340{341	struct vf610_adc_feature *adc_feature = &(info->adc_feature);342	int cfg_data, gc_data;343 344	cfg_data = readl(info->regs + VF610_REG_ADC_CFG);345	gc_data = readl(info->regs + VF610_REG_ADC_GC);346 347	/* resolution mode */348	cfg_data &= ~VF610_ADC_MODE_MASK;349	switch (adc_feature->res_mode) {350	case 8:351		cfg_data |= VF610_ADC_MODE_BIT8;352		break;353	case 10:354		cfg_data |= VF610_ADC_MODE_BIT10;355		break;356	case 12:357		cfg_data |= VF610_ADC_MODE_BIT12;358		break;359	default:360		dev_err(info->dev, "error resolution mode\n");361		break;362	}363 364	/* clock select and clock divider */365	cfg_data &= ~(VF610_ADC_CLK_MASK | VF610_ADC_ADCCLK_MASK);366	switch (adc_feature->clk_div) {367	case 1:368		break;369	case 2:370		cfg_data |= VF610_ADC_CLK_DIV2;371		break;372	case 4:373		cfg_data |= VF610_ADC_CLK_DIV4;374		break;375	case 8:376		cfg_data |= VF610_ADC_CLK_DIV8;377		break;378	case 16:379		switch (adc_feature->clk_sel) {380		case VF610_ADCIOC_BUSCLK_SET:381			cfg_data |= VF610_ADC_BUSCLK2_SEL | VF610_ADC_CLK_DIV8;382			break;383		default:384			dev_err(info->dev, "error clk divider\n");385			break;386		}387		break;388	}389 390	/*391	 * Set ADLSMP and ADSTS based on the Long Sample Time Adder value392	 * determined.393	 */394	switch (adc_feature->lst_adder_index) {395	case VF610_ADCK_CYCLES_3:396		break;397	case VF610_ADCK_CYCLES_5:398		cfg_data |= VF610_ADC_ADSTS_SHORT;399		break;400	case VF610_ADCK_CYCLES_7:401		cfg_data |= VF610_ADC_ADSTS_NORMAL;402		break;403	case VF610_ADCK_CYCLES_9:404		cfg_data |= VF610_ADC_ADSTS_LONG;405		break;406	case VF610_ADCK_CYCLES_13:407		cfg_data |= VF610_ADC_ADLSMP_LONG;408		break;409	case VF610_ADCK_CYCLES_17:410		cfg_data |= VF610_ADC_ADLSMP_LONG;411		cfg_data |= VF610_ADC_ADSTS_SHORT;412		break;413	case VF610_ADCK_CYCLES_21:414		cfg_data |= VF610_ADC_ADLSMP_LONG;415		cfg_data |= VF610_ADC_ADSTS_NORMAL;416		break;417	case VF610_ADCK_CYCLES_25:418		cfg_data |= VF610_ADC_ADLSMP_LONG;419		cfg_data |= VF610_ADC_ADSTS_NORMAL;420		break;421	default:422		dev_err(info->dev, "error in sample time select\n");423	}424 425	/* update hardware average selection */426	cfg_data &= ~VF610_ADC_AVGS_MASK;427	gc_data &= ~VF610_ADC_AVGEN;428	switch (adc_feature->sample_rate) {429	case VF610_ADC_SAMPLE_1:430		break;431	case VF610_ADC_SAMPLE_4:432		gc_data |= VF610_ADC_AVGEN;433		break;434	case VF610_ADC_SAMPLE_8:435		gc_data |= VF610_ADC_AVGEN;436		cfg_data |= VF610_ADC_AVGS_8;437		break;438	case VF610_ADC_SAMPLE_16:439		gc_data |= VF610_ADC_AVGEN;440		cfg_data |= VF610_ADC_AVGS_16;441		break;442	case VF610_ADC_SAMPLE_32:443		gc_data |= VF610_ADC_AVGEN;444		cfg_data |= VF610_ADC_AVGS_32;445		break;446	default:447		dev_err(info->dev,448			"error hardware sample average select\n");449	}450 451	writel(cfg_data, info->regs + VF610_REG_ADC_CFG);452	writel(gc_data, info->regs + VF610_REG_ADC_GC);453}454 455static void vf610_adc_hw_init(struct vf610_adc *info)456{457	/* CFG: Feature set */458	vf610_adc_cfg_post_set(info);459	vf610_adc_sample_set(info);460 461	/* adc calibration */462	vf610_adc_calibration(info);463 464	/* CFG: power and speed set */465	vf610_adc_cfg_set(info);466}467 468static int vf610_set_conversion_mode(struct iio_dev *indio_dev,469				     const struct iio_chan_spec *chan,470				     unsigned int mode)471{472	struct vf610_adc *info = iio_priv(indio_dev);473 474	mutex_lock(&info->lock);475	info->adc_feature.conv_mode = mode;476	vf610_adc_calculate_rates(info);477	vf610_adc_hw_init(info);478	mutex_unlock(&info->lock);479 480	return 0;481}482 483static int vf610_get_conversion_mode(struct iio_dev *indio_dev,484				     const struct iio_chan_spec *chan)485{486	struct vf610_adc *info = iio_priv(indio_dev);487 488	return info->adc_feature.conv_mode;489}490 491static const char * const vf610_conv_modes[] = { "normal", "high-speed",492						 "low-power" };493 494static const struct iio_enum vf610_conversion_mode = {495	.items = vf610_conv_modes,496	.num_items = ARRAY_SIZE(vf610_conv_modes),497	.get = vf610_get_conversion_mode,498	.set = vf610_set_conversion_mode,499};500 501static const struct iio_chan_spec_ext_info vf610_ext_info[] = {502	IIO_ENUM("conversion_mode", IIO_SHARED_BY_DIR, &vf610_conversion_mode),503	{},504};505 506#define VF610_ADC_CHAN(_idx, _chan_type) {			\507	.type = (_chan_type),					\508	.indexed = 1,						\509	.channel = (_idx),					\510	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\511	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\512				BIT(IIO_CHAN_INFO_SAMP_FREQ),	\513	.ext_info = vf610_ext_info,				\514	.scan_index = (_idx),			\515	.scan_type = {					\516		.sign = 'u',				\517		.realbits = 12,				\518		.storagebits = 16,			\519	},						\520}521 522#define VF610_ADC_TEMPERATURE_CHAN(_idx, _chan_type) {	\523	.type = (_chan_type),	\524	.channel = (_idx),		\525	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),	\526	.scan_index = (_idx),					\527	.scan_type = {						\528		.sign = 'u',					\529		.realbits = 12,					\530		.storagebits = 16,				\531	},							\532}533 534static const struct iio_chan_spec vf610_adc_iio_channels[] = {535	VF610_ADC_CHAN(0, IIO_VOLTAGE),536	VF610_ADC_CHAN(1, IIO_VOLTAGE),537	VF610_ADC_CHAN(2, IIO_VOLTAGE),538	VF610_ADC_CHAN(3, IIO_VOLTAGE),539	VF610_ADC_CHAN(4, IIO_VOLTAGE),540	VF610_ADC_CHAN(5, IIO_VOLTAGE),541	VF610_ADC_CHAN(6, IIO_VOLTAGE),542	VF610_ADC_CHAN(7, IIO_VOLTAGE),543	VF610_ADC_CHAN(8, IIO_VOLTAGE),544	VF610_ADC_CHAN(9, IIO_VOLTAGE),545	VF610_ADC_CHAN(10, IIO_VOLTAGE),546	VF610_ADC_CHAN(11, IIO_VOLTAGE),547	VF610_ADC_CHAN(12, IIO_VOLTAGE),548	VF610_ADC_CHAN(13, IIO_VOLTAGE),549	VF610_ADC_CHAN(14, IIO_VOLTAGE),550	VF610_ADC_CHAN(15, IIO_VOLTAGE),551	VF610_ADC_TEMPERATURE_CHAN(26, IIO_TEMP),552	IIO_CHAN_SOFT_TIMESTAMP(32),553	/* sentinel */554};555 556static int vf610_adc_read_data(struct vf610_adc *info)557{558	int result;559 560	result = readl(info->regs + VF610_REG_ADC_R0);561 562	switch (info->adc_feature.res_mode) {563	case 8:564		result &= 0xFF;565		break;566	case 10:567		result &= 0x3FF;568		break;569	case 12:570		result &= 0xFFF;571		break;572	default:573		break;574	}575 576	return result;577}578 579static irqreturn_t vf610_adc_isr(int irq, void *dev_id)580{581	struct iio_dev *indio_dev = dev_id;582	struct vf610_adc *info = iio_priv(indio_dev);583	int coco;584 585	coco = readl(info->regs + VF610_REG_ADC_HS);586	if (coco & VF610_ADC_HS_COCO0) {587		info->value = vf610_adc_read_data(info);588		if (iio_buffer_enabled(indio_dev)) {589			info->scan.chan = info->value;590			iio_push_to_buffers_with_timestamp(indio_dev,591					&info->scan,592					iio_get_time_ns(indio_dev));593			iio_trigger_notify_done(indio_dev->trig);594		} else595			complete(&info->completion);596	}597 598	return IRQ_HANDLED;599}600 601static ssize_t vf610_show_samp_freq_avail(struct device *dev,602				struct device_attribute *attr, char *buf)603{604	struct vf610_adc *info = iio_priv(dev_to_iio_dev(dev));605	size_t len = 0;606	int i;607 608	for (i = 0; i < ARRAY_SIZE(info->sample_freq_avail); i++)609		len += scnprintf(buf + len, PAGE_SIZE - len,610			"%u ", info->sample_freq_avail[i]);611 612	/* replace trailing space by newline */613	buf[len - 1] = '\n';614 615	return len;616}617 618static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(vf610_show_samp_freq_avail);619 620static struct attribute *vf610_attributes[] = {621	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,622	NULL623};624 625static const struct attribute_group vf610_attribute_group = {626	.attrs = vf610_attributes,627};628 629static int vf610_read_sample(struct iio_dev *indio_dev,630			     struct iio_chan_spec const *chan, int *val)631{632	struct vf610_adc *info = iio_priv(indio_dev);633	unsigned int hc_cfg;634	int ret;635 636	ret = iio_device_claim_direct_mode(indio_dev);637	if (ret)638		return ret;639 640	mutex_lock(&info->lock);641	reinit_completion(&info->completion);642	hc_cfg = VF610_ADC_ADCHC(chan->channel);643	hc_cfg |= VF610_ADC_AIEN;644	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);645	ret = wait_for_completion_interruptible_timeout(&info->completion,646							VF610_ADC_TIMEOUT);647	if (ret == 0) {648		ret = -ETIMEDOUT;649		goto out_unlock;650	}651 652	if (ret < 0)653		goto out_unlock;654 655	switch (chan->type) {656	case IIO_VOLTAGE:657		*val = info->value;658		break;659	case IIO_TEMP:660		/*661		 * Calculate in degree Celsius times 1000662		 * Using the typical sensor slope of 1.84 mV/°C663		 * and VREFH_ADC at 3.3V, V at 25°C of 699 mV664		 */665		*val = 25000 - ((int)info->value - VF610_VTEMP25_3V3) *666				1000000 / VF610_TEMP_SLOPE_COEFF;667 668		break;669	default:670		ret = -EINVAL;671		break;672	}673 674out_unlock:675	mutex_unlock(&info->lock);676	iio_device_release_direct_mode(indio_dev);677 678	return ret;679}680 681static int vf610_read_raw(struct iio_dev *indio_dev,682			struct iio_chan_spec const *chan,683			int *val,684			int *val2,685			long mask)686{687	struct vf610_adc *info = iio_priv(indio_dev);688	long ret;689 690	switch (mask) {691	case IIO_CHAN_INFO_RAW:692	case IIO_CHAN_INFO_PROCESSED:693		ret = vf610_read_sample(indio_dev, chan, val);694		if (ret < 0)695			return ret;696 697		return IIO_VAL_INT;698 699	case IIO_CHAN_INFO_SCALE:700		*val = info->vref_uv / 1000;701		*val2 = info->adc_feature.res_mode;702		return IIO_VAL_FRACTIONAL_LOG2;703 704	case IIO_CHAN_INFO_SAMP_FREQ:705		*val = info->sample_freq_avail[info->adc_feature.sample_rate];706		*val2 = 0;707		return IIO_VAL_INT;708 709	default:710		break;711	}712 713	return -EINVAL;714}715 716static int vf610_write_raw(struct iio_dev *indio_dev,717			struct iio_chan_spec const *chan,718			int val,719			int val2,720			long mask)721{722	struct vf610_adc *info = iio_priv(indio_dev);723	int i;724 725	switch (mask) {726	case IIO_CHAN_INFO_SAMP_FREQ:727		for (i = 0;728			i < ARRAY_SIZE(info->sample_freq_avail);729			i++)730			if (val == info->sample_freq_avail[i]) {731				info->adc_feature.sample_rate = i;732				vf610_adc_sample_set(info);733				return 0;734			}735		break;736 737	default:738		break;739	}740 741	return -EINVAL;742}743 744static int vf610_adc_buffer_postenable(struct iio_dev *indio_dev)745{746	struct vf610_adc *info = iio_priv(indio_dev);747	unsigned int channel;748	int val;749 750	val = readl(info->regs + VF610_REG_ADC_GC);751	val |= VF610_ADC_ADCON;752	writel(val, info->regs + VF610_REG_ADC_GC);753 754	channel = find_first_bit(indio_dev->active_scan_mask,755				 iio_get_masklength(indio_dev));756 757	val = VF610_ADC_ADCHC(channel);758	val |= VF610_ADC_AIEN;759 760	writel(val, info->regs + VF610_REG_ADC_HC0);761 762	return 0;763}764 765static int vf610_adc_buffer_predisable(struct iio_dev *indio_dev)766{767	struct vf610_adc *info = iio_priv(indio_dev);768	unsigned int hc_cfg = 0;769	int val;770 771	val = readl(info->regs + VF610_REG_ADC_GC);772	val &= ~VF610_ADC_ADCON;773	writel(val, info->regs + VF610_REG_ADC_GC);774 775	hc_cfg |= VF610_ADC_CONV_DISABLE;776	hc_cfg &= ~VF610_ADC_AIEN;777 778	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);779 780	return 0;781}782 783static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {784	.postenable = &vf610_adc_buffer_postenable,785	.predisable = &vf610_adc_buffer_predisable,786	.validate_scan_mask = &iio_validate_scan_mask_onehot,787};788 789static int vf610_adc_reg_access(struct iio_dev *indio_dev,790			unsigned reg, unsigned writeval,791			unsigned *readval)792{793	struct vf610_adc *info = iio_priv(indio_dev);794 795	if ((readval == NULL) ||796		((reg % 4) || (reg > VF610_REG_ADC_PCTL)))797		return -EINVAL;798 799	*readval = readl(info->regs + reg);800 801	return 0;802}803 804static const struct iio_info vf610_adc_iio_info = {805	.read_raw = &vf610_read_raw,806	.write_raw = &vf610_write_raw,807	.debugfs_reg_access = &vf610_adc_reg_access,808	.attrs = &vf610_attribute_group,809};810 811static const struct of_device_id vf610_adc_match[] = {812	{ .compatible = "fsl,vf610-adc", },813	{ /* sentinel */ }814};815MODULE_DEVICE_TABLE(of, vf610_adc_match);816 817static int vf610_adc_probe(struct platform_device *pdev)818{819	struct device *dev = &pdev->dev;820	struct vf610_adc *info;821	struct iio_dev *indio_dev;822	int irq;823	int ret;824 825	indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct vf610_adc));826	if (!indio_dev) {827		dev_err(&pdev->dev, "Failed allocating iio device\n");828		return -ENOMEM;829	}830 831	info = iio_priv(indio_dev);832	info->dev = &pdev->dev;833 834	info->regs = devm_platform_ioremap_resource(pdev, 0);835	if (IS_ERR(info->regs))836		return PTR_ERR(info->regs);837 838	irq = platform_get_irq(pdev, 0);839	if (irq < 0)840		return irq;841 842	ret = devm_request_irq(info->dev, irq,843				vf610_adc_isr, 0,844				dev_name(&pdev->dev), indio_dev);845	if (ret < 0) {846		dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", irq);847		return ret;848	}849 850	info->clk = devm_clk_get(&pdev->dev, "adc");851	if (IS_ERR(info->clk)) {852		dev_err(&pdev->dev, "failed getting clock, err = %ld\n",853						PTR_ERR(info->clk));854		return PTR_ERR(info->clk);855	}856 857	info->vref = devm_regulator_get(&pdev->dev, "vref");858	if (IS_ERR(info->vref))859		return PTR_ERR(info->vref);860 861	ret = regulator_enable(info->vref);862	if (ret)863		return ret;864 865	info->vref_uv = regulator_get_voltage(info->vref);866 867	device_property_read_u32_array(dev, "fsl,adck-max-frequency", info->max_adck_rate, 3);868 869	info->adc_feature.default_sample_time = DEFAULT_SAMPLE_TIME;870	device_property_read_u32(dev, "min-sample-time", &info->adc_feature.default_sample_time);871 872	platform_set_drvdata(pdev, indio_dev);873 874	init_completion(&info->completion);875 876	indio_dev->name = dev_name(&pdev->dev);877	indio_dev->info = &vf610_adc_iio_info;878	indio_dev->modes = INDIO_DIRECT_MODE;879	indio_dev->channels = vf610_adc_iio_channels;880	indio_dev->num_channels = ARRAY_SIZE(vf610_adc_iio_channels);881 882	ret = clk_prepare_enable(info->clk);883	if (ret) {884		dev_err(&pdev->dev,885			"Could not prepare or enable the clock.\n");886		goto error_adc_clk_enable;887	}888 889	vf610_adc_cfg_init(info);890	vf610_adc_hw_init(info);891 892	ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time,893					NULL, &iio_triggered_buffer_setup_ops);894	if (ret < 0) {895		dev_err(&pdev->dev, "Couldn't initialise the buffer\n");896		goto error_iio_device_register;897	}898 899	mutex_init(&info->lock);900 901	ret = iio_device_register(indio_dev);902	if (ret) {903		dev_err(&pdev->dev, "Couldn't register the device.\n");904		goto error_adc_buffer_init;905	}906 907	return 0;908 909error_adc_buffer_init:910	iio_triggered_buffer_cleanup(indio_dev);911error_iio_device_register:912	clk_disable_unprepare(info->clk);913error_adc_clk_enable:914	regulator_disable(info->vref);915 916	return ret;917}918 919static void vf610_adc_remove(struct platform_device *pdev)920{921	struct iio_dev *indio_dev = platform_get_drvdata(pdev);922	struct vf610_adc *info = iio_priv(indio_dev);923 924	iio_device_unregister(indio_dev);925	iio_triggered_buffer_cleanup(indio_dev);926	regulator_disable(info->vref);927	clk_disable_unprepare(info->clk);928}929 930static int vf610_adc_suspend(struct device *dev)931{932	struct iio_dev *indio_dev = dev_get_drvdata(dev);933	struct vf610_adc *info = iio_priv(indio_dev);934	int hc_cfg;935 936	/* ADC controller enters to stop mode */937	hc_cfg = readl(info->regs + VF610_REG_ADC_HC0);938	hc_cfg |= VF610_ADC_CONV_DISABLE;939	writel(hc_cfg, info->regs + VF610_REG_ADC_HC0);940 941	clk_disable_unprepare(info->clk);942	regulator_disable(info->vref);943 944	return 0;945}946 947static int vf610_adc_resume(struct device *dev)948{949	struct iio_dev *indio_dev = dev_get_drvdata(dev);950	struct vf610_adc *info = iio_priv(indio_dev);951	int ret;952 953	ret = regulator_enable(info->vref);954	if (ret)955		return ret;956 957	ret = clk_prepare_enable(info->clk);958	if (ret)959		goto disable_reg;960 961	vf610_adc_hw_init(info);962 963	return 0;964 965disable_reg:966	regulator_disable(info->vref);967	return ret;968}969 970static DEFINE_SIMPLE_DEV_PM_OPS(vf610_adc_pm_ops, vf610_adc_suspend,971				vf610_adc_resume);972 973static struct platform_driver vf610_adc_driver = {974	.probe          = vf610_adc_probe,975	.remove_new     = vf610_adc_remove,976	.driver         = {977		.name   = DRIVER_NAME,978		.of_match_table = vf610_adc_match,979		.pm     = pm_sleep_ptr(&vf610_adc_pm_ops),980	},981};982 983module_platform_driver(vf610_adc_driver);984 985MODULE_AUTHOR("Fugang Duan <B38611@freescale.com>");986MODULE_DESCRIPTION("Freescale VF610 ADC driver");987MODULE_LICENSE("GPL v2");988