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 154*ead1c9f3SAlexandru Ardelean enum atmel_adc_ts_type { 155*ead1c9f3SAlexandru Ardelean ATMEL_ADC_TOUCHSCREEN_NONE = 0, 156*ead1c9f3SAlexandru Ardelean ATMEL_ADC_TOUCHSCREEN_4WIRE = 4, 157*ead1c9f3SAlexandru Ardelean ATMEL_ADC_TOUCHSCREEN_5WIRE = 5, 158*ead1c9f3SAlexandru Ardelean }; 159*ead1c9f3SAlexandru Ardelean 160*ead1c9f3SAlexandru Ardelean /** 161*ead1c9f3SAlexandru Ardelean * struct at91_adc_trigger - description of triggers 162*ead1c9f3SAlexandru Ardelean * @name: name of the trigger advertised to the user 163*ead1c9f3SAlexandru Ardelean * @value: value to set in the ADC's trigger setup register 164*ead1c9f3SAlexandru Ardelean * to enable the trigger 165*ead1c9f3SAlexandru Ardelean * @is_external: Does the trigger rely on an external pin? 166*ead1c9f3SAlexandru Ardelean */ 167*ead1c9f3SAlexandru Ardelean struct at91_adc_trigger { 168*ead1c9f3SAlexandru Ardelean const char *name; 169*ead1c9f3SAlexandru Ardelean u8 value; 170*ead1c9f3SAlexandru Ardelean bool is_external; 171*ead1c9f3SAlexandru Ardelean }; 172*ead1c9f3SAlexandru 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; 207e1811f97SJosh Wu struct at91_adc_reg_desc registers; 208e1811f97SJosh Wu }; 209e1811f97SJosh Wu 2100e589d5fSMaxime Ripard struct at91_adc_state { 2110e589d5fSMaxime Ripard struct clk *adc_clk; 2120e589d5fSMaxime Ripard u16 *buffer; 2130e589d5fSMaxime Ripard unsigned long channels_mask; 2140e589d5fSMaxime Ripard struct clk *clk; 2150e589d5fSMaxime Ripard bool done; 2160e589d5fSMaxime Ripard int irq; 2170e589d5fSMaxime Ripard u16 last_value; 218d4f51956SLudovic Desroches int chnb; 2190e589d5fSMaxime Ripard struct mutex lock; 2200e589d5fSMaxime Ripard u8 num_channels; 2210e589d5fSMaxime Ripard void __iomem *reg_base; 2223e4ef8e8SAlexandru Ardelean const struct at91_adc_reg_desc *registers; 2232ab5f39bSJan Leupold u32 startup_time; 224beca9e76SJean-Christophe PLAGNIOL-VILLARD u8 sample_hold_time; 225e748783cSJean-Christophe PLAGNIOL-VILLARD bool sleep_mode; 2260e589d5fSMaxime Ripard struct iio_trigger **trig; 2270e589d5fSMaxime Ripard struct at91_adc_trigger *trigger_list; 2280e589d5fSMaxime Ripard u32 trigger_number; 2290e589d5fSMaxime Ripard bool use_external; 2300e589d5fSMaxime Ripard u32 vref_mv; 23147be16b6SLudovic Desroches u32 res; /* resolution used for convertions */ 23247be16b6SLudovic Desroches bool low_res; /* the resolution corresponds to the lowest one */ 2330e589d5fSMaxime Ripard wait_queue_head_t wq_data_avail; 2343e4ef8e8SAlexandru Ardelean const struct at91_adc_caps *caps; 235c8b11de0SJosh Wu 236c8b11de0SJosh Wu /* 237c8b11de0SJosh Wu * Following ADC channels are shared by touchscreen: 238c8b11de0SJosh Wu * 239c8b11de0SJosh Wu * CH0 -- Touch screen XP/UL 240c8b11de0SJosh Wu * CH1 -- Touch screen XM/UR 241c8b11de0SJosh Wu * CH2 -- Touch screen YP/LL 242c8b11de0SJosh Wu * CH3 -- Touch screen YM/Sense 243c8b11de0SJosh Wu * CH4 -- Touch screen LR(5-wire only) 244c8b11de0SJosh Wu * 245c8b11de0SJosh Wu * The bitfields below represents the reserved channel in the 246c8b11de0SJosh Wu * touchscreen mode. 247c8b11de0SJosh Wu */ 248c8b11de0SJosh Wu #define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 0) 249c8b11de0SJosh Wu #define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 0) 250c8b11de0SJosh Wu enum atmel_adc_ts_type touchscreen_type; 251c8b11de0SJosh Wu struct input_dev *ts_input; 252c8b11de0SJosh Wu 253c8b11de0SJosh Wu u16 ts_sample_period_val; 254c8b11de0SJosh Wu u32 ts_pressure_threshold; 25584882b06SAlexandre Belloni u16 ts_pendbc; 25684882b06SAlexandre Belloni 25784882b06SAlexandre Belloni bool ts_bufferedmeasure; 25884882b06SAlexandre Belloni u32 ts_prev_absx; 25984882b06SAlexandre Belloni u32 ts_prev_absy; 2600e589d5fSMaxime Ripard }; 2610e589d5fSMaxime Ripard 2620e589d5fSMaxime Ripard static irqreturn_t at91_adc_trigger_handler(int irq, void *p) 2630e589d5fSMaxime Ripard { 2640e589d5fSMaxime Ripard struct iio_poll_func *pf = p; 2650e589d5fSMaxime Ripard struct iio_dev *idev = pf->indio_dev; 2660e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 267aea835f2SEugen Hristev struct iio_chan_spec const *chan; 2680e589d5fSMaxime Ripard int i, j = 0; 2690e589d5fSMaxime Ripard 2700e589d5fSMaxime Ripard for (i = 0; i < idev->masklength; i++) { 2710e589d5fSMaxime Ripard if (!test_bit(i, idev->active_scan_mask)) 2720e589d5fSMaxime Ripard continue; 273aea835f2SEugen Hristev chan = idev->channels + i; 274aea835f2SEugen Hristev st->buffer[j] = at91_adc_readl(st, AT91_ADC_CHAN(st, chan->channel)); 2750e589d5fSMaxime Ripard j++; 2760e589d5fSMaxime Ripard } 2770e589d5fSMaxime Ripard 278e79cece0SLars-Peter Clausen iio_push_to_buffers_with_timestamp(idev, st->buffer, pf->timestamp); 2790e589d5fSMaxime Ripard 2800e589d5fSMaxime Ripard iio_trigger_notify_done(idev->trig); 2810e589d5fSMaxime Ripard 2820e589d5fSMaxime Ripard /* Needed to ACK the DRDY interruption */ 2830e589d5fSMaxime Ripard at91_adc_readl(st, AT91_ADC_LCDR); 2840e589d5fSMaxime Ripard 2850e589d5fSMaxime Ripard enable_irq(st->irq); 2860e589d5fSMaxime Ripard 2870e589d5fSMaxime Ripard return IRQ_HANDLED; 2880e589d5fSMaxime Ripard } 2890e589d5fSMaxime Ripard 290c8b11de0SJosh Wu /* Handler for classic adc channel eoc trigger */ 2913068ab20SJosh Wu static void handle_adc_eoc_trigger(int irq, struct iio_dev *idev) 2920e589d5fSMaxime Ripard { 2930e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 2940e589d5fSMaxime Ripard 2950e589d5fSMaxime Ripard if (iio_buffer_enabled(idev)) { 2960e589d5fSMaxime Ripard disable_irq_nosync(irq); 297398fd22bSPeter Meerwald iio_trigger_poll(idev->trig); 2980e589d5fSMaxime Ripard } else { 299d4f51956SLudovic Desroches st->last_value = at91_adc_readl(st, AT91_ADC_CHAN(st, st->chnb)); 300bc1b4532SEugen Hristev /* Needed to ACK the DRDY interruption */ 301bc1b4532SEugen Hristev at91_adc_readl(st, AT91_ADC_LCDR); 3020e589d5fSMaxime Ripard st->done = true; 3030e589d5fSMaxime Ripard wake_up_interruptible(&st->wq_data_avail); 3040e589d5fSMaxime Ripard } 305c8b11de0SJosh Wu } 306c8b11de0SJosh Wu 307044d406aSAlexandru Ardelean static int at91_ts_sample(struct iio_dev *idev) 308c8b11de0SJosh Wu { 309044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 310c8b11de0SJosh Wu unsigned int xscale, yscale, reg, z1, z2; 311c8b11de0SJosh Wu unsigned int x, y, pres, xpos, ypos; 312c8b11de0SJosh Wu unsigned int rxp = 1; 313c8b11de0SJosh Wu unsigned int factor = 1000; 314c8b11de0SJosh Wu 315c8b11de0SJosh Wu unsigned int xyz_mask_bits = st->res; 316c8b11de0SJosh Wu unsigned int xyz_mask = (1 << xyz_mask_bits) - 1; 317c8b11de0SJosh Wu 318c8b11de0SJosh Wu /* calculate position */ 319c8b11de0SJosh Wu /* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */ 320c8b11de0SJosh Wu reg = at91_adc_readl(st, AT91_ADC_TSXPOSR); 321c8b11de0SJosh Wu xpos = reg & xyz_mask; 322c8b11de0SJosh Wu x = (xpos << MAX_POS_BITS) - xpos; 323c8b11de0SJosh Wu xscale = (reg >> 16) & xyz_mask; 324c8b11de0SJosh Wu if (xscale == 0) { 325c8b11de0SJosh Wu dev_err(&idev->dev, "Error: xscale == 0!\n"); 326c8b11de0SJosh Wu return -1; 327c8b11de0SJosh Wu } 328c8b11de0SJosh Wu x /= xscale; 329c8b11de0SJosh Wu 330c8b11de0SJosh Wu /* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */ 331c8b11de0SJosh Wu reg = at91_adc_readl(st, AT91_ADC_TSYPOSR); 332c8b11de0SJosh Wu ypos = reg & xyz_mask; 333c8b11de0SJosh Wu y = (ypos << MAX_POS_BITS) - ypos; 334c8b11de0SJosh Wu yscale = (reg >> 16) & xyz_mask; 335c8b11de0SJosh Wu if (yscale == 0) { 336c8b11de0SJosh Wu dev_err(&idev->dev, "Error: yscale == 0!\n"); 337c8b11de0SJosh Wu return -1; 338c8b11de0SJosh Wu } 339c8b11de0SJosh Wu y /= yscale; 340c8b11de0SJosh Wu 341c8b11de0SJosh Wu /* calculate the pressure */ 342c8b11de0SJosh Wu reg = at91_adc_readl(st, AT91_ADC_TSPRESSR); 343c8b11de0SJosh Wu z1 = reg & xyz_mask; 344c8b11de0SJosh Wu z2 = (reg >> 16) & xyz_mask; 345c8b11de0SJosh Wu 346c8b11de0SJosh Wu if (z1 != 0) 347c8b11de0SJosh Wu pres = rxp * (x * factor / 1024) * (z2 * factor / z1 - factor) 348c8b11de0SJosh Wu / factor; 349c8b11de0SJosh Wu else 350c8b11de0SJosh Wu pres = st->ts_pressure_threshold; /* no pen contacted */ 351c8b11de0SJosh Wu 352c8b11de0SJosh Wu dev_dbg(&idev->dev, "xpos = %d, xscale = %d, ypos = %d, yscale = %d, z1 = %d, z2 = %d, press = %d\n", 353c8b11de0SJosh Wu xpos, xscale, ypos, yscale, z1, z2, pres); 354c8b11de0SJosh Wu 355c8b11de0SJosh Wu if (pres < st->ts_pressure_threshold) { 356c8b11de0SJosh Wu dev_dbg(&idev->dev, "x = %d, y = %d, pressure = %d\n", 357c8b11de0SJosh Wu x, y, pres / factor); 358c8b11de0SJosh Wu input_report_abs(st->ts_input, ABS_X, x); 359c8b11de0SJosh Wu input_report_abs(st->ts_input, ABS_Y, y); 360c8b11de0SJosh Wu input_report_abs(st->ts_input, ABS_PRESSURE, pres); 361c8b11de0SJosh Wu input_report_key(st->ts_input, BTN_TOUCH, 1); 362c8b11de0SJosh Wu input_sync(st->ts_input); 363c8b11de0SJosh Wu } else { 364c8b11de0SJosh Wu dev_dbg(&idev->dev, "pressure too low: not reporting\n"); 365c8b11de0SJosh Wu } 366c8b11de0SJosh Wu 367c8b11de0SJosh Wu return 0; 368c8b11de0SJosh Wu } 369c8b11de0SJosh Wu 37084882b06SAlexandre Belloni static irqreturn_t at91_adc_rl_interrupt(int irq, void *private) 37184882b06SAlexandre Belloni { 37284882b06SAlexandre Belloni struct iio_dev *idev = private; 37384882b06SAlexandre Belloni struct at91_adc_state *st = iio_priv(idev); 37484882b06SAlexandre Belloni u32 status = at91_adc_readl(st, st->registers->status_register); 37584882b06SAlexandre Belloni unsigned int reg; 37684882b06SAlexandre Belloni 37784882b06SAlexandre Belloni status &= at91_adc_readl(st, AT91_ADC_IMR); 378d4f51956SLudovic Desroches if (status & GENMASK(st->num_channels - 1, 0)) 37984882b06SAlexandre Belloni handle_adc_eoc_trigger(irq, idev); 38084882b06SAlexandre Belloni 38184882b06SAlexandre Belloni if (status & AT91RL_ADC_IER_PEN) { 38284882b06SAlexandre Belloni /* Disabling pen debounce is required to get a NOPEN irq */ 38384882b06SAlexandre Belloni reg = at91_adc_readl(st, AT91_ADC_MR); 38484882b06SAlexandre Belloni reg &= ~AT91_ADC_PENDBC; 38584882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_MR, reg); 38684882b06SAlexandre Belloni 38784882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); 38884882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_NOPEN 38984882b06SAlexandre Belloni | AT91_ADC_EOC(3)); 39084882b06SAlexandre Belloni /* Set up period trigger for sampling */ 39184882b06SAlexandre Belloni at91_adc_writel(st, st->registers->trigger_register, 39284882b06SAlexandre Belloni AT91_ADC_TRGR_MOD_PERIOD_TRIG | 39384882b06SAlexandre Belloni AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val)); 39484882b06SAlexandre Belloni } else if (status & AT91RL_ADC_IER_NOPEN) { 39584882b06SAlexandre Belloni reg = at91_adc_readl(st, AT91_ADC_MR); 39684882b06SAlexandre Belloni reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; 39784882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_MR, reg); 39884882b06SAlexandre Belloni at91_adc_writel(st, st->registers->trigger_register, 39984882b06SAlexandre Belloni AT91_ADC_TRGR_NONE); 40084882b06SAlexandre Belloni 40184882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_NOPEN 40284882b06SAlexandre Belloni | AT91_ADC_EOC(3)); 40384882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); 40484882b06SAlexandre Belloni st->ts_bufferedmeasure = false; 40584882b06SAlexandre Belloni input_report_key(st->ts_input, BTN_TOUCH, 0); 40684882b06SAlexandre Belloni input_sync(st->ts_input); 407c2ab4474SAnders Darander } else if (status & AT91_ADC_EOC(3) && st->ts_input) { 408c2ab4474SAnders Darander /* Conversion finished and we've a touchscreen */ 40984882b06SAlexandre Belloni if (st->ts_bufferedmeasure) { 41084882b06SAlexandre Belloni /* 41184882b06SAlexandre Belloni * Last measurement is always discarded, since it can 41284882b06SAlexandre Belloni * be erroneous. 41384882b06SAlexandre Belloni * Always report previous measurement 41484882b06SAlexandre Belloni */ 41584882b06SAlexandre Belloni input_report_abs(st->ts_input, ABS_X, st->ts_prev_absx); 41684882b06SAlexandre Belloni input_report_abs(st->ts_input, ABS_Y, st->ts_prev_absy); 41784882b06SAlexandre Belloni input_report_key(st->ts_input, BTN_TOUCH, 1); 41884882b06SAlexandre Belloni input_sync(st->ts_input); 41984882b06SAlexandre Belloni } else 42084882b06SAlexandre Belloni st->ts_bufferedmeasure = true; 42184882b06SAlexandre Belloni 42284882b06SAlexandre Belloni /* Now make new measurement */ 42384882b06SAlexandre Belloni st->ts_prev_absx = at91_adc_readl(st, AT91_ADC_CHAN(st, 3)) 42484882b06SAlexandre Belloni << MAX_RLPOS_BITS; 42584882b06SAlexandre Belloni st->ts_prev_absx /= at91_adc_readl(st, AT91_ADC_CHAN(st, 2)); 42684882b06SAlexandre Belloni 42784882b06SAlexandre Belloni st->ts_prev_absy = at91_adc_readl(st, AT91_ADC_CHAN(st, 1)) 42884882b06SAlexandre Belloni << MAX_RLPOS_BITS; 42984882b06SAlexandre Belloni st->ts_prev_absy /= at91_adc_readl(st, AT91_ADC_CHAN(st, 0)); 43084882b06SAlexandre Belloni } 43184882b06SAlexandre Belloni 43284882b06SAlexandre Belloni return IRQ_HANDLED; 43384882b06SAlexandre Belloni } 43484882b06SAlexandre Belloni 43584882b06SAlexandre Belloni static irqreturn_t at91_adc_9x5_interrupt(int irq, void *private) 436c8b11de0SJosh Wu { 437c8b11de0SJosh Wu struct iio_dev *idev = private; 438c8b11de0SJosh Wu struct at91_adc_state *st = iio_priv(idev); 439c8b11de0SJosh Wu u32 status = at91_adc_readl(st, st->registers->status_register); 440c8b11de0SJosh Wu const uint32_t ts_data_irq_mask = 441c8b11de0SJosh Wu AT91_ADC_IER_XRDY | 442c8b11de0SJosh Wu AT91_ADC_IER_YRDY | 443c8b11de0SJosh Wu AT91_ADC_IER_PRDY; 444c8b11de0SJosh Wu 445d4f51956SLudovic Desroches if (status & GENMASK(st->num_channels - 1, 0)) 446c8b11de0SJosh Wu handle_adc_eoc_trigger(irq, idev); 447c8b11de0SJosh Wu 448c8b11de0SJosh Wu if (status & AT91_ADC_IER_PEN) { 449c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); 450c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_NOPEN | 451c8b11de0SJosh Wu ts_data_irq_mask); 452c8b11de0SJosh Wu /* Set up period trigger for sampling */ 453c8b11de0SJosh Wu at91_adc_writel(st, st->registers->trigger_register, 454c8b11de0SJosh Wu AT91_ADC_TRGR_MOD_PERIOD_TRIG | 455c8b11de0SJosh Wu AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val)); 456c8b11de0SJosh Wu } else if (status & AT91_ADC_IER_NOPEN) { 457c8b11de0SJosh Wu at91_adc_writel(st, st->registers->trigger_register, 0); 458c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_NOPEN | 459c8b11de0SJosh Wu ts_data_irq_mask); 460c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); 461c8b11de0SJosh Wu 462c8b11de0SJosh Wu input_report_key(st->ts_input, BTN_TOUCH, 0); 463c8b11de0SJosh Wu input_sync(st->ts_input); 464c8b11de0SJosh Wu } else if ((status & ts_data_irq_mask) == ts_data_irq_mask) { 465c8b11de0SJosh Wu /* Now all touchscreen data is ready */ 466c8b11de0SJosh Wu 467c8b11de0SJosh Wu if (status & AT91_ADC_ISR_PENS) { 468c8b11de0SJosh Wu /* validate data by pen contact */ 469044d406aSAlexandru Ardelean at91_ts_sample(idev); 470c8b11de0SJosh Wu } else { 471c8b11de0SJosh Wu /* triggered by event that is no pen contact, just read 472c8b11de0SJosh Wu * them to clean the interrupt and discard all. 473c8b11de0SJosh Wu */ 474c8b11de0SJosh Wu at91_adc_readl(st, AT91_ADC_TSXPOSR); 475c8b11de0SJosh Wu at91_adc_readl(st, AT91_ADC_TSYPOSR); 476c8b11de0SJosh Wu at91_adc_readl(st, AT91_ADC_TSPRESSR); 477c8b11de0SJosh Wu } 478c8b11de0SJosh Wu } 4790e589d5fSMaxime Ripard 4800e589d5fSMaxime Ripard return IRQ_HANDLED; 4810e589d5fSMaxime Ripard } 4820e589d5fSMaxime Ripard 4830e589d5fSMaxime Ripard static int at91_adc_channel_init(struct iio_dev *idev) 4840e589d5fSMaxime Ripard { 4850e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 4860e589d5fSMaxime Ripard struct iio_chan_spec *chan_array, *timestamp; 4870e589d5fSMaxime Ripard int bit, idx = 0; 488c8b11de0SJosh Wu unsigned long rsvd_mask = 0; 489c8b11de0SJosh Wu 490c8b11de0SJosh Wu /* If touchscreen is enable, then reserve the adc channels */ 491c8b11de0SJosh Wu if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) 492c8b11de0SJosh Wu rsvd_mask = CHAN_MASK_TOUCHSCREEN_4WIRE; 493c8b11de0SJosh Wu else if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_5WIRE) 494c8b11de0SJosh Wu rsvd_mask = CHAN_MASK_TOUCHSCREEN_5WIRE; 495c8b11de0SJosh Wu 496c8b11de0SJosh Wu /* set up the channel mask to reserve touchscreen channels */ 497c8b11de0SJosh Wu st->channels_mask &= ~rsvd_mask; 4980e589d5fSMaxime Ripard 4990e589d5fSMaxime Ripard idev->num_channels = bitmap_weight(&st->channels_mask, 5000e589d5fSMaxime Ripard st->num_channels) + 1; 5010e589d5fSMaxime Ripard 5026b3aa313SAxel Lin chan_array = devm_kzalloc(&idev->dev, 5036b3aa313SAxel Lin ((idev->num_channels + 1) * 5046b3aa313SAxel Lin sizeof(struct iio_chan_spec)), 5056b3aa313SAxel Lin GFP_KERNEL); 5060e589d5fSMaxime Ripard 5070e589d5fSMaxime Ripard if (!chan_array) 5080e589d5fSMaxime Ripard return -ENOMEM; 5090e589d5fSMaxime Ripard 5100e589d5fSMaxime Ripard for_each_set_bit(bit, &st->channels_mask, st->num_channels) { 5110e589d5fSMaxime Ripard struct iio_chan_spec *chan = chan_array + idx; 5120e589d5fSMaxime Ripard 5130e589d5fSMaxime Ripard chan->type = IIO_VOLTAGE; 5140e589d5fSMaxime Ripard chan->indexed = 1; 5150e589d5fSMaxime Ripard chan->channel = bit; 5160e589d5fSMaxime Ripard chan->scan_index = idx; 5170e589d5fSMaxime Ripard chan->scan_type.sign = 'u'; 51847be16b6SLudovic Desroches chan->scan_type.realbits = st->res; 5190e589d5fSMaxime Ripard chan->scan_type.storagebits = 16; 52001bdab66SJonathan Cameron chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); 52101bdab66SJonathan Cameron chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); 5220e589d5fSMaxime Ripard idx++; 5230e589d5fSMaxime Ripard } 5240e589d5fSMaxime Ripard timestamp = chan_array + idx; 5250e589d5fSMaxime Ripard 5260e589d5fSMaxime Ripard timestamp->type = IIO_TIMESTAMP; 5270e589d5fSMaxime Ripard timestamp->channel = -1; 5280e589d5fSMaxime Ripard timestamp->scan_index = idx; 5290e589d5fSMaxime Ripard timestamp->scan_type.sign = 's'; 5300e589d5fSMaxime Ripard timestamp->scan_type.realbits = 64; 5310e589d5fSMaxime Ripard timestamp->scan_type.storagebits = 64; 5320e589d5fSMaxime Ripard 5330e589d5fSMaxime Ripard idev->channels = chan_array; 5340e589d5fSMaxime Ripard return idev->num_channels; 5350e589d5fSMaxime Ripard } 5360e589d5fSMaxime Ripard 5374f3bcd87SDan Carpenter static int at91_adc_get_trigger_value_by_name(struct iio_dev *idev, 5380e589d5fSMaxime Ripard struct at91_adc_trigger *triggers, 5390e589d5fSMaxime Ripard const char *trigger_name) 5400e589d5fSMaxime Ripard { 5410e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 5420e589d5fSMaxime Ripard int i; 5430e589d5fSMaxime Ripard 5440e589d5fSMaxime Ripard for (i = 0; i < st->trigger_number; i++) { 5450e589d5fSMaxime Ripard char *name = kasprintf(GFP_KERNEL, 5460e589d5fSMaxime Ripard "%s-dev%d-%s", 5470e589d5fSMaxime Ripard idev->name, 5480e589d5fSMaxime Ripard idev->id, 5490e589d5fSMaxime Ripard triggers[i].name); 5500e589d5fSMaxime Ripard if (!name) 5510e589d5fSMaxime Ripard return -ENOMEM; 5520e589d5fSMaxime Ripard 5530e589d5fSMaxime Ripard if (strcmp(trigger_name, name) == 0) { 5540e589d5fSMaxime Ripard kfree(name); 5554f3bcd87SDan Carpenter if (triggers[i].value == 0) 5564f3bcd87SDan Carpenter return -EINVAL; 5574f3bcd87SDan Carpenter return triggers[i].value; 5580e589d5fSMaxime Ripard } 5590e589d5fSMaxime Ripard 5600e589d5fSMaxime Ripard kfree(name); 5610e589d5fSMaxime Ripard } 5620e589d5fSMaxime Ripard 5634f3bcd87SDan Carpenter return -EINVAL; 5640e589d5fSMaxime Ripard } 5650e589d5fSMaxime Ripard 5660e589d5fSMaxime Ripard static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state) 5670e589d5fSMaxime Ripard { 5681e9663c6SLars-Peter Clausen struct iio_dev *idev = iio_trigger_get_drvdata(trig); 5690e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 5703e4ef8e8SAlexandru Ardelean const struct at91_adc_reg_desc *reg = st->registers; 5710e589d5fSMaxime Ripard u32 status = at91_adc_readl(st, reg->trigger_register); 5724f3bcd87SDan Carpenter int value; 5730e589d5fSMaxime Ripard u8 bit; 5740e589d5fSMaxime Ripard 5750e589d5fSMaxime Ripard value = at91_adc_get_trigger_value_by_name(idev, 5760e589d5fSMaxime Ripard st->trigger_list, 5770e589d5fSMaxime Ripard idev->trig->name); 5784f3bcd87SDan Carpenter if (value < 0) 5794f3bcd87SDan Carpenter return value; 5800e589d5fSMaxime Ripard 5810e589d5fSMaxime Ripard if (state) { 5820e589d5fSMaxime Ripard st->buffer = kmalloc(idev->scan_bytes, GFP_KERNEL); 5830e589d5fSMaxime Ripard if (st->buffer == NULL) 5840e589d5fSMaxime Ripard return -ENOMEM; 5850e589d5fSMaxime Ripard 5860e589d5fSMaxime Ripard at91_adc_writel(st, reg->trigger_register, 5870e589d5fSMaxime Ripard status | value); 5880e589d5fSMaxime Ripard 58970dddeeeSOctavian Purdila for_each_set_bit(bit, idev->active_scan_mask, 5900e589d5fSMaxime Ripard st->num_channels) { 5910e589d5fSMaxime Ripard struct iio_chan_spec const *chan = idev->channels + bit; 5920e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHER, 5930e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 5940e589d5fSMaxime Ripard } 5950e589d5fSMaxime Ripard 5960e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IER, reg->drdy_mask); 5970e589d5fSMaxime Ripard 5980e589d5fSMaxime Ripard } else { 5990e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, reg->drdy_mask); 6000e589d5fSMaxime Ripard 6010e589d5fSMaxime Ripard at91_adc_writel(st, reg->trigger_register, 6020e589d5fSMaxime Ripard status & ~value); 6030e589d5fSMaxime Ripard 60470dddeeeSOctavian Purdila for_each_set_bit(bit, idev->active_scan_mask, 6050e589d5fSMaxime Ripard st->num_channels) { 6060e589d5fSMaxime Ripard struct iio_chan_spec const *chan = idev->channels + bit; 6070e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHDR, 6080e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 6090e589d5fSMaxime Ripard } 6100e589d5fSMaxime Ripard kfree(st->buffer); 6110e589d5fSMaxime Ripard } 6120e589d5fSMaxime Ripard 6130e589d5fSMaxime Ripard return 0; 6140e589d5fSMaxime Ripard } 6150e589d5fSMaxime Ripard 6160e589d5fSMaxime Ripard static const struct iio_trigger_ops at91_adc_trigger_ops = { 6170e589d5fSMaxime Ripard .set_trigger_state = &at91_adc_configure_trigger, 6180e589d5fSMaxime Ripard }; 6190e589d5fSMaxime Ripard 6200e589d5fSMaxime Ripard static struct iio_trigger *at91_adc_allocate_trigger(struct iio_dev *idev, 6210e589d5fSMaxime Ripard struct at91_adc_trigger *trigger) 6220e589d5fSMaxime Ripard { 6230e589d5fSMaxime Ripard struct iio_trigger *trig; 6240e589d5fSMaxime Ripard int ret; 6250e589d5fSMaxime Ripard 6260e589d5fSMaxime Ripard trig = iio_trigger_alloc("%s-dev%d-%s", idev->name, 6270e589d5fSMaxime Ripard idev->id, trigger->name); 6280e589d5fSMaxime Ripard if (trig == NULL) 6290e589d5fSMaxime Ripard return NULL; 6300e589d5fSMaxime Ripard 6310e589d5fSMaxime Ripard trig->dev.parent = idev->dev.parent; 6321e9663c6SLars-Peter Clausen iio_trigger_set_drvdata(trig, idev); 6330e589d5fSMaxime Ripard trig->ops = &at91_adc_trigger_ops; 6340e589d5fSMaxime Ripard 6350e589d5fSMaxime Ripard ret = iio_trigger_register(trig); 6360e589d5fSMaxime Ripard if (ret) 6370e589d5fSMaxime Ripard return NULL; 6380e589d5fSMaxime Ripard 6390e589d5fSMaxime Ripard return trig; 6400e589d5fSMaxime Ripard } 6410e589d5fSMaxime Ripard 6420e589d5fSMaxime Ripard static int at91_adc_trigger_init(struct iio_dev *idev) 6430e589d5fSMaxime Ripard { 6440e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 6450e589d5fSMaxime Ripard int i, ret; 6460e589d5fSMaxime Ripard 647a86854d0SKees Cook st->trig = devm_kcalloc(&idev->dev, 648a86854d0SKees Cook st->trigger_number, sizeof(*st->trig), 6496b3aa313SAxel Lin GFP_KERNEL); 6500e589d5fSMaxime Ripard 6510e589d5fSMaxime Ripard if (st->trig == NULL) { 6520e589d5fSMaxime Ripard ret = -ENOMEM; 6530e589d5fSMaxime Ripard goto error_ret; 6540e589d5fSMaxime Ripard } 6550e589d5fSMaxime Ripard 6560e589d5fSMaxime Ripard for (i = 0; i < st->trigger_number; i++) { 6570e589d5fSMaxime Ripard if (st->trigger_list[i].is_external && !(st->use_external)) 6580e589d5fSMaxime Ripard continue; 6590e589d5fSMaxime Ripard 6600e589d5fSMaxime Ripard st->trig[i] = at91_adc_allocate_trigger(idev, 6610e589d5fSMaxime Ripard st->trigger_list + i); 6620e589d5fSMaxime Ripard if (st->trig[i] == NULL) { 6630e589d5fSMaxime Ripard dev_err(&idev->dev, 6640e589d5fSMaxime Ripard "Could not allocate trigger %d\n", i); 6650e589d5fSMaxime Ripard ret = -ENOMEM; 6660e589d5fSMaxime Ripard goto error_trigger; 6670e589d5fSMaxime Ripard } 6680e589d5fSMaxime Ripard } 6690e589d5fSMaxime Ripard 6700e589d5fSMaxime Ripard return 0; 6710e589d5fSMaxime Ripard 6720e589d5fSMaxime Ripard error_trigger: 6730e589d5fSMaxime Ripard for (i--; i >= 0; i--) { 6740e589d5fSMaxime Ripard iio_trigger_unregister(st->trig[i]); 6750e589d5fSMaxime Ripard iio_trigger_free(st->trig[i]); 6760e589d5fSMaxime Ripard } 6770e589d5fSMaxime Ripard error_ret: 6780e589d5fSMaxime Ripard return ret; 6790e589d5fSMaxime Ripard } 6800e589d5fSMaxime Ripard 6810e589d5fSMaxime Ripard static void at91_adc_trigger_remove(struct iio_dev *idev) 6820e589d5fSMaxime Ripard { 6830e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 6840e589d5fSMaxime Ripard int i; 6850e589d5fSMaxime Ripard 6860e589d5fSMaxime Ripard for (i = 0; i < st->trigger_number; i++) { 6870e589d5fSMaxime Ripard iio_trigger_unregister(st->trig[i]); 6880e589d5fSMaxime Ripard iio_trigger_free(st->trig[i]); 6890e589d5fSMaxime Ripard } 6900e589d5fSMaxime Ripard } 6910e589d5fSMaxime Ripard 6920e589d5fSMaxime Ripard static int at91_adc_buffer_init(struct iio_dev *idev) 6930e589d5fSMaxime Ripard { 69490032e4eSLars-Peter Clausen return iio_triggered_buffer_setup(idev, &iio_pollfunc_store_time, 69590032e4eSLars-Peter Clausen &at91_adc_trigger_handler, NULL); 6960e589d5fSMaxime Ripard } 6970e589d5fSMaxime Ripard 6980e589d5fSMaxime Ripard static void at91_adc_buffer_remove(struct iio_dev *idev) 6990e589d5fSMaxime Ripard { 70090032e4eSLars-Peter Clausen iio_triggered_buffer_cleanup(idev); 7010e589d5fSMaxime Ripard } 7020e589d5fSMaxime Ripard 7030e589d5fSMaxime Ripard static int at91_adc_read_raw(struct iio_dev *idev, 7040e589d5fSMaxime Ripard struct iio_chan_spec const *chan, 7050e589d5fSMaxime Ripard int *val, int *val2, long mask) 7060e589d5fSMaxime Ripard { 7070e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 7080e589d5fSMaxime Ripard int ret; 7090e589d5fSMaxime Ripard 7100e589d5fSMaxime Ripard switch (mask) { 7110e589d5fSMaxime Ripard case IIO_CHAN_INFO_RAW: 7120e589d5fSMaxime Ripard mutex_lock(&st->lock); 7130e589d5fSMaxime Ripard 714d4f51956SLudovic Desroches st->chnb = chan->channel; 7150e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHER, 7160e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 717d4f51956SLudovic Desroches at91_adc_writel(st, AT91_ADC_IER, BIT(chan->channel)); 7180e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_START); 7190e589d5fSMaxime Ripard 7200e589d5fSMaxime Ripard ret = wait_event_interruptible_timeout(st->wq_data_avail, 7210e589d5fSMaxime Ripard st->done, 7220e589d5fSMaxime Ripard msecs_to_jiffies(1000)); 7230e589d5fSMaxime Ripard 72409c6bdeeSGeorg Ottinger /* Disable interrupts, regardless if adc conversion was 72509c6bdeeSGeorg Ottinger * successful or not 72609c6bdeeSGeorg Ottinger */ 7270e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CHDR, 7280e589d5fSMaxime Ripard AT91_ADC_CH(chan->channel)); 729d4f51956SLudovic Desroches at91_adc_writel(st, AT91_ADC_IDR, BIT(chan->channel)); 7300e589d5fSMaxime Ripard 73109c6bdeeSGeorg Ottinger if (ret > 0) { 73209c6bdeeSGeorg Ottinger /* a valid conversion took place */ 73309c6bdeeSGeorg Ottinger *val = st->last_value; 7340e589d5fSMaxime Ripard st->last_value = 0; 7350e589d5fSMaxime Ripard st->done = false; 73609c6bdeeSGeorg Ottinger ret = IIO_VAL_INT; 73709c6bdeeSGeorg Ottinger } else if (ret == 0) { 73809c6bdeeSGeorg Ottinger /* conversion timeout */ 73909c6bdeeSGeorg Ottinger dev_err(&idev->dev, "ADC Channel %d timeout.\n", 74009c6bdeeSGeorg Ottinger chan->channel); 74109c6bdeeSGeorg Ottinger ret = -ETIMEDOUT; 74209c6bdeeSGeorg Ottinger } 74309c6bdeeSGeorg Ottinger 7440e589d5fSMaxime Ripard mutex_unlock(&st->lock); 74509c6bdeeSGeorg Ottinger return ret; 7460e589d5fSMaxime Ripard 7470e589d5fSMaxime Ripard case IIO_CHAN_INFO_SCALE: 748c45e561eSLars-Peter Clausen *val = st->vref_mv; 749c45e561eSLars-Peter Clausen *val2 = chan->scan_type.realbits; 750c45e561eSLars-Peter Clausen return IIO_VAL_FRACTIONAL_LOG2; 7510e589d5fSMaxime Ripard default: 7520e589d5fSMaxime Ripard break; 7530e589d5fSMaxime Ripard } 7540e589d5fSMaxime Ripard return -EINVAL; 7550e589d5fSMaxime Ripard } 7560e589d5fSMaxime Ripard 757044d406aSAlexandru Ardelean static int at91_adc_of_get_resolution(struct iio_dev *idev, 75847be16b6SLudovic Desroches struct platform_device *pdev) 75947be16b6SLudovic Desroches { 760044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 76147be16b6SLudovic Desroches struct device_node *np = pdev->dev.of_node; 76247be16b6SLudovic Desroches int count, i, ret = 0; 76347be16b6SLudovic Desroches char *res_name, *s; 76447be16b6SLudovic Desroches u32 *resolutions; 76547be16b6SLudovic Desroches 76647be16b6SLudovic Desroches count = of_property_count_strings(np, "atmel,adc-res-names"); 76747be16b6SLudovic Desroches if (count < 2) { 76847be16b6SLudovic Desroches dev_err(&idev->dev, "You must specified at least two resolution names for " 76947be16b6SLudovic Desroches "adc-res-names property in the DT\n"); 77047be16b6SLudovic Desroches return count; 77147be16b6SLudovic Desroches } 77247be16b6SLudovic Desroches 7733fba9b5fSNizam Haider resolutions = kmalloc_array(count, sizeof(*resolutions), GFP_KERNEL); 77447be16b6SLudovic Desroches if (!resolutions) 77547be16b6SLudovic Desroches return -ENOMEM; 77647be16b6SLudovic Desroches 77747be16b6SLudovic Desroches if (of_property_read_u32_array(np, "atmel,adc-res", resolutions, count)) { 77847be16b6SLudovic Desroches dev_err(&idev->dev, "Missing adc-res property in the DT.\n"); 77947be16b6SLudovic Desroches ret = -ENODEV; 78047be16b6SLudovic Desroches goto ret; 78147be16b6SLudovic Desroches } 78247be16b6SLudovic Desroches 78347be16b6SLudovic Desroches if (of_property_read_string(np, "atmel,adc-use-res", (const char **)&res_name)) 78447be16b6SLudovic Desroches res_name = "highres"; 78547be16b6SLudovic Desroches 78647be16b6SLudovic Desroches for (i = 0; i < count; i++) { 78747be16b6SLudovic Desroches if (of_property_read_string_index(np, "atmel,adc-res-names", i, (const char **)&s)) 78847be16b6SLudovic Desroches continue; 78947be16b6SLudovic Desroches 79047be16b6SLudovic Desroches if (strcmp(res_name, s)) 79147be16b6SLudovic Desroches continue; 79247be16b6SLudovic Desroches 79347be16b6SLudovic Desroches st->res = resolutions[i]; 79447be16b6SLudovic Desroches if (!strcmp(res_name, "lowres")) 79547be16b6SLudovic Desroches st->low_res = true; 79647be16b6SLudovic Desroches else 79747be16b6SLudovic Desroches st->low_res = false; 79847be16b6SLudovic Desroches 79947be16b6SLudovic Desroches dev_info(&idev->dev, "Resolution used: %u bits\n", st->res); 80047be16b6SLudovic Desroches goto ret; 80147be16b6SLudovic Desroches } 80247be16b6SLudovic Desroches 80347be16b6SLudovic Desroches dev_err(&idev->dev, "There is no resolution for %s\n", res_name); 80447be16b6SLudovic Desroches 80547be16b6SLudovic Desroches ret: 80647be16b6SLudovic Desroches kfree(resolutions); 80747be16b6SLudovic Desroches return ret; 80847be16b6SLudovic Desroches } 80947be16b6SLudovic Desroches 8102ab5f39bSJan Leupold static u32 calc_startup_ticks_9260(u32 startup_time, u32 adc_clk_khz) 811c4601666SJosh Wu { 812c4601666SJosh Wu /* 813c4601666SJosh Wu * Number of ticks needed to cover the startup time of the ADC 814c4601666SJosh Wu * as defined in the electrical characteristics of the board, 815c4601666SJosh Wu * divided by 8. The formula thus is : 816c4601666SJosh Wu * Startup Time = (ticks + 1) * 8 / ADC Clock 817c4601666SJosh Wu */ 818c4601666SJosh Wu return round_up((startup_time * adc_clk_khz / 1000) - 1, 8) / 8; 819c4601666SJosh Wu } 820c4601666SJosh Wu 8212ab5f39bSJan Leupold static u32 calc_startup_ticks_9x5(u32 startup_time, u32 adc_clk_khz) 822c4601666SJosh Wu { 823c4601666SJosh Wu /* 824c4601666SJosh Wu * For sama5d3x and at91sam9x5, the formula changes to: 825c4601666SJosh Wu * Startup Time = <lookup_table_value> / ADC Clock 826c4601666SJosh Wu */ 8275b4e17c9SColin Ian King static const int startup_lookup[] = { 828c4601666SJosh Wu 0, 8, 16, 24, 829c4601666SJosh Wu 64, 80, 96, 112, 830c4601666SJosh Wu 512, 576, 640, 704, 831c4601666SJosh Wu 768, 832, 896, 960 832c4601666SJosh Wu }; 833c4601666SJosh Wu int i, size = ARRAY_SIZE(startup_lookup); 834c4601666SJosh Wu unsigned int ticks; 835c4601666SJosh Wu 836c4601666SJosh Wu ticks = startup_time * adc_clk_khz / 1000; 837c4601666SJosh Wu for (i = 0; i < size; i++) 838c4601666SJosh Wu if (ticks < startup_lookup[i]) 839c4601666SJosh Wu break; 840c4601666SJosh Wu 841c4601666SJosh Wu ticks = i; 842c4601666SJosh Wu if (ticks == size) 843c4601666SJosh Wu /* Reach the end of lookup table */ 844c4601666SJosh Wu ticks = size - 1; 845c4601666SJosh Wu 846c4601666SJosh Wu return ticks; 847c4601666SJosh Wu } 848c4601666SJosh Wu 849c8b11de0SJosh Wu static int at91_adc_probe_dt_ts(struct device_node *node, 850c8b11de0SJosh Wu struct at91_adc_state *st, struct device *dev) 851c8b11de0SJosh Wu { 852c8b11de0SJosh Wu int ret; 853c8b11de0SJosh Wu u32 prop; 854c8b11de0SJosh Wu 855c8b11de0SJosh Wu ret = of_property_read_u32(node, "atmel,adc-ts-wires", &prop); 856c8b11de0SJosh Wu if (ret) { 857c8b11de0SJosh Wu dev_info(dev, "ADC Touch screen is disabled.\n"); 858c8b11de0SJosh Wu return 0; 859c8b11de0SJosh Wu } 860c8b11de0SJosh Wu 861c8b11de0SJosh Wu switch (prop) { 862c8b11de0SJosh Wu case 4: 863c8b11de0SJosh Wu case 5: 864c8b11de0SJosh Wu st->touchscreen_type = prop; 865c8b11de0SJosh Wu break; 866c8b11de0SJosh Wu default: 867c8b11de0SJosh Wu dev_err(dev, "Unsupported number of touchscreen wires (%d). Should be 4 or 5.\n", prop); 868c8b11de0SJosh Wu return -EINVAL; 869c8b11de0SJosh Wu } 870c8b11de0SJosh Wu 87184882b06SAlexandre Belloni if (!st->caps->has_tsmr) 87284882b06SAlexandre Belloni return 0; 873c8b11de0SJosh Wu prop = 0; 874c8b11de0SJosh Wu of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop); 875c8b11de0SJosh Wu st->ts_pressure_threshold = prop; 876c8b11de0SJosh Wu if (st->ts_pressure_threshold) { 877c8b11de0SJosh Wu return 0; 878c8b11de0SJosh Wu } else { 879c8b11de0SJosh Wu dev_err(dev, "Invalid pressure threshold for the touchscreen\n"); 880c8b11de0SJosh Wu return -EINVAL; 881c8b11de0SJosh Wu } 882c8b11de0SJosh Wu } 883c8b11de0SJosh Wu 884044d406aSAlexandru Ardelean static int at91_adc_probe_dt(struct iio_dev *idev, 885e364185fSMaxime Ripard struct platform_device *pdev) 886e364185fSMaxime Ripard { 887044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 888e364185fSMaxime Ripard struct device_node *node = pdev->dev.of_node; 889e364185fSMaxime Ripard struct device_node *trig_node; 890e364185fSMaxime Ripard int i = 0, ret; 891e364185fSMaxime Ripard u32 prop; 892e364185fSMaxime Ripard 8933e4ef8e8SAlexandru Ardelean st->caps = of_device_get_match_data(&pdev->dev); 894e1811f97SJosh Wu 895e364185fSMaxime Ripard st->use_external = of_property_read_bool(node, "atmel,adc-use-external-triggers"); 896e364185fSMaxime Ripard 897e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-channels-used", &prop)) { 898e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-channels-used property in the DT.\n"); 899e364185fSMaxime Ripard ret = -EINVAL; 900e364185fSMaxime Ripard goto error_ret; 901e364185fSMaxime Ripard } 902e364185fSMaxime Ripard st->channels_mask = prop; 903e364185fSMaxime Ripard 904e748783cSJean-Christophe PLAGNIOL-VILLARD st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode"); 905e748783cSJean-Christophe PLAGNIOL-VILLARD 906e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) { 907e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n"); 908e364185fSMaxime Ripard ret = -EINVAL; 909e364185fSMaxime Ripard goto error_ret; 910e364185fSMaxime Ripard } 911e364185fSMaxime Ripard st->startup_time = prop; 912e364185fSMaxime Ripard 913beca9e76SJean-Christophe PLAGNIOL-VILLARD prop = 0; 914beca9e76SJean-Christophe PLAGNIOL-VILLARD of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop); 915beca9e76SJean-Christophe PLAGNIOL-VILLARD st->sample_hold_time = prop; 916e364185fSMaxime Ripard 917e364185fSMaxime Ripard if (of_property_read_u32(node, "atmel,adc-vref", &prop)) { 918e364185fSMaxime Ripard dev_err(&idev->dev, "Missing adc-vref property in the DT.\n"); 919e364185fSMaxime Ripard ret = -EINVAL; 920e364185fSMaxime Ripard goto error_ret; 921e364185fSMaxime Ripard } 922e364185fSMaxime Ripard st->vref_mv = prop; 923e364185fSMaxime Ripard 924044d406aSAlexandru Ardelean ret = at91_adc_of_get_resolution(idev, pdev); 92547be16b6SLudovic Desroches if (ret) 92647be16b6SLudovic Desroches goto error_ret; 92747be16b6SLudovic Desroches 928e1811f97SJosh Wu st->registers = &st->caps->registers; 9292b6d598bSJosh Wu st->num_channels = st->caps->num_channels; 930e364185fSMaxime Ripard st->trigger_number = of_get_child_count(node); 931a86854d0SKees Cook st->trigger_list = devm_kcalloc(&idev->dev, 932a86854d0SKees Cook st->trigger_number, 9336b3aa313SAxel Lin sizeof(struct at91_adc_trigger), 9346b3aa313SAxel Lin GFP_KERNEL); 935e364185fSMaxime Ripard if (!st->trigger_list) { 936e364185fSMaxime Ripard dev_err(&idev->dev, "Could not allocate trigger list memory.\n"); 937e364185fSMaxime Ripard ret = -ENOMEM; 938e364185fSMaxime Ripard goto error_ret; 939e364185fSMaxime Ripard } 940e364185fSMaxime Ripard 941e364185fSMaxime Ripard for_each_child_of_node(node, trig_node) { 942e364185fSMaxime Ripard struct at91_adc_trigger *trig = st->trigger_list + i; 943e364185fSMaxime Ripard const char *name; 944e364185fSMaxime Ripard 945e364185fSMaxime Ripard if (of_property_read_string(trig_node, "trigger-name", &name)) { 946e364185fSMaxime Ripard dev_err(&idev->dev, "Missing trigger-name property in the DT.\n"); 947e364185fSMaxime Ripard ret = -EINVAL; 948e364185fSMaxime Ripard goto error_ret; 949e364185fSMaxime Ripard } 950e364185fSMaxime Ripard trig->name = name; 951e364185fSMaxime Ripard 952e364185fSMaxime Ripard if (of_property_read_u32(trig_node, "trigger-value", &prop)) { 953e364185fSMaxime Ripard dev_err(&idev->dev, "Missing trigger-value property in the DT.\n"); 954e364185fSMaxime Ripard ret = -EINVAL; 955e364185fSMaxime Ripard goto error_ret; 956e364185fSMaxime Ripard } 957e364185fSMaxime Ripard trig->value = prop; 958e364185fSMaxime Ripard trig->is_external = of_property_read_bool(trig_node, "trigger-external"); 959e364185fSMaxime Ripard i++; 960e364185fSMaxime Ripard } 961e364185fSMaxime Ripard 962c8b11de0SJosh Wu /* Check if touchscreen is supported. */ 963c8b11de0SJosh Wu if (st->caps->has_ts) 964c8b11de0SJosh Wu return at91_adc_probe_dt_ts(node, st, &idev->dev); 965c8b11de0SJosh Wu else 966c8b11de0SJosh Wu dev_info(&idev->dev, "not support touchscreen in the adc compatible string.\n"); 967c8b11de0SJosh Wu 968e364185fSMaxime Ripard return 0; 969e364185fSMaxime Ripard 970e364185fSMaxime Ripard error_ret: 971e364185fSMaxime Ripard return ret; 972e364185fSMaxime Ripard } 973e364185fSMaxime Ripard 9740e589d5fSMaxime Ripard static const struct iio_info at91_adc_info = { 9750e589d5fSMaxime Ripard .read_raw = &at91_adc_read_raw, 9760e589d5fSMaxime Ripard }; 9770e589d5fSMaxime Ripard 978c8b11de0SJosh Wu /* Touchscreen related functions */ 979c8b11de0SJosh Wu static int atmel_ts_open(struct input_dev *dev) 980c8b11de0SJosh Wu { 981c8b11de0SJosh Wu struct at91_adc_state *st = input_get_drvdata(dev); 982c8b11de0SJosh Wu 98384882b06SAlexandre Belloni if (st->caps->has_tsmr) 984c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); 98584882b06SAlexandre Belloni else 98684882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); 987c8b11de0SJosh Wu return 0; 988c8b11de0SJosh Wu } 989c8b11de0SJosh Wu 990c8b11de0SJosh Wu static void atmel_ts_close(struct input_dev *dev) 991c8b11de0SJosh Wu { 992c8b11de0SJosh Wu struct at91_adc_state *st = input_get_drvdata(dev); 993c8b11de0SJosh Wu 99484882b06SAlexandre Belloni if (st->caps->has_tsmr) 995c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); 99684882b06SAlexandre Belloni else 99784882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); 998c8b11de0SJosh Wu } 999c8b11de0SJosh Wu 1000044d406aSAlexandru Ardelean static int at91_ts_hw_init(struct iio_dev *idev, u32 adc_clk_khz) 1001c8b11de0SJosh Wu { 1002044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 100384882b06SAlexandre Belloni u32 reg = 0; 1004ede63aafSNicolas Ferre u32 tssctim = 0; 1005c8b11de0SJosh Wu int i = 0; 1006c8b11de0SJosh Wu 100784882b06SAlexandre Belloni /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid 100884882b06SAlexandre Belloni * pen detect noise. 100984882b06SAlexandre Belloni * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock 101084882b06SAlexandre Belloni */ 101184882b06SAlexandre Belloni st->ts_pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 101284882b06SAlexandre Belloni 1000, 1); 101384882b06SAlexandre Belloni 101484882b06SAlexandre Belloni while (st->ts_pendbc >> ++i) 101584882b06SAlexandre Belloni ; /* Empty! Find the shift offset */ 101684882b06SAlexandre Belloni if (abs(st->ts_pendbc - (1 << i)) < abs(st->ts_pendbc - (1 << (i - 1)))) 101784882b06SAlexandre Belloni st->ts_pendbc = i; 101884882b06SAlexandre Belloni else 101984882b06SAlexandre Belloni st->ts_pendbc = i - 1; 102084882b06SAlexandre Belloni 102184882b06SAlexandre Belloni if (!st->caps->has_tsmr) { 102284882b06SAlexandre Belloni reg = at91_adc_readl(st, AT91_ADC_MR); 102384882b06SAlexandre Belloni reg |= AT91_ADC_TSAMOD_TS_ONLY_MODE | AT91_ADC_PENDET; 102484882b06SAlexandre Belloni 102584882b06SAlexandre Belloni reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; 102684882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_MR, reg); 102784882b06SAlexandre Belloni 102884882b06SAlexandre Belloni reg = AT91_ADC_TSR_SHTIM_(TOUCH_SHTIM) & AT91_ADC_TSR_SHTIM; 102984882b06SAlexandre Belloni at91_adc_writel(st, AT91_ADC_TSR, reg); 103084882b06SAlexandre Belloni 103184882b06SAlexandre Belloni st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US_RL * 103284882b06SAlexandre Belloni adc_clk_khz / 1000) - 1, 1); 103384882b06SAlexandre Belloni 103484882b06SAlexandre Belloni return 0; 103584882b06SAlexandre Belloni } 103684882b06SAlexandre Belloni 1037ede63aafSNicolas Ferre /* Touchscreen Switches Closure time needed for allowing the value to 1038ede63aafSNicolas Ferre * stabilize. 1039ede63aafSNicolas Ferre * Switch Closure Time = (TSSCTIM * 4) ADCClock periods 1040ede63aafSNicolas Ferre */ 1041ede63aafSNicolas Ferre tssctim = DIV_ROUND_UP(TOUCH_SCTIM_US * adc_clk_khz / 1000, 4); 1042ede63aafSNicolas Ferre dev_dbg(&idev->dev, "adc_clk at: %d KHz, tssctim at: %d\n", 1043ede63aafSNicolas Ferre adc_clk_khz, tssctim); 1044ede63aafSNicolas Ferre 1045c8b11de0SJosh Wu if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) 1046c8b11de0SJosh Wu reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS; 1047c8b11de0SJosh Wu else 1048c8b11de0SJosh Wu reg = AT91_ADC_TSMR_TSMODE_5WIRE; 1049c8b11de0SJosh Wu 1050ede63aafSNicolas Ferre reg |= AT91_ADC_TSMR_SCTIM_(tssctim) & AT91_ADC_TSMR_SCTIM; 1051c8b11de0SJosh Wu reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average) 1052c8b11de0SJosh Wu & AT91_ADC_TSMR_TSAV; 105384882b06SAlexandre Belloni reg |= AT91_ADC_TSMR_PENDBC_(st->ts_pendbc) & AT91_ADC_TSMR_PENDBC; 1054c8b11de0SJosh Wu reg |= AT91_ADC_TSMR_NOTSDMA; 1055c8b11de0SJosh Wu reg |= AT91_ADC_TSMR_PENDET_ENA; 105684882b06SAlexandre Belloni reg |= 0x03 << 8; /* TSFREQ, needs to be bigger than TSAV */ 1057c8b11de0SJosh Wu 1058c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_TSMR, reg); 1059c8b11de0SJosh Wu 1060c8b11de0SJosh Wu /* Change adc internal resistor value for better pen detection, 1061c8b11de0SJosh Wu * default value is 100 kOhm. 1062c8b11de0SJosh Wu * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm 1063c8b11de0SJosh Wu * option only available on ES2 and higher 1064c8b11de0SJosh Wu */ 1065c8b11de0SJosh Wu at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity 1066c8b11de0SJosh Wu & AT91_ADC_ACR_PENDETSENS); 1067c8b11de0SJosh Wu 106884882b06SAlexandre Belloni /* Sample Period Time = (TRGPER + 1) / ADCClock */ 1069c8b11de0SJosh Wu st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US * 1070c8b11de0SJosh Wu adc_clk_khz / 1000) - 1, 1); 1071c8b11de0SJosh Wu 1072c8b11de0SJosh Wu return 0; 1073c8b11de0SJosh Wu } 1074c8b11de0SJosh Wu 1075044d406aSAlexandru Ardelean static int at91_ts_register(struct iio_dev *idev, 1076c8b11de0SJosh Wu struct platform_device *pdev) 1077c8b11de0SJosh Wu { 1078044d406aSAlexandru Ardelean struct at91_adc_state *st = iio_priv(idev); 1079c8b11de0SJosh Wu struct input_dev *input; 1080c8b11de0SJosh Wu int ret; 1081c8b11de0SJosh Wu 1082c8b11de0SJosh Wu input = input_allocate_device(); 1083c8b11de0SJosh Wu if (!input) { 1084c8b11de0SJosh Wu dev_err(&idev->dev, "Failed to allocate TS device!\n"); 1085c8b11de0SJosh Wu return -ENOMEM; 1086c8b11de0SJosh Wu } 1087c8b11de0SJosh Wu 1088c8b11de0SJosh Wu input->name = DRIVER_NAME; 1089c8b11de0SJosh Wu input->id.bustype = BUS_HOST; 1090c8b11de0SJosh Wu input->dev.parent = &pdev->dev; 1091c8b11de0SJosh Wu input->open = atmel_ts_open; 1092c8b11de0SJosh Wu input->close = atmel_ts_close; 1093c8b11de0SJosh Wu 1094c8b11de0SJosh Wu __set_bit(EV_ABS, input->evbit); 1095c8b11de0SJosh Wu __set_bit(EV_KEY, input->evbit); 1096c8b11de0SJosh Wu __set_bit(BTN_TOUCH, input->keybit); 109784882b06SAlexandre Belloni if (st->caps->has_tsmr) { 109884882b06SAlexandre Belloni input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 109984882b06SAlexandre Belloni 0, 0); 110084882b06SAlexandre Belloni input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 110184882b06SAlexandre Belloni 0, 0); 1102c8b11de0SJosh Wu input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0); 110384882b06SAlexandre Belloni } else { 110484882b06SAlexandre Belloni if (st->touchscreen_type != ATMEL_ADC_TOUCHSCREEN_4WIRE) { 110584882b06SAlexandre Belloni dev_err(&pdev->dev, 110684882b06SAlexandre Belloni "This touchscreen controller only support 4 wires\n"); 110784882b06SAlexandre Belloni ret = -EINVAL; 110884882b06SAlexandre Belloni goto err; 110984882b06SAlexandre Belloni } 111084882b06SAlexandre Belloni 111184882b06SAlexandre Belloni input_set_abs_params(input, ABS_X, 0, (1 << MAX_RLPOS_BITS) - 1, 111284882b06SAlexandre Belloni 0, 0); 111384882b06SAlexandre Belloni input_set_abs_params(input, ABS_Y, 0, (1 << MAX_RLPOS_BITS) - 1, 111484882b06SAlexandre Belloni 0, 0); 111584882b06SAlexandre Belloni } 1116c8b11de0SJosh Wu 1117c8b11de0SJosh Wu st->ts_input = input; 1118c8b11de0SJosh Wu input_set_drvdata(input, st); 1119c8b11de0SJosh Wu 1120c8b11de0SJosh Wu ret = input_register_device(input); 1121c8b11de0SJosh Wu if (ret) 112284882b06SAlexandre Belloni goto err; 1123c8b11de0SJosh Wu 1124c8b11de0SJosh Wu return ret; 112584882b06SAlexandre Belloni 112684882b06SAlexandre Belloni err: 112784882b06SAlexandre Belloni input_free_device(st->ts_input); 112884882b06SAlexandre Belloni return ret; 1129c8b11de0SJosh Wu } 1130c8b11de0SJosh Wu 1131c8b11de0SJosh Wu static void at91_ts_unregister(struct at91_adc_state *st) 1132c8b11de0SJosh Wu { 1133c8b11de0SJosh Wu input_unregister_device(st->ts_input); 1134c8b11de0SJosh Wu } 1135c8b11de0SJosh Wu 1136fc52692cSGreg Kroah-Hartman static int at91_adc_probe(struct platform_device *pdev) 11370e589d5fSMaxime Ripard { 1138db10e201SJosh Wu unsigned int prsc, mstrclk, ticks, adc_clk, adc_clk_khz, shtim; 11390e589d5fSMaxime Ripard int ret; 11400e589d5fSMaxime Ripard struct iio_dev *idev; 11410e589d5fSMaxime Ripard struct at91_adc_state *st; 1142e748783cSJean-Christophe PLAGNIOL-VILLARD u32 reg; 11430e589d5fSMaxime Ripard 1144f8837532SSachin Kamat idev = devm_iio_device_alloc(&pdev->dev, sizeof(struct at91_adc_state)); 1145f8837532SSachin Kamat if (!idev) 1146f8837532SSachin Kamat return -ENOMEM; 11470e589d5fSMaxime Ripard 11480e589d5fSMaxime Ripard st = iio_priv(idev); 11490e589d5fSMaxime Ripard 1150044d406aSAlexandru Ardelean ret = at91_adc_probe_dt(idev, pdev); 1151*ead1c9f3SAlexandru Ardelean if (ret) 1152*ead1c9f3SAlexandru Ardelean return ret; 11530e589d5fSMaxime Ripard 11540e589d5fSMaxime Ripard platform_set_drvdata(pdev, idev); 11550e589d5fSMaxime Ripard 11560e589d5fSMaxime Ripard idev->name = dev_name(&pdev->dev); 11570e589d5fSMaxime Ripard idev->modes = INDIO_DIRECT_MODE; 11580e589d5fSMaxime Ripard idev->info = &at91_adc_info; 11590e589d5fSMaxime Ripard 11600e589d5fSMaxime Ripard st->irq = platform_get_irq(pdev, 0); 11617c279229SStephen Boyd if (st->irq < 0) 1162f8837532SSachin Kamat return -ENODEV; 11630e589d5fSMaxime Ripard 1164af5c2174SAishwarya Ramakrishnan st->reg_base = devm_platform_ioremap_resource(pdev, 0); 1165c34812e4SVenkat Prashanth B U if (IS_ERR(st->reg_base)) 1166f8837532SSachin Kamat return PTR_ERR(st->reg_base); 1167c34812e4SVenkat Prashanth B U 11680e589d5fSMaxime Ripard 11690e589d5fSMaxime Ripard /* 11700e589d5fSMaxime Ripard * Disable all IRQs before setting up the handler 11710e589d5fSMaxime Ripard */ 11720e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); 11730e589d5fSMaxime Ripard at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); 117484882b06SAlexandre Belloni 117584882b06SAlexandre Belloni if (st->caps->has_tsmr) 117684882b06SAlexandre Belloni ret = request_irq(st->irq, at91_adc_9x5_interrupt, 0, 117784882b06SAlexandre Belloni pdev->dev.driver->name, idev); 117884882b06SAlexandre Belloni else 117984882b06SAlexandre Belloni ret = request_irq(st->irq, at91_adc_rl_interrupt, 0, 118084882b06SAlexandre Belloni pdev->dev.driver->name, idev); 11810e589d5fSMaxime Ripard if (ret) { 11820e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); 1183f8837532SSachin Kamat return ret; 11840e589d5fSMaxime Ripard } 11850e589d5fSMaxime Ripard 1186390d75c1SJulia Lawall st->clk = devm_clk_get(&pdev->dev, "adc_clk"); 11870e589d5fSMaxime Ripard if (IS_ERR(st->clk)) { 11880e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to get the clock.\n"); 11890e589d5fSMaxime Ripard ret = PTR_ERR(st->clk); 11900e589d5fSMaxime Ripard goto error_free_irq; 11910e589d5fSMaxime Ripard } 11920e589d5fSMaxime Ripard 119300062a9cSJulia Lawall ret = clk_prepare_enable(st->clk); 11940e589d5fSMaxime Ripard if (ret) { 119500062a9cSJulia Lawall dev_err(&pdev->dev, 119600062a9cSJulia Lawall "Could not prepare or enable the clock.\n"); 1197390d75c1SJulia Lawall goto error_free_irq; 11980e589d5fSMaxime Ripard } 11990e589d5fSMaxime Ripard 1200390d75c1SJulia Lawall st->adc_clk = devm_clk_get(&pdev->dev, "adc_op_clk"); 12010e589d5fSMaxime Ripard if (IS_ERR(st->adc_clk)) { 12020e589d5fSMaxime Ripard dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); 1203f755bbbfSJulia Lawall ret = PTR_ERR(st->adc_clk); 12040e589d5fSMaxime Ripard goto error_disable_clk; 12050e589d5fSMaxime Ripard } 12060e589d5fSMaxime Ripard 120700062a9cSJulia Lawall ret = clk_prepare_enable(st->adc_clk); 12080e589d5fSMaxime Ripard if (ret) { 120900062a9cSJulia Lawall dev_err(&pdev->dev, 121000062a9cSJulia Lawall "Could not prepare or enable the ADC clock.\n"); 1211390d75c1SJulia Lawall goto error_disable_clk; 12120e589d5fSMaxime Ripard } 12130e589d5fSMaxime Ripard 12140e589d5fSMaxime Ripard /* 12150e589d5fSMaxime Ripard * Prescaler rate computation using the formula from the Atmel's 12160e589d5fSMaxime Ripard * datasheet : ADC Clock = MCK / ((Prescaler + 1) * 2), ADC Clock being 12170e589d5fSMaxime Ripard * specified by the electrical characteristics of the board. 12180e589d5fSMaxime Ripard */ 12190e589d5fSMaxime Ripard mstrclk = clk_get_rate(st->clk); 12200e589d5fSMaxime Ripard adc_clk = clk_get_rate(st->adc_clk); 1221db10e201SJosh Wu adc_clk_khz = adc_clk / 1000; 1222c8b11de0SJosh Wu 1223c8b11de0SJosh Wu dev_dbg(&pdev->dev, "Master clock is set as: %d Hz, adc_clk should set as: %d Hz\n", 1224c8b11de0SJosh Wu mstrclk, adc_clk); 1225c8b11de0SJosh Wu 12260e589d5fSMaxime Ripard prsc = (mstrclk / (2 * adc_clk)) - 1; 12270e589d5fSMaxime Ripard 12280e589d5fSMaxime Ripard if (!st->startup_time) { 12290e589d5fSMaxime Ripard dev_err(&pdev->dev, "No startup time available.\n"); 12300e589d5fSMaxime Ripard ret = -EINVAL; 12310e589d5fSMaxime Ripard goto error_disable_adc_clk; 12320e589d5fSMaxime Ripard } 1233c4601666SJosh Wu ticks = (*st->caps->calc_startup_ticks)(st->startup_time, adc_clk_khz); 12340e589d5fSMaxime Ripard 12350e589d5fSMaxime Ripard /* 1236beca9e76SJean-Christophe PLAGNIOL-VILLARD * a minimal Sample and Hold Time is necessary for the ADC to guarantee 1237beca9e76SJean-Christophe PLAGNIOL-VILLARD * the best converted final value between two channels selection 1238beca9e76SJean-Christophe PLAGNIOL-VILLARD * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock 1239beca9e76SJean-Christophe PLAGNIOL-VILLARD */ 12408f32b6baSAlexandre Belloni if (st->sample_hold_time > 0) 12418f32b6baSAlexandre Belloni shtim = round_up((st->sample_hold_time * adc_clk_khz / 1000) 12428f32b6baSAlexandre Belloni - 1, 1); 12438f32b6baSAlexandre Belloni else 12448f32b6baSAlexandre Belloni shtim = 0; 1245beca9e76SJean-Christophe PLAGNIOL-VILLARD 12469120c0beSJosh Wu reg = AT91_ADC_PRESCAL_(prsc) & st->registers->mr_prescal_mask; 12479120c0beSJosh Wu reg |= AT91_ADC_STARTUP_(ticks) & st->registers->mr_startup_mask; 124847be16b6SLudovic Desroches if (st->low_res) 1249e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_LOWRES; 1250e748783cSJean-Christophe PLAGNIOL-VILLARD if (st->sleep_mode) 1251e748783cSJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_SLEEP; 1252beca9e76SJean-Christophe PLAGNIOL-VILLARD reg |= AT91_ADC_SHTIM_(shtim) & AT91_ADC_SHTIM; 1253e748783cSJean-Christophe PLAGNIOL-VILLARD at91_adc_writel(st, AT91_ADC_MR, reg); 12540e589d5fSMaxime Ripard 12550e589d5fSMaxime Ripard /* Setup the ADC channels available on the board */ 12560e589d5fSMaxime Ripard ret = at91_adc_channel_init(idev); 12570e589d5fSMaxime Ripard if (ret < 0) { 12580e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't initialize the channels.\n"); 12590e589d5fSMaxime Ripard goto error_disable_adc_clk; 12600e589d5fSMaxime Ripard } 12610e589d5fSMaxime Ripard 12620e589d5fSMaxime Ripard init_waitqueue_head(&st->wq_data_avail); 12630e589d5fSMaxime Ripard mutex_init(&st->lock); 12640e589d5fSMaxime Ripard 1265c8b11de0SJosh Wu /* 1266c8b11de0SJosh Wu * Since touch screen will set trigger register as period trigger. So 1267c8b11de0SJosh Wu * when touch screen is enabled, then we have to disable hardware 1268c8b11de0SJosh Wu * trigger for classic adc. 1269c8b11de0SJosh Wu */ 1270c8b11de0SJosh Wu if (!st->touchscreen_type) { 12710e589d5fSMaxime Ripard ret = at91_adc_buffer_init(idev); 12720e589d5fSMaxime Ripard if (ret < 0) { 12730e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't initialize the buffer.\n"); 12740e589d5fSMaxime Ripard goto error_disable_adc_clk; 12750e589d5fSMaxime Ripard } 12760e589d5fSMaxime Ripard 12770e589d5fSMaxime Ripard ret = at91_adc_trigger_init(idev); 12780e589d5fSMaxime Ripard if (ret < 0) { 12790e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't setup the triggers.\n"); 1280c8b11de0SJosh Wu at91_adc_buffer_remove(idev); 1281c8b11de0SJosh Wu goto error_disable_adc_clk; 1282c8b11de0SJosh Wu } 1283c8b11de0SJosh Wu } else { 1284044d406aSAlexandru Ardelean ret = at91_ts_register(idev, pdev); 1285c8b11de0SJosh Wu if (ret) 1286c8b11de0SJosh Wu goto error_disable_adc_clk; 1287c8b11de0SJosh Wu 1288044d406aSAlexandru Ardelean at91_ts_hw_init(idev, adc_clk_khz); 12890e589d5fSMaxime Ripard } 12900e589d5fSMaxime Ripard 12910e589d5fSMaxime Ripard ret = iio_device_register(idev); 12920e589d5fSMaxime Ripard if (ret < 0) { 12930e589d5fSMaxime Ripard dev_err(&pdev->dev, "Couldn't register the device.\n"); 1294c8b11de0SJosh Wu goto error_iio_device_register; 12950e589d5fSMaxime Ripard } 12960e589d5fSMaxime Ripard 12970e589d5fSMaxime Ripard return 0; 12980e589d5fSMaxime Ripard 1299c8b11de0SJosh Wu error_iio_device_register: 1300c8b11de0SJosh Wu if (!st->touchscreen_type) { 13010e589d5fSMaxime Ripard at91_adc_trigger_remove(idev); 13020e589d5fSMaxime Ripard at91_adc_buffer_remove(idev); 1303c8b11de0SJosh Wu } else { 1304c8b11de0SJosh Wu at91_ts_unregister(st); 1305c8b11de0SJosh Wu } 13060e589d5fSMaxime Ripard error_disable_adc_clk: 130700062a9cSJulia Lawall clk_disable_unprepare(st->adc_clk); 13080e589d5fSMaxime Ripard error_disable_clk: 130900062a9cSJulia Lawall clk_disable_unprepare(st->clk); 13100e589d5fSMaxime Ripard error_free_irq: 13110e589d5fSMaxime Ripard free_irq(st->irq, idev); 13120e589d5fSMaxime Ripard return ret; 13130e589d5fSMaxime Ripard } 13140e589d5fSMaxime Ripard 1315fc52692cSGreg Kroah-Hartman static int at91_adc_remove(struct platform_device *pdev) 13160e589d5fSMaxime Ripard { 13170e589d5fSMaxime Ripard struct iio_dev *idev = platform_get_drvdata(pdev); 13180e589d5fSMaxime Ripard struct at91_adc_state *st = iio_priv(idev); 13190e589d5fSMaxime Ripard 13200e589d5fSMaxime Ripard iio_device_unregister(idev); 1321c8b11de0SJosh Wu if (!st->touchscreen_type) { 13220e589d5fSMaxime Ripard at91_adc_trigger_remove(idev); 13230e589d5fSMaxime Ripard at91_adc_buffer_remove(idev); 1324c8b11de0SJosh Wu } else { 1325c8b11de0SJosh Wu at91_ts_unregister(st); 1326c8b11de0SJosh Wu } 13270e589d5fSMaxime Ripard clk_disable_unprepare(st->adc_clk); 132800062a9cSJulia Lawall clk_disable_unprepare(st->clk); 13290e589d5fSMaxime Ripard free_irq(st->irq, idev); 13300e589d5fSMaxime Ripard 13310e589d5fSMaxime Ripard return 0; 13320e589d5fSMaxime Ripard } 13330e589d5fSMaxime Ripard 1334bc3ae982SWenyou Yang #ifdef CONFIG_PM_SLEEP 1335bc3ae982SWenyou Yang static int at91_adc_suspend(struct device *dev) 1336bc3ae982SWenyou Yang { 1337e3faedf7SKefeng Wang struct iio_dev *idev = dev_get_drvdata(dev); 1338bc3ae982SWenyou Yang struct at91_adc_state *st = iio_priv(idev); 1339bc3ae982SWenyou Yang 1340bc3ae982SWenyou Yang pinctrl_pm_select_sleep_state(dev); 1341bc3ae982SWenyou Yang clk_disable_unprepare(st->clk); 1342bc3ae982SWenyou Yang 1343bc3ae982SWenyou Yang return 0; 1344bc3ae982SWenyou Yang } 1345bc3ae982SWenyou Yang 1346bc3ae982SWenyou Yang static int at91_adc_resume(struct device *dev) 1347bc3ae982SWenyou Yang { 1348e3faedf7SKefeng Wang struct iio_dev *idev = dev_get_drvdata(dev); 1349bc3ae982SWenyou Yang struct at91_adc_state *st = iio_priv(idev); 1350bc3ae982SWenyou Yang 1351bc3ae982SWenyou Yang clk_prepare_enable(st->clk); 1352bc3ae982SWenyou Yang pinctrl_pm_select_default_state(dev); 1353bc3ae982SWenyou Yang 1354bc3ae982SWenyou Yang return 0; 1355bc3ae982SWenyou Yang } 1356bc3ae982SWenyou Yang #endif 1357bc3ae982SWenyou Yang 1358bc3ae982SWenyou Yang static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume); 1359bc3ae982SWenyou Yang 1360e1811f97SJosh Wu static struct at91_adc_caps at91sam9260_caps = { 1361c4601666SJosh Wu .calc_startup_ticks = calc_startup_ticks_9260, 13622b6d598bSJosh Wu .num_channels = 4, 1363e1811f97SJosh Wu .registers = { 1364e1811f97SJosh Wu .channel_base = AT91_ADC_CHR(0), 1365e1811f97SJosh Wu .drdy_mask = AT91_ADC_DRDY, 1366e1811f97SJosh Wu .status_register = AT91_ADC_SR, 1367e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9260, 13689120c0beSJosh Wu .mr_prescal_mask = AT91_ADC_PRESCAL_9260, 13699120c0beSJosh Wu .mr_startup_mask = AT91_ADC_STARTUP_9260, 1370e1811f97SJosh Wu }, 1371e1811f97SJosh Wu }; 1372e1811f97SJosh Wu 137365b1fdbaSAlexandre Belloni static struct at91_adc_caps at91sam9rl_caps = { 137465b1fdbaSAlexandre Belloni .has_ts = true, 137565b1fdbaSAlexandre Belloni .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */ 137665b1fdbaSAlexandre Belloni .num_channels = 6, 137765b1fdbaSAlexandre Belloni .registers = { 137865b1fdbaSAlexandre Belloni .channel_base = AT91_ADC_CHR(0), 137965b1fdbaSAlexandre Belloni .drdy_mask = AT91_ADC_DRDY, 138065b1fdbaSAlexandre Belloni .status_register = AT91_ADC_SR, 138165b1fdbaSAlexandre Belloni .trigger_register = AT91_ADC_TRGR_9G45, 138265b1fdbaSAlexandre Belloni .mr_prescal_mask = AT91_ADC_PRESCAL_9260, 138365b1fdbaSAlexandre Belloni .mr_startup_mask = AT91_ADC_STARTUP_9G45, 138465b1fdbaSAlexandre Belloni }, 138565b1fdbaSAlexandre Belloni }; 138665b1fdbaSAlexandre Belloni 1387e1811f97SJosh Wu static struct at91_adc_caps at91sam9g45_caps = { 1388c8b11de0SJosh Wu .has_ts = true, 1389c4601666SJosh Wu .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */ 13902b6d598bSJosh Wu .num_channels = 8, 1391e1811f97SJosh Wu .registers = { 1392e1811f97SJosh Wu .channel_base = AT91_ADC_CHR(0), 1393e1811f97SJosh Wu .drdy_mask = AT91_ADC_DRDY, 1394e1811f97SJosh Wu .status_register = AT91_ADC_SR, 1395e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9G45, 13969120c0beSJosh Wu .mr_prescal_mask = AT91_ADC_PRESCAL_9G45, 13979120c0beSJosh Wu .mr_startup_mask = AT91_ADC_STARTUP_9G45, 1398e1811f97SJosh Wu }, 1399e1811f97SJosh Wu }; 1400e1811f97SJosh Wu 1401e1811f97SJosh Wu static struct at91_adc_caps at91sam9x5_caps = { 1402c8b11de0SJosh Wu .has_ts = true, 1403c8b11de0SJosh Wu .has_tsmr = true, 1404c8b11de0SJosh Wu .ts_filter_average = 3, 1405c8b11de0SJosh Wu .ts_pen_detect_sensitivity = 2, 1406c4601666SJosh Wu .calc_startup_ticks = calc_startup_ticks_9x5, 14072b6d598bSJosh Wu .num_channels = 12, 1408e1811f97SJosh Wu .registers = { 1409e1811f97SJosh Wu .channel_base = AT91_ADC_CDR0_9X5, 1410e1811f97SJosh Wu .drdy_mask = AT91_ADC_SR_DRDY_9X5, 1411e1811f97SJosh Wu .status_register = AT91_ADC_SR_9X5, 1412e1811f97SJosh Wu .trigger_register = AT91_ADC_TRGR_9X5, 14139120c0beSJosh Wu /* prescal mask is same as 9G45 */ 14149120c0beSJosh Wu .mr_prescal_mask = AT91_ADC_PRESCAL_9G45, 14159120c0beSJosh Wu .mr_startup_mask = AT91_ADC_STARTUP_9X5, 1416e1811f97SJosh Wu }, 1417e1811f97SJosh Wu }; 1418e1811f97SJosh Wu 1419e364185fSMaxime Ripard static const struct of_device_id at91_adc_dt_ids[] = { 1420e1811f97SJosh Wu { .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps }, 142165b1fdbaSAlexandre Belloni { .compatible = "atmel,at91sam9rl-adc", .data = &at91sam9rl_caps }, 1422e1811f97SJosh Wu { .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps }, 1423e1811f97SJosh Wu { .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps }, 1424e364185fSMaxime Ripard {}, 1425e364185fSMaxime Ripard }; 1426e364185fSMaxime Ripard MODULE_DEVICE_TABLE(of, at91_adc_dt_ids); 1427467a44b0SAlexandre Belloni 1428467a44b0SAlexandre Belloni static const struct platform_device_id at91_adc_ids[] = { 1429467a44b0SAlexandre Belloni { 1430467a44b0SAlexandre Belloni .name = "at91sam9260-adc", 1431467a44b0SAlexandre Belloni .driver_data = (unsigned long)&at91sam9260_caps, 1432467a44b0SAlexandre Belloni }, { 143365b1fdbaSAlexandre Belloni .name = "at91sam9rl-adc", 143465b1fdbaSAlexandre Belloni .driver_data = (unsigned long)&at91sam9rl_caps, 143565b1fdbaSAlexandre Belloni }, { 1436467a44b0SAlexandre Belloni .name = "at91sam9g45-adc", 1437467a44b0SAlexandre Belloni .driver_data = (unsigned long)&at91sam9g45_caps, 1438467a44b0SAlexandre Belloni }, { 1439467a44b0SAlexandre Belloni .name = "at91sam9x5-adc", 1440467a44b0SAlexandre Belloni .driver_data = (unsigned long)&at91sam9x5_caps, 1441467a44b0SAlexandre Belloni }, { 1442467a44b0SAlexandre Belloni /* terminator */ 1443467a44b0SAlexandre Belloni } 1444467a44b0SAlexandre Belloni }; 1445467a44b0SAlexandre Belloni MODULE_DEVICE_TABLE(platform, at91_adc_ids); 1446e364185fSMaxime Ripard 14470e589d5fSMaxime Ripard static struct platform_driver at91_adc_driver = { 14480e589d5fSMaxime Ripard .probe = at91_adc_probe, 1449fc52692cSGreg Kroah-Hartman .remove = at91_adc_remove, 1450467a44b0SAlexandre Belloni .id_table = at91_adc_ids, 14510e589d5fSMaxime Ripard .driver = { 1452c8b11de0SJosh Wu .name = DRIVER_NAME, 1453f091d7c5SAlexandru Ardelean .of_match_table = at91_adc_dt_ids, 1454bc3ae982SWenyou Yang .pm = &at91_adc_pm_ops, 14550e589d5fSMaxime Ripard }, 14560e589d5fSMaxime Ripard }; 14570e589d5fSMaxime Ripard 14580e589d5fSMaxime Ripard module_platform_driver(at91_adc_driver); 14590e589d5fSMaxime Ripard 14600e589d5fSMaxime Ripard MODULE_LICENSE("GPL"); 14610e589d5fSMaxime Ripard MODULE_DESCRIPTION("Atmel AT91 ADC Driver"); 14620e589d5fSMaxime Ripard MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 1463