1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21664f6a5SPhani Movva /* 31664f6a5SPhani Movva * Copyright (c) 2014-2015 Imagination Technologies Ltd. 41664f6a5SPhani Movva */ 51664f6a5SPhani Movva 61664f6a5SPhani Movva #include <linux/clk.h> 71664f6a5SPhani Movva #include <linux/delay.h> 81664f6a5SPhani Movva #include <linux/err.h> 91664f6a5SPhani Movva #include <linux/kernel.h> 101664f6a5SPhani Movva #include <linux/module.h> 111664f6a5SPhani Movva #include <linux/of.h> 121664f6a5SPhani Movva #include <linux/of_device.h> 131664f6a5SPhani Movva #include <linux/platform_device.h> 141664f6a5SPhani Movva #include <linux/regulator/consumer.h> 151664f6a5SPhani Movva #include <linux/slab.h> 161664f6a5SPhani Movva 171664f6a5SPhani Movva #include <linux/iio/buffer.h> 181664f6a5SPhani Movva #include <linux/iio/iio.h> 191664f6a5SPhani Movva #include <linux/iio/sysfs.h> 201664f6a5SPhani Movva #include <linux/iio/trigger.h> 211664f6a5SPhani Movva #include <linux/iio/trigger_consumer.h> 221664f6a5SPhani Movva #include <linux/iio/triggered_buffer.h> 231664f6a5SPhani Movva 241664f6a5SPhani Movva /* Registers */ 251664f6a5SPhani Movva #define CC10001_ADC_CONFIG 0x00 261664f6a5SPhani Movva #define CC10001_ADC_START_CONV BIT(4) 271664f6a5SPhani Movva #define CC10001_ADC_MODE_SINGLE_CONV BIT(5) 281664f6a5SPhani Movva 291664f6a5SPhani Movva #define CC10001_ADC_DDATA_OUT 0x04 301664f6a5SPhani Movva #define CC10001_ADC_EOC 0x08 311664f6a5SPhani Movva #define CC10001_ADC_EOC_SET BIT(0) 321664f6a5SPhani Movva 331664f6a5SPhani Movva #define CC10001_ADC_CHSEL_SAMPLED 0x0c 34713276eaSNaidu Tellapati #define CC10001_ADC_POWER_DOWN 0x10 35713276eaSNaidu Tellapati #define CC10001_ADC_POWER_DOWN_SET BIT(0) 36713276eaSNaidu Tellapati 371664f6a5SPhani Movva #define CC10001_ADC_DEBUG 0x14 381664f6a5SPhani Movva #define CC10001_ADC_DATA_COUNT 0x20 391664f6a5SPhani Movva 401664f6a5SPhani Movva #define CC10001_ADC_DATA_MASK GENMASK(9, 0) 411664f6a5SPhani Movva #define CC10001_ADC_NUM_CHANNELS 8 421664f6a5SPhani Movva #define CC10001_ADC_CH_MASK GENMASK(2, 0) 431664f6a5SPhani Movva 441664f6a5SPhani Movva #define CC10001_INVALID_SAMPLED 0xffff 451664f6a5SPhani Movva #define CC10001_MAX_POLL_COUNT 20 461664f6a5SPhani Movva 471664f6a5SPhani Movva /* 481664f6a5SPhani Movva * As per device specification, wait six clock cycles after power-up to 491664f6a5SPhani Movva * activate START. Since adding two more clock cycles delay does not 501664f6a5SPhani Movva * impact the performance too much, we are adding two additional cycles delay 511664f6a5SPhani Movva * intentionally here. 521664f6a5SPhani Movva */ 531664f6a5SPhani Movva #define CC10001_WAIT_CYCLES 8 541664f6a5SPhani Movva 551664f6a5SPhani Movva struct cc10001_adc_device { 561664f6a5SPhani Movva void __iomem *reg_base; 571664f6a5SPhani Movva struct clk *adc_clk; 581664f6a5SPhani Movva struct regulator *reg; 591664f6a5SPhani Movva u16 *buf; 601664f6a5SPhani Movva 61ae354962SNaidu Tellapati bool shared; 621664f6a5SPhani Movva struct mutex lock; 631664f6a5SPhani Movva unsigned int start_delay_ns; 641664f6a5SPhani Movva unsigned int eoc_delay_ns; 651664f6a5SPhani Movva }; 661664f6a5SPhani Movva 671664f6a5SPhani Movva static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev, 681664f6a5SPhani Movva u32 reg, u32 val) 691664f6a5SPhani Movva { 701664f6a5SPhani Movva writel(val, adc_dev->reg_base + reg); 711664f6a5SPhani Movva } 721664f6a5SPhani Movva 731664f6a5SPhani Movva static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev, 741664f6a5SPhani Movva u32 reg) 751664f6a5SPhani Movva { 761664f6a5SPhani Movva return readl(adc_dev->reg_base + reg); 771664f6a5SPhani Movva } 781664f6a5SPhani Movva 79713276eaSNaidu Tellapati static void cc10001_adc_power_up(struct cc10001_adc_device *adc_dev) 80713276eaSNaidu Tellapati { 81713276eaSNaidu Tellapati cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 0); 82713276eaSNaidu Tellapati ndelay(adc_dev->start_delay_ns); 83713276eaSNaidu Tellapati } 84713276eaSNaidu Tellapati 85713276eaSNaidu Tellapati static void cc10001_adc_power_down(struct cc10001_adc_device *adc_dev) 86713276eaSNaidu Tellapati { 87713276eaSNaidu Tellapati cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_DOWN, 88713276eaSNaidu Tellapati CC10001_ADC_POWER_DOWN_SET); 89713276eaSNaidu Tellapati } 90713276eaSNaidu Tellapati 911664f6a5SPhani Movva static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, 921664f6a5SPhani Movva unsigned int channel) 931664f6a5SPhani Movva { 941664f6a5SPhani Movva u32 val; 951664f6a5SPhani Movva 961664f6a5SPhani Movva /* Channel selection and mode of operation */ 971664f6a5SPhani Movva val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV; 981664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); 991664f6a5SPhani Movva 100f29b212eSNaidu Tellapati udelay(1); 1011664f6a5SPhani Movva val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG); 1021664f6a5SPhani Movva val = val | CC10001_ADC_START_CONV; 1031664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); 1041664f6a5SPhani Movva } 1051664f6a5SPhani Movva 1061664f6a5SPhani Movva static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev, 1071664f6a5SPhani Movva unsigned int channel, 1081664f6a5SPhani Movva unsigned int delay) 1091664f6a5SPhani Movva { 1101664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 1111664f6a5SPhani Movva unsigned int poll_count = 0; 1121664f6a5SPhani Movva 1131664f6a5SPhani Movva while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) & 1141664f6a5SPhani Movva CC10001_ADC_EOC_SET)) { 1151664f6a5SPhani Movva 1161664f6a5SPhani Movva ndelay(delay); 1171664f6a5SPhani Movva if (poll_count++ == CC10001_MAX_POLL_COUNT) 1181664f6a5SPhani Movva return CC10001_INVALID_SAMPLED; 1191664f6a5SPhani Movva } 1201664f6a5SPhani Movva 1211664f6a5SPhani Movva poll_count = 0; 1221664f6a5SPhani Movva while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) & 1231664f6a5SPhani Movva CC10001_ADC_CH_MASK) != channel) { 1241664f6a5SPhani Movva 1251664f6a5SPhani Movva ndelay(delay); 1261664f6a5SPhani Movva if (poll_count++ == CC10001_MAX_POLL_COUNT) 1271664f6a5SPhani Movva return CC10001_INVALID_SAMPLED; 1281664f6a5SPhani Movva } 1291664f6a5SPhani Movva 1301664f6a5SPhani Movva /* Read the 10 bit output register */ 1311664f6a5SPhani Movva return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) & 1321664f6a5SPhani Movva CC10001_ADC_DATA_MASK; 1331664f6a5SPhani Movva } 1341664f6a5SPhani Movva 1351664f6a5SPhani Movva static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) 1361664f6a5SPhani Movva { 1371664f6a5SPhani Movva struct cc10001_adc_device *adc_dev; 1381664f6a5SPhani Movva struct iio_poll_func *pf = p; 1391664f6a5SPhani Movva struct iio_dev *indio_dev; 1401664f6a5SPhani Movva unsigned int delay_ns; 1411664f6a5SPhani Movva unsigned int channel; 14213415a99SNaidu Tellapati unsigned int scan_idx; 1431664f6a5SPhani Movva bool sample_invalid; 1441664f6a5SPhani Movva u16 *data; 1451664f6a5SPhani Movva int i; 1461664f6a5SPhani Movva 1471664f6a5SPhani Movva indio_dev = pf->indio_dev; 1481664f6a5SPhani Movva adc_dev = iio_priv(indio_dev); 1491664f6a5SPhani Movva data = adc_dev->buf; 1501664f6a5SPhani Movva 1511664f6a5SPhani Movva mutex_lock(&adc_dev->lock); 1521664f6a5SPhani Movva 153ae354962SNaidu Tellapati if (!adc_dev->shared) 154713276eaSNaidu Tellapati cc10001_adc_power_up(adc_dev); 1551664f6a5SPhani Movva 1561664f6a5SPhani Movva /* Calculate delay step for eoc and sampled data */ 1571664f6a5SPhani Movva delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; 1581664f6a5SPhani Movva 1591664f6a5SPhani Movva i = 0; 1601664f6a5SPhani Movva sample_invalid = false; 16113415a99SNaidu Tellapati for_each_set_bit(scan_idx, indio_dev->active_scan_mask, 1621664f6a5SPhani Movva indio_dev->masklength) { 1631664f6a5SPhani Movva 16413415a99SNaidu Tellapati channel = indio_dev->channels[scan_idx].channel; 1651664f6a5SPhani Movva cc10001_adc_start(adc_dev, channel); 1661664f6a5SPhani Movva 1671664f6a5SPhani Movva data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns); 1681664f6a5SPhani Movva if (data[i] == CC10001_INVALID_SAMPLED) { 1691664f6a5SPhani Movva dev_warn(&indio_dev->dev, 1701664f6a5SPhani Movva "invalid sample on channel %d\n", channel); 1711664f6a5SPhani Movva sample_invalid = true; 1721664f6a5SPhani Movva goto done; 1731664f6a5SPhani Movva } 1741664f6a5SPhani Movva i++; 1751664f6a5SPhani Movva } 1761664f6a5SPhani Movva 1771664f6a5SPhani Movva done: 178ae354962SNaidu Tellapati if (!adc_dev->shared) 179713276eaSNaidu Tellapati cc10001_adc_power_down(adc_dev); 1801664f6a5SPhani Movva 1811664f6a5SPhani Movva mutex_unlock(&adc_dev->lock); 1821664f6a5SPhani Movva 1831664f6a5SPhani Movva if (!sample_invalid) 1841664f6a5SPhani Movva iio_push_to_buffers_with_timestamp(indio_dev, data, 185bc2b7dabSGregor Boirie iio_get_time_ns(indio_dev)); 1861664f6a5SPhani Movva iio_trigger_notify_done(indio_dev->trig); 1871664f6a5SPhani Movva 1881664f6a5SPhani Movva return IRQ_HANDLED; 1891664f6a5SPhani Movva } 1901664f6a5SPhani Movva 1911664f6a5SPhani Movva static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, 1921664f6a5SPhani Movva struct iio_chan_spec const *chan) 1931664f6a5SPhani Movva { 1941664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 1951664f6a5SPhani Movva unsigned int delay_ns; 1961664f6a5SPhani Movva u16 val; 1971664f6a5SPhani Movva 198ae354962SNaidu Tellapati if (!adc_dev->shared) 199713276eaSNaidu Tellapati cc10001_adc_power_up(adc_dev); 2001664f6a5SPhani Movva 2011664f6a5SPhani Movva /* Calculate delay step for eoc and sampled data */ 2021664f6a5SPhani Movva delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; 2031664f6a5SPhani Movva 2041664f6a5SPhani Movva cc10001_adc_start(adc_dev, chan->channel); 2051664f6a5SPhani Movva 2061664f6a5SPhani Movva val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); 2071664f6a5SPhani Movva 208ae354962SNaidu Tellapati if (!adc_dev->shared) 209713276eaSNaidu Tellapati cc10001_adc_power_down(adc_dev); 2101664f6a5SPhani Movva 2111664f6a5SPhani Movva return val; 2121664f6a5SPhani Movva } 2131664f6a5SPhani Movva 2141664f6a5SPhani Movva static int cc10001_adc_read_raw(struct iio_dev *indio_dev, 2151664f6a5SPhani Movva struct iio_chan_spec const *chan, 2161664f6a5SPhani Movva int *val, int *val2, long mask) 2171664f6a5SPhani Movva { 2181664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 2191664f6a5SPhani Movva int ret; 2201664f6a5SPhani Movva 2211664f6a5SPhani Movva switch (mask) { 2221664f6a5SPhani Movva case IIO_CHAN_INFO_RAW: 2231664f6a5SPhani Movva if (iio_buffer_enabled(indio_dev)) 2241664f6a5SPhani Movva return -EBUSY; 2251664f6a5SPhani Movva mutex_lock(&adc_dev->lock); 2261664f6a5SPhani Movva *val = cc10001_adc_read_raw_voltage(indio_dev, chan); 2271664f6a5SPhani Movva mutex_unlock(&adc_dev->lock); 2281664f6a5SPhani Movva 2291664f6a5SPhani Movva if (*val == CC10001_INVALID_SAMPLED) 2301664f6a5SPhani Movva return -EIO; 2311664f6a5SPhani Movva return IIO_VAL_INT; 2321664f6a5SPhani Movva 2331664f6a5SPhani Movva case IIO_CHAN_INFO_SCALE: 2341664f6a5SPhani Movva ret = regulator_get_voltage(adc_dev->reg); 23565a761bfSNaidu Tellapati if (ret < 0) 2361664f6a5SPhani Movva return ret; 2371664f6a5SPhani Movva 2381664f6a5SPhani Movva *val = ret / 1000; 2391664f6a5SPhani Movva *val2 = chan->scan_type.realbits; 2401664f6a5SPhani Movva return IIO_VAL_FRACTIONAL_LOG2; 2411664f6a5SPhani Movva 2421664f6a5SPhani Movva default: 2431664f6a5SPhani Movva return -EINVAL; 2441664f6a5SPhani Movva } 2451664f6a5SPhani Movva } 2461664f6a5SPhani Movva 2471664f6a5SPhani Movva static int cc10001_update_scan_mode(struct iio_dev *indio_dev, 2481664f6a5SPhani Movva const unsigned long *scan_mask) 2491664f6a5SPhani Movva { 2501664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 2511664f6a5SPhani Movva 2521664f6a5SPhani Movva kfree(adc_dev->buf); 2531664f6a5SPhani Movva adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); 2541664f6a5SPhani Movva if (!adc_dev->buf) 2551664f6a5SPhani Movva return -ENOMEM; 2561664f6a5SPhani Movva 2571664f6a5SPhani Movva return 0; 2581664f6a5SPhani Movva } 2591664f6a5SPhani Movva 2601664f6a5SPhani Movva static const struct iio_info cc10001_adc_info = { 2611664f6a5SPhani Movva .read_raw = &cc10001_adc_read_raw, 2621664f6a5SPhani Movva .update_scan_mode = &cc10001_update_scan_mode, 2631664f6a5SPhani Movva }; 2641664f6a5SPhani Movva 26513415a99SNaidu Tellapati static int cc10001_adc_channel_init(struct iio_dev *indio_dev, 26613415a99SNaidu Tellapati unsigned long channel_map) 2671664f6a5SPhani Movva { 2681664f6a5SPhani Movva struct iio_chan_spec *chan_array, *timestamp; 2691664f6a5SPhani Movva unsigned int bit, idx = 0; 2701664f6a5SPhani Movva 27113415a99SNaidu Tellapati indio_dev->num_channels = bitmap_weight(&channel_map, 27213415a99SNaidu Tellapati CC10001_ADC_NUM_CHANNELS) + 1; 2731664f6a5SPhani Movva 27413415a99SNaidu Tellapati chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels, 2751664f6a5SPhani Movva sizeof(struct iio_chan_spec), 2761664f6a5SPhani Movva GFP_KERNEL); 2771664f6a5SPhani Movva if (!chan_array) 2781664f6a5SPhani Movva return -ENOMEM; 2791664f6a5SPhani Movva 28013415a99SNaidu Tellapati for_each_set_bit(bit, &channel_map, CC10001_ADC_NUM_CHANNELS) { 2811664f6a5SPhani Movva struct iio_chan_spec *chan = &chan_array[idx]; 2821664f6a5SPhani Movva 2831664f6a5SPhani Movva chan->type = IIO_VOLTAGE; 2841664f6a5SPhani Movva chan->indexed = 1; 2851664f6a5SPhani Movva chan->channel = bit; 2861664f6a5SPhani Movva chan->scan_index = idx; 2871664f6a5SPhani Movva chan->scan_type.sign = 'u'; 2881664f6a5SPhani Movva chan->scan_type.realbits = 10; 2891664f6a5SPhani Movva chan->scan_type.storagebits = 16; 2901664f6a5SPhani Movva chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); 2911664f6a5SPhani Movva chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 2921664f6a5SPhani Movva idx++; 2931664f6a5SPhani Movva } 2941664f6a5SPhani Movva 2951664f6a5SPhani Movva timestamp = &chan_array[idx]; 2961664f6a5SPhani Movva timestamp->type = IIO_TIMESTAMP; 2971664f6a5SPhani Movva timestamp->channel = -1; 2981664f6a5SPhani Movva timestamp->scan_index = idx; 2991664f6a5SPhani Movva timestamp->scan_type.sign = 's'; 3001664f6a5SPhani Movva timestamp->scan_type.realbits = 64; 3011664f6a5SPhani Movva timestamp->scan_type.storagebits = 64; 3021664f6a5SPhani Movva 3031664f6a5SPhani Movva indio_dev->channels = chan_array; 3041664f6a5SPhani Movva 3051664f6a5SPhani Movva return 0; 3061664f6a5SPhani Movva } 3071664f6a5SPhani Movva 308*dc0ba516SJonathan Cameron static void cc10001_reg_disable(void *priv) 309*dc0ba516SJonathan Cameron { 310*dc0ba516SJonathan Cameron regulator_disable(priv); 311*dc0ba516SJonathan Cameron } 312*dc0ba516SJonathan Cameron 3131664f6a5SPhani Movva static int cc10001_adc_probe(struct platform_device *pdev) 3141664f6a5SPhani Movva { 31526bfb581SJonathan Cameron struct device *dev = &pdev->dev; 31626bfb581SJonathan Cameron struct device_node *node = dev->of_node; 3171664f6a5SPhani Movva struct cc10001_adc_device *adc_dev; 3181664f6a5SPhani Movva unsigned long adc_clk_rate; 3191664f6a5SPhani Movva struct iio_dev *indio_dev; 32013415a99SNaidu Tellapati unsigned long channel_map; 3211664f6a5SPhani Movva int ret; 3221664f6a5SPhani Movva 32326bfb581SJonathan Cameron indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_dev)); 3241664f6a5SPhani Movva if (indio_dev == NULL) 3251664f6a5SPhani Movva return -ENOMEM; 3261664f6a5SPhani Movva 3271664f6a5SPhani Movva adc_dev = iio_priv(indio_dev); 3281664f6a5SPhani Movva 32913415a99SNaidu Tellapati channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); 330ae354962SNaidu Tellapati if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) { 331ae354962SNaidu Tellapati adc_dev->shared = true; 33213415a99SNaidu Tellapati channel_map &= ~ret; 333ae354962SNaidu Tellapati } 3341664f6a5SPhani Movva 33526bfb581SJonathan Cameron adc_dev->reg = devm_regulator_get(dev, "vref"); 3361664f6a5SPhani Movva if (IS_ERR(adc_dev->reg)) 3371664f6a5SPhani Movva return PTR_ERR(adc_dev->reg); 3381664f6a5SPhani Movva 3391664f6a5SPhani Movva ret = regulator_enable(adc_dev->reg); 3401664f6a5SPhani Movva if (ret) 3411664f6a5SPhani Movva return ret; 3421664f6a5SPhani Movva 343*dc0ba516SJonathan Cameron ret = devm_add_action_or_reset(dev, cc10001_reg_disable, adc_dev->reg); 344*dc0ba516SJonathan Cameron if (ret) 345*dc0ba516SJonathan Cameron return ret; 346*dc0ba516SJonathan Cameron 34726bfb581SJonathan Cameron indio_dev->name = dev_name(dev); 3481664f6a5SPhani Movva indio_dev->info = &cc10001_adc_info; 3491664f6a5SPhani Movva indio_dev->modes = INDIO_DIRECT_MODE; 3501664f6a5SPhani Movva 35146e55d06SJonathan Cameron adc_dev->reg_base = devm_platform_ioremap_resource(pdev, 0); 352*dc0ba516SJonathan Cameron if (IS_ERR(adc_dev->reg_base)) 353*dc0ba516SJonathan Cameron return PTR_ERR(adc_dev->reg_base); 3541664f6a5SPhani Movva 35526bfb581SJonathan Cameron adc_dev->adc_clk = devm_clk_get(dev, "adc"); 3561664f6a5SPhani Movva if (IS_ERR(adc_dev->adc_clk)) { 35726bfb581SJonathan Cameron dev_err(dev, "failed to get the clock\n"); 358*dc0ba516SJonathan Cameron return PTR_ERR(adc_dev->adc_clk); 3591664f6a5SPhani Movva } 3601664f6a5SPhani Movva 3611664f6a5SPhani Movva ret = clk_prepare_enable(adc_dev->adc_clk); 3621664f6a5SPhani Movva if (ret) { 36326bfb581SJonathan Cameron dev_err(dev, "failed to enable the clock\n"); 364*dc0ba516SJonathan Cameron return ret; 3651664f6a5SPhani Movva } 3661664f6a5SPhani Movva 3671664f6a5SPhani Movva adc_clk_rate = clk_get_rate(adc_dev->adc_clk); 3681664f6a5SPhani Movva if (!adc_clk_rate) { 3691664f6a5SPhani Movva ret = -EINVAL; 37026bfb581SJonathan Cameron dev_err(dev, "null clock rate!\n"); 3711664f6a5SPhani Movva goto err_disable_clk; 3721664f6a5SPhani Movva } 3731664f6a5SPhani Movva 3741664f6a5SPhani Movva adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate; 3751664f6a5SPhani Movva adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; 3761664f6a5SPhani Movva 377ae354962SNaidu Tellapati /* 378ae354962SNaidu Tellapati * There is only one register to power-up/power-down the AUX ADC. 379ae354962SNaidu Tellapati * If the ADC is shared among multiple CPUs, always power it up here. 380ae354962SNaidu Tellapati * If the ADC is used only by the MIPS, power-up/power-down at runtime. 381ae354962SNaidu Tellapati */ 382ae354962SNaidu Tellapati if (adc_dev->shared) 383ae354962SNaidu Tellapati cc10001_adc_power_up(adc_dev); 384ae354962SNaidu Tellapati 3851664f6a5SPhani Movva /* Setup the ADC channels available on the device */ 38613415a99SNaidu Tellapati ret = cc10001_adc_channel_init(indio_dev, channel_map); 3871664f6a5SPhani Movva if (ret < 0) 3881664f6a5SPhani Movva goto err_disable_clk; 3891664f6a5SPhani Movva 3901664f6a5SPhani Movva mutex_init(&adc_dev->lock); 3911664f6a5SPhani Movva 3921664f6a5SPhani Movva ret = iio_triggered_buffer_setup(indio_dev, NULL, 3931664f6a5SPhani Movva &cc10001_adc_trigger_h, NULL); 3941664f6a5SPhani Movva if (ret < 0) 3951664f6a5SPhani Movva goto err_disable_clk; 3961664f6a5SPhani Movva 3971664f6a5SPhani Movva ret = iio_device_register(indio_dev); 3981664f6a5SPhani Movva if (ret < 0) 3991664f6a5SPhani Movva goto err_cleanup_buffer; 4001664f6a5SPhani Movva 4011664f6a5SPhani Movva platform_set_drvdata(pdev, indio_dev); 4021664f6a5SPhani Movva 4031664f6a5SPhani Movva return 0; 4041664f6a5SPhani Movva 4051664f6a5SPhani Movva err_cleanup_buffer: 4061664f6a5SPhani Movva iio_triggered_buffer_cleanup(indio_dev); 4071664f6a5SPhani Movva err_disable_clk: 4081664f6a5SPhani Movva clk_disable_unprepare(adc_dev->adc_clk); 4091664f6a5SPhani Movva return ret; 4101664f6a5SPhani Movva } 4111664f6a5SPhani Movva 4121664f6a5SPhani Movva static int cc10001_adc_remove(struct platform_device *pdev) 4131664f6a5SPhani Movva { 4141664f6a5SPhani Movva struct iio_dev *indio_dev = platform_get_drvdata(pdev); 4151664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 4161664f6a5SPhani Movva 417ae354962SNaidu Tellapati cc10001_adc_power_down(adc_dev); 4181664f6a5SPhani Movva iio_device_unregister(indio_dev); 4191664f6a5SPhani Movva iio_triggered_buffer_cleanup(indio_dev); 4201664f6a5SPhani Movva clk_disable_unprepare(adc_dev->adc_clk); 4211664f6a5SPhani Movva 4221664f6a5SPhani Movva return 0; 4231664f6a5SPhani Movva } 4241664f6a5SPhani Movva 4251664f6a5SPhani Movva static const struct of_device_id cc10001_adc_dt_ids[] = { 4261664f6a5SPhani Movva { .compatible = "cosmic,10001-adc", }, 4271664f6a5SPhani Movva { } 4281664f6a5SPhani Movva }; 4291664f6a5SPhani Movva MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids); 4301664f6a5SPhani Movva 4311664f6a5SPhani Movva static struct platform_driver cc10001_adc_driver = { 4321664f6a5SPhani Movva .driver = { 4331664f6a5SPhani Movva .name = "cc10001-adc", 4341664f6a5SPhani Movva .of_match_table = cc10001_adc_dt_ids, 4351664f6a5SPhani Movva }, 4361664f6a5SPhani Movva .probe = cc10001_adc_probe, 4371664f6a5SPhani Movva .remove = cc10001_adc_remove, 4381664f6a5SPhani Movva }; 4391664f6a5SPhani Movva module_platform_driver(cc10001_adc_driver); 4401664f6a5SPhani Movva 4411664f6a5SPhani Movva MODULE_AUTHOR("Phani Movva <Phani.Movva@imgtec.com>"); 4421664f6a5SPhani Movva MODULE_DESCRIPTION("Cosmic Circuits ADC driver"); 4431664f6a5SPhani Movva MODULE_LICENSE("GPL v2"); 444