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