1c51cb3f5SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 20e589d5fSMaxime Ripard /* 30e589d5fSMaxime Ripard * Driver for the ADC present in the Atmel AT91 evaluation boards. 40e589d5fSMaxime Ripard * 50e589d5fSMaxime Ripard * Copyright 2011 Free Electrons 60e589d5fSMaxime Ripard */ 70e589d5fSMaxime Ripard 80e589d5fSMaxime Ripard #include <linux/bitmap.h> 90e589d5fSMaxime Ripard #include <linux/bitops.h> 100e589d5fSMaxime Ripard #include <linux/clk.h> 110e589d5fSMaxime Ripard #include <linux/err.h> 120e589d5fSMaxime Ripard #include <linux/io.h> 13c8b11de0SJosh Wu #include <linux/input.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/iio/iio.h> 260e589d5fSMaxime Ripard #include <linux/iio/buffer.h> 270e589d5fSMaxime Ripard #include <linux/iio/trigger.h> 280e589d5fSMaxime Ripard #include <linux/iio/trigger_consumer.h> 2990032e4eSLars-Peter Clausen #include <linux/iio/triggered_buffer.h> 30bc3ae982SWenyou Yang #include <linux/pinctrl/consumer.h> 310e589d5fSMaxime Ripard 32bee20c4bSAlexandre Belloni /* Registers */ 33bee20c4bSAlexandre Belloni #define AT91_ADC_CR 0x00 /* Control Register */ 34bee20c4bSAlexandre Belloni #define AT91_ADC_SWRST (1 << 0) /* Software Reset */ 35bee20c4bSAlexandre Belloni #define AT91_ADC_START (1 << 1) /* Start Conversion */ 36bee20c4bSAlexandre Belloni 37bee20c4bSAlexandre Belloni #define AT91_ADC_MR 0x04 /* Mode Register */ 38bee20c4bSAlexandre Belloni #define AT91_ADC_TSAMOD (3 << 0) /* ADC mode */ 39bee20c4bSAlexandre Belloni #define AT91_ADC_TSAMOD_ADC_ONLY_MODE (0 << 0) /* ADC Mode */ 40bee20c4bSAlexandre Belloni #define AT91_ADC_TSAMOD_TS_ONLY_MODE (1 << 0) /* Touch Screen Only Mode */ 41bee20c4bSAlexandre Belloni #define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */ 42bee20c4bSAlexandre Belloni #define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */ 43bee20c4bSAlexandre Belloni #define AT91_ADC_TRGSEL_TC0 (0 << 1) 44bee20c4bSAlexandre Belloni #define AT91_ADC_TRGSEL_TC1 (1 << 1) 45bee20c4bSAlexandre Belloni #define AT91_ADC_TRGSEL_TC2 (2 << 1) 46bee20c4bSAlexandre Belloni #define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) 47bee20c4bSAlexandre Belloni #define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ 48bee20c4bSAlexandre Belloni #define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ 49bee20c4bSAlexandre Belloni #define AT91_ADC_PENDET (1 << 6) /* Pen contact detection enable */ 50bee20c4bSAlexandre Belloni #define AT91_ADC_PRESCAL_9260 (0x3f << 8) /* Prescalar Rate Selection */ 51bee20c4bSAlexandre Belloni #define AT91_ADC_PRESCAL_9G45 (0xff << 8) 52bee20c4bSAlexandre Belloni #define AT91_ADC_PRESCAL_(x) ((x) << 8) 53bee20c4bSAlexandre Belloni #define AT91_ADC_STARTUP_9260 (0x1f << 16) /* Startup Up Time */ 54bee20c4bSAlexandre Belloni #define AT91_ADC_STARTUP_9G45 (0x7f << 16) 55bee20c4bSAlexandre Belloni #define AT91_ADC_STARTUP_9X5 (0xf << 16) 56bee20c4bSAlexandre Belloni #define AT91_ADC_STARTUP_(x) ((x) << 16) 57bee20c4bSAlexandre Belloni #define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ 58bee20c4bSAlexandre Belloni #define AT91_ADC_SHTIM_(x) ((x) << 24) 59bee20c4bSAlexandre Belloni #define AT91_ADC_PENDBC (0x0f << 28) /* Pen Debounce time */ 60bee20c4bSAlexandre Belloni #define AT91_ADC_PENDBC_(x) ((x) << 28) 61bee20c4bSAlexandre Belloni 62bee20c4bSAlexandre Belloni #define AT91_ADC_TSR 0x0C 63bee20c4bSAlexandre Belloni #define AT91_ADC_TSR_SHTIM (0xf << 24) /* Sample & Hold Time */ 64bee20c4bSAlexandre Belloni #define AT91_ADC_TSR_SHTIM_(x) ((x) << 24) 65bee20c4bSAlexandre Belloni 66bee20c4bSAlexandre Belloni #define AT91_ADC_CHER 0x10 /* Channel Enable Register */ 67bee20c4bSAlexandre Belloni #define AT91_ADC_CHDR 0x14 /* Channel Disable Register */ 68bee20c4bSAlexandre Belloni #define AT91_ADC_CHSR 0x18 /* Channel Status Register */ 69bee20c4bSAlexandre Belloni #define AT91_ADC_CH(n) (1 << (n)) /* Channel Number */ 70bee20c4bSAlexandre Belloni 71bee20c4bSAlexandre Belloni #define AT91_ADC_SR 0x1C /* Status Register */ 72bee20c4bSAlexandre Belloni #define AT91_ADC_EOC(n) (1 << (n)) /* End of Conversion on Channel N */ 73bee20c4bSAlexandre Belloni #define AT91_ADC_OVRE(n) (1 << ((n) + 8))/* Overrun Error on Channel N */ 74bee20c4bSAlexandre Belloni #define AT91_ADC_DRDY (1 << 16) /* Data Ready */ 75bee20c4bSAlexandre Belloni #define AT91_ADC_GOVRE (1 << 17) /* General Overrun Error */ 76bee20c4bSAlexandre Belloni #define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */ 77bee20c4bSAlexandre Belloni #define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */ 78bee20c4bSAlexandre Belloni 79bee20c4bSAlexandre Belloni #define AT91_ADC_SR_9X5 0x30 /* Status Register for 9x5 */ 80bee20c4bSAlexandre Belloni #define AT91_ADC_SR_DRDY_9X5 (1 << 24) /* Data Ready */ 81bee20c4bSAlexandre Belloni 82bee20c4bSAlexandre Belloni #define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */ 83bee20c4bSAlexandre Belloni #define AT91_ADC_LDATA (0x3ff) 84bee20c4bSAlexandre Belloni 85bee20c4bSAlexandre Belloni #define AT91_ADC_IER 0x24 /* Interrupt Enable Register */ 86bee20c4bSAlexandre Belloni #define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */ 87bee20c4bSAlexandre Belloni #define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */ 88bee20c4bSAlexandre Belloni #define AT91RL_ADC_IER_PEN (1 << 20) 89bee20c4bSAlexandre Belloni #define AT91RL_ADC_IER_NOPEN (1 << 21) 90bee20c4bSAlexandre Belloni #define AT91_ADC_IER_PEN (1 << 29) 91bee20c4bSAlexandre Belloni #define AT91_ADC_IER_NOPEN (1 << 30) 92bee20c4bSAlexandre Belloni #define AT91_ADC_IER_XRDY (1 << 20) 93bee20c4bSAlexandre Belloni #define AT91_ADC_IER_YRDY (1 << 21) 94bee20c4bSAlexandre Belloni #define AT91_ADC_IER_PRDY (1 << 22) 95bee20c4bSAlexandre Belloni #define AT91_ADC_ISR_PENS (1 << 31) 96bee20c4bSAlexandre Belloni 97bee20c4bSAlexandre Belloni #define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ 98bee20c4bSAlexandre Belloni #define AT91_ADC_DATA (0x3ff) 99bee20c4bSAlexandre Belloni 100bee20c4bSAlexandre Belloni #define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */ 101bee20c4bSAlexandre Belloni 102bee20c4bSAlexandre Belloni #define AT91_ADC_ACR 0x94 /* Analog Control Register */ 103bee20c4bSAlexandre Belloni #define AT91_ADC_ACR_PENDETSENS (0x3 << 0) /* pull-up resistor */ 104bee20c4bSAlexandre Belloni 105bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR 0xB0 106bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSMODE (3 << 0) /* Touch Screen Mode */ 107bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSMODE_NONE (0 << 0) 108bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0) 109bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0) 110bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0) 111bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */ 112bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_TSAV_(x) ((x) << 4) 113bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */ 114ede63aafSNicolas Ferre #define AT91_ADC_TSMR_SCTIM_(x) ((x) << 16) 115bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */ 116bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28) 117bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */ 118bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_PENDET_DIS (0 << 24) /* Pen contact detection disable */ 119bee20c4bSAlexandre Belloni #define AT91_ADC_TSMR_PENDET_ENA (1 << 24) /* Pen contact detection enable */ 120bee20c4bSAlexandre Belloni 121bee20c4bSAlexandre Belloni #define AT91_ADC_TSXPOSR 0xB4 122bee20c4bSAlexandre Belloni #define AT91_ADC_TSYPOSR 0xB8 123bee20c4bSAlexandre Belloni #define AT91_ADC_TSPRESSR 0xBC 124bee20c4bSAlexandre Belloni 125bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_9260 AT91_ADC_MR 126bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_9G45 0x08 127bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_9X5 0xC0 128bee20c4bSAlexandre Belloni 129bee20c4bSAlexandre Belloni /* Trigger Register bit field */ 130bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_TRGPER (0xffff << 16) 131bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16) 132bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_TRGMOD (0x7 << 0) 133bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_NONE (0 << 0) 134bee20c4bSAlexandre Belloni #define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0) 1350e589d5fSMaxime Ripard 1360e589d5fSMaxime Ripard #define AT91_ADC_CHAN(st, ch) \ 1370e589d5fSMaxime Ripard (st->registers->channel_base + (ch * 4)) 1380e589d5fSMaxime Ripard #define at91_adc_readl(st, reg) \ 1390e589d5fSMaxime Ripard (readl_relaxed(st->reg_base + reg)) 1400e589d5fSMaxime Ripard #define at91_adc_writel(st, reg, val) \ 1410e589d5fSMaxime Ripard (writel_relaxed(val, st->reg_base + reg)) 1420e589d5fSMaxime Ripard 143c8b11de0SJosh Wu #define DRIVER_NAME "at91_adc" 144c8b11de0SJosh Wu #define MAX_POS_BITS 12 145c8b11de0SJosh Wu 146c8b11de0SJosh Wu #define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */ 147c8b11de0SJosh Wu #define TOUCH_PEN_DETECT_DEBOUNCE_US 200 148c8b11de0SJosh Wu 14984882b06SAlexandre Belloni #define MAX_RLPOS_BITS 10 15084882b06SAlexandre Belloni #define TOUCH_SAMPLE_PERIOD_US_RL 10000 /* 10ms, the SoC can't keep up with 2ms */ 15184882b06SAlexandre Belloni #define TOUCH_SHTIM 0xa 152ede63aafSNicolas Ferre #define TOUCH_SCTIM_US 10 /* 10us for the Touchscreen Switches Closure Time */ 15384882b06SAlexandre Belloni 154ead1c9f3SAlexandru Ardelean enum atmel_adc_ts_type { 155ead1c9f3SAlexandru Ardelean ATMEL_ADC_TOUCHSCREEN_NONE = 0, 156ead1c9f3SAlexandru Ardelean ATMEL_ADC_TOUCHSCREEN_4WIRE = 4, 157ead1c9f3SAlexandru Ardelean ATMEL_ADC_TOUCHSCREEN_5WIRE = 5, 158ead1c9f3SAlexandru Ardelean }; 159ead1c9f3SAlexandru Ardelean 160ead1c9f3SAlexandru Ardelean /** 161ead1c9f3SAlexandru Ardelean * struct at91_adc_trigger - description of triggers 162ead1c9f3SAlexandru Ardelean * @name: name of the trigger advertised to the user 163ead1c9f3SAlexandru Ardelean * @value: value to set in the ADC's trigger setup register 164ead1c9f3SAlexandru Ardelean * to enable the trigger 165ead1c9f3SAlexandru Ardelean * @is_external: Does the trigger rely on an external pin? 166ead1c9f3SAlexandru Ardelean */ 167ead1c9f3SAlexandru Ardelean struct at91_adc_trigger { 168ead1c9f3SAlexandru Ardelean const char *name; 169ead1c9f3SAlexandru Ardelean u8 value; 170ead1c9f3SAlexandru Ardelean bool is_external; 171ead1c9f3SAlexandru Ardelean }; 172ead1c9f3SAlexandru Ardelean 1732de0c019SAlexandre Belloni /** 1742de0c019SAlexandre Belloni * struct at91_adc_reg_desc - Various informations relative to registers 1752de0c019SAlexandre Belloni * @channel_base: Base offset for the channel data registers 1762de0c019SAlexandre Belloni * @drdy_mask: Mask of the DRDY field in the relevant registers 1774ab559a6SLee Jones * (Interruptions registers mostly) 1782de0c019SAlexandre Belloni * @status_register: Offset of the Interrupt Status Register 1792de0c019SAlexandre Belloni * @trigger_register: Offset of the Trigger setup register 1802de0c019SAlexandre Belloni * @mr_prescal_mask: Mask of the PRESCAL field in the adc MR register 1812de0c019SAlexandre Belloni * @mr_startup_mask: Mask of the STARTUP field in the adc MR register 1822de0c019SAlexandre Belloni */ 1832de0c019SAlexandre Belloni struct at91_adc_reg_desc { 1842de0c019SAlexandre Belloni u8 channel_base; 1852de0c019SAlexandre Belloni u32 drdy_mask; 1862de0c019SAlexandre Belloni u8 status_register; 1872de0c019SAlexandre Belloni u8 trigger_register; 1882de0c019SAlexandre Belloni u32 mr_prescal_mask; 1892de0c019SAlexandre Belloni u32 mr_startup_mask; 1902de0c019SAlexandre Belloni }; 1912de0c019SAlexandre Belloni 192e1811f97SJosh Wu struct at91_adc_caps { 193c8b11de0SJosh Wu bool has_ts; /* Support touch screen */ 194c8b11de0SJosh Wu bool has_tsmr; /* only at91sam9x5, sama5d3 have TSMR reg */ 195c8b11de0SJosh Wu /* 196c8b11de0SJosh Wu * Numbers of sampling data will be averaged. Can be 0~3. 197c8b11de0SJosh Wu * Hardware can average (2 ^ ts_filter_average) sample data. 198c8b11de0SJosh Wu */ 199c8b11de0SJosh Wu u8 ts_filter_average; 200c8b11de0SJosh Wu /* Pen Detection input pull-up resistor, can be 0~3 */ 201c8b11de0SJosh Wu u8 ts_pen_detect_sensitivity; 202c8b11de0SJosh Wu 203c4601666SJosh Wu /* startup time calculate function */ 2042ab5f39bSJan Leupold u32 (*calc_startup_ticks)(u32 startup_time, u32 adc_clk_khz); 205c4601666SJosh Wu 2062b6d598bSJosh Wu u8 num_channels; 2075eb39ef8SAlexandre Belloni 2085eb39ef8SAlexandre Belloni u8 low_res_bits; 2095eb39ef8SAlexandre Belloni u8 high_res_bits; 21009d4726bSAlexandre Belloni u32 trigger_number; 21109d4726bSAlexandre Belloni const struct at91_adc_trigger *triggers; 212e1811f97SJosh Wu struct at91_adc_reg_desc registers; 213e1811f97SJosh Wu }; 214e1811f97SJosh Wu 2150e589d5fSMaxime Ripard struct at91_adc_state { 2160e589d5fSMaxime Ripard struct clk *adc_clk; 2170e589d5fSMaxime Ripard u16 *buffer; 2180e589d5fSMaxime Ripard unsigned long channels_mask; 2190e589d5fSMaxime Ripard struct clk *clk; 2200e589d5fSMaxime Ripard bool done; 2210e589d5fSMaxime Ripard int irq; 2220e589d5fSMaxime Ripard u16 last_value; 223d4f51956SLudovic Desroches int chnb; 2240e589d5fSMaxime Ripard struct mutex lock; 2250e589d5fSMaxime Ripard u8 num_channels; 2260e589d5fSMaxime Ripard void __iomem *reg_base; 2273e4ef8e8SAlexandru Ardelean const struct at91_adc_reg_desc *registers; 2282ab5f39bSJan Leupold u32 startup_time; 229beca9e76SJean-Christophe PLAGNIOL-VILLARD u8 sample_hold_time; 230e748783cSJean-Christophe PLAGNIOL-VILLARD bool sleep_mode; 2310e589d5fSMaxime Ripard struct iio_trigger **trig; 2320e589d5fSMaxime Ripard bool use_external; 2330e589d5fSMaxime Ripard u32 vref_mv; 23447be16b6SLudovic Desroches u32 res; /* resolution used for convertions */ 2350e589d5fSMaxime Ripard wait_queue_head_t wq_data_avail; 2363e4ef8e8SAlexandru Ardelean const struct at91_adc_caps *caps; 237c8b11de0SJosh Wu 238c8b11de0SJosh Wu /* 239c8b11de0SJosh Wu * Following ADC channels are shared by touchscreen: 240c8b11de0SJosh Wu * 241c8b11de0SJosh Wu * CH0 -- Touch screen XP/UL 242c8b11de0SJosh Wu * CH1 -- Touch screen XM/UR 243c8b11de0SJosh Wu * CH2 -- Touch screen YP/LL 244c8b11de0SJosh Wu * CH3 -- Touch screen YM/Sense 245c8b11de0SJosh Wu * CH4 -- Touch screen LR(5-wire only) 246c8b11de0SJosh Wu * 247c8b11de0SJosh Wu * The bitfields below represents the reserved channel in the 248c8b11de0SJosh Wu * touchscreen mode. 249c8b11de0SJosh Wu */ 250c8b11de0SJosh Wu #define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 0) 251c8b11de0SJosh Wu #define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 0) 252c8b11de0SJosh Wu enum atmel_adc_ts_type touchscreen_type; 253c8b11de0SJosh Wu struct input_dev *ts_input; 254c8b11de0SJosh Wu 255c8b11de0SJosh Wu u16 ts_sample_period_val; 256c8b11de0SJosh Wu u32 ts_pressure_threshold; 25784882b06SAlexandre Belloni u16 ts_pendbc; 25884882b06SAlexandre Belloni 25984882b06SAlexandre Belloni bool ts_bufferedmeasure; 26084882b06SAlexandre Belloni u32 ts_prev_absx; 26184882b06SAlexandre Belloni u32 ts_prev_absy; 2620e589d5fSMaxime Ripard }; 2630e589d5fSMaxime Ripard 2640e589d5fSMaxime Ripard static irqreturn_t at91_adc_trigger_handler(int irq, void *p) 2650e589d5fSMaxime Ripard { 2660e589d5fSMaxime Ripard struct iio_poll_func *pf = p; 2670e589d5fSMaxime Ripard struct iio_dev *idev = pf->indio_dev; 2680e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 269aea835f2SEugen Hristev struct iio_chan_spec const *chan; 2700e589d5fSMaxime Ripard int i, j = 0; 2710e589d5fSMaxime Ripard 2720e589d5fSMaxime Ripard for (i = 0; i < idev->masklength; i++) { 2730e589d5fSMaxime Ripard if (!test_bit(i, idev->active_scan_mask)) 2740e589d5fSMaxime Ripard continue; 275aea835f2SEugen Hristev chan = idev->channels + i; 276aea835f2SEugen Hristev st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, chan->channel)); 2770e589d5fSMaxime Ripard j++; 2780e589d5fSMaxime Ripard } 2790e589d5fSMaxime Ripard 280e79cece0SLars-Peter Clausen iio_push_to_buffers_with_timestamp(idev, st->buffer, pf->timestamp); 2810e589d5fSMaxime Ripard 2820e589d5fSMaxime Ripard iio_trigger_notify_done(idev->trig); 2830e589d5fSMaxime Ripard 2840e589d5fSMaxime Ripard /* Needed to ACK the DRDY interruption */ 2850e589d5fSMaxime Ripard at91_adc_readl(st, AT91_ADC_LCDR); 2860e589d5fSMaxime Ripard 2870e589d5fSMaxime Ripard enable_irq(st->irq); 2880e589d5fSMaxime Ripard 2890e589d5fSMaxime Ripard return IRQ_HANDLED; 2900e589d5fSMaxime Ripard } 2910e589d5fSMaxime Ripard 292c8b11de0SJosh Wu /* Handler for classic adc channel eoc trigger */ 2933068ab20SJosh Wu static void handle_adc_eoc_trigger(int irq, struct iio_dev *idev) 2940e589d5fSMaxime Ripard { 2950e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 2960e589d5fSMaxime Ripard 2970e589d5fSMaxime Ripard if (iio_buffer_enabled(idev)) { 2980e589d5fSMaxime Ripard disable_irq_nosync(irq); 299398fd22bSPeter Meerwald iio_trigger_poll(idev->trig); 3000e589d5fSMaxime Ripard } else { 301d4f51956SLudovic Desroches st->last_value = at91_adc_readl(st, AT91_ADC_CHAN(st, st->chnb)); 302bc1b4532SEugen Hristev /* Needed to ACK the DRDY interruption */ 303bc1b4532SEugen Hristev at91_adc_readl(st, AT91_ADC_LCDR); 3040e589d5fSMaxime Ripard st->done = true; 3050e589d5fSMaxime Ripard wake_up_interruptible(&st->wq_data_avail); 3060e589d5fSMaxime Ripard } 307c8b11de0SJosh Wu } 308c8b11de0SJosh Wu 309044d406aSAlexandru Ardelean static int at91_ts_sample(struct iio_dev *idev) 310c8b11de0SJosh Wu { 311044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 312c8b11de0SJosh Wu unsigned int xscale, yscale, reg, z1, z2; 313c8b11de0SJosh Wu unsigned int x, y, pres, xpos, ypos; 314c8b11de0SJosh Wu unsigned int rxp = 1; 315c8b11de0SJosh Wu unsigned int factor = 1000; 316c8b11de0SJosh Wu 317c8b11de0SJosh Wu unsigned int xyz_mask_bits = st->res; 318c8b11de0SJosh Wu unsigned int xyz_mask = (1 << xyz_mask_bits) - 1; 319c8b11de0SJosh Wu 320c8b11de0SJosh Wu /* calculate position */ 321c8b11de0SJosh Wu /* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */ 322c8b11de0SJosh Wu reg = at91_adc_readl(st, AT91_ADC_TSXPOSR); 323c8b11de0SJosh Wu xpos = reg & xyz_mask; 324c8b11de0SJosh Wu x = (xpos << MAX_POS_BITS) - xpos; 325c8b11de0SJosh Wu xscale = (reg >> 16) & xyz_mask; 326c8b11de0SJosh Wu if (xscale == 0) { 327c8b11de0SJosh Wu dev_err(&idev->dev, "Error: xscale == 0!\n"); 328c8b11de0SJosh Wu return -1; 329c8b11de0SJosh Wu } 330c8b11de0SJosh Wu x /= xscale; 331c8b11de0SJosh Wu 332c8b11de0SJosh Wu /* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */ 333c8b11de0SJosh Wu reg = at91_adc_readl(st, AT91_ADC_TSYPOSR); 334c8b11de0SJosh Wu ypos = reg & xyz_mask; 335c8b11de0SJosh Wu y = (ypos << MAX_POS_BITS) - ypos; 336c8b11de0SJosh Wu yscale = (reg >> 16) & xyz_mask; 337c8b11de0SJosh Wu if (yscale == 0) { 338c8b11de0SJosh Wu dev_err(&idev->dev, "Error: yscale == 0!\n"); 339c8b11de0SJosh Wu return -1; 340c8b11de0SJosh Wu } 341c8b11de0SJosh Wu y /= yscale; 342c8b11de0SJosh Wu 343c8b11de0SJosh Wu /* calculate the pressure */ 344c8b11de0SJosh Wu reg = at91_adc_readl(st, AT91_ADC_TSPRESSR); 345c8b11de0SJosh Wu z1 = reg & xyz_mask; 346c8b11de0SJosh Wu z2 = (reg >> 16) & xyz_mask; 347c8b11de0SJosh Wu 348c8b11de0SJosh Wu if (z1 != 0) 349c8b11de0SJosh Wu pres = rxp * (x * factor / 1024) * (z2 * factor / z1 - factor) 350c8b11de0SJosh Wu / factor; 351c8b11de0SJosh Wu else 352c8b11de0SJosh Wu pres = st->ts_pressure_threshold; /* no pen contacted */ 353c8b11de0SJosh Wu 354c8b11de0SJosh Wu dev_dbg(&idev->dev, "xpos = %d, xscale = %d, ypos = %d, yscale = %d, z1 = %d, z2 = %d, press = %d\n", 355c8b11de0SJosh Wu xpos, xscale, ypos, yscale, z1, z2, pres); 356c8b11de0SJosh Wu 357c8b11de0SJosh Wu if (pres < st->ts_pressure_threshold) { 358c8b11de0SJosh Wu dev_dbg(&idev->dev, "x = %d, y = %d, pressure = %d\n", 359c8b11de0SJosh Wu x, y, pres / factor); 360c8b11de0SJosh Wu input_report_abs(st->ts_input, ABS_X, x); 361c8b11de0SJosh Wu input_report_abs(st->ts_input, ABS_Y, y); 362c8b11de0SJosh Wu input_report_abs(st->ts_input, ABS_PRESSURE, pres); 363c8b11de0SJosh Wu input_report_key(st->ts_input, BTN_TOUCH, 1); 364c8b11de0SJosh Wu input_sync(st->ts_input); 365c8b11de0SJosh Wu } else { 366c8b11de0SJosh Wu dev_dbg(&idev->dev, "pressure too low: not reporting\n"); 367c8b11de0SJosh Wu } 368c8b11de0SJosh Wu 369c8b11de0SJosh Wu return 0; 370c8b11de0SJosh Wu } 371c8b11de0SJosh Wu 37284882b06SAlexandre Belloni static irqreturn_t at91_adc_rl_interrupt(int irq, void *private) 37384882b06SAlexandre Belloni { 37484882b06SAlexandre Belloni struct iio_dev *idev = private; 37584882b06SAlexandre Belloni struct at91_adc_state *st = iio_priv(idev); 37684882b06SAlexandre Belloni u32 status = at91_adc_readl(st, st->registers->status_register); 37784882b06SAlexandre Belloni unsigned int reg; 37884882b06SAlexandre Belloni 37984882b06SAlexandre Belloni status &= at91_adc_readl(st, AT91_ADC_IMR); 380d4f51956SLudovic Desroches if (status & GENMASK(st->num_channels - 1, 0)) 38184882b06SAlexandre Belloni handle_adc_eoc_trigger(irq, idev); 38284882b06SAlexandre Belloni 38384882b06SAlexandre Belloni if (status & AT91RL_ADC_IER_PEN) { 38484882b06SAlexandre Belloni /* Disabling pen debounce is required to get a NOPEN irq */ 38584882b06SAlexandre Belloni reg = at91_adc_readl(st, AT91_ADC_MR); 38684882b06SAlexandre Belloni reg &= ~AT91_ADC_PENDBC; 38784882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_MR, reg); 38884882b06SAlexandre Belloni 38984882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); 39084882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_NOPEN 39184882b06SAlexandre Belloni | AT91_ADC_EOC(3)); 39284882b06SAlexandre Belloni /* Set up period trigger for sampling */ 39384882b06SAlexandre Belloni at91_adc_writel(st, st->registers->trigger_register, 39484882b06SAlexandre Belloni AT91_ADC_TRGR_MOD_PERIOD_TRIG | 39584882b06SAlexandre Belloni AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val)); 39684882b06SAlexandre Belloni } else if (status & AT91RL_ADC_IER_NOPEN) { 39784882b06SAlexandre Belloni reg = at91_adc_readl(st, AT91_ADC_MR); 39884882b06SAlexandre Belloni reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; 39984882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_MR, reg); 40084882b06SAlexandre Belloni at91_adc_writel(st, st->registers->trigger_register, 40184882b06SAlexandre Belloni AT91_ADC_TRGR_NONE); 40284882b06SAlexandre Belloni 40384882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_NOPEN 40484882b06SAlexandre Belloni | AT91_ADC_EOC(3)); 40584882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); 40684882b06SAlexandre Belloni st->ts_bufferedmeasure = false; 40784882b06SAlexandre Belloni input_report_key(st->ts_input, BTN_TOUCH, 0); 40884882b06SAlexandre Belloni input_sync(st->ts_input); 409c2ab4474SAnders Darander } else if (status & AT91_ADC_EOC(3) && st->ts_input) { 410c2ab4474SAnders Darander /* Conversion finished and we've a touchscreen */ 41184882b06SAlexandre Belloni if (st->ts_bufferedmeasure) { 41284882b06SAlexandre Belloni /* 41384882b06SAlexandre Belloni * Last measurement is always discarded, since it can 41484882b06SAlexandre Belloni * be erroneous. 41584882b06SAlexandre Belloni * Always report previous measurement 41684882b06SAlexandre Belloni */ 41784882b06SAlexandre Belloni input_report_abs(st->ts_input, ABS_X, st->ts_prev_absx); 41884882b06SAlexandre Belloni input_report_abs(st->ts_input, ABS_Y, st->ts_prev_absy); 41984882b06SAlexandre Belloni input_report_key(st->ts_input, BTN_TOUCH, 1); 42084882b06SAlexandre Belloni input_sync(st->ts_input); 42184882b06SAlexandre Belloni } else 42284882b06SAlexandre Belloni st->ts_bufferedmeasure = true; 42384882b06SAlexandre Belloni 42484882b06SAlexandre Belloni /* Now make new measurement */ 42584882b06SAlexandre Belloni st->ts_prev_absx = at91_adc_readl(st, AT91_ADC_CHAN(st, 3)) 42684882b06SAlexandre Belloni << MAX_RLPOS_BITS; 42784882b06SAlexandre Belloni st->ts_prev_absx /= at91_adc_readl(st, AT91_ADC_CHAN(st, 2)); 42884882b06SAlexandre Belloni 42984882b06SAlexandre Belloni st->ts_prev_absy = at91_adc_readl(st, AT91_ADC_CHAN(st, 1)) 43084882b06SAlexandre Belloni << MAX_RLPOS_BITS; 43184882b06SAlexandre Belloni st->ts_prev_absy /= at91_adc_readl(st, AT91_ADC_CHAN(st, 0)); 43284882b06SAlexandre Belloni } 43384882b06SAlexandre Belloni 43484882b06SAlexandre Belloni return IRQ_HANDLED; 43584882b06SAlexandre Belloni } 43684882b06SAlexandre Belloni 43784882b06SAlexandre Belloni static irqreturn_t at91_adc_9x5_interrupt(int irq, void *private) 438c8b11de0SJosh Wu { 439c8b11de0SJosh Wu struct iio_dev *idev = private; 440c8b11de0SJosh Wu struct at91_adc_state *st = iio_priv(idev); 441c8b11de0SJosh Wu u32 status = at91_adc_readl(st, st->registers->status_register); 442c8b11de0SJosh Wu const uint32_t ts_data_irq_mask = 443c8b11de0SJosh Wu AT91_ADC_IER_XRDY | 444c8b11de0SJosh Wu AT91_ADC_IER_YRDY | 445c8b11de0SJosh Wu AT91_ADC_IER_PRDY; 446c8b11de0SJosh Wu 447d4f51956SLudovic Desroches if (status & GENMASK(st->num_channels - 1, 0)) 448c8b11de0SJosh Wu handle_adc_eoc_trigger(irq, idev); 449c8b11de0SJosh Wu 450c8b11de0SJosh Wu if (status & AT91_ADC_IER_PEN) { 451c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); 452c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_NOPEN | 453c8b11de0SJosh Wu ts_data_irq_mask); 454c8b11de0SJosh Wu /* Set up period trigger for sampling */ 455c8b11de0SJosh Wu at91_adc_writel(st, st->registers->trigger_register, 456c8b11de0SJosh Wu AT91_ADC_TRGR_MOD_PERIOD_TRIG | 457c8b11de0SJosh Wu AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val)); 458c8b11de0SJosh Wu } else if (status & AT91_ADC_IER_NOPEN) { 459c8b11de0SJosh Wu at91_adc_writel(st, st->registers->trigger_register, 0); 460c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_NOPEN | 461c8b11de0SJosh Wu ts_data_irq_mask); 462c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); 463c8b11de0SJosh Wu 464c8b11de0SJosh Wu input_report_key(st->ts_input, BTN_TOUCH, 0); 465c8b11de0SJosh Wu input_sync(st->ts_input); 466c8b11de0SJosh Wu } else if ((status & ts_data_irq_mask) == ts_data_irq_mask) { 467c8b11de0SJosh Wu /* Now all touchscreen data is ready */ 468c8b11de0SJosh Wu 469c8b11de0SJosh Wu if (status & AT91_ADC_ISR_PENS) { 470c8b11de0SJosh Wu /* validate data by pen contact */ 471044d406aSAlexandru Ardelean at91_ts_sample(idev); 472c8b11de0SJosh Wu } else { 473c8b11de0SJosh Wu /* triggered by event that is no pen contact, just read 474c8b11de0SJosh Wu * them to clean the interrupt and discard all. 475c8b11de0SJosh Wu */ 476c8b11de0SJosh Wu at91_adc_readl(st, AT91_ADC_TSXPOSR); 477c8b11de0SJosh Wu at91_adc_readl(st, AT91_ADC_TSYPOSR); 478c8b11de0SJosh Wu at91_adc_readl(st, AT91_ADC_TSPRESSR); 479c8b11de0SJosh Wu } 480c8b11de0SJosh Wu } 4810e589d5fSMaxime Ripard 4820e589d5fSMaxime Ripard return IRQ_HANDLED; 4830e589d5fSMaxime Ripard } 4840e589d5fSMaxime Ripard 4850e589d5fSMaxime Ripard static int at91_adc_channel_init(struct iio_dev *idev) 4860e589d5fSMaxime Ripard { 4870e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 4880e589d5fSMaxime Ripard struct iio_chan_spec *chan_array, *timestamp; 4890e589d5fSMaxime Ripard int bit, idx = 0; 490c8b11de0SJosh Wu unsigned long rsvd_mask = 0; 491c8b11de0SJosh Wu 492c8b11de0SJosh Wu /* If touchscreen is enable, then reserve the adc channels */ 493c8b11de0SJosh Wu if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) 494c8b11de0SJosh Wu rsvd_mask = CHAN_MASK_TOUCHSCREEN_4WIRE; 495c8b11de0SJosh Wu else if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_5WIRE) 496c8b11de0SJosh Wu rsvd_mask = CHAN_MASK_TOUCHSCREEN_5WIRE; 497c8b11de0SJosh Wu 498c8b11de0SJosh Wu /* set up the channel mask to reserve touchscreen channels */ 499c8b11de0SJosh Wu st->channels_mask &= ~rsvd_mask; 5000e589d5fSMaxime Ripard 5010e589d5fSMaxime Ripard idev->num_channels = bitmap_weight(&st->channels_mask, 5020e589d5fSMaxime Ripard st->num_channels) + 1; 5030e589d5fSMaxime Ripard 5046b3aa313SAxel Lin chan_array = devm_kzalloc(&idev->dev, 5056b3aa313SAxel Lin ((idev->num_channels + 1) * 5066b3aa313SAxel Lin sizeof(struct iio_chan_spec)), 5076b3aa313SAxel Lin GFP_KERNEL); 5080e589d5fSMaxime Ripard 5090e589d5fSMaxime Ripard if (!chan_array) 5100e589d5fSMaxime Ripard return -ENOMEM; 5110e589d5fSMaxime Ripard 5120e589d5fSMaxime Ripard for_each_set_bit(bit, &st->channels_mask, st->num_channels) { 5130e589d5fSMaxime Ripard struct iio_chan_spec *chan = chan_array + idx; 5140e589d5fSMaxime Ripard 5150e589d5fSMaxime Ripard chan->type = IIO_VOLTAGE; 5160e589d5fSMaxime Ripard chan->indexed = 1; 5170e589d5fSMaxime Ripard chan->channel = bit; 5180e589d5fSMaxime Ripard chan->scan_index = idx; 5190e589d5fSMaxime Ripard chan->scan_type.sign = 'u'; 52047be16b6SLudovic Desroches chan->scan_type.realbits = st->res; 5210e589d5fSMaxime Ripard chan->scan_type.storagebits = 16; 52201bdab66SJonathan Cameron chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); 52301bdab66SJonathan Cameron chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 5240e589d5fSMaxime Ripard idx++; 5250e589d5fSMaxime Ripard } 5260e589d5fSMaxime Ripard timestamp = chan_array + idx; 5270e589d5fSMaxime Ripard 5280e589d5fSMaxime Ripard timestamp->type = IIO_TIMESTAMP; 5290e589d5fSMaxime Ripard timestamp->channel = -1; 5300e589d5fSMaxime Ripard timestamp->scan_index = idx; 5310e589d5fSMaxime Ripard timestamp->scan_type.sign = 's'; 5320e589d5fSMaxime Ripard timestamp->scan_type.realbits = 64; 5330e589d5fSMaxime Ripard timestamp->scan_type.storagebits = 64; 5340e589d5fSMaxime Ripard 5350e589d5fSMaxime Ripard idev->channels = chan_array; 5360e589d5fSMaxime Ripard return idev->num_channels; 5370e589d5fSMaxime Ripard } 5380e589d5fSMaxime Ripard 5394f3bcd87SDan Carpenter static int at91_adc_get_trigger_value_by_name(struct iio_dev *idev, 54009d4726bSAlexandre Belloni const struct at91_adc_trigger *triggers, 5410e589d5fSMaxime Ripard const char *trigger_name) 5420e589d5fSMaxime Ripard { 5430e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 5440e589d5fSMaxime Ripard int i; 5450e589d5fSMaxime Ripard 54609d4726bSAlexandre Belloni for (i = 0; i < st->caps->trigger_number; i++) { 5470e589d5fSMaxime Ripard char *name = kasprintf(GFP_KERNEL, 5480e589d5fSMaxime Ripard "%s-dev%d-%s", 5490e589d5fSMaxime Ripard idev->name, 55015ea2878SJonathan Cameron iio_device_id(idev), 5510e589d5fSMaxime Ripard triggers[i].name); 5520e589d5fSMaxime Ripard if (!name) 5530e589d5fSMaxime Ripard return -ENOMEM; 5540e589d5fSMaxime Ripard 5550e589d5fSMaxime Ripard if (strcmp(trigger_name, name) == 0) { 5560e589d5fSMaxime Ripard kfree(name); 5574f3bcd87SDan Carpenter if (triggers[i].value == 0) 5584f3bcd87SDan Carpenter return -EINVAL; 5594f3bcd87SDan Carpenter return triggers[i].value; 5600e589d5fSMaxime Ripard } 5610e589d5fSMaxime Ripard 5620e589d5fSMaxime Ripard kfree(name); 5630e589d5fSMaxime Ripard } 5640e589d5fSMaxime Ripard 5654f3bcd87SDan Carpenter return -EINVAL; 5660e589d5fSMaxime Ripard } 5670e589d5fSMaxime Ripard 5680e589d5fSMaxime Ripard static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) 5690e589d5fSMaxime Ripard { 5701e9663c6SLars-Peter Clausen struct iio_dev *idev = iio_trigger_get_drvdata(trig); 5710e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 5723e4ef8e8SAlexandru Ardelean const struct at91_adc_reg_desc *reg = st->registers; 5730e589d5fSMaxime Ripard u32 status = at91_adc_readl(st, reg->trigger_register); 5744f3bcd87SDan Carpenter int value; 5750e589d5fSMaxime Ripard u8 bit; 5760e589d5fSMaxime Ripard 5770e589d5fSMaxime Ripard value = at91_adc_get_trigger_value_by_name(idev, 57809d4726bSAlexandre Belloni st->caps->triggers, 5790e589d5fSMaxime Ripard idev->trig->name); 5804f3bcd87SDan Carpenter if (value < 0) 5814f3bcd87SDan Carpenter return value; 5820e589d5fSMaxime Ripard 5830e589d5fSMaxime Ripard if (state) { 5840e589d5fSMaxime Ripard st->buffer = kmalloc(idev->scan_bytes, GFP_KERNEL); 5850e589d5fSMaxime Ripard if (st->buffer == NULL) 5860e589d5fSMaxime Ripard return -ENOMEM; 5870e589d5fSMaxime Ripard 5880e589d5fSMaxime Ripard at91_adc_writel(st, reg->trigger_register, 5890e589d5fSMaxime Ripard status | value); 5900e589d5fSMaxime Ripard 59170dddeeeSOctavian Purdila for_each_set_bit(bit, idev->active_scan_mask, 5920e589d5fSMaxime Ripard st->num_channels) { 5930e589d5fSMaxime Ripard struct iio_chan_spec const *chan = idev->channels + bit; 5940e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHER, 5950e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 5960e589d5fSMaxime Ripard } 5970e589d5fSMaxime Ripard 5980e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IER, reg->drdy_mask); 5990e589d5fSMaxime Ripard 6000e589d5fSMaxime Ripard } else { 6010e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, reg->drdy_mask); 6020e589d5fSMaxime Ripard 6030e589d5fSMaxime Ripard at91_adc_writel(st, reg->trigger_register, 6040e589d5fSMaxime Ripard status & ~value); 6050e589d5fSMaxime Ripard 60670dddeeeSOctavian Purdila for_each_set_bit(bit, idev->active_scan_mask, 6070e589d5fSMaxime Ripard st->num_channels) { 6080e589d5fSMaxime Ripard struct iio_chan_spec const *chan = idev->channels + bit; 6090e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHDR, 6100e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 6110e589d5fSMaxime Ripard } 6120e589d5fSMaxime Ripard kfree(st->buffer); 6130e589d5fSMaxime Ripard } 6140e589d5fSMaxime Ripard 6150e589d5fSMaxime Ripard return 0; 6160e589d5fSMaxime Ripard } 6170e589d5fSMaxime Ripard 6180e589d5fSMaxime Ripard static const struct iio_trigger_ops at91_adc_trigger_ops = { 6190e589d5fSMaxime Ripard .set_trigger_state = &at91_adc_configure_trigger, 6200e589d5fSMaxime Ripard }; 6210e589d5fSMaxime Ripard 6220e589d5fSMaxime Ripard static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev, 62309d4726bSAlexandre Belloni const struct at91_adc_trigger *trigger) 6240e589d5fSMaxime Ripard { 6250e589d5fSMaxime Ripard struct iio_trigger *trig; 6260e589d5fSMaxime Ripard int ret; 6270e589d5fSMaxime Ripard 628995071d3SGwendal Grignou trig = iio_trigger_alloc(idev->dev.parent, "%s-dev%d-%s", idev->name, 62915ea2878SJonathan Cameron iio_device_id(idev), trigger->name); 6300e589d5fSMaxime Ripard if (trig == NULL) 6310e589d5fSMaxime Ripard return NULL; 6320e589d5fSMaxime Ripard 6331e9663c6SLars-Peter Clausen iio_trigger_set_drvdata(trig, idev); 6340e589d5fSMaxime Ripard trig->ops = &at91_adc_trigger_ops; 6350e589d5fSMaxime Ripard 6360e589d5fSMaxime Ripard ret = iio_trigger_register(trig); 6370e589d5fSMaxime Ripard if (ret) 6380e589d5fSMaxime Ripard return NULL; 6390e589d5fSMaxime Ripard 6400e589d5fSMaxime Ripard return trig; 6410e589d5fSMaxime Ripard } 6420e589d5fSMaxime Ripard 6430e589d5fSMaxime Ripard static int at91_adc_trigger_init(struct iio_dev *idev) 6440e589d5fSMaxime Ripard { 6450e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 6460e589d5fSMaxime Ripard int i, ret; 6470e589d5fSMaxime Ripard 648a86854d0SKees Cook st->trig = devm_kcalloc(&idev->dev, 64909d4726bSAlexandre Belloni st->caps->trigger_number, sizeof(*st->trig), 6506b3aa313SAxel Lin GFP_KERNEL); 6510e589d5fSMaxime Ripard 6520e589d5fSMaxime Ripard if (st->trig == NULL) { 6530e589d5fSMaxime Ripard ret = -ENOMEM; 6540e589d5fSMaxime Ripard goto error_ret; 6550e589d5fSMaxime Ripard } 6560e589d5fSMaxime Ripard 65709d4726bSAlexandre Belloni for (i = 0; i < st->caps->trigger_number; i++) { 65809d4726bSAlexandre Belloni if (st->caps->triggers[i].is_external && !(st->use_external)) 6590e589d5fSMaxime Ripard continue; 6600e589d5fSMaxime Ripard 6610e589d5fSMaxime Ripard st->trig[i] = at91_adc_allocate_trigger(idev, 66209d4726bSAlexandre Belloni st->caps->triggers + i); 6630e589d5fSMaxime Ripard if (st->trig[i] == NULL) { 6640e589d5fSMaxime Ripard dev_err(&idev->dev, 6650e589d5fSMaxime Ripard "Could not allocate trigger %d\n", i); 6660e589d5fSMaxime Ripard ret = -ENOMEM; 6670e589d5fSMaxime Ripard goto error_trigger; 6680e589d5fSMaxime Ripard } 6690e589d5fSMaxime Ripard } 6700e589d5fSMaxime Ripard 6710e589d5fSMaxime Ripard return 0; 6720e589d5fSMaxime Ripard 6730e589d5fSMaxime Ripard error_trigger: 6740e589d5fSMaxime Ripard for (i--; i >= 0; i--) { 6750e589d5fSMaxime Ripard iio_trigger_unregister(st->trig[i]); 6760e589d5fSMaxime Ripard iio_trigger_free(st->trig[i]); 6770e589d5fSMaxime Ripard } 6780e589d5fSMaxime Ripard error_ret: 6790e589d5fSMaxime Ripard return ret; 6800e589d5fSMaxime Ripard } 6810e589d5fSMaxime Ripard 6820e589d5fSMaxime Ripard static void at91_adc_trigger_remove(struct iio_dev *idev) 6830e589d5fSMaxime Ripard { 6840e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 6850e589d5fSMaxime Ripard int i; 6860e589d5fSMaxime Ripard 68709d4726bSAlexandre Belloni for (i = 0; i < st->caps->trigger_number; i++) { 6880e589d5fSMaxime Ripard iio_trigger_unregister(st->trig[i]); 6890e589d5fSMaxime Ripard iio_trigger_free(st->trig[i]); 6900e589d5fSMaxime Ripard } 6910e589d5fSMaxime Ripard } 6920e589d5fSMaxime Ripard 6930e589d5fSMaxime Ripard static int at91_adc_buffer_init(struct iio_dev *idev) 6940e589d5fSMaxime Ripard { 69590032e4eSLars-Peter Clausen return iio_triggered_buffer_setup(idev, &iio_pollfunc_store_time, 69690032e4eSLars-Peter Clausen &at91_adc_trigger_handler, NULL); 6970e589d5fSMaxime Ripard } 6980e589d5fSMaxime Ripard 6990e589d5fSMaxime Ripard static void at91_adc_buffer_remove(struct iio_dev *idev) 7000e589d5fSMaxime Ripard { 70190032e4eSLars-Peter Clausen iio_triggered_buffer_cleanup(idev); 7020e589d5fSMaxime Ripard } 7030e589d5fSMaxime Ripard 7040e589d5fSMaxime Ripard static int at91_adc_read_raw(struct iio_dev *idev, 7050e589d5fSMaxime Ripard struct iio_chan_spec const *chan, 7060e589d5fSMaxime Ripard int *val, int *val2, long mask) 7070e589d5fSMaxime Ripard { 7080e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 7090e589d5fSMaxime Ripard int ret; 7100e589d5fSMaxime Ripard 7110e589d5fSMaxime Ripard switch (mask) { 7120e589d5fSMaxime Ripard case IIO_CHAN_INFO_RAW: 7130e589d5fSMaxime Ripard mutex_lock(&st->lock); 7140e589d5fSMaxime Ripard 715d4f51956SLudovic Desroches st->chnb = chan->channel; 7160e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHER, 7170e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 718d4f51956SLudovic Desroches at91_adc_writel(st, AT91_ADC_IER, BIT(chan->channel)); 7190e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_START); 7200e589d5fSMaxime Ripard 7210e589d5fSMaxime Ripard ret = wait_event_interruptible_timeout(st->wq_data_avail, 7220e589d5fSMaxime Ripard st->done, 7230e589d5fSMaxime Ripard msecs_to_jiffies(1000)); 7240e589d5fSMaxime Ripard 72509c6bdeeSGeorg Ottinger /* Disable interrupts, regardless if adc conversion was 72609c6bdeeSGeorg Ottinger * successful or not 72709c6bdeeSGeorg Ottinger */ 7280e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHDR, 7290e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 730d4f51956SLudovic Desroches at91_adc_writel(st, AT91_ADC_IDR, BIT(chan->channel)); 7310e589d5fSMaxime Ripard 73209c6bdeeSGeorg Ottinger if (ret > 0) { 73309c6bdeeSGeorg Ottinger /* a valid conversion took place */ 73409c6bdeeSGeorg Ottinger *val = st->last_value; 7350e589d5fSMaxime Ripard st->last_value = 0; 7360e589d5fSMaxime Ripard st->done = false; 73709c6bdeeSGeorg Ottinger ret = IIO_VAL_INT; 73809c6bdeeSGeorg Ottinger } else if (ret == 0) { 73909c6bdeeSGeorg Ottinger /* conversion timeout */ 74009c6bdeeSGeorg Ottinger dev_err(&idev->dev, "ADC Channel %d timeout.\n", 74109c6bdeeSGeorg Ottinger chan->channel); 74209c6bdeeSGeorg Ottinger ret = -ETIMEDOUT; 74309c6bdeeSGeorg Ottinger } 74409c6bdeeSGeorg Ottinger 7450e589d5fSMaxime Ripard mutex_unlock(&st->lock); 74609c6bdeeSGeorg Ottinger return ret; 7470e589d5fSMaxime Ripard 7480e589d5fSMaxime Ripard case IIO_CHAN_INFO_SCALE: 749c45e561eSLars-Peter Clausen *val = st->vref_mv; 750c45e561eSLars-Peter Clausen *val2 = chan->scan_type.realbits; 751c45e561eSLars-Peter Clausen return IIO_VAL_FRACTIONAL_LOG2; 7520e589d5fSMaxime Ripard default: 7530e589d5fSMaxime Ripard break; 7540e589d5fSMaxime Ripard } 7550e589d5fSMaxime Ripard return -EINVAL; 7560e589d5fSMaxime Ripard } 7570e589d5fSMaxime Ripard 75847be16b6SLudovic Desroches 7592ab5f39bSJan Leupold static u32 calc_startup_ticks_9260(u32 startup_time, u32 adc_clk_khz) 760c4601666SJosh Wu { 761c4601666SJosh Wu /* 762c4601666SJosh Wu * Number of ticks needed to cover the startup time of the ADC 763c4601666SJosh Wu * as defined in the electrical characteristics of the board, 764c4601666SJosh Wu * divided by 8. The formula thus is : 765c4601666SJosh Wu * Startup Time = (ticks + 1) * 8 / ADC Clock 766c4601666SJosh Wu */ 767c4601666SJosh Wu return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8; 768c4601666SJosh Wu } 769c4601666SJosh Wu 7702ab5f39bSJan Leupold static u32 calc_startup_ticks_9x5(u32 startup_time, u32 adc_clk_khz) 771c4601666SJosh Wu { 772c4601666SJosh Wu /* 773c4601666SJosh Wu * For sama5d3x and at91sam9x5, the formula changes to: 774c4601666SJosh Wu * Startup Time = <lookup_table_value> / ADC Clock 775c4601666SJosh Wu */ 7765b4e17c9SColin Ian King static const int startup_lookup[] = { 777c4601666SJosh Wu 0, 8, 16, 24, 778c4601666SJosh Wu 64, 80, 96, 112, 779c4601666SJosh Wu 512, 576, 640, 704, 780c4601666SJosh Wu 768, 832, 896, 960 781c4601666SJosh Wu }; 782c4601666SJosh Wu int i, size = ARRAY_SIZE(startup_lookup); 783c4601666SJosh Wu unsigned int ticks; 784c4601666SJosh Wu 785c4601666SJosh Wu ticks = startup_time * adc_clk_khz / 1000; 786c4601666SJosh Wu for (i = 0; i < size; i++) 787c4601666SJosh Wu if (ticks < startup_lookup[i]) 788c4601666SJosh Wu break; 789c4601666SJosh Wu 790c4601666SJosh Wu ticks = i; 791c4601666SJosh Wu if (ticks == size) 792c4601666SJosh Wu /* Reach the end of lookup table */ 793c4601666SJosh Wu ticks = size - 1; 794c4601666SJosh Wu 795c4601666SJosh Wu return ticks; 796c4601666SJosh Wu } 797c4601666SJosh Wu 798c8b11de0SJosh Wu static int at91_adc_probe_dt_ts(struct device_node *node, 799c8b11de0SJosh Wu struct at91_adc_state *st, struct device *dev) 800c8b11de0SJosh Wu { 801c8b11de0SJosh Wu int ret; 802c8b11de0SJosh Wu u32 prop; 803c8b11de0SJosh Wu 804c8b11de0SJosh Wu ret = of_property_read_u32(node, "atmel,adc-ts-wires", &prop); 805c8b11de0SJosh Wu if (ret) { 806c8b11de0SJosh Wu dev_info(dev, "ADC Touch screen is disabled.\n"); 807c8b11de0SJosh Wu return 0; 808c8b11de0SJosh Wu } 809c8b11de0SJosh Wu 810c8b11de0SJosh Wu switch (prop) { 811c8b11de0SJosh Wu case 4: 812c8b11de0SJosh Wu case 5: 813c8b11de0SJosh Wu st->touchscreen_type = prop; 814c8b11de0SJosh Wu break; 815c8b11de0SJosh Wu default: 816c8b11de0SJosh Wu dev_err(dev, "Unsupported number of touchscreen wires (%d). Should be 4 or 5.\n", prop); 817c8b11de0SJosh Wu return -EINVAL; 818c8b11de0SJosh Wu } 819c8b11de0SJosh Wu 82084882b06SAlexandre Belloni if (!st->caps->has_tsmr) 82184882b06SAlexandre Belloni return 0; 822c8b11de0SJosh Wu prop = 0; 823c8b11de0SJosh Wu of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop); 824c8b11de0SJosh Wu st->ts_pressure_threshold = prop; 825c8b11de0SJosh Wu if (st->ts_pressure_threshold) { 826c8b11de0SJosh Wu return 0; 827c8b11de0SJosh Wu } else { 828c8b11de0SJosh Wu dev_err(dev, "Invalid pressure threshold for the touchscreen\n"); 829c8b11de0SJosh Wu return -EINVAL; 830c8b11de0SJosh Wu } 831c8b11de0SJosh Wu } 832c8b11de0SJosh Wu 8330e589d5fSMaxime Ripard static const struct iio_info at91_adc_info = { 8340e589d5fSMaxime Ripard .read_raw = &at91_adc_read_raw, 8350e589d5fSMaxime Ripard }; 8360e589d5fSMaxime Ripard 837c8b11de0SJosh Wu /* Touchscreen related functions */ 838c8b11de0SJosh Wu static int atmel_ts_open(struct input_dev *dev) 839c8b11de0SJosh Wu { 840c8b11de0SJosh Wu struct at91_adc_state *st = input_get_drvdata(dev); 841c8b11de0SJosh Wu 84284882b06SAlexandre Belloni if (st->caps->has_tsmr) 843c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); 84484882b06SAlexandre Belloni else 84584882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); 846c8b11de0SJosh Wu return 0; 847c8b11de0SJosh Wu } 848c8b11de0SJosh Wu 849c8b11de0SJosh Wu static void atmel_ts_close(struct input_dev *dev) 850c8b11de0SJosh Wu { 851c8b11de0SJosh Wu struct at91_adc_state *st = input_get_drvdata(dev); 852c8b11de0SJosh Wu 85384882b06SAlexandre Belloni if (st->caps->has_tsmr) 854c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); 85584882b06SAlexandre Belloni else 85684882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); 857c8b11de0SJosh Wu } 858c8b11de0SJosh Wu 859044d406aSAlexandru Ardelean static int at91_ts_hw_init(struct iio_dev *idev, u32 adc_clk_khz) 860c8b11de0SJosh Wu { 861044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 86284882b06SAlexandre Belloni u32 reg = 0; 863ede63aafSNicolas Ferre u32 tssctim = 0; 864c8b11de0SJosh Wu int i = 0; 865c8b11de0SJosh Wu 86684882b06SAlexandre Belloni /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid 86784882b06SAlexandre Belloni * pen detect noise. 86884882b06SAlexandre Belloni * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock 86984882b06SAlexandre Belloni */ 87084882b06SAlexandre Belloni st->ts_pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 87184882b06SAlexandre Belloni 1000, 1); 87284882b06SAlexandre Belloni 87384882b06SAlexandre Belloni while (st->ts_pendbc >> ++i) 87484882b06SAlexandre Belloni ; /* Empty! Find the shift offset */ 87584882b06SAlexandre Belloni if (abs(st->ts_pendbc - (1 << i)) < abs(st->ts_pendbc - (1 << (i - 1)))) 87684882b06SAlexandre Belloni st->ts_pendbc = i; 87784882b06SAlexandre Belloni else 87884882b06SAlexandre Belloni st->ts_pendbc = i - 1; 87984882b06SAlexandre Belloni 88084882b06SAlexandre Belloni if (!st->caps->has_tsmr) { 88184882b06SAlexandre Belloni reg = at91_adc_readl(st, AT91_ADC_MR); 88284882b06SAlexandre Belloni reg |= AT91_ADC_TSAMOD_TS_ONLY_MODE | AT91_ADC_PENDET; 88384882b06SAlexandre Belloni 88484882b06SAlexandre Belloni reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; 88584882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_MR, reg); 88684882b06SAlexandre Belloni 88784882b06SAlexandre Belloni reg = AT91_ADC_TSR_SHTIM_(TOUCH_SHTIM) & AT91_ADC_TSR_SHTIM; 88884882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_TSR, reg); 88984882b06SAlexandre Belloni 89084882b06SAlexandre Belloni st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US_RL * 89184882b06SAlexandre Belloni adc_clk_khz / 1000) - 1, 1); 89284882b06SAlexandre Belloni 89384882b06SAlexandre Belloni return 0; 89484882b06SAlexandre Belloni } 89584882b06SAlexandre Belloni 896ede63aafSNicolas Ferre /* Touchscreen Switches Closure time needed for allowing the value to 897ede63aafSNicolas Ferre * stabilize. 898ede63aafSNicolas Ferre * Switch Closure Time = (TSSCTIM * 4) ADCClock periods 899ede63aafSNicolas Ferre */ 900ede63aafSNicolas Ferre tssctim = DIV_ROUND_UP(TOUCH_SCTIM_US * adc_clk_khz / 1000, 4); 901ede63aafSNicolas Ferre dev_dbg(&idev->dev, "adc_clk at: %d KHz, tssctim at: %d\n", 902ede63aafSNicolas Ferre adc_clk_khz, tssctim); 903ede63aafSNicolas Ferre 904c8b11de0SJosh Wu if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) 905c8b11de0SJosh Wu reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS; 906c8b11de0SJosh Wu else 907c8b11de0SJosh Wu reg = AT91_ADC_TSMR_TSMODE_5WIRE; 908c8b11de0SJosh Wu 909ede63aafSNicolas Ferre reg |= AT91_ADC_TSMR_SCTIM_(tssctim) & AT91_ADC_TSMR_SCTIM; 910c8b11de0SJosh Wu reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average) 911c8b11de0SJosh Wu & AT91_ADC_TSMR_TSAV; 91284882b06SAlexandre Belloni reg |= AT91_ADC_TSMR_PENDBC_(st->ts_pendbc) & AT91_ADC_TSMR_PENDBC; 913c8b11de0SJosh Wu reg |= AT91_ADC_TSMR_NOTSDMA; 914c8b11de0SJosh Wu reg |= AT91_ADC_TSMR_PENDET_ENA; 91584882b06SAlexandre Belloni reg |= 0x03 << 8; /* TSFREQ, needs to be bigger than TSAV */ 916c8b11de0SJosh Wu 917c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_TSMR, reg); 918c8b11de0SJosh Wu 919c8b11de0SJosh Wu /* Change adc internal resistor value for better pen detection, 920c8b11de0SJosh Wu * default value is 100 kOhm. 921c8b11de0SJosh Wu * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm 922c8b11de0SJosh Wu * option only available on ES2 and higher 923c8b11de0SJosh Wu */ 924c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity 925c8b11de0SJosh Wu & AT91_ADC_ACR_PENDETSENS); 926c8b11de0SJosh Wu 92784882b06SAlexandre Belloni /* Sample Period Time = (TRGPER + 1) / ADCClock */ 928c8b11de0SJosh Wu st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US * 929c8b11de0SJosh Wu adc_clk_khz / 1000) - 1, 1); 930c8b11de0SJosh Wu 931c8b11de0SJosh Wu return 0; 932c8b11de0SJosh Wu } 933c8b11de0SJosh Wu 934044d406aSAlexandru Ardelean static int at91_ts_register(struct iio_dev *idev, 935c8b11de0SJosh Wu struct platform_device *pdev) 936c8b11de0SJosh Wu { 937044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 938c8b11de0SJosh Wu struct input_dev *input; 939c8b11de0SJosh Wu int ret; 940c8b11de0SJosh Wu 941c8b11de0SJosh Wu input = input_allocate_device(); 942c8b11de0SJosh Wu if (!input) { 943c8b11de0SJosh Wu dev_err(&idev->dev, "Failed to allocate TS device!\n"); 944c8b11de0SJosh Wu return -ENOMEM; 945c8b11de0SJosh Wu } 946c8b11de0SJosh Wu 947c8b11de0SJosh Wu input->name = DRIVER_NAME; 948c8b11de0SJosh Wu input->id.bustype = BUS_HOST; 949c8b11de0SJosh Wu input->dev.parent = &pdev->dev; 950c8b11de0SJosh Wu input->open = atmel_ts_open; 951c8b11de0SJosh Wu input->close = atmel_ts_close; 952c8b11de0SJosh Wu 953c8b11de0SJosh Wu __set_bit(EV_ABS, input->evbit); 954c8b11de0SJosh Wu __set_bit(EV_KEY, input->evbit); 955c8b11de0SJosh Wu __set_bit(BTN_TOUCH, input->keybit); 95684882b06SAlexandre Belloni if (st->caps->has_tsmr) { 95784882b06SAlexandre Belloni input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 95884882b06SAlexandre Belloni 0, 0); 95984882b06SAlexandre Belloni input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 96084882b06SAlexandre Belloni 0, 0); 961c8b11de0SJosh Wu input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0); 96284882b06SAlexandre Belloni } else { 96384882b06SAlexandre Belloni if (st->touchscreen_type != ATMEL_ADC_TOUCHSCREEN_4WIRE) { 96484882b06SAlexandre Belloni dev_err(&pdev->dev, 96584882b06SAlexandre Belloni "This touchscreen controller only support 4 wires\n"); 96684882b06SAlexandre Belloni ret = -EINVAL; 96784882b06SAlexandre Belloni goto err; 96884882b06SAlexandre Belloni } 96984882b06SAlexandre Belloni 97084882b06SAlexandre Belloni input_set_abs_params(input, ABS_X, 0, (1 << MAX_RLPOS_BITS) - 1, 97184882b06SAlexandre Belloni 0, 0); 97284882b06SAlexandre Belloni input_set_abs_params(input, ABS_Y, 0, (1 << MAX_RLPOS_BITS) - 1, 97384882b06SAlexandre Belloni 0, 0); 97484882b06SAlexandre Belloni } 975c8b11de0SJosh Wu 976c8b11de0SJosh Wu st->ts_input = input; 977c8b11de0SJosh Wu input_set_drvdata(input, st); 978c8b11de0SJosh Wu 979c8b11de0SJosh Wu ret = input_register_device(input); 980c8b11de0SJosh Wu if (ret) 98184882b06SAlexandre Belloni goto err; 982c8b11de0SJosh Wu 983c8b11de0SJosh Wu return ret; 98484882b06SAlexandre Belloni 98584882b06SAlexandre Belloni err: 98684882b06SAlexandre Belloni input_free_device(st->ts_input); 98784882b06SAlexandre Belloni return ret; 988c8b11de0SJosh Wu } 989c8b11de0SJosh Wu 990c8b11de0SJosh Wu static void at91_ts_unregister(struct at91_adc_state *st) 991c8b11de0SJosh Wu { 992c8b11de0SJosh Wu input_unregister_device(st->ts_input); 993c8b11de0SJosh Wu } 994c8b11de0SJosh Wu 995fc52692cSGreg Kroah-Hartman static int at91_adc_probe(struct platform_device *pdev) 9960e589d5fSMaxime Ripard { 997db10e201SJosh Wu unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim; 9989054c15cSAlexandre Belloni struct device_node *node = pdev->dev.of_node; 9990e589d5fSMaxime Ripard int ret; 10000e589d5fSMaxime Ripard struct iio_dev *idev; 10010e589d5fSMaxime Ripard struct at91_adc_state *st; 10029054c15cSAlexandre Belloni u32 reg, prop; 10039054c15cSAlexandre Belloni char *s; 10040e589d5fSMaxime Ripard 1005f8837532SSachin Kamat idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state)); 1006f8837532SSachin Kamat if (!idev) 1007f8837532SSachin Kamat return -ENOMEM; 10080e589d5fSMaxime Ripard 10090e589d5fSMaxime Ripard st = iio_priv(idev); 10100e589d5fSMaxime Ripard 10119054c15cSAlexandre Belloni st->caps = of_device_get_match_data(&pdev->dev); 10129054c15cSAlexandre Belloni 10139054c15cSAlexandre Belloni st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers"); 10149054c15cSAlexandre Belloni 10159054c15cSAlexandre Belloni if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) { 10169054c15cSAlexandre Belloni dev_err(&idev->dev, "Missing adc-channels-used property in the DT.\n"); 10179054c15cSAlexandre Belloni return -EINVAL; 10189054c15cSAlexandre Belloni } 10199054c15cSAlexandre Belloni st->channels_mask = prop; 10209054c15cSAlexandre Belloni 10219054c15cSAlexandre Belloni st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode"); 10229054c15cSAlexandre Belloni 10239054c15cSAlexandre Belloni if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) { 10249054c15cSAlexandre Belloni dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n"); 10259054c15cSAlexandre Belloni return -EINVAL; 10269054c15cSAlexandre Belloni } 10279054c15cSAlexandre Belloni st->startup_time = prop; 10289054c15cSAlexandre Belloni 10299054c15cSAlexandre Belloni prop = 0; 10309054c15cSAlexandre Belloni of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop); 10319054c15cSAlexandre Belloni st->sample_hold_time = prop; 10329054c15cSAlexandre Belloni 10339054c15cSAlexandre Belloni if (of_property_read_u32(node, "atmel,adc-vref", &prop)) { 10349054c15cSAlexandre Belloni dev_err(&idev->dev, "Missing adc-vref property in the DT.\n"); 10359054c15cSAlexandre Belloni return -EINVAL; 10369054c15cSAlexandre Belloni } 10379054c15cSAlexandre Belloni st->vref_mv = prop; 10389054c15cSAlexandre Belloni 10399054c15cSAlexandre Belloni st->res = st->caps->high_res_bits; 10409054c15cSAlexandre Belloni if (st->caps->low_res_bits && 10419054c15cSAlexandre Belloni !of_property_read_string(node, "atmel,adc-use-res", (const char **)&s) 10429054c15cSAlexandre Belloni && !strcmp(s, "lowres")) 10439054c15cSAlexandre Belloni st->res = st->caps->low_res_bits; 10449054c15cSAlexandre Belloni 10459054c15cSAlexandre Belloni dev_info(&idev->dev, "Resolution used: %u bits\n", st->res); 10469054c15cSAlexandre Belloni 10479054c15cSAlexandre Belloni st->registers = &st->caps->registers; 10489054c15cSAlexandre Belloni st->num_channels = st->caps->num_channels; 10499054c15cSAlexandre Belloni 10509054c15cSAlexandre Belloni /* Check if touchscreen is supported. */ 10519054c15cSAlexandre Belloni if (st->caps->has_ts) { 10529054c15cSAlexandre Belloni ret = at91_adc_probe_dt_ts(node, st, &idev->dev); 1053ead1c9f3SAlexandru Ardelean if (ret) 1054ead1c9f3SAlexandru Ardelean return ret; 10559054c15cSAlexandre Belloni } 10560e589d5fSMaxime Ripard 10570e589d5fSMaxime Ripard platform_set_drvdata(pdev, idev); 10580e589d5fSMaxime Ripard 10590e589d5fSMaxime Ripard idev->name = dev_name(&pdev->dev); 10600e589d5fSMaxime Ripard idev->modes = INDIO_DIRECT_MODE; 10610e589d5fSMaxime Ripard idev->info = &at91_adc_info; 10620e589d5fSMaxime Ripard 10630e589d5fSMaxime Ripard st->irq = platform_get_irq(pdev, 0); 10647c279229SStephen Boyd if (st->irq < 0) 1065f8837532SSachin Kamat return -ENODEV; 10660e589d5fSMaxime Ripard 1067af5c2174SAishwarya Ramakrishnan st->reg_base = devm_platform_ioremap_resource(pdev, 0); 1068c34812e4SVenkat Prashanth B U if (IS_ERR(st->reg_base)) 1069f8837532SSachin Kamat return PTR_ERR(st->reg_base); 1070c34812e4SVenkat Prashanth B U 10710e589d5fSMaxime Ripard 10720e589d5fSMaxime Ripard /* 10730e589d5fSMaxime Ripard * Disable all IRQs before setting up the handler 10740e589d5fSMaxime Ripard */ 10750e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); 10760e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); 107784882b06SAlexandre Belloni 107884882b06SAlexandre Belloni if (st->caps->has_tsmr) 107984882b06SAlexandre Belloni ret = request_irq(st->irq, at91_adc_9x5_interrupt, 0, 108084882b06SAlexandre Belloni pdev->dev.driver->name, idev); 108184882b06SAlexandre Belloni else 108284882b06SAlexandre Belloni ret = request_irq(st->irq, at91_adc_rl_interrupt, 0, 108384882b06SAlexandre Belloni pdev->dev.driver->name, idev); 10840e589d5fSMaxime Ripard if (ret) { 10850e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); 1086f8837532SSachin Kamat return ret; 10870e589d5fSMaxime Ripard } 10880e589d5fSMaxime Ripard 1089390d75c1SJulia Lawall st->clk = devm_clk_get(&pdev->dev, "adc_clk"); 10900e589d5fSMaxime Ripard if (IS_ERR(st->clk)) { 10910e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to get the clock.\n"); 10920e589d5fSMaxime Ripard ret = PTR_ERR(st->clk); 10930e589d5fSMaxime Ripard goto error_free_irq; 10940e589d5fSMaxime Ripard } 10950e589d5fSMaxime Ripard 109600062a9cSJulia Lawall ret = clk_prepare_enable(st->clk); 10970e589d5fSMaxime Ripard if (ret) { 109800062a9cSJulia Lawall dev_err(&pdev->dev, 109900062a9cSJulia Lawall "Could not prepare or enable the clock.\n"); 1100390d75c1SJulia Lawall goto error_free_irq; 11010e589d5fSMaxime Ripard } 11020e589d5fSMaxime Ripard 1103390d75c1SJulia Lawall st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk"); 11040e589d5fSMaxime Ripard if (IS_ERR(st->adc_clk)) { 11050e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); 1106f755bbbfSJulia Lawall ret = PTR_ERR(st->adc_clk); 11070e589d5fSMaxime Ripard goto error_disable_clk; 11080e589d5fSMaxime Ripard } 11090e589d5fSMaxime Ripard 111000062a9cSJulia Lawall ret = clk_prepare_enable(st->adc_clk); 11110e589d5fSMaxime Ripard if (ret) { 111200062a9cSJulia Lawall dev_err(&pdev->dev, 111300062a9cSJulia Lawall "Could not prepare or enable the ADC clock.\n"); 1114390d75c1SJulia Lawall goto error_disable_clk; 11150e589d5fSMaxime Ripard } 11160e589d5fSMaxime Ripard 11170e589d5fSMaxime Ripard /* 11180e589d5fSMaxime Ripard * Prescaler rate computation using the formula from the Atmel's 11190e589d5fSMaxime Ripard * datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being 11200e589d5fSMaxime Ripard * specified by the electrical characteristics of the board. 11210e589d5fSMaxime Ripard */ 11220e589d5fSMaxime Ripard mstrclk = clk_get_rate(st->clk); 11230e589d5fSMaxime Ripard adc_clk = clk_get_rate(st->adc_clk); 1124db10e201SJosh Wu adc_clk_khz = adc_clk / 1000; 1125c8b11de0SJosh Wu 1126c8b11de0SJosh Wu dev_dbg(&pdev->dev, "Master clock is set as: %d Hz, adc_clk should set as: %d Hz\n", 1127c8b11de0SJosh Wu mstrclk, adc_clk); 1128c8b11de0SJosh Wu 11290e589d5fSMaxime Ripard prsc = (mstrclk / (2 * adc_clk)) - 1; 11300e589d5fSMaxime Ripard 11310e589d5fSMaxime Ripard if (!st->startup_time) { 11320e589d5fSMaxime Ripard dev_err(&pdev->dev, "No startup time available.\n"); 11330e589d5fSMaxime Ripard ret = -EINVAL; 11340e589d5fSMaxime Ripard goto error_disable_adc_clk; 11350e589d5fSMaxime Ripard } 1136c4601666SJosh Wu ticks = (*st->caps->calc_startup_ticks)(st->startup_time, adc_clk_khz); 11370e589d5fSMaxime Ripard 11380e589d5fSMaxime Ripard /* 1139beca9e76SJean-Christophe PLAGNIOL-VILLARD * a minimal Sample and Hold Time is necessary for the ADC to guarantee 1140beca9e76SJean-Christophe PLAGNIOL-VILLARD * the best converted final value between two channels selection 1141beca9e76SJean-Christophe PLAGNIOL-VILLARD * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock 1142beca9e76SJean-Christophe PLAGNIOL-VILLARD */ 11438f32b6baSAlexandre Belloni if (st->sample_hold_time > 0) 11448f32b6baSAlexandre Belloni shtim = round_up((st->sample_hold_time * adc_clk_khz / 1000) 11458f32b6baSAlexandre Belloni - 1, 1); 11468f32b6baSAlexandre Belloni else 11478f32b6baSAlexandre Belloni shtim = 0; 1148beca9e76SJean-Christophe PLAGNIOL-VILLARD 11499120c0beSJosh Wu reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask; 11509120c0beSJosh Wu reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask; 11515eb39ef8SAlexandre Belloni if (st->res == st->caps->low_res_bits) 1152e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_LOWRES; 1153e748783cSJean-Christophe PLAGNIOL-VILLARD if (st->sleep_mode) 1154e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_SLEEP; 1155beca9e76SJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_SHTIM_(shtim) & AT91_ADC_SHTIM; 1156e748783cSJean-Christophe PLAGNIOL-VILLARD at91_adc_writel(st, AT91_ADC_MR, reg); 11570e589d5fSMaxime Ripard 11580e589d5fSMaxime Ripard /* Setup the ADC channels available on the board */ 11590e589d5fSMaxime Ripard ret = at91_adc_channel_init(idev); 11600e589d5fSMaxime Ripard if (ret < 0) { 11610e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't initialize the channels.\n"); 11620e589d5fSMaxime Ripard goto error_disable_adc_clk; 11630e589d5fSMaxime Ripard } 11640e589d5fSMaxime Ripard 11650e589d5fSMaxime Ripard init_waitqueue_head(&st->wq_data_avail); 11660e589d5fSMaxime Ripard mutex_init(&st->lock); 11670e589d5fSMaxime Ripard 1168c8b11de0SJosh Wu /* 1169c8b11de0SJosh Wu * Since touch screen will set trigger register as period trigger. So 1170c8b11de0SJosh Wu * when touch screen is enabled, then we have to disable hardware 1171c8b11de0SJosh Wu * trigger for classic adc. 1172c8b11de0SJosh Wu */ 1173c8b11de0SJosh Wu if (!st->touchscreen_type) { 11740e589d5fSMaxime Ripard ret = at91_adc_buffer_init(idev); 11750e589d5fSMaxime Ripard if (ret < 0) { 11760e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't initialize the buffer.\n"); 11770e589d5fSMaxime Ripard goto error_disable_adc_clk; 11780e589d5fSMaxime Ripard } 11790e589d5fSMaxime Ripard 11800e589d5fSMaxime Ripard ret = at91_adc_trigger_init(idev); 11810e589d5fSMaxime Ripard if (ret < 0) { 11820e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't setup the triggers.\n"); 1183c8b11de0SJosh Wu at91_adc_buffer_remove(idev); 1184c8b11de0SJosh Wu goto error_disable_adc_clk; 1185c8b11de0SJosh Wu } 1186c8b11de0SJosh Wu } else { 1187044d406aSAlexandru Ardelean ret = at91_ts_register(idev, pdev); 1188c8b11de0SJosh Wu if (ret) 1189c8b11de0SJosh Wu goto error_disable_adc_clk; 1190c8b11de0SJosh Wu 1191044d406aSAlexandru Ardelean at91_ts_hw_init(idev, adc_clk_khz); 11920e589d5fSMaxime Ripard } 11930e589d5fSMaxime Ripard 11940e589d5fSMaxime Ripard ret = iio_device_register(idev); 11950e589d5fSMaxime Ripard if (ret < 0) { 11960e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't register the device.\n"); 1197c8b11de0SJosh Wu goto error_iio_device_register; 11980e589d5fSMaxime Ripard } 11990e589d5fSMaxime Ripard 12000e589d5fSMaxime Ripard return 0; 12010e589d5fSMaxime Ripard 1202c8b11de0SJosh Wu error_iio_device_register: 1203c8b11de0SJosh Wu if (!st->touchscreen_type) { 12040e589d5fSMaxime Ripard at91_adc_trigger_remove(idev); 12050e589d5fSMaxime Ripard at91_adc_buffer_remove(idev); 1206c8b11de0SJosh Wu } else { 1207c8b11de0SJosh Wu at91_ts_unregister(st); 1208c8b11de0SJosh Wu } 12090e589d5fSMaxime Ripard error_disable_adc_clk: 121000062a9cSJulia Lawall clk_disable_unprepare(st->adc_clk); 12110e589d5fSMaxime Ripard error_disable_clk: 121200062a9cSJulia Lawall clk_disable_unprepare(st->clk); 12130e589d5fSMaxime Ripard error_free_irq: 12140e589d5fSMaxime Ripard free_irq(st->irq, idev); 12150e589d5fSMaxime Ripard return ret; 12160e589d5fSMaxime Ripard } 12170e589d5fSMaxime Ripard 1218fc52692cSGreg Kroah-Hartman static int at91_adc_remove(struct platform_device *pdev) 12190e589d5fSMaxime Ripard { 12200e589d5fSMaxime Ripard struct iio_dev *idev = platform_get_drvdata(pdev); 12210e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 12220e589d5fSMaxime Ripard 12230e589d5fSMaxime Ripard iio_device_unregister(idev); 1224c8b11de0SJosh Wu if (!st->touchscreen_type) { 12250e589d5fSMaxime Ripard at91_adc_trigger_remove(idev); 12260e589d5fSMaxime Ripard at91_adc_buffer_remove(idev); 1227c8b11de0SJosh Wu } else { 1228c8b11de0SJosh Wu at91_ts_unregister(st); 1229c8b11de0SJosh Wu } 12300e589d5fSMaxime Ripard clk_disable_unprepare(st->adc_clk); 123100062a9cSJulia Lawall clk_disable_unprepare(st->clk); 12320e589d5fSMaxime Ripard free_irq(st->irq, idev); 12330e589d5fSMaxime Ripard 12340e589d5fSMaxime Ripard return 0; 12350e589d5fSMaxime Ripard } 12360e589d5fSMaxime Ripard 1237bc3ae982SWenyou Yang static int at91_adc_suspend(struct device *dev) 1238bc3ae982SWenyou Yang { 1239e3faedf7SKefeng Wang struct iio_dev *idev = dev_get_drvdata(dev); 1240bc3ae982SWenyou Yang struct at91_adc_state *st = iio_priv(idev); 1241bc3ae982SWenyou Yang 1242bc3ae982SWenyou Yang pinctrl_pm_select_sleep_state(dev); 1243bc3ae982SWenyou Yang clk_disable_unprepare(st->clk); 1244bc3ae982SWenyou Yang 1245bc3ae982SWenyou Yang return 0; 1246bc3ae982SWenyou Yang } 1247bc3ae982SWenyou Yang 1248bc3ae982SWenyou Yang static int at91_adc_resume(struct device *dev) 1249bc3ae982SWenyou Yang { 1250e3faedf7SKefeng Wang struct iio_dev *idev = dev_get_drvdata(dev); 1251bc3ae982SWenyou Yang struct at91_adc_state *st = iio_priv(idev); 1252bc3ae982SWenyou Yang 1253bc3ae982SWenyou Yang clk_prepare_enable(st->clk); 1254bc3ae982SWenyou Yang pinctrl_pm_select_default_state(dev); 1255bc3ae982SWenyou Yang 1256bc3ae982SWenyou Yang return 0; 1257bc3ae982SWenyou Yang } 1258bc3ae982SWenyou Yang 1259*19e2ed80SJonathan Cameron static DEFINE_SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, 1260*19e2ed80SJonathan Cameron at91_adc_resume); 1261bc3ae982SWenyou Yang 126209d4726bSAlexandre Belloni static const struct at91_adc_trigger at91sam9260_triggers[] = { 126309d4726bSAlexandre Belloni { .name = "timer-counter-0", .value = 0x1 }, 126409d4726bSAlexandre Belloni { .name = "timer-counter-1", .value = 0x3 }, 126509d4726bSAlexandre Belloni { .name = "timer-counter-2", .value = 0x5 }, 126609d4726bSAlexandre Belloni { .name = "external", .value = 0xd, .is_external = true }, 126709d4726bSAlexandre Belloni }; 126809d4726bSAlexandre Belloni 1269e1811f97SJosh Wu static struct at91_adc_caps at91sam9260_caps = { 1270c4601666SJosh Wu .calc_startup_ticks = calc_startup_ticks_9260, 12712b6d598bSJosh Wu .num_channels = 4, 12725eb39ef8SAlexandre Belloni .low_res_bits = 8, 12735eb39ef8SAlexandre Belloni .high_res_bits = 10, 1274e1811f97SJosh Wu .registers = { 1275e1811f97SJosh Wu .channel_base = AT91_ADC_CHR(0), 1276e1811f97SJosh Wu .drdy_mask = AT91_ADC_DRDY, 1277e1811f97SJosh Wu .status_register = AT91_ADC_SR, 1278e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9260, 12799120c0beSJosh Wu .mr_prescal_mask = AT91_ADC_PRESCAL_9260, 12809120c0beSJosh Wu .mr_startup_mask = AT91_ADC_STARTUP_9260, 1281e1811f97SJosh Wu }, 128209d4726bSAlexandre Belloni .triggers = at91sam9260_triggers, 128309d4726bSAlexandre Belloni .trigger_number = ARRAY_SIZE(at91sam9260_triggers), 128409d4726bSAlexandre Belloni }; 128509d4726bSAlexandre Belloni 128609d4726bSAlexandre Belloni static const struct at91_adc_trigger at91sam9x5_triggers[] = { 128709d4726bSAlexandre Belloni { .name = "external-rising", .value = 0x1, .is_external = true }, 128809d4726bSAlexandre Belloni { .name = "external-falling", .value = 0x2, .is_external = true }, 128909d4726bSAlexandre Belloni { .name = "external-any", .value = 0x3, .is_external = true }, 129009d4726bSAlexandre Belloni { .name = "continuous", .value = 0x6 }, 1291e1811f97SJosh Wu }; 1292e1811f97SJosh Wu 129365b1fdbaSAlexandre Belloni static struct at91_adc_caps at91sam9rl_caps = { 129465b1fdbaSAlexandre Belloni .has_ts = true, 129565b1fdbaSAlexandre Belloni .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */ 129665b1fdbaSAlexandre Belloni .num_channels = 6, 12975eb39ef8SAlexandre Belloni .low_res_bits = 8, 12985eb39ef8SAlexandre Belloni .high_res_bits = 10, 129965b1fdbaSAlexandre Belloni .registers = { 130065b1fdbaSAlexandre Belloni .channel_base = AT91_ADC_CHR(0), 130165b1fdbaSAlexandre Belloni .drdy_mask = AT91_ADC_DRDY, 130265b1fdbaSAlexandre Belloni .status_register = AT91_ADC_SR, 130365b1fdbaSAlexandre Belloni .trigger_register = AT91_ADC_TRGR_9G45, 130465b1fdbaSAlexandre Belloni .mr_prescal_mask = AT91_ADC_PRESCAL_9260, 130565b1fdbaSAlexandre Belloni .mr_startup_mask = AT91_ADC_STARTUP_9G45, 130665b1fdbaSAlexandre Belloni }, 130709d4726bSAlexandre Belloni .triggers = at91sam9x5_triggers, 130809d4726bSAlexandre Belloni .trigger_number = ARRAY_SIZE(at91sam9x5_triggers), 130965b1fdbaSAlexandre Belloni }; 131065b1fdbaSAlexandre Belloni 1311e1811f97SJosh Wu static struct at91_adc_caps at91sam9g45_caps = { 1312c8b11de0SJosh Wu .has_ts = true, 1313c4601666SJosh Wu .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */ 13142b6d598bSJosh Wu .num_channels = 8, 13155eb39ef8SAlexandre Belloni .low_res_bits = 8, 13165eb39ef8SAlexandre Belloni .high_res_bits = 10, 1317e1811f97SJosh Wu .registers = { 1318e1811f97SJosh Wu .channel_base = AT91_ADC_CHR(0), 1319e1811f97SJosh Wu .drdy_mask = AT91_ADC_DRDY, 1320e1811f97SJosh Wu .status_register = AT91_ADC_SR, 1321e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9G45, 13229120c0beSJosh Wu .mr_prescal_mask = AT91_ADC_PRESCAL_9G45, 13239120c0beSJosh Wu .mr_startup_mask = AT91_ADC_STARTUP_9G45, 1324e1811f97SJosh Wu }, 132509d4726bSAlexandre Belloni .triggers = at91sam9x5_triggers, 132609d4726bSAlexandre Belloni .trigger_number = ARRAY_SIZE(at91sam9x5_triggers), 1327e1811f97SJosh Wu }; 1328e1811f97SJosh Wu 1329e1811f97SJosh Wu static struct at91_adc_caps at91sam9x5_caps = { 1330c8b11de0SJosh Wu .has_ts = true, 1331c8b11de0SJosh Wu .has_tsmr = true, 1332c8b11de0SJosh Wu .ts_filter_average = 3, 1333c8b11de0SJosh Wu .ts_pen_detect_sensitivity = 2, 1334c4601666SJosh Wu .calc_startup_ticks = calc_startup_ticks_9x5, 13352b6d598bSJosh Wu .num_channels = 12, 13365eb39ef8SAlexandre Belloni .low_res_bits = 8, 13375eb39ef8SAlexandre Belloni .high_res_bits = 10, 1338e1811f97SJosh Wu .registers = { 1339e1811f97SJosh Wu .channel_base = AT91_ADC_CDR0_9X5, 1340e1811f97SJosh Wu .drdy_mask = AT91_ADC_SR_DRDY_9X5, 1341e1811f97SJosh Wu .status_register = AT91_ADC_SR_9X5, 1342e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9X5, 13439120c0beSJosh Wu /* prescal mask is same as 9G45 */ 13449120c0beSJosh Wu .mr_prescal_mask = AT91_ADC_PRESCAL_9G45, 13459120c0beSJosh Wu .mr_startup_mask = AT91_ADC_STARTUP_9X5, 1346e1811f97SJosh Wu }, 134709d4726bSAlexandre Belloni .triggers = at91sam9x5_triggers, 134809d4726bSAlexandre Belloni .trigger_number = ARRAY_SIZE(at91sam9x5_triggers), 1349e1811f97SJosh Wu }; 1350e1811f97SJosh Wu 13515eb39ef8SAlexandre Belloni static struct at91_adc_caps sama5d3_caps = { 13525eb39ef8SAlexandre Belloni .has_ts = true, 13535eb39ef8SAlexandre Belloni .has_tsmr = true, 13545eb39ef8SAlexandre Belloni .ts_filter_average = 3, 13555eb39ef8SAlexandre Belloni .ts_pen_detect_sensitivity = 2, 13565eb39ef8SAlexandre Belloni .calc_startup_ticks = calc_startup_ticks_9x5, 13575eb39ef8SAlexandre Belloni .num_channels = 12, 13585eb39ef8SAlexandre Belloni .low_res_bits = 0, 13595eb39ef8SAlexandre Belloni .high_res_bits = 12, 13605eb39ef8SAlexandre Belloni .registers = { 13615eb39ef8SAlexandre Belloni .channel_base = AT91_ADC_CDR0_9X5, 13625eb39ef8SAlexandre Belloni .drdy_mask = AT91_ADC_SR_DRDY_9X5, 13635eb39ef8SAlexandre Belloni .status_register = AT91_ADC_SR_9X5, 13645eb39ef8SAlexandre Belloni .trigger_register = AT91_ADC_TRGR_9X5, 13655eb39ef8SAlexandre Belloni .mr_prescal_mask = AT91_ADC_PRESCAL_9G45, 13665eb39ef8SAlexandre Belloni .mr_startup_mask = AT91_ADC_STARTUP_9X5, 13675eb39ef8SAlexandre Belloni }, 136809d4726bSAlexandre Belloni .triggers = at91sam9x5_triggers, 136909d4726bSAlexandre Belloni .trigger_number = ARRAY_SIZE(at91sam9x5_triggers), 13705eb39ef8SAlexandre Belloni }; 13715eb39ef8SAlexandre Belloni 1372e364185fSMaxime Ripard static const struct of_device_id at91_adc_dt_ids[] = { 1373e1811f97SJosh Wu { .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps }, 137465b1fdbaSAlexandre Belloni { .compatible = "atmel,at91sam9rl-adc", .data = &at91sam9rl_caps }, 1375e1811f97SJosh Wu { .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps }, 1376e1811f97SJosh Wu { .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps }, 13775eb39ef8SAlexandre Belloni { .compatible = "atmel,sama5d3-adc", .data = &sama5d3_caps }, 1378e364185fSMaxime Ripard {}, 1379e364185fSMaxime Ripard }; 1380e364185fSMaxime Ripard MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); 1381467a44b0SAlexandre Belloni 13820e589d5fSMaxime Ripard static struct platform_driver at91_adc_driver = { 13830e589d5fSMaxime Ripard .probe = at91_adc_probe, 1384fc52692cSGreg Kroah-Hartman .remove = at91_adc_remove, 13850e589d5fSMaxime Ripard .driver = { 1386c8b11de0SJosh Wu .name = DRIVER_NAME, 1387f091d7c5SAlexandru Ardelean .of_match_table = at91_adc_dt_ids, 1388*19e2ed80SJonathan Cameron .pm = pm_sleep_ptr(&at91_adc_pm_ops), 13890e589d5fSMaxime Ripard }, 13900e589d5fSMaxime Ripard }; 13910e589d5fSMaxime Ripard 13920e589d5fSMaxime Ripard module_platform_driver(at91_adc_driver); 13930e589d5fSMaxime Ripard 13940e589d5fSMaxime Ripard MODULE_LICENSE("GPL"); 13950e589d5fSMaxime Ripard MODULE_DESCRIPTION("Atmel AT91 ADC Driver"); 13960e589d5fSMaxime Ripard MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 1397