11664f6a5SPhani Movva /* 21664f6a5SPhani Movva * Copyright (c) 2014-2015 Imagination Technologies Ltd. 31664f6a5SPhani Movva * 41664f6a5SPhani Movva * This program is free software; you can redistribute it and/or modify it 51664f6a5SPhani Movva * under the terms of the GNU General Public License version 2 as published by 61664f6a5SPhani Movva * the Free Software Foundation. 71664f6a5SPhani Movva * 81664f6a5SPhani Movva */ 91664f6a5SPhani Movva 101664f6a5SPhani Movva #include <linux/clk.h> 111664f6a5SPhani Movva #include <linux/delay.h> 121664f6a5SPhani Movva #include <linux/err.h> 131664f6a5SPhani Movva #include <linux/kernel.h> 141664f6a5SPhani Movva #include <linux/module.h> 151664f6a5SPhani Movva #include <linux/of.h> 161664f6a5SPhani Movva #include <linux/of_device.h> 171664f6a5SPhani Movva #include <linux/platform_device.h> 181664f6a5SPhani Movva #include <linux/regulator/consumer.h> 191664f6a5SPhani Movva #include <linux/slab.h> 201664f6a5SPhani Movva 211664f6a5SPhani Movva #include <linux/iio/buffer.h> 221664f6a5SPhani Movva #include <linux/iio/iio.h> 231664f6a5SPhani Movva #include <linux/iio/sysfs.h> 241664f6a5SPhani Movva #include <linux/iio/trigger.h> 251664f6a5SPhani Movva #include <linux/iio/trigger_consumer.h> 261664f6a5SPhani Movva #include <linux/iio/triggered_buffer.h> 271664f6a5SPhani Movva 281664f6a5SPhani Movva /* Registers */ 291664f6a5SPhani Movva #define CC10001_ADC_CONFIG 0x00 301664f6a5SPhani Movva #define CC10001_ADC_START_CONV BIT(4) 311664f6a5SPhani Movva #define CC10001_ADC_MODE_SINGLE_CONV BIT(5) 321664f6a5SPhani Movva 331664f6a5SPhani Movva #define CC10001_ADC_DDATA_OUT 0x04 341664f6a5SPhani Movva #define CC10001_ADC_EOC 0x08 351664f6a5SPhani Movva #define CC10001_ADC_EOC_SET BIT(0) 361664f6a5SPhani Movva 371664f6a5SPhani Movva #define CC10001_ADC_CHSEL_SAMPLED 0x0c 381664f6a5SPhani Movva #define CC10001_ADC_POWER_UP 0x10 391664f6a5SPhani Movva #define CC10001_ADC_POWER_UP_SET BIT(0) 401664f6a5SPhani Movva #define CC10001_ADC_DEBUG 0x14 411664f6a5SPhani Movva #define CC10001_ADC_DATA_COUNT 0x20 421664f6a5SPhani Movva 431664f6a5SPhani Movva #define CC10001_ADC_DATA_MASK GENMASK(9, 0) 441664f6a5SPhani Movva #define CC10001_ADC_NUM_CHANNELS 8 451664f6a5SPhani Movva #define CC10001_ADC_CH_MASK GENMASK(2, 0) 461664f6a5SPhani Movva 471664f6a5SPhani Movva #define CC10001_INVALID_SAMPLED 0xffff 481664f6a5SPhani Movva #define CC10001_MAX_POLL_COUNT 20 491664f6a5SPhani Movva 501664f6a5SPhani Movva /* 511664f6a5SPhani Movva * As per device specification, wait six clock cycles after power-up to 521664f6a5SPhani Movva * activate START. Since adding two more clock cycles delay does not 531664f6a5SPhani Movva * impact the performance too much, we are adding two additional cycles delay 541664f6a5SPhani Movva * intentionally here. 551664f6a5SPhani Movva */ 561664f6a5SPhani Movva #define CC10001_WAIT_CYCLES 8 571664f6a5SPhani Movva 581664f6a5SPhani Movva struct cc10001_adc_device { 591664f6a5SPhani Movva void __iomem *reg_base; 601664f6a5SPhani Movva struct clk *adc_clk; 611664f6a5SPhani Movva struct regulator *reg; 621664f6a5SPhani Movva u16 *buf; 631664f6a5SPhani Movva 641664f6a5SPhani Movva struct mutex lock; 651664f6a5SPhani Movva unsigned long channel_map; 661664f6a5SPhani Movva unsigned int start_delay_ns; 671664f6a5SPhani Movva unsigned int eoc_delay_ns; 681664f6a5SPhani Movva }; 691664f6a5SPhani Movva 701664f6a5SPhani Movva static inline void cc10001_adc_write_reg(struct cc10001_adc_device *adc_dev, 711664f6a5SPhani Movva u32 reg, u32 val) 721664f6a5SPhani Movva { 731664f6a5SPhani Movva writel(val, adc_dev->reg_base + reg); 741664f6a5SPhani Movva } 751664f6a5SPhani Movva 761664f6a5SPhani Movva static inline u32 cc10001_adc_read_reg(struct cc10001_adc_device *adc_dev, 771664f6a5SPhani Movva u32 reg) 781664f6a5SPhani Movva { 791664f6a5SPhani Movva return readl(adc_dev->reg_base + reg); 801664f6a5SPhani Movva } 811664f6a5SPhani Movva 821664f6a5SPhani Movva static void cc10001_adc_start(struct cc10001_adc_device *adc_dev, 831664f6a5SPhani Movva unsigned int channel) 841664f6a5SPhani Movva { 851664f6a5SPhani Movva u32 val; 861664f6a5SPhani Movva 871664f6a5SPhani Movva /* Channel selection and mode of operation */ 881664f6a5SPhani Movva val = (channel & CC10001_ADC_CH_MASK) | CC10001_ADC_MODE_SINGLE_CONV; 891664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); 901664f6a5SPhani Movva 911664f6a5SPhani Movva val = cc10001_adc_read_reg(adc_dev, CC10001_ADC_CONFIG); 921664f6a5SPhani Movva val = val | CC10001_ADC_START_CONV; 931664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_CONFIG, val); 941664f6a5SPhani Movva } 951664f6a5SPhani Movva 961664f6a5SPhani Movva static u16 cc10001_adc_poll_done(struct iio_dev *indio_dev, 971664f6a5SPhani Movva unsigned int channel, 981664f6a5SPhani Movva unsigned int delay) 991664f6a5SPhani Movva { 1001664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 1011664f6a5SPhani Movva unsigned int poll_count = 0; 1021664f6a5SPhani Movva 1031664f6a5SPhani Movva while (!(cc10001_adc_read_reg(adc_dev, CC10001_ADC_EOC) & 1041664f6a5SPhani Movva CC10001_ADC_EOC_SET)) { 1051664f6a5SPhani Movva 1061664f6a5SPhani Movva ndelay(delay); 1071664f6a5SPhani Movva if (poll_count++ == CC10001_MAX_POLL_COUNT) 1081664f6a5SPhani Movva return CC10001_INVALID_SAMPLED; 1091664f6a5SPhani Movva } 1101664f6a5SPhani Movva 1111664f6a5SPhani Movva poll_count = 0; 1121664f6a5SPhani Movva while ((cc10001_adc_read_reg(adc_dev, CC10001_ADC_CHSEL_SAMPLED) & 1131664f6a5SPhani Movva CC10001_ADC_CH_MASK) != channel) { 1141664f6a5SPhani Movva 1151664f6a5SPhani Movva ndelay(delay); 1161664f6a5SPhani Movva if (poll_count++ == CC10001_MAX_POLL_COUNT) 1171664f6a5SPhani Movva return CC10001_INVALID_SAMPLED; 1181664f6a5SPhani Movva } 1191664f6a5SPhani Movva 1201664f6a5SPhani Movva /* Read the 10 bit output register */ 1211664f6a5SPhani Movva return cc10001_adc_read_reg(adc_dev, CC10001_ADC_DDATA_OUT) & 1221664f6a5SPhani Movva CC10001_ADC_DATA_MASK; 1231664f6a5SPhani Movva } 1241664f6a5SPhani Movva 1251664f6a5SPhani Movva static irqreturn_t cc10001_adc_trigger_h(int irq, void *p) 1261664f6a5SPhani Movva { 1271664f6a5SPhani Movva struct cc10001_adc_device *adc_dev; 1281664f6a5SPhani Movva struct iio_poll_func *pf = p; 1291664f6a5SPhani Movva struct iio_dev *indio_dev; 1301664f6a5SPhani Movva unsigned int delay_ns; 1311664f6a5SPhani Movva unsigned int channel; 1321664f6a5SPhani Movva bool sample_invalid; 1331664f6a5SPhani Movva u16 *data; 1341664f6a5SPhani Movva int i; 1351664f6a5SPhani Movva 1361664f6a5SPhani Movva indio_dev = pf->indio_dev; 1371664f6a5SPhani Movva adc_dev = iio_priv(indio_dev); 1381664f6a5SPhani Movva data = adc_dev->buf; 1391664f6a5SPhani Movva 1401664f6a5SPhani Movva mutex_lock(&adc_dev->lock); 1411664f6a5SPhani Movva 1421664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 1431664f6a5SPhani Movva CC10001_ADC_POWER_UP_SET); 1441664f6a5SPhani Movva 1451664f6a5SPhani Movva /* Wait for 8 (6+2) clock cycles before activating START */ 1461664f6a5SPhani Movva ndelay(adc_dev->start_delay_ns); 1471664f6a5SPhani Movva 1481664f6a5SPhani Movva /* Calculate delay step for eoc and sampled data */ 1491664f6a5SPhani Movva delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; 1501664f6a5SPhani Movva 1511664f6a5SPhani Movva i = 0; 1521664f6a5SPhani Movva sample_invalid = false; 1531664f6a5SPhani Movva for_each_set_bit(channel, indio_dev->active_scan_mask, 1541664f6a5SPhani Movva indio_dev->masklength) { 1551664f6a5SPhani Movva 1561664f6a5SPhani Movva cc10001_adc_start(adc_dev, channel); 1571664f6a5SPhani Movva 1581664f6a5SPhani Movva data[i] = cc10001_adc_poll_done(indio_dev, channel, delay_ns); 1591664f6a5SPhani Movva if (data[i] == CC10001_INVALID_SAMPLED) { 1601664f6a5SPhani Movva dev_warn(&indio_dev->dev, 1611664f6a5SPhani Movva "invalid sample on channel %d\n", channel); 1621664f6a5SPhani Movva sample_invalid = true; 1631664f6a5SPhani Movva goto done; 1641664f6a5SPhani Movva } 1651664f6a5SPhani Movva i++; 1661664f6a5SPhani Movva } 1671664f6a5SPhani Movva 1681664f6a5SPhani Movva done: 1691664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); 1701664f6a5SPhani Movva 1711664f6a5SPhani Movva mutex_unlock(&adc_dev->lock); 1721664f6a5SPhani Movva 1731664f6a5SPhani Movva if (!sample_invalid) 1741664f6a5SPhani Movva iio_push_to_buffers_with_timestamp(indio_dev, data, 1751664f6a5SPhani Movva iio_get_time_ns()); 1761664f6a5SPhani Movva iio_trigger_notify_done(indio_dev->trig); 1771664f6a5SPhani Movva 1781664f6a5SPhani Movva return IRQ_HANDLED; 1791664f6a5SPhani Movva } 1801664f6a5SPhani Movva 1811664f6a5SPhani Movva static u16 cc10001_adc_read_raw_voltage(struct iio_dev *indio_dev, 1821664f6a5SPhani Movva struct iio_chan_spec const *chan) 1831664f6a5SPhani Movva { 1841664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 1851664f6a5SPhani Movva unsigned int delay_ns; 1861664f6a5SPhani Movva u16 val; 1871664f6a5SPhani Movva 1881664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 1891664f6a5SPhani Movva CC10001_ADC_POWER_UP_SET); 1901664f6a5SPhani Movva 1911664f6a5SPhani Movva /* Wait for 8 (6+2) clock cycles before activating START */ 1921664f6a5SPhani Movva ndelay(adc_dev->start_delay_ns); 1931664f6a5SPhani Movva 1941664f6a5SPhani Movva /* Calculate delay step for eoc and sampled data */ 1951664f6a5SPhani Movva delay_ns = adc_dev->eoc_delay_ns / CC10001_MAX_POLL_COUNT; 1961664f6a5SPhani Movva 1971664f6a5SPhani Movva cc10001_adc_start(adc_dev, chan->channel); 1981664f6a5SPhani Movva 1991664f6a5SPhani Movva val = cc10001_adc_poll_done(indio_dev, chan->channel, delay_ns); 2001664f6a5SPhani Movva 2011664f6a5SPhani Movva cc10001_adc_write_reg(adc_dev, CC10001_ADC_POWER_UP, 0); 2021664f6a5SPhani Movva 2031664f6a5SPhani Movva return val; 2041664f6a5SPhani Movva } 2051664f6a5SPhani Movva 2061664f6a5SPhani Movva static int cc10001_adc_read_raw(struct iio_dev *indio_dev, 2071664f6a5SPhani Movva struct iio_chan_spec const *chan, 2081664f6a5SPhani Movva int *val, int *val2, long mask) 2091664f6a5SPhani Movva { 2101664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 2111664f6a5SPhani Movva int ret; 2121664f6a5SPhani Movva 2131664f6a5SPhani Movva switch (mask) { 2141664f6a5SPhani Movva case IIO_CHAN_INFO_RAW: 2151664f6a5SPhani Movva if (iio_buffer_enabled(indio_dev)) 2161664f6a5SPhani Movva return -EBUSY; 2171664f6a5SPhani Movva mutex_lock(&adc_dev->lock); 2181664f6a5SPhani Movva *val = cc10001_adc_read_raw_voltage(indio_dev, chan); 2191664f6a5SPhani Movva mutex_unlock(&adc_dev->lock); 2201664f6a5SPhani Movva 2211664f6a5SPhani Movva if (*val == CC10001_INVALID_SAMPLED) 2221664f6a5SPhani Movva return -EIO; 2231664f6a5SPhani Movva return IIO_VAL_INT; 2241664f6a5SPhani Movva 2251664f6a5SPhani Movva case IIO_CHAN_INFO_SCALE: 2261664f6a5SPhani Movva ret = regulator_get_voltage(adc_dev->reg); 2271664f6a5SPhani Movva if (ret) 2281664f6a5SPhani Movva return ret; 2291664f6a5SPhani Movva 2301664f6a5SPhani Movva *val = ret / 1000; 2311664f6a5SPhani Movva *val2 = chan->scan_type.realbits; 2321664f6a5SPhani Movva return IIO_VAL_FRACTIONAL_LOG2; 2331664f6a5SPhani Movva 2341664f6a5SPhani Movva default: 2351664f6a5SPhani Movva return -EINVAL; 2361664f6a5SPhani Movva } 2371664f6a5SPhani Movva } 2381664f6a5SPhani Movva 2391664f6a5SPhani Movva static int cc10001_update_scan_mode(struct iio_dev *indio_dev, 2401664f6a5SPhani Movva const unsigned long *scan_mask) 2411664f6a5SPhani Movva { 2421664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 2431664f6a5SPhani Movva 2441664f6a5SPhani Movva kfree(adc_dev->buf); 2451664f6a5SPhani Movva adc_dev->buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); 2461664f6a5SPhani Movva if (!adc_dev->buf) 2471664f6a5SPhani Movva return -ENOMEM; 2481664f6a5SPhani Movva 2491664f6a5SPhani Movva return 0; 2501664f6a5SPhani Movva } 2511664f6a5SPhani Movva 2521664f6a5SPhani Movva static const struct iio_info cc10001_adc_info = { 2531664f6a5SPhani Movva .driver_module = THIS_MODULE, 2541664f6a5SPhani Movva .read_raw = &cc10001_adc_read_raw, 2551664f6a5SPhani Movva .update_scan_mode = &cc10001_update_scan_mode, 2561664f6a5SPhani Movva }; 2571664f6a5SPhani Movva 2581664f6a5SPhani Movva static int cc10001_adc_channel_init(struct iio_dev *indio_dev) 2591664f6a5SPhani Movva { 2601664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 2611664f6a5SPhani Movva struct iio_chan_spec *chan_array, *timestamp; 2621664f6a5SPhani Movva unsigned int bit, idx = 0; 2631664f6a5SPhani Movva 2641664f6a5SPhani Movva indio_dev->num_channels = bitmap_weight(&adc_dev->channel_map, 2651664f6a5SPhani Movva CC10001_ADC_NUM_CHANNELS); 2661664f6a5SPhani Movva 2671664f6a5SPhani Movva chan_array = devm_kcalloc(&indio_dev->dev, indio_dev->num_channels + 1, 2681664f6a5SPhani Movva sizeof(struct iio_chan_spec), 2691664f6a5SPhani Movva GFP_KERNEL); 2701664f6a5SPhani Movva if (!chan_array) 2711664f6a5SPhani Movva return -ENOMEM; 2721664f6a5SPhani Movva 2731664f6a5SPhani Movva for_each_set_bit(bit, &adc_dev->channel_map, CC10001_ADC_NUM_CHANNELS) { 2741664f6a5SPhani Movva struct iio_chan_spec *chan = &chan_array[idx]; 2751664f6a5SPhani Movva 2761664f6a5SPhani Movva chan->type = IIO_VOLTAGE; 2771664f6a5SPhani Movva chan->indexed = 1; 2781664f6a5SPhani Movva chan->channel = bit; 2791664f6a5SPhani Movva chan->scan_index = idx; 2801664f6a5SPhani Movva chan->scan_type.sign = 'u'; 2811664f6a5SPhani Movva chan->scan_type.realbits = 10; 2821664f6a5SPhani Movva chan->scan_type.storagebits = 16; 2831664f6a5SPhani Movva chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); 2841664f6a5SPhani Movva chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 2851664f6a5SPhani Movva idx++; 2861664f6a5SPhani Movva } 2871664f6a5SPhani Movva 2881664f6a5SPhani Movva timestamp = &chan_array[idx]; 2891664f6a5SPhani Movva timestamp->type = IIO_TIMESTAMP; 2901664f6a5SPhani Movva timestamp->channel = -1; 2911664f6a5SPhani Movva timestamp->scan_index = idx; 2921664f6a5SPhani Movva timestamp->scan_type.sign = 's'; 2931664f6a5SPhani Movva timestamp->scan_type.realbits = 64; 2941664f6a5SPhani Movva timestamp->scan_type.storagebits = 64; 2951664f6a5SPhani Movva 2961664f6a5SPhani Movva indio_dev->channels = chan_array; 2971664f6a5SPhani Movva 2981664f6a5SPhani Movva return 0; 2991664f6a5SPhani Movva } 3001664f6a5SPhani Movva 3011664f6a5SPhani Movva static int cc10001_adc_probe(struct platform_device *pdev) 3021664f6a5SPhani Movva { 3031664f6a5SPhani Movva struct device_node *node = pdev->dev.of_node; 3041664f6a5SPhani Movva struct cc10001_adc_device *adc_dev; 3051664f6a5SPhani Movva unsigned long adc_clk_rate; 3061664f6a5SPhani Movva struct resource *res; 3071664f6a5SPhani Movva struct iio_dev *indio_dev; 3081664f6a5SPhani Movva int ret; 3091664f6a5SPhani Movva 3101664f6a5SPhani Movva indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*adc_dev)); 3111664f6a5SPhani Movva if (indio_dev == NULL) 3121664f6a5SPhani Movva return -ENOMEM; 3131664f6a5SPhani Movva 3141664f6a5SPhani Movva adc_dev = iio_priv(indio_dev); 3151664f6a5SPhani Movva 3161664f6a5SPhani Movva adc_dev->channel_map = GENMASK(CC10001_ADC_NUM_CHANNELS - 1, 0); 3171664f6a5SPhani Movva if (!of_property_read_u32(node, "adc-reserved-channels", &ret)) 3181664f6a5SPhani Movva adc_dev->channel_map &= ~ret; 3191664f6a5SPhani Movva 3201664f6a5SPhani Movva adc_dev->reg = devm_regulator_get(&pdev->dev, "vref"); 3211664f6a5SPhani Movva if (IS_ERR(adc_dev->reg)) 3221664f6a5SPhani Movva return PTR_ERR(adc_dev->reg); 3231664f6a5SPhani Movva 3241664f6a5SPhani Movva ret = regulator_enable(adc_dev->reg); 3251664f6a5SPhani Movva if (ret) 3261664f6a5SPhani Movva return ret; 3271664f6a5SPhani Movva 3281664f6a5SPhani Movva indio_dev->dev.parent = &pdev->dev; 3291664f6a5SPhani Movva indio_dev->name = dev_name(&pdev->dev); 3301664f6a5SPhani Movva indio_dev->info = &cc10001_adc_info; 3311664f6a5SPhani Movva indio_dev->modes = INDIO_DIRECT_MODE; 3321664f6a5SPhani Movva 3331664f6a5SPhani Movva res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 3341664f6a5SPhani Movva adc_dev->reg_base = devm_ioremap_resource(&pdev->dev, res); 3351664f6a5SPhani Movva if (IS_ERR(adc_dev->reg_base)) { 3361664f6a5SPhani Movva ret = PTR_ERR(adc_dev->reg_base); 3371664f6a5SPhani Movva goto err_disable_reg; 3381664f6a5SPhani Movva } 3391664f6a5SPhani Movva 3401664f6a5SPhani Movva adc_dev->adc_clk = devm_clk_get(&pdev->dev, "adc"); 3411664f6a5SPhani Movva if (IS_ERR(adc_dev->adc_clk)) { 3421664f6a5SPhani Movva dev_err(&pdev->dev, "failed to get the clock\n"); 3431664f6a5SPhani Movva ret = PTR_ERR(adc_dev->adc_clk); 3441664f6a5SPhani Movva goto err_disable_reg; 3451664f6a5SPhani Movva } 3461664f6a5SPhani Movva 3471664f6a5SPhani Movva ret = clk_prepare_enable(adc_dev->adc_clk); 3481664f6a5SPhani Movva if (ret) { 3491664f6a5SPhani Movva dev_err(&pdev->dev, "failed to enable the clock\n"); 3501664f6a5SPhani Movva goto err_disable_reg; 3511664f6a5SPhani Movva } 3521664f6a5SPhani Movva 3531664f6a5SPhani Movva adc_clk_rate = clk_get_rate(adc_dev->adc_clk); 3541664f6a5SPhani Movva if (!adc_clk_rate) { 3551664f6a5SPhani Movva ret = -EINVAL; 3561664f6a5SPhani Movva dev_err(&pdev->dev, "null clock rate!\n"); 3571664f6a5SPhani Movva goto err_disable_clk; 3581664f6a5SPhani Movva } 3591664f6a5SPhani Movva 3601664f6a5SPhani Movva adc_dev->eoc_delay_ns = NSEC_PER_SEC / adc_clk_rate; 3611664f6a5SPhani Movva adc_dev->start_delay_ns = adc_dev->eoc_delay_ns * CC10001_WAIT_CYCLES; 3621664f6a5SPhani Movva 3631664f6a5SPhani Movva /* Setup the ADC channels available on the device */ 3641664f6a5SPhani Movva ret = cc10001_adc_channel_init(indio_dev); 3651664f6a5SPhani Movva if (ret < 0) 3661664f6a5SPhani Movva goto err_disable_clk; 3671664f6a5SPhani Movva 3681664f6a5SPhani Movva mutex_init(&adc_dev->lock); 3691664f6a5SPhani Movva 3701664f6a5SPhani Movva ret = iio_triggered_buffer_setup(indio_dev, NULL, 3711664f6a5SPhani Movva &cc10001_adc_trigger_h, NULL); 3721664f6a5SPhani Movva if (ret < 0) 3731664f6a5SPhani Movva goto err_disable_clk; 3741664f6a5SPhani Movva 3751664f6a5SPhani Movva ret = iio_device_register(indio_dev); 3761664f6a5SPhani Movva if (ret < 0) 3771664f6a5SPhani Movva goto err_cleanup_buffer; 3781664f6a5SPhani Movva 3791664f6a5SPhani Movva platform_set_drvdata(pdev, indio_dev); 3801664f6a5SPhani Movva 3811664f6a5SPhani Movva return 0; 3821664f6a5SPhani Movva 3831664f6a5SPhani Movva err_cleanup_buffer: 3841664f6a5SPhani Movva iio_triggered_buffer_cleanup(indio_dev); 3851664f6a5SPhani Movva err_disable_clk: 3861664f6a5SPhani Movva clk_disable_unprepare(adc_dev->adc_clk); 3871664f6a5SPhani Movva err_disable_reg: 3881664f6a5SPhani Movva regulator_disable(adc_dev->reg); 3891664f6a5SPhani Movva return ret; 3901664f6a5SPhani Movva } 3911664f6a5SPhani Movva 3921664f6a5SPhani Movva static int cc10001_adc_remove(struct platform_device *pdev) 3931664f6a5SPhani Movva { 3941664f6a5SPhani Movva struct iio_dev *indio_dev = platform_get_drvdata(pdev); 3951664f6a5SPhani Movva struct cc10001_adc_device *adc_dev = iio_priv(indio_dev); 3961664f6a5SPhani Movva 3971664f6a5SPhani Movva iio_device_unregister(indio_dev); 3981664f6a5SPhani Movva iio_triggered_buffer_cleanup(indio_dev); 3991664f6a5SPhani Movva clk_disable_unprepare(adc_dev->adc_clk); 4001664f6a5SPhani Movva regulator_disable(adc_dev->reg); 4011664f6a5SPhani Movva 4021664f6a5SPhani Movva return 0; 4031664f6a5SPhani Movva } 4041664f6a5SPhani Movva 4051664f6a5SPhani Movva static const struct of_device_id cc10001_adc_dt_ids[] = { 4061664f6a5SPhani Movva { .compatible = "cosmic,10001-adc", }, 4071664f6a5SPhani Movva { } 4081664f6a5SPhani Movva }; 4091664f6a5SPhani Movva MODULE_DEVICE_TABLE(of, cc10001_adc_dt_ids); 4101664f6a5SPhani Movva 4111664f6a5SPhani Movva static struct platform_driver cc10001_adc_driver = { 4121664f6a5SPhani Movva .driver = { 4131664f6a5SPhani Movva .name = "cc10001-adc", 4141664f6a5SPhani Movva .of_match_table = cc10001_adc_dt_ids, 4151664f6a5SPhani Movva }, 4161664f6a5SPhani Movva .probe = cc10001_adc_probe, 4171664f6a5SPhani Movva .remove = cc10001_adc_remove, 4181664f6a5SPhani Movva }; 4191664f6a5SPhani Movva module_platform_driver(cc10001_adc_driver); 4201664f6a5SPhani Movva 4211664f6a5SPhani Movva MODULE_AUTHOR("Phani Movva <Phani.Movva@imgtec.com>"); 4221664f6a5SPhani Movva MODULE_DESCRIPTION("Cosmic Circuits ADC driver"); 4231664f6a5SPhani Movva MODULE_LICENSE("GPL v2"); 424