10e589d5fSMaxime Ripard /* 20e589d5fSMaxime Ripard * Driver for the ADC present in the Atmel AT91 evaluation boards. 30e589d5fSMaxime Ripard * 40e589d5fSMaxime Ripard * Copyright 2011 Free Electrons 50e589d5fSMaxime Ripard * 60e589d5fSMaxime Ripard * Licensed under the GPLv2 or later. 70e589d5fSMaxime Ripard */ 80e589d5fSMaxime Ripard 90e589d5fSMaxime Ripard #include <linux/bitmap.h> 100e589d5fSMaxime Ripard #include <linux/bitops.h> 110e589d5fSMaxime Ripard #include <linux/clk.h> 120e589d5fSMaxime Ripard #include <linux/err.h> 130e589d5fSMaxime Ripard #include <linux/io.h> 140e589d5fSMaxime Ripard #include <linux/interrupt.h> 150e589d5fSMaxime Ripard #include <linux/jiffies.h> 160e589d5fSMaxime Ripard #include <linux/kernel.h> 170e589d5fSMaxime Ripard #include <linux/module.h> 18e364185fSMaxime Ripard #include <linux/of.h> 19e364185fSMaxime Ripard #include <linux/of_device.h> 200e589d5fSMaxime Ripard #include <linux/platform_device.h> 210e589d5fSMaxime Ripard #include <linux/sched.h> 220e589d5fSMaxime Ripard #include <linux/slab.h> 230e589d5fSMaxime Ripard #include <linux/wait.h> 240e589d5fSMaxime Ripard 250e589d5fSMaxime Ripard #include <linux/platform_data/at91_adc.h> 260e589d5fSMaxime Ripard 270e589d5fSMaxime Ripard #include <linux/iio/iio.h> 280e589d5fSMaxime Ripard #include <linux/iio/buffer.h> 290e589d5fSMaxime Ripard #include <linux/iio/trigger.h> 300e589d5fSMaxime Ripard #include <linux/iio/trigger_consumer.h> 3190032e4eSLars-Peter Clausen #include <linux/iio/triggered_buffer.h> 320e589d5fSMaxime Ripard 330e589d5fSMaxime Ripard #include <mach/at91_adc.h> 340e589d5fSMaxime Ripard 350e589d5fSMaxime Ripard #define AT91_ADC_CHAN(st, ch) \ 360e589d5fSMaxime Ripard (st->registers->channel_base + (ch * 4)) 370e589d5fSMaxime Ripard #define at91_adc_readl(st, reg) \ 380e589d5fSMaxime Ripard (readl_relaxed(st->reg_base + reg)) 390e589d5fSMaxime Ripard #define at91_adc_writel(st, reg, val) \ 400e589d5fSMaxime Ripard (writel_relaxed(val, st->reg_base + reg)) 410e589d5fSMaxime Ripard 42e1811f97SJosh Wu struct at91_adc_caps { 43e1811f97SJosh Wu struct at91_adc_reg_desc registers; 44e1811f97SJosh Wu }; 45e1811f97SJosh Wu 460e589d5fSMaxime Ripard struct at91_adc_state { 470e589d5fSMaxime Ripard struct clk *adc_clk; 480e589d5fSMaxime Ripard u16 *buffer; 490e589d5fSMaxime Ripard unsigned long channels_mask; 500e589d5fSMaxime Ripard struct clk *clk; 510e589d5fSMaxime Ripard bool done; 520e589d5fSMaxime Ripard int irq; 530e589d5fSMaxime Ripard u16 last_value; 540e589d5fSMaxime Ripard struct mutex lock; 550e589d5fSMaxime Ripard u8 num_channels; 560e589d5fSMaxime Ripard void __iomem *reg_base; 570e589d5fSMaxime Ripard struct at91_adc_reg_desc *registers; 580e589d5fSMaxime Ripard u8 startup_time; 59beca9e76SJean-Christophe PLAGNIOL-VILLARD u8 sample_hold_time; 60e748783cSJean-Christophe PLAGNIOL-VILLARD bool sleep_mode; 610e589d5fSMaxime Ripard struct iio_trigger **trig; 620e589d5fSMaxime Ripard struct at91_adc_trigger *trigger_list; 630e589d5fSMaxime Ripard u32 trigger_number; 640e589d5fSMaxime Ripard bool use_external; 650e589d5fSMaxime Ripard u32 vref_mv; 6647be16b6SLudovic Desroches u32 res; /* resolution used for convertions */ 6747be16b6SLudovic Desroches bool low_res; /* the resolution corresponds to the lowest one */ 680e589d5fSMaxime Ripard wait_queue_head_t wq_data_avail; 69e1811f97SJosh Wu struct at91_adc_caps *caps; 700e589d5fSMaxime Ripard }; 710e589d5fSMaxime Ripard 720e589d5fSMaxime Ripard static irqreturn_t at91_adc_trigger_handler(int irq, void *p) 730e589d5fSMaxime Ripard { 740e589d5fSMaxime Ripard struct iio_poll_func *pf = p; 750e589d5fSMaxime Ripard struct iio_dev *idev = pf->indio_dev; 760e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 770e589d5fSMaxime Ripard int i, j = 0; 780e589d5fSMaxime Ripard 790e589d5fSMaxime Ripard for (i = 0; i < idev->masklength; i++) { 800e589d5fSMaxime Ripard if (!test_bit(i, idev->active_scan_mask)) 810e589d5fSMaxime Ripard continue; 820e589d5fSMaxime Ripard st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, i)); 830e589d5fSMaxime Ripard j++; 840e589d5fSMaxime Ripard } 850e589d5fSMaxime Ripard 860e589d5fSMaxime Ripard if (idev->scan_timestamp) { 870e589d5fSMaxime Ripard s64 *timestamp = (s64 *)((u8 *)st->buffer + 880e589d5fSMaxime Ripard ALIGN(j, sizeof(s64))); 890e589d5fSMaxime Ripard *timestamp = pf->timestamp; 900e589d5fSMaxime Ripard } 910e589d5fSMaxime Ripard 9211679767SJean-Christophe PLAGNIOL-VILLARD iio_push_to_buffers(idev, (u8 *)st->buffer); 930e589d5fSMaxime Ripard 940e589d5fSMaxime Ripard iio_trigger_notify_done(idev->trig); 950e589d5fSMaxime Ripard 960e589d5fSMaxime Ripard /* Needed to ACK the DRDY interruption */ 970e589d5fSMaxime Ripard at91_adc_readl(st, AT91_ADC_LCDR); 980e589d5fSMaxime Ripard 990e589d5fSMaxime Ripard enable_irq(st->irq); 1000e589d5fSMaxime Ripard 1010e589d5fSMaxime Ripard return IRQ_HANDLED; 1020e589d5fSMaxime Ripard } 1030e589d5fSMaxime Ripard 1040e589d5fSMaxime Ripard static irqreturn_t at91_adc_eoc_trigger(int irq, void *private) 1050e589d5fSMaxime Ripard { 1060e589d5fSMaxime Ripard struct iio_dev *idev = private; 1070e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 1080e589d5fSMaxime Ripard u32 status = at91_adc_readl(st, st->registers->status_register); 1090e589d5fSMaxime Ripard 1100e589d5fSMaxime Ripard if (!(status & st->registers->drdy_mask)) 1110e589d5fSMaxime Ripard return IRQ_HANDLED; 1120e589d5fSMaxime Ripard 1130e589d5fSMaxime Ripard if (iio_buffer_enabled(idev)) { 1140e589d5fSMaxime Ripard disable_irq_nosync(irq); 1150e589d5fSMaxime Ripard iio_trigger_poll(idev->trig, iio_get_time_ns()); 1160e589d5fSMaxime Ripard } else { 1170e589d5fSMaxime Ripard st->last_value = at91_adc_readl(st, AT91_ADC_LCDR); 1180e589d5fSMaxime Ripard st->done = true; 1190e589d5fSMaxime Ripard wake_up_interruptible(&st->wq_data_avail); 1200e589d5fSMaxime Ripard } 1210e589d5fSMaxime Ripard 1220e589d5fSMaxime Ripard return IRQ_HANDLED; 1230e589d5fSMaxime Ripard } 1240e589d5fSMaxime Ripard 1250e589d5fSMaxime Ripard static int at91_adc_channel_init(struct iio_dev *idev) 1260e589d5fSMaxime Ripard { 1270e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 1280e589d5fSMaxime Ripard struct iio_chan_spec *chan_array, *timestamp; 1290e589d5fSMaxime Ripard int bit, idx = 0; 1300e589d5fSMaxime Ripard 1310e589d5fSMaxime Ripard idev->num_channels = bitmap_weight(&st->channels_mask, 1320e589d5fSMaxime Ripard st->num_channels) + 1; 1330e589d5fSMaxime Ripard 1346b3aa313SAxel Lin chan_array = devm_kzalloc(&idev->dev, 1356b3aa313SAxel Lin ((idev->num_channels + 1) * 1366b3aa313SAxel Lin sizeof(struct iio_chan_spec)), 1376b3aa313SAxel Lin GFP_KERNEL); 1380e589d5fSMaxime Ripard 1390e589d5fSMaxime Ripard if (!chan_array) 1400e589d5fSMaxime Ripard return -ENOMEM; 1410e589d5fSMaxime Ripard 1420e589d5fSMaxime Ripard for_each_set_bit(bit, &st->channels_mask, st->num_channels) { 1430e589d5fSMaxime Ripard struct iio_chan_spec *chan = chan_array + idx; 1440e589d5fSMaxime Ripard 1450e589d5fSMaxime Ripard chan->type = IIO_VOLTAGE; 1460e589d5fSMaxime Ripard chan->indexed = 1; 1470e589d5fSMaxime Ripard chan->channel = bit; 1480e589d5fSMaxime Ripard chan->scan_index = idx; 1490e589d5fSMaxime Ripard chan->scan_type.sign = 'u'; 15047be16b6SLudovic Desroches chan->scan_type.realbits = st->res; 1510e589d5fSMaxime Ripard chan->scan_type.storagebits = 16; 15201bdab66SJonathan Cameron chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); 15301bdab66SJonathan Cameron chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 1540e589d5fSMaxime Ripard idx++; 1550e589d5fSMaxime Ripard } 1560e589d5fSMaxime Ripard timestamp = chan_array + idx; 1570e589d5fSMaxime Ripard 1580e589d5fSMaxime Ripard timestamp->type = IIO_TIMESTAMP; 1590e589d5fSMaxime Ripard timestamp->channel = -1; 1600e589d5fSMaxime Ripard timestamp->scan_index = idx; 1610e589d5fSMaxime Ripard timestamp->scan_type.sign = 's'; 1620e589d5fSMaxime Ripard timestamp->scan_type.realbits = 64; 1630e589d5fSMaxime Ripard timestamp->scan_type.storagebits = 64; 1640e589d5fSMaxime Ripard 1650e589d5fSMaxime Ripard idev->channels = chan_array; 1660e589d5fSMaxime Ripard return idev->num_channels; 1670e589d5fSMaxime Ripard } 1680e589d5fSMaxime Ripard 1690e589d5fSMaxime Ripard static u8 at91_adc_get_trigger_value_by_name(struct iio_dev *idev, 1700e589d5fSMaxime Ripard struct at91_adc_trigger *triggers, 1710e589d5fSMaxime Ripard const char *trigger_name) 1720e589d5fSMaxime Ripard { 1730e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 1740e589d5fSMaxime Ripard u8 value = 0; 1750e589d5fSMaxime Ripard int i; 1760e589d5fSMaxime Ripard 1770e589d5fSMaxime Ripard for (i = 0; i < st->trigger_number; i++) { 1780e589d5fSMaxime Ripard char *name = kasprintf(GFP_KERNEL, 1790e589d5fSMaxime Ripard "%s-dev%d-%s", 1800e589d5fSMaxime Ripard idev->name, 1810e589d5fSMaxime Ripard idev->id, 1820e589d5fSMaxime Ripard triggers[i].name); 1830e589d5fSMaxime Ripard if (!name) 1840e589d5fSMaxime Ripard return -ENOMEM; 1850e589d5fSMaxime Ripard 1860e589d5fSMaxime Ripard if (strcmp(trigger_name, name) == 0) { 1870e589d5fSMaxime Ripard value = triggers[i].value; 1880e589d5fSMaxime Ripard kfree(name); 1890e589d5fSMaxime Ripard break; 1900e589d5fSMaxime Ripard } 1910e589d5fSMaxime Ripard 1920e589d5fSMaxime Ripard kfree(name); 1930e589d5fSMaxime Ripard } 1940e589d5fSMaxime Ripard 1950e589d5fSMaxime Ripard return value; 1960e589d5fSMaxime Ripard } 1970e589d5fSMaxime Ripard 1980e589d5fSMaxime Ripard static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) 1990e589d5fSMaxime Ripard { 2001e9663c6SLars-Peter Clausen struct iio_dev *idev = iio_trigger_get_drvdata(trig); 2010e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 2020e589d5fSMaxime Ripard struct iio_buffer *buffer = idev->buffer; 2030e589d5fSMaxime Ripard struct at91_adc_reg_desc *reg = st->registers; 2040e589d5fSMaxime Ripard u32 status = at91_adc_readl(st, reg->trigger_register); 2050e589d5fSMaxime Ripard u8 value; 2060e589d5fSMaxime Ripard u8 bit; 2070e589d5fSMaxime Ripard 2080e589d5fSMaxime Ripard value = at91_adc_get_trigger_value_by_name(idev, 2090e589d5fSMaxime Ripard st->trigger_list, 2100e589d5fSMaxime Ripard idev->trig->name); 2110e589d5fSMaxime Ripard if (value == 0) 2120e589d5fSMaxime Ripard return -EINVAL; 2130e589d5fSMaxime Ripard 2140e589d5fSMaxime Ripard if (state) { 2150e589d5fSMaxime Ripard st->buffer = kmalloc(idev->scan_bytes, GFP_KERNEL); 2160e589d5fSMaxime Ripard if (st->buffer == NULL) 2170e589d5fSMaxime Ripard return -ENOMEM; 2180e589d5fSMaxime Ripard 2190e589d5fSMaxime Ripard at91_adc_writel(st, reg->trigger_register, 2200e589d5fSMaxime Ripard status | value); 2210e589d5fSMaxime Ripard 2220e589d5fSMaxime Ripard for_each_set_bit(bit, buffer->scan_mask, 2230e589d5fSMaxime Ripard st->num_channels) { 2240e589d5fSMaxime Ripard struct iio_chan_spec const *chan = idev->channels + bit; 2250e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHER, 2260e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 2270e589d5fSMaxime Ripard } 2280e589d5fSMaxime Ripard 2290e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IER, reg->drdy_mask); 2300e589d5fSMaxime Ripard 2310e589d5fSMaxime Ripard } else { 2320e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, reg->drdy_mask); 2330e589d5fSMaxime Ripard 2340e589d5fSMaxime Ripard at91_adc_writel(st, reg->trigger_register, 2350e589d5fSMaxime Ripard status & ~value); 2360e589d5fSMaxime Ripard 2370e589d5fSMaxime Ripard for_each_set_bit(bit, buffer->scan_mask, 2380e589d5fSMaxime Ripard st->num_channels) { 2390e589d5fSMaxime Ripard struct iio_chan_spec const *chan = idev->channels + bit; 2400e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHDR, 2410e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 2420e589d5fSMaxime Ripard } 2430e589d5fSMaxime Ripard kfree(st->buffer); 2440e589d5fSMaxime Ripard } 2450e589d5fSMaxime Ripard 2460e589d5fSMaxime Ripard return 0; 2470e589d5fSMaxime Ripard } 2480e589d5fSMaxime Ripard 2490e589d5fSMaxime Ripard static const struct iio_trigger_ops at91_adc_trigger_ops = { 2500e589d5fSMaxime Ripard .owner = THIS_MODULE, 2510e589d5fSMaxime Ripard .set_trigger_state = &at91_adc_configure_trigger, 2520e589d5fSMaxime Ripard }; 2530e589d5fSMaxime Ripard 2540e589d5fSMaxime Ripard static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev, 2550e589d5fSMaxime Ripard struct at91_adc_trigger *trigger) 2560e589d5fSMaxime Ripard { 2570e589d5fSMaxime Ripard struct iio_trigger *trig; 2580e589d5fSMaxime Ripard int ret; 2590e589d5fSMaxime Ripard 2600e589d5fSMaxime Ripard trig = iio_trigger_alloc("%s-dev%d-%s", idev->name, 2610e589d5fSMaxime Ripard idev->id, trigger->name); 2620e589d5fSMaxime Ripard if (trig == NULL) 2630e589d5fSMaxime Ripard return NULL; 2640e589d5fSMaxime Ripard 2650e589d5fSMaxime Ripard trig->dev.parent = idev->dev.parent; 2661e9663c6SLars-Peter Clausen iio_trigger_set_drvdata(trig, idev); 2670e589d5fSMaxime Ripard trig->ops = &at91_adc_trigger_ops; 2680e589d5fSMaxime Ripard 2690e589d5fSMaxime Ripard ret = iio_trigger_register(trig); 2700e589d5fSMaxime Ripard if (ret) 2710e589d5fSMaxime Ripard return NULL; 2720e589d5fSMaxime Ripard 2730e589d5fSMaxime Ripard return trig; 2740e589d5fSMaxime Ripard } 2750e589d5fSMaxime Ripard 2760e589d5fSMaxime Ripard static int at91_adc_trigger_init(struct iio_dev *idev) 2770e589d5fSMaxime Ripard { 2780e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 2790e589d5fSMaxime Ripard int i, ret; 2800e589d5fSMaxime Ripard 2816b3aa313SAxel Lin st->trig = devm_kzalloc(&idev->dev, 2826b3aa313SAxel Lin st->trigger_number * sizeof(st->trig), 2836b3aa313SAxel Lin GFP_KERNEL); 2840e589d5fSMaxime Ripard 2850e589d5fSMaxime Ripard if (st->trig == NULL) { 2860e589d5fSMaxime Ripard ret = -ENOMEM; 2870e589d5fSMaxime Ripard goto error_ret; 2880e589d5fSMaxime Ripard } 2890e589d5fSMaxime Ripard 2900e589d5fSMaxime Ripard for (i = 0; i < st->trigger_number; i++) { 2910e589d5fSMaxime Ripard if (st->trigger_list[i].is_external && !(st->use_external)) 2920e589d5fSMaxime Ripard continue; 2930e589d5fSMaxime Ripard 2940e589d5fSMaxime Ripard st->trig[i] = at91_adc_allocate_trigger(idev, 2950e589d5fSMaxime Ripard st->trigger_list + i); 2960e589d5fSMaxime Ripard if (st->trig[i] == NULL) { 2970e589d5fSMaxime Ripard dev_err(&idev->dev, 2980e589d5fSMaxime Ripard "Could not allocate trigger %d\n", i); 2990e589d5fSMaxime Ripard ret = -ENOMEM; 3000e589d5fSMaxime Ripard goto error_trigger; 3010e589d5fSMaxime Ripard } 3020e589d5fSMaxime Ripard } 3030e589d5fSMaxime Ripard 3040e589d5fSMaxime Ripard return 0; 3050e589d5fSMaxime Ripard 3060e589d5fSMaxime Ripard error_trigger: 3070e589d5fSMaxime Ripard for (i--; i >= 0; i--) { 3080e589d5fSMaxime Ripard iio_trigger_unregister(st->trig[i]); 3090e589d5fSMaxime Ripard iio_trigger_free(st->trig[i]); 3100e589d5fSMaxime Ripard } 3110e589d5fSMaxime Ripard error_ret: 3120e589d5fSMaxime Ripard return ret; 3130e589d5fSMaxime Ripard } 3140e589d5fSMaxime Ripard 3150e589d5fSMaxime Ripard static void at91_adc_trigger_remove(struct iio_dev *idev) 3160e589d5fSMaxime Ripard { 3170e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 3180e589d5fSMaxime Ripard int i; 3190e589d5fSMaxime Ripard 3200e589d5fSMaxime Ripard for (i = 0; i < st->trigger_number; i++) { 3210e589d5fSMaxime Ripard iio_trigger_unregister(st->trig[i]); 3220e589d5fSMaxime Ripard iio_trigger_free(st->trig[i]); 3230e589d5fSMaxime Ripard } 3240e589d5fSMaxime Ripard } 3250e589d5fSMaxime Ripard 3260e589d5fSMaxime Ripard static int at91_adc_buffer_init(struct iio_dev *idev) 3270e589d5fSMaxime Ripard { 32890032e4eSLars-Peter Clausen return iio_triggered_buffer_setup(idev, &iio_pollfunc_store_time, 32990032e4eSLars-Peter Clausen &at91_adc_trigger_handler, NULL); 3300e589d5fSMaxime Ripard } 3310e589d5fSMaxime Ripard 3320e589d5fSMaxime Ripard static void at91_adc_buffer_remove(struct iio_dev *idev) 3330e589d5fSMaxime Ripard { 33490032e4eSLars-Peter Clausen iio_triggered_buffer_cleanup(idev); 3350e589d5fSMaxime Ripard } 3360e589d5fSMaxime Ripard 3370e589d5fSMaxime Ripard static int at91_adc_read_raw(struct iio_dev *idev, 3380e589d5fSMaxime Ripard struct iio_chan_spec const *chan, 3390e589d5fSMaxime Ripard int *val, int *val2, long mask) 3400e589d5fSMaxime Ripard { 3410e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 3420e589d5fSMaxime Ripard int ret; 3430e589d5fSMaxime Ripard 3440e589d5fSMaxime Ripard switch (mask) { 3450e589d5fSMaxime Ripard case IIO_CHAN_INFO_RAW: 3460e589d5fSMaxime Ripard mutex_lock(&st->lock); 3470e589d5fSMaxime Ripard 3480e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHER, 3490e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 3500e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IER, st->registers->drdy_mask); 3510e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_START); 3520e589d5fSMaxime Ripard 3530e589d5fSMaxime Ripard ret = wait_event_interruptible_timeout(st->wq_data_avail, 3540e589d5fSMaxime Ripard st->done, 3550e589d5fSMaxime Ripard msecs_to_jiffies(1000)); 3560e589d5fSMaxime Ripard if (ret == 0) 35790e6dc7cSLars-Peter Clausen ret = -ETIMEDOUT; 35890e6dc7cSLars-Peter Clausen if (ret < 0) { 35990e6dc7cSLars-Peter Clausen mutex_unlock(&st->lock); 3600e589d5fSMaxime Ripard return ret; 36190e6dc7cSLars-Peter Clausen } 3620e589d5fSMaxime Ripard 3630e589d5fSMaxime Ripard *val = st->last_value; 3640e589d5fSMaxime Ripard 3650e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHDR, 3660e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 3670e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, st->registers->drdy_mask); 3680e589d5fSMaxime Ripard 3690e589d5fSMaxime Ripard st->last_value = 0; 3700e589d5fSMaxime Ripard st->done = false; 3710e589d5fSMaxime Ripard mutex_unlock(&st->lock); 3720e589d5fSMaxime Ripard return IIO_VAL_INT; 3730e589d5fSMaxime Ripard 3740e589d5fSMaxime Ripard case IIO_CHAN_INFO_SCALE: 3750e589d5fSMaxime Ripard *val = (st->vref_mv * 1000) >> chan->scan_type.realbits; 3760e589d5fSMaxime Ripard *val2 = 0; 3770e589d5fSMaxime Ripard return IIO_VAL_INT_PLUS_MICRO; 3780e589d5fSMaxime Ripard default: 3790e589d5fSMaxime Ripard break; 3800e589d5fSMaxime Ripard } 3810e589d5fSMaxime Ripard return -EINVAL; 3820e589d5fSMaxime Ripard } 3830e589d5fSMaxime Ripard 38447be16b6SLudovic Desroches static int at91_adc_of_get_resolution(struct at91_adc_state *st, 38547be16b6SLudovic Desroches struct platform_device *pdev) 38647be16b6SLudovic Desroches { 38747be16b6SLudovic Desroches struct iio_dev *idev = iio_priv_to_dev(st); 38847be16b6SLudovic Desroches struct device_node *np = pdev->dev.of_node; 38947be16b6SLudovic Desroches int count, i, ret = 0; 39047be16b6SLudovic Desroches char *res_name, *s; 39147be16b6SLudovic Desroches u32 *resolutions; 39247be16b6SLudovic Desroches 39347be16b6SLudovic Desroches count = of_property_count_strings(np, "atmel,adc-res-names"); 39447be16b6SLudovic Desroches if (count < 2) { 39547be16b6SLudovic Desroches dev_err(&idev->dev, "You must specified at least two resolution names for " 39647be16b6SLudovic Desroches "adc-res-names property in the DT\n"); 39747be16b6SLudovic Desroches return count; 39847be16b6SLudovic Desroches } 39947be16b6SLudovic Desroches 40047be16b6SLudovic Desroches resolutions = kmalloc(count * sizeof(*resolutions), GFP_KERNEL); 40147be16b6SLudovic Desroches if (!resolutions) 40247be16b6SLudovic Desroches return -ENOMEM; 40347be16b6SLudovic Desroches 40447be16b6SLudovic Desroches if (of_property_read_u32_array(np, "atmel,adc-res", resolutions, count)) { 40547be16b6SLudovic Desroches dev_err(&idev->dev, "Missing adc-res property in the DT.\n"); 40647be16b6SLudovic Desroches ret = -ENODEV; 40747be16b6SLudovic Desroches goto ret; 40847be16b6SLudovic Desroches } 40947be16b6SLudovic Desroches 41047be16b6SLudovic Desroches if (of_property_read_string(np, "atmel,adc-use-res", (const char **)&res_name)) 41147be16b6SLudovic Desroches res_name = "highres"; 41247be16b6SLudovic Desroches 41347be16b6SLudovic Desroches for (i = 0; i < count; i++) { 41447be16b6SLudovic Desroches if (of_property_read_string_index(np, "atmel,adc-res-names", i, (const char **)&s)) 41547be16b6SLudovic Desroches continue; 41647be16b6SLudovic Desroches 41747be16b6SLudovic Desroches if (strcmp(res_name, s)) 41847be16b6SLudovic Desroches continue; 41947be16b6SLudovic Desroches 42047be16b6SLudovic Desroches st->res = resolutions[i]; 42147be16b6SLudovic Desroches if (!strcmp(res_name, "lowres")) 42247be16b6SLudovic Desroches st->low_res = true; 42347be16b6SLudovic Desroches else 42447be16b6SLudovic Desroches st->low_res = false; 42547be16b6SLudovic Desroches 42647be16b6SLudovic Desroches dev_info(&idev->dev, "Resolution used: %u bits\n", st->res); 42747be16b6SLudovic Desroches goto ret; 42847be16b6SLudovic Desroches } 42947be16b6SLudovic Desroches 43047be16b6SLudovic Desroches dev_err(&idev->dev, "There is no resolution for %s\n", res_name); 43147be16b6SLudovic Desroches 43247be16b6SLudovic Desroches ret: 43347be16b6SLudovic Desroches kfree(resolutions); 43447be16b6SLudovic Desroches return ret; 43547be16b6SLudovic Desroches } 43647be16b6SLudovic Desroches 437e1811f97SJosh Wu static const struct of_device_id at91_adc_dt_ids[]; 438e1811f97SJosh Wu 439e364185fSMaxime Ripard static int at91_adc_probe_dt(struct at91_adc_state *st, 440e364185fSMaxime Ripard struct platform_device *pdev) 441e364185fSMaxime Ripard { 442e364185fSMaxime Ripard struct iio_dev *idev = iio_priv_to_dev(st); 443e364185fSMaxime Ripard struct device_node *node = pdev->dev.of_node; 444e364185fSMaxime Ripard struct device_node *trig_node; 445e364185fSMaxime Ripard int i = 0, ret; 446e364185fSMaxime Ripard u32 prop; 447e364185fSMaxime Ripard 448e364185fSMaxime Ripard if (!node) 449e364185fSMaxime Ripard return -EINVAL; 450e364185fSMaxime Ripard 451e1811f97SJosh Wu st->caps = (struct at91_adc_caps *) 452e1811f97SJosh Wu of_match_device(at91_adc_dt_ids, &pdev->dev)->data; 453e1811f97SJosh Wu 454e364185fSMaxime Ripard st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers"); 455e364185fSMaxime Ripard 456e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) { 457e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-channels-used property in the DT.\n"); 458e364185fSMaxime Ripard ret = -EINVAL; 459e364185fSMaxime Ripard goto error_ret; 460e364185fSMaxime Ripard } 461e364185fSMaxime Ripard st->channels_mask = prop; 462e364185fSMaxime Ripard 463e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-num-channels", &prop)) { 464e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-num-channels property in the DT.\n"); 465e364185fSMaxime Ripard ret = -EINVAL; 466e364185fSMaxime Ripard goto error_ret; 467e364185fSMaxime Ripard } 468e364185fSMaxime Ripard st->num_channels = prop; 469e364185fSMaxime Ripard 470e748783cSJean-Christophe PLAGNIOL-VILLARD st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode"); 471e748783cSJean-Christophe PLAGNIOL-VILLARD 472e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) { 473e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n"); 474e364185fSMaxime Ripard ret = -EINVAL; 475e364185fSMaxime Ripard goto error_ret; 476e364185fSMaxime Ripard } 477e364185fSMaxime Ripard st->startup_time = prop; 478e364185fSMaxime Ripard 479beca9e76SJean-Christophe PLAGNIOL-VILLARD prop = 0; 480beca9e76SJean-Christophe PLAGNIOL-VILLARD of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop); 481beca9e76SJean-Christophe PLAGNIOL-VILLARD st->sample_hold_time = prop; 482e364185fSMaxime Ripard 483e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-vref", &prop)) { 484e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-vref property in the DT.\n"); 485e364185fSMaxime Ripard ret = -EINVAL; 486e364185fSMaxime Ripard goto error_ret; 487e364185fSMaxime Ripard } 488e364185fSMaxime Ripard st->vref_mv = prop; 489e364185fSMaxime Ripard 49047be16b6SLudovic Desroches ret = at91_adc_of_get_resolution(st, pdev); 49147be16b6SLudovic Desroches if (ret) 49247be16b6SLudovic Desroches goto error_ret; 49347be16b6SLudovic Desroches 494e1811f97SJosh Wu st->registers = &st->caps->registers; 495e364185fSMaxime Ripard st->trigger_number = of_get_child_count(node); 4966b3aa313SAxel Lin st->trigger_list = devm_kzalloc(&idev->dev, st->trigger_number * 4976b3aa313SAxel Lin sizeof(struct at91_adc_trigger), 4986b3aa313SAxel Lin GFP_KERNEL); 499e364185fSMaxime Ripard if (!st->trigger_list) { 500e364185fSMaxime Ripard dev_err(&idev->dev, "Could not allocate trigger list memory.\n"); 501e364185fSMaxime Ripard ret = -ENOMEM; 502e364185fSMaxime Ripard goto error_ret; 503e364185fSMaxime Ripard } 504e364185fSMaxime Ripard 505e364185fSMaxime Ripard for_each_child_of_node(node, trig_node) { 506e364185fSMaxime Ripard struct at91_adc_trigger *trig = st->trigger_list + i; 507e364185fSMaxime Ripard const char *name; 508e364185fSMaxime Ripard 509e364185fSMaxime Ripard if (of_property_read_string(trig_node, "trigger-name", &name)) { 510e364185fSMaxime Ripard dev_err(&idev->dev, "Missing trigger-name property in the DT.\n"); 511e364185fSMaxime Ripard ret = -EINVAL; 512e364185fSMaxime Ripard goto error_ret; 513e364185fSMaxime Ripard } 514e364185fSMaxime Ripard trig->name = name; 515e364185fSMaxime Ripard 516e364185fSMaxime Ripard if (of_property_read_u32(trig_node, "trigger-value", &prop)) { 517e364185fSMaxime Ripard dev_err(&idev->dev, "Missing trigger-value property in the DT.\n"); 518e364185fSMaxime Ripard ret = -EINVAL; 519e364185fSMaxime Ripard goto error_ret; 520e364185fSMaxime Ripard } 521e364185fSMaxime Ripard trig->value = prop; 522e364185fSMaxime Ripard trig->is_external = of_property_read_bool(trig_node, "trigger-external"); 523e364185fSMaxime Ripard i++; 524e364185fSMaxime Ripard } 525e364185fSMaxime Ripard 526e364185fSMaxime Ripard return 0; 527e364185fSMaxime Ripard 528e364185fSMaxime Ripard error_ret: 529e364185fSMaxime Ripard return ret; 530e364185fSMaxime Ripard } 531e364185fSMaxime Ripard 5320e589d5fSMaxime Ripard static int at91_adc_probe_pdata(struct at91_adc_state *st, 5330e589d5fSMaxime Ripard struct platform_device *pdev) 5340e589d5fSMaxime Ripard { 5350e589d5fSMaxime Ripard struct at91_adc_data *pdata = pdev->dev.platform_data; 5360e589d5fSMaxime Ripard 5370e589d5fSMaxime Ripard if (!pdata) 5380e589d5fSMaxime Ripard return -EINVAL; 5390e589d5fSMaxime Ripard 5400e589d5fSMaxime Ripard st->use_external = pdata->use_external_triggers; 5410e589d5fSMaxime Ripard st->vref_mv = pdata->vref; 5420e589d5fSMaxime Ripard st->channels_mask = pdata->channels_used; 5430e589d5fSMaxime Ripard st->num_channels = pdata->num_channels; 5440e589d5fSMaxime Ripard st->startup_time = pdata->startup_time; 5450e589d5fSMaxime Ripard st->trigger_number = pdata->trigger_number; 5460e589d5fSMaxime Ripard st->trigger_list = pdata->trigger_list; 5470e589d5fSMaxime Ripard st->registers = pdata->registers; 5480e589d5fSMaxime Ripard 5490e589d5fSMaxime Ripard return 0; 5500e589d5fSMaxime Ripard } 5510e589d5fSMaxime Ripard 5520e589d5fSMaxime Ripard static const struct iio_info at91_adc_info = { 5530e589d5fSMaxime Ripard .driver_module = THIS_MODULE, 5540e589d5fSMaxime Ripard .read_raw = &at91_adc_read_raw, 5550e589d5fSMaxime Ripard }; 5560e589d5fSMaxime Ripard 557fc52692cSGreg Kroah-Hartman static int at91_adc_probe(struct platform_device *pdev) 5580e589d5fSMaxime Ripard { 559beca9e76SJean-Christophe PLAGNIOL-VILLARD unsigned int prsc, mstrclk, ticks, adc_clk, shtim; 5600e589d5fSMaxime Ripard int ret; 5610e589d5fSMaxime Ripard struct iio_dev *idev; 5620e589d5fSMaxime Ripard struct at91_adc_state *st; 5630e589d5fSMaxime Ripard struct resource *res; 564e748783cSJean-Christophe PLAGNIOL-VILLARD u32 reg; 5650e589d5fSMaxime Ripard 566f8837532SSachin Kamat idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state)); 567f8837532SSachin Kamat if (!idev) 568f8837532SSachin Kamat return -ENOMEM; 5690e589d5fSMaxime Ripard 5700e589d5fSMaxime Ripard st = iio_priv(idev); 5710e589d5fSMaxime Ripard 572e364185fSMaxime Ripard if (pdev->dev.of_node) 573e364185fSMaxime Ripard ret = at91_adc_probe_dt(st, pdev); 574e364185fSMaxime Ripard else 5750e589d5fSMaxime Ripard ret = at91_adc_probe_pdata(st, pdev); 576e364185fSMaxime Ripard 5770e589d5fSMaxime Ripard if (ret) { 5780e589d5fSMaxime Ripard dev_err(&pdev->dev, "No platform data available.\n"); 579f8837532SSachin Kamat return -EINVAL; 5800e589d5fSMaxime Ripard } 5810e589d5fSMaxime Ripard 5820e589d5fSMaxime Ripard platform_set_drvdata(pdev, idev); 5830e589d5fSMaxime Ripard 5840e589d5fSMaxime Ripard idev->dev.parent = &pdev->dev; 5850e589d5fSMaxime Ripard idev->name = dev_name(&pdev->dev); 5860e589d5fSMaxime Ripard idev->modes = INDIO_DIRECT_MODE; 5870e589d5fSMaxime Ripard idev->info = &at91_adc_info; 5880e589d5fSMaxime Ripard 5890e589d5fSMaxime Ripard st->irq = platform_get_irq(pdev, 0); 5900e589d5fSMaxime Ripard if (st->irq < 0) { 5910e589d5fSMaxime Ripard dev_err(&pdev->dev, "No IRQ ID is designated\n"); 592f8837532SSachin Kamat return -ENODEV; 5930e589d5fSMaxime Ripard } 5940e589d5fSMaxime Ripard 595390d75c1SJulia Lawall res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 5960e589d5fSMaxime Ripard 5975fd98466SThierry Reding st->reg_base = devm_ioremap_resource(&pdev->dev, res); 5985fd98466SThierry Reding if (IS_ERR(st->reg_base)) { 599f8837532SSachin Kamat return PTR_ERR(st->reg_base); 6000e589d5fSMaxime Ripard } 6010e589d5fSMaxime Ripard 6020e589d5fSMaxime Ripard /* 6030e589d5fSMaxime Ripard * Disable all IRQs before setting up the handler 6040e589d5fSMaxime Ripard */ 6050e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); 6060e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); 6070e589d5fSMaxime Ripard ret = request_irq(st->irq, 6080e589d5fSMaxime Ripard at91_adc_eoc_trigger, 6090e589d5fSMaxime Ripard 0, 6100e589d5fSMaxime Ripard pdev->dev.driver->name, 6110e589d5fSMaxime Ripard idev); 6120e589d5fSMaxime Ripard if (ret) { 6130e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); 614f8837532SSachin Kamat return ret; 6150e589d5fSMaxime Ripard } 6160e589d5fSMaxime Ripard 617390d75c1SJulia Lawall st->clk = devm_clk_get(&pdev->dev, "adc_clk"); 6180e589d5fSMaxime Ripard if (IS_ERR(st->clk)) { 6190e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to get the clock.\n"); 6200e589d5fSMaxime Ripard ret = PTR_ERR(st->clk); 6210e589d5fSMaxime Ripard goto error_free_irq; 6220e589d5fSMaxime Ripard } 6230e589d5fSMaxime Ripard 62400062a9cSJulia Lawall ret = clk_prepare_enable(st->clk); 6250e589d5fSMaxime Ripard if (ret) { 62600062a9cSJulia Lawall dev_err(&pdev->dev, 62700062a9cSJulia Lawall "Could not prepare or enable the clock.\n"); 628390d75c1SJulia Lawall goto error_free_irq; 6290e589d5fSMaxime Ripard } 6300e589d5fSMaxime Ripard 631390d75c1SJulia Lawall st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk"); 6320e589d5fSMaxime Ripard if (IS_ERR(st->adc_clk)) { 6330e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); 634f755bbbfSJulia Lawall ret = PTR_ERR(st->adc_clk); 6350e589d5fSMaxime Ripard goto error_disable_clk; 6360e589d5fSMaxime Ripard } 6370e589d5fSMaxime Ripard 63800062a9cSJulia Lawall ret = clk_prepare_enable(st->adc_clk); 6390e589d5fSMaxime Ripard if (ret) { 64000062a9cSJulia Lawall dev_err(&pdev->dev, 64100062a9cSJulia Lawall "Could not prepare or enable the ADC clock.\n"); 642390d75c1SJulia Lawall goto error_disable_clk; 6430e589d5fSMaxime Ripard } 6440e589d5fSMaxime Ripard 6450e589d5fSMaxime Ripard /* 6460e589d5fSMaxime Ripard * Prescaler rate computation using the formula from the Atmel's 6470e589d5fSMaxime Ripard * datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being 6480e589d5fSMaxime Ripard * specified by the electrical characteristics of the board. 6490e589d5fSMaxime Ripard */ 6500e589d5fSMaxime Ripard mstrclk = clk_get_rate(st->clk); 6510e589d5fSMaxime Ripard adc_clk = clk_get_rate(st->adc_clk); 6520e589d5fSMaxime Ripard prsc = (mstrclk / (2 * adc_clk)) - 1; 6530e589d5fSMaxime Ripard 6540e589d5fSMaxime Ripard if (!st->startup_time) { 6550e589d5fSMaxime Ripard dev_err(&pdev->dev, "No startup time available.\n"); 6560e589d5fSMaxime Ripard ret = -EINVAL; 6570e589d5fSMaxime Ripard goto error_disable_adc_clk; 6580e589d5fSMaxime Ripard } 6590e589d5fSMaxime Ripard 6600e589d5fSMaxime Ripard /* 6610e589d5fSMaxime Ripard * Number of ticks needed to cover the startup time of the ADC as 6620e589d5fSMaxime Ripard * defined in the electrical characteristics of the board, divided by 8. 6630e589d5fSMaxime Ripard * The formula thus is : Startup Time = (ticks + 1) * 8 / ADC Clock 6640e589d5fSMaxime Ripard */ 6650e589d5fSMaxime Ripard ticks = round_up((st->startup_time * adc_clk / 6660e589d5fSMaxime Ripard 1000000) - 1, 8) / 8; 667beca9e76SJean-Christophe PLAGNIOL-VILLARD /* 668beca9e76SJean-Christophe PLAGNIOL-VILLARD * a minimal Sample and Hold Time is necessary for the ADC to guarantee 669beca9e76SJean-Christophe PLAGNIOL-VILLARD * the best converted final value between two channels selection 670beca9e76SJean-Christophe PLAGNIOL-VILLARD * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock 671beca9e76SJean-Christophe PLAGNIOL-VILLARD */ 672beca9e76SJean-Christophe PLAGNIOL-VILLARD shtim = round_up((st->sample_hold_time * adc_clk / 673beca9e76SJean-Christophe PLAGNIOL-VILLARD 1000000) - 1, 1); 674beca9e76SJean-Christophe PLAGNIOL-VILLARD 675e748783cSJean-Christophe PLAGNIOL-VILLARD reg = AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL; 676e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP; 67747be16b6SLudovic Desroches if (st->low_res) 678e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_LOWRES; 679e748783cSJean-Christophe PLAGNIOL-VILLARD if (st->sleep_mode) 680e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_SLEEP; 681beca9e76SJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_SHTIM_(shtim) & AT91_ADC_SHTIM; 682e748783cSJean-Christophe PLAGNIOL-VILLARD at91_adc_writel(st, AT91_ADC_MR, reg); 6830e589d5fSMaxime Ripard 6840e589d5fSMaxime Ripard /* Setup the ADC channels available on the board */ 6850e589d5fSMaxime Ripard ret = at91_adc_channel_init(idev); 6860e589d5fSMaxime Ripard if (ret < 0) { 6870e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't initialize the channels.\n"); 6880e589d5fSMaxime Ripard goto error_disable_adc_clk; 6890e589d5fSMaxime Ripard } 6900e589d5fSMaxime Ripard 6910e589d5fSMaxime Ripard init_waitqueue_head(&st->wq_data_avail); 6920e589d5fSMaxime Ripard mutex_init(&st->lock); 6930e589d5fSMaxime Ripard 6940e589d5fSMaxime Ripard ret = at91_adc_buffer_init(idev); 6950e589d5fSMaxime Ripard if (ret < 0) { 6960e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't initialize the buffer.\n"); 6970e589d5fSMaxime Ripard goto error_disable_adc_clk; 6980e589d5fSMaxime Ripard } 6990e589d5fSMaxime Ripard 7000e589d5fSMaxime Ripard ret = at91_adc_trigger_init(idev); 7010e589d5fSMaxime Ripard if (ret < 0) { 7020e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't setup the triggers.\n"); 7030e589d5fSMaxime Ripard goto error_unregister_buffer; 7040e589d5fSMaxime Ripard } 7050e589d5fSMaxime Ripard 7060e589d5fSMaxime Ripard ret = iio_device_register(idev); 7070e589d5fSMaxime Ripard if (ret < 0) { 7080e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't register the device.\n"); 7090e589d5fSMaxime Ripard goto error_remove_triggers; 7100e589d5fSMaxime Ripard } 7110e589d5fSMaxime Ripard 7120e589d5fSMaxime Ripard return 0; 7130e589d5fSMaxime Ripard 7140e589d5fSMaxime Ripard error_remove_triggers: 7150e589d5fSMaxime Ripard at91_adc_trigger_remove(idev); 7160e589d5fSMaxime Ripard error_unregister_buffer: 7170e589d5fSMaxime Ripard at91_adc_buffer_remove(idev); 7180e589d5fSMaxime Ripard error_disable_adc_clk: 71900062a9cSJulia Lawall clk_disable_unprepare(st->adc_clk); 7200e589d5fSMaxime Ripard error_disable_clk: 72100062a9cSJulia Lawall clk_disable_unprepare(st->clk); 7220e589d5fSMaxime Ripard error_free_irq: 7230e589d5fSMaxime Ripard free_irq(st->irq, idev); 7240e589d5fSMaxime Ripard return ret; 7250e589d5fSMaxime Ripard } 7260e589d5fSMaxime Ripard 727fc52692cSGreg Kroah-Hartman static int at91_adc_remove(struct platform_device *pdev) 7280e589d5fSMaxime Ripard { 7290e589d5fSMaxime Ripard struct iio_dev *idev = platform_get_drvdata(pdev); 7300e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 7310e589d5fSMaxime Ripard 7320e589d5fSMaxime Ripard iio_device_unregister(idev); 7330e589d5fSMaxime Ripard at91_adc_trigger_remove(idev); 7340e589d5fSMaxime Ripard at91_adc_buffer_remove(idev); 7350e589d5fSMaxime Ripard clk_disable_unprepare(st->adc_clk); 73600062a9cSJulia Lawall clk_disable_unprepare(st->clk); 7370e589d5fSMaxime Ripard free_irq(st->irq, idev); 7380e589d5fSMaxime Ripard 7390e589d5fSMaxime Ripard return 0; 7400e589d5fSMaxime Ripard } 7410e589d5fSMaxime Ripard 74200738ff6SSachin Kamat #ifdef CONFIG_OF 743e1811f97SJosh Wu static struct at91_adc_caps at91sam9260_caps = { 744e1811f97SJosh Wu .registers = { 745e1811f97SJosh Wu .channel_base = AT91_ADC_CHR(0), 746e1811f97SJosh Wu .drdy_mask = AT91_ADC_DRDY, 747e1811f97SJosh Wu .status_register = AT91_ADC_SR, 748e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9260, 749e1811f97SJosh Wu }, 750e1811f97SJosh Wu }; 751e1811f97SJosh Wu 752e1811f97SJosh Wu static struct at91_adc_caps at91sam9g45_caps = { 753e1811f97SJosh Wu .registers = { 754e1811f97SJosh Wu .channel_base = AT91_ADC_CHR(0), 755e1811f97SJosh Wu .drdy_mask = AT91_ADC_DRDY, 756e1811f97SJosh Wu .status_register = AT91_ADC_SR, 757e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9G45, 758e1811f97SJosh Wu }, 759e1811f97SJosh Wu }; 760e1811f97SJosh Wu 761e1811f97SJosh Wu static struct at91_adc_caps at91sam9x5_caps = { 762e1811f97SJosh Wu .registers = { 763e1811f97SJosh Wu .channel_base = AT91_ADC_CDR0_9X5, 764e1811f97SJosh Wu .drdy_mask = AT91_ADC_SR_DRDY_9X5, 765e1811f97SJosh Wu .status_register = AT91_ADC_SR_9X5, 766e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9X5, 767e1811f97SJosh Wu }, 768e1811f97SJosh Wu }; 769e1811f97SJosh Wu 770e364185fSMaxime Ripard static const struct of_device_id at91_adc_dt_ids[] = { 771e1811f97SJosh Wu { .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps }, 772e1811f97SJosh Wu { .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps }, 773e1811f97SJosh Wu { .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps }, 774e364185fSMaxime Ripard {}, 775e364185fSMaxime Ripard }; 776e364185fSMaxime Ripard MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); 77700738ff6SSachin Kamat #endif 778e364185fSMaxime Ripard 7790e589d5fSMaxime Ripard static struct platform_driver at91_adc_driver = { 7800e589d5fSMaxime Ripard .probe = at91_adc_probe, 781fc52692cSGreg Kroah-Hartman .remove = at91_adc_remove, 7820e589d5fSMaxime Ripard .driver = { 7830e589d5fSMaxime Ripard .name = "at91_adc", 784e364185fSMaxime Ripard .of_match_table = of_match_ptr(at91_adc_dt_ids), 7850e589d5fSMaxime Ripard }, 7860e589d5fSMaxime Ripard }; 7870e589d5fSMaxime Ripard 7880e589d5fSMaxime Ripard module_platform_driver(at91_adc_driver); 7890e589d5fSMaxime Ripard 7900e589d5fSMaxime Ripard MODULE_LICENSE("GPL"); 7910e589d5fSMaxime Ripard MODULE_DESCRIPTION("Atmel AT91 ADC Driver"); 7920e589d5fSMaxime Ripard MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 793