2012-05-11 15:35:33 +02:00
/*
* Driver for the ADC present in the Atmel AT91 evaluation boards .
*
* Copyright 2011 Free Electrons
*
* Licensed under the GPLv2 or later .
*/
# include <linux/bitmap.h>
# include <linux/bitops.h>
# include <linux/clk.h>
# include <linux/err.h>
# include <linux/io.h>
2013-10-08 04:48:00 +01:00
# include <linux/input.h>
2012-05-11 15:35:33 +02:00
# include <linux/interrupt.h>
# include <linux/jiffies.h>
# include <linux/kernel.h>
# include <linux/module.h>
2012-05-11 15:35:37 +02:00
# include <linux/of.h>
# include <linux/of_device.h>
2012-05-11 15:35:33 +02:00
# include <linux/platform_device.h>
# include <linux/sched.h>
# include <linux/slab.h>
# include <linux/wait.h>
# include <linux/platform_data/at91_adc.h>
# include <linux/iio/iio.h>
# include <linux/iio/buffer.h>
# include <linux/iio/trigger.h>
# include <linux/iio/trigger_consumer.h>
2012-06-18 18:33:49 +02:00
# include <linux/iio/triggered_buffer.h>
2016-11-02 17:21:48 +08:00
# include <linux/pinctrl/consumer.h>
2012-05-11 15:35:33 +02:00
2014-04-15 12:28:01 +02:00
/* Registers */
# define AT91_ADC_CR 0x00 /* Control Register */
# define AT91_ADC_SWRST (1 << 0) /* Software Reset */
# define AT91_ADC_START (1 << 1) /* Start Conversion */
# define AT91_ADC_MR 0x04 /* Mode Register */
# define AT91_ADC_TSAMOD (3 << 0) /* ADC mode */
# define AT91_ADC_TSAMOD_ADC_ONLY_MODE (0 << 0) /* ADC Mode */
# define AT91_ADC_TSAMOD_TS_ONLY_MODE (1 << 0) /* Touch Screen Only Mode */
# define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */
# define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */
# define AT91_ADC_TRGSEL_TC0 (0 << 1)
# define AT91_ADC_TRGSEL_TC1 (1 << 1)
# define AT91_ADC_TRGSEL_TC2 (2 << 1)
# define AT91_ADC_TRGSEL_EXTERNAL (6 << 1)
# define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */
# define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */
# define AT91_ADC_PENDET (1 << 6) /* Pen contact detection enable */
# define AT91_ADC_PRESCAL_9260 (0x3f << 8) /* Prescalar Rate Selection */
# define AT91_ADC_PRESCAL_9G45 (0xff << 8)
# define AT91_ADC_PRESCAL_(x) ((x) << 8)
# define AT91_ADC_STARTUP_9260 (0x1f << 16) /* Startup Up Time */
# define AT91_ADC_STARTUP_9G45 (0x7f << 16)
# define AT91_ADC_STARTUP_9X5 (0xf << 16)
# define AT91_ADC_STARTUP_(x) ((x) << 16)
# define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */
# define AT91_ADC_SHTIM_(x) ((x) << 24)
# define AT91_ADC_PENDBC (0x0f << 28) /* Pen Debounce time */
# define AT91_ADC_PENDBC_(x) ((x) << 28)
# define AT91_ADC_TSR 0x0C
# define AT91_ADC_TSR_SHTIM (0xf << 24) /* Sample & Hold Time */
# define AT91_ADC_TSR_SHTIM_(x) ((x) << 24)
# define AT91_ADC_CHER 0x10 /* Channel Enable Register */
# define AT91_ADC_CHDR 0x14 /* Channel Disable Register */
# define AT91_ADC_CHSR 0x18 /* Channel Status Register */
# define AT91_ADC_CH(n) (1 << (n)) /* Channel Number */
# define AT91_ADC_SR 0x1C /* Status Register */
# define AT91_ADC_EOC(n) (1 << (n)) /* End of Conversion on Channel N */
# define AT91_ADC_OVRE(n) (1 << ((n) + 8)) /* Overrun Error on Channel N */
# define AT91_ADC_DRDY (1 << 16) /* Data Ready */
# define AT91_ADC_GOVRE (1 << 17) /* General Overrun Error */
# define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */
# define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */
# define AT91_ADC_SR_9X5 0x30 /* Status Register for 9x5 */
# define AT91_ADC_SR_DRDY_9X5 (1 << 24) /* Data Ready */
# define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */
# define AT91_ADC_LDATA (0x3ff)
# define AT91_ADC_IER 0x24 /* Interrupt Enable Register */
# define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */
# define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */
# define AT91RL_ADC_IER_PEN (1 << 20)
# define AT91RL_ADC_IER_NOPEN (1 << 21)
# define AT91_ADC_IER_PEN (1 << 29)
# define AT91_ADC_IER_NOPEN (1 << 30)
# define AT91_ADC_IER_XRDY (1 << 20)
# define AT91_ADC_IER_YRDY (1 << 21)
# define AT91_ADC_IER_PRDY (1 << 22)
# define AT91_ADC_ISR_PENS (1 << 31)
# define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */
# define AT91_ADC_DATA (0x3ff)
# define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */
# define AT91_ADC_ACR 0x94 /* Analog Control Register */
# define AT91_ADC_ACR_PENDETSENS (0x3 << 0) /* pull-up resistor */
# define AT91_ADC_TSMR 0xB0
# define AT91_ADC_TSMR_TSMODE (3 << 0) /* Touch Screen Mode */
# define AT91_ADC_TSMR_TSMODE_NONE (0 << 0)
# define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0)
# define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0)
# define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0)
# define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */
# define AT91_ADC_TSMR_TSAV_(x) ((x) << 4)
# define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */
2016-08-30 14:27:01 +02:00
# define AT91_ADC_TSMR_SCTIM_(x) ((x) << 16)
2014-04-15 12:28:01 +02:00
# define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */
# define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28)
# define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */
# define AT91_ADC_TSMR_PENDET_DIS (0 << 24) /* Pen contact detection disable */
# define AT91_ADC_TSMR_PENDET_ENA (1 << 24) /* Pen contact detection enable */
# define AT91_ADC_TSXPOSR 0xB4
# define AT91_ADC_TSYPOSR 0xB8
# define AT91_ADC_TSPRESSR 0xBC
# define AT91_ADC_TRGR_9260 AT91_ADC_MR
# define AT91_ADC_TRGR_9G45 0x08
# define AT91_ADC_TRGR_9X5 0xC0
/* Trigger Register bit field */
# define AT91_ADC_TRGR_TRGPER (0xffff << 16)
# define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16)
# define AT91_ADC_TRGR_TRGMOD (0x7 << 0)
# define AT91_ADC_TRGR_NONE (0 << 0)
# define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0)
2012-05-11 15:35:33 +02:00
# define AT91_ADC_CHAN(st, ch) \
( st - > registers - > channel_base + ( ch * 4 ) )
# define at91_adc_readl(st, reg) \
( readl_relaxed ( st - > reg_base + reg ) )
# define at91_adc_writel(st, reg, val) \
( writel_relaxed ( val , st - > reg_base + reg ) )
2013-10-08 04:48:00 +01:00
# define DRIVER_NAME "at91_adc"
# define MAX_POS_BITS 12
# define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */
# define TOUCH_PEN_DETECT_DEBOUNCE_US 200
2014-04-15 12:27:59 +02:00
# define MAX_RLPOS_BITS 10
# define TOUCH_SAMPLE_PERIOD_US_RL 10000 /* 10ms, the SoC can't keep up with 2ms */
# define TOUCH_SHTIM 0xa
2016-08-30 14:27:01 +02:00
# define TOUCH_SCTIM_US 10 /* 10us for the Touchscreen Switches Closure Time */
2014-04-15 12:27:59 +02:00
2014-04-15 12:27:58 +02:00
/**
* struct at91_adc_reg_desc - Various informations relative to registers
* @ channel_base : Base offset for the channel data registers
* @ drdy_mask : Mask of the DRDY field in the relevant registers
( Interruptions registers mostly )
* @ status_register : Offset of the Interrupt Status Register
* @ trigger_register : Offset of the Trigger setup register
* @ mr_prescal_mask : Mask of the PRESCAL field in the adc MR register
* @ mr_startup_mask : Mask of the STARTUP field in the adc MR register
*/
struct at91_adc_reg_desc {
u8 channel_base ;
u32 drdy_mask ;
u8 status_register ;
u8 trigger_register ;
u32 mr_prescal_mask ;
u32 mr_startup_mask ;
} ;
2013-08-27 12:28:00 +01:00
struct at91_adc_caps {
2013-10-08 04:48:00 +01:00
bool has_ts ; /* Support touch screen */
bool has_tsmr ; /* only at91sam9x5, sama5d3 have TSMR reg */
/*
* Numbers of sampling data will be averaged . Can be 0 ~ 3.
* Hardware can average ( 2 ^ ts_filter_average ) sample data .
*/
u8 ts_filter_average ;
/* Pen Detection input pull-up resistor, can be 0~3 */
u8 ts_pen_detect_sensitivity ;
2013-10-08 04:48:00 +01:00
/* startup time calculate function */
2015-06-17 18:21:36 +02:00
u32 ( * calc_startup_ticks ) ( u32 startup_time , u32 adc_clk_khz ) ;
2013-10-08 04:48:00 +01:00
2013-10-08 04:48:00 +01:00
u8 num_channels ;
2013-08-27 12:28:00 +01:00
struct at91_adc_reg_desc registers ;
} ;
2012-05-11 15:35:33 +02:00
struct at91_adc_state {
struct clk * adc_clk ;
u16 * buffer ;
unsigned long channels_mask ;
struct clk * clk ;
bool done ;
int irq ;
u16 last_value ;
2014-10-09 15:02:00 +01:00
int chnb ;
2012-05-11 15:35:33 +02:00
struct mutex lock ;
u8 num_channels ;
void __iomem * reg_base ;
struct at91_adc_reg_desc * registers ;
2015-06-17 18:21:36 +02:00
u32 startup_time ;
2013-03-29 14:54:00 +00:00
u8 sample_hold_time ;
2013-03-29 14:54:00 +00:00
bool sleep_mode ;
2012-05-11 15:35:33 +02:00
struct iio_trigger * * trig ;
struct at91_adc_trigger * trigger_list ;
u32 trigger_number ;
bool use_external ;
u32 vref_mv ;
2013-03-29 14:54:00 +00:00
u32 res ; /* resolution used for convertions */
bool low_res ; /* the resolution corresponds to the lowest one */
2012-05-11 15:35:33 +02:00
wait_queue_head_t wq_data_avail ;
2013-08-27 12:28:00 +01:00
struct at91_adc_caps * caps ;
2013-10-08 04:48:00 +01:00
/*
* Following ADC channels are shared by touchscreen :
*
* CH0 - - Touch screen XP / UL
* CH1 - - Touch screen XM / UR
* CH2 - - Touch screen YP / LL
* CH3 - - Touch screen YM / Sense
* CH4 - - Touch screen LR ( 5 - wire only )
*
* The bitfields below represents the reserved channel in the
* touchscreen mode .
*/
# define CHAN_MASK_TOUCHSCREEN_4WIRE (0xf << 0)
# define CHAN_MASK_TOUCHSCREEN_5WIRE (0x1f << 0)
enum atmel_adc_ts_type touchscreen_type ;
struct input_dev * ts_input ;
u16 ts_sample_period_val ;
u32 ts_pressure_threshold ;
2014-04-15 12:27:59 +02:00
u16 ts_pendbc ;
bool ts_bufferedmeasure ;
u32 ts_prev_absx ;
u32 ts_prev_absy ;
2012-05-11 15:35:33 +02:00
} ;
static irqreturn_t at91_adc_trigger_handler ( int irq , void * p )
{
struct iio_poll_func * pf = p ;
struct iio_dev * idev = pf - > indio_dev ;
struct at91_adc_state * st = iio_priv ( idev ) ;
int i , j = 0 ;
for ( i = 0 ; i < idev - > masklength ; i + + ) {
if ( ! test_bit ( i , idev - > active_scan_mask ) )
continue ;
st - > buffer [ j ] = at91_adc_readl ( st , AT91_ADC_CHAN ( st , i ) ) ;
j + + ;
}
2013-09-19 13:59:00 +01:00
iio_push_to_buffers_with_timestamp ( idev , st - > buffer , pf - > timestamp ) ;
2012-05-11 15:35:33 +02:00
iio_trigger_notify_done ( idev - > trig ) ;
/* Needed to ACK the DRDY interruption */
at91_adc_readl ( st , AT91_ADC_LCDR ) ;
enable_irq ( st - > irq ) ;
return IRQ_HANDLED ;
}
2013-10-08 04:48:00 +01:00
/* Handler for classic adc channel eoc trigger */
2014-08-27 09:31:00 +01:00
static void handle_adc_eoc_trigger ( int irq , struct iio_dev * idev )
2012-05-11 15:35:33 +02:00
{
struct at91_adc_state * st = iio_priv ( idev ) ;
if ( iio_buffer_enabled ( idev ) ) {
disable_irq_nosync ( irq ) ;
2014-12-06 06:46:00 +00:00
iio_trigger_poll ( idev - > trig ) ;
2012-05-11 15:35:33 +02:00
} else {
2014-10-09 15:02:00 +01:00
st - > last_value = at91_adc_readl ( st , AT91_ADC_CHAN ( st , st - > chnb ) ) ;
2012-05-11 15:35:33 +02:00
st - > done = true ;
wake_up_interruptible ( & st - > wq_data_avail ) ;
}
2013-10-08 04:48:00 +01:00
}
static int at91_ts_sample ( struct at91_adc_state * st )
{
unsigned int xscale , yscale , reg , z1 , z2 ;
unsigned int x , y , pres , xpos , ypos ;
unsigned int rxp = 1 ;
unsigned int factor = 1000 ;
struct iio_dev * idev = iio_priv_to_dev ( st ) ;
unsigned int xyz_mask_bits = st - > res ;
unsigned int xyz_mask = ( 1 < < xyz_mask_bits ) - 1 ;
/* calculate position */
/* x position = (x / xscale) * max, max = 2^MAX_POS_BITS - 1 */
reg = at91_adc_readl ( st , AT91_ADC_TSXPOSR ) ;
xpos = reg & xyz_mask ;
x = ( xpos < < MAX_POS_BITS ) - xpos ;
xscale = ( reg > > 16 ) & xyz_mask ;
if ( xscale = = 0 ) {
dev_err ( & idev - > dev , " Error: xscale == 0! \n " ) ;
return - 1 ;
}
x / = xscale ;
/* y position = (y / yscale) * max, max = 2^MAX_POS_BITS - 1 */
reg = at91_adc_readl ( st , AT91_ADC_TSYPOSR ) ;
ypos = reg & xyz_mask ;
y = ( ypos < < MAX_POS_BITS ) - ypos ;
yscale = ( reg > > 16 ) & xyz_mask ;
if ( yscale = = 0 ) {
dev_err ( & idev - > dev , " Error: yscale == 0! \n " ) ;
return - 1 ;
}
y / = yscale ;
/* calculate the pressure */
reg = at91_adc_readl ( st , AT91_ADC_TSPRESSR ) ;
z1 = reg & xyz_mask ;
z2 = ( reg > > 16 ) & xyz_mask ;
if ( z1 ! = 0 )
pres = rxp * ( x * factor / 1024 ) * ( z2 * factor / z1 - factor )
/ factor ;
else
pres = st - > ts_pressure_threshold ; /* no pen contacted */
dev_dbg ( & idev - > dev , " xpos = %d, xscale = %d, ypos = %d, yscale = %d, z1 = %d, z2 = %d, press = %d \n " ,
xpos , xscale , ypos , yscale , z1 , z2 , pres ) ;
if ( pres < st - > ts_pressure_threshold ) {
dev_dbg ( & idev - > dev , " x = %d, y = %d, pressure = %d \n " ,
x , y , pres / factor ) ;
input_report_abs ( st - > ts_input , ABS_X , x ) ;
input_report_abs ( st - > ts_input , ABS_Y , y ) ;
input_report_abs ( st - > ts_input , ABS_PRESSURE , pres ) ;
input_report_key ( st - > ts_input , BTN_TOUCH , 1 ) ;
input_sync ( st - > ts_input ) ;
} else {
dev_dbg ( & idev - > dev , " pressure too low: not reporting \n " ) ;
}
return 0 ;
}
2014-04-15 12:27:59 +02:00
static irqreturn_t at91_adc_rl_interrupt ( int irq , void * private )
{
struct iio_dev * idev = private ;
struct at91_adc_state * st = iio_priv ( idev ) ;
u32 status = at91_adc_readl ( st , st - > registers - > status_register ) ;
unsigned int reg ;
status & = at91_adc_readl ( st , AT91_ADC_IMR ) ;
2014-10-09 15:02:00 +01:00
if ( status & GENMASK ( st - > num_channels - 1 , 0 ) )
2014-04-15 12:27:59 +02:00
handle_adc_eoc_trigger ( irq , idev ) ;
if ( status & AT91RL_ADC_IER_PEN ) {
/* Disabling pen debounce is required to get a NOPEN irq */
reg = at91_adc_readl ( st , AT91_ADC_MR ) ;
reg & = ~ AT91_ADC_PENDBC ;
at91_adc_writel ( st , AT91_ADC_MR , reg ) ;
at91_adc_writel ( st , AT91_ADC_IDR , AT91RL_ADC_IER_PEN ) ;
at91_adc_writel ( st , AT91_ADC_IER , AT91RL_ADC_IER_NOPEN
| AT91_ADC_EOC ( 3 ) ) ;
/* Set up period trigger for sampling */
at91_adc_writel ( st , st - > registers - > trigger_register ,
AT91_ADC_TRGR_MOD_PERIOD_TRIG |
AT91_ADC_TRGR_TRGPER_ ( st - > ts_sample_period_val ) ) ;
} else if ( status & AT91RL_ADC_IER_NOPEN ) {
reg = at91_adc_readl ( st , AT91_ADC_MR ) ;
reg | = AT91_ADC_PENDBC_ ( st - > ts_pendbc ) & AT91_ADC_PENDBC ;
at91_adc_writel ( st , AT91_ADC_MR , reg ) ;
at91_adc_writel ( st , st - > registers - > trigger_register ,
AT91_ADC_TRGR_NONE ) ;
at91_adc_writel ( st , AT91_ADC_IDR , AT91RL_ADC_IER_NOPEN
| AT91_ADC_EOC ( 3 ) ) ;
at91_adc_writel ( st , AT91_ADC_IER , AT91RL_ADC_IER_PEN ) ;
st - > ts_bufferedmeasure = false ;
input_report_key ( st - > ts_input , BTN_TOUCH , 0 ) ;
input_sync ( st - > ts_input ) ;
2016-08-08 14:42:16 +02:00
} else if ( status & AT91_ADC_EOC ( 3 ) & & st - > ts_input ) {
/* Conversion finished and we've a touchscreen */
2014-04-15 12:27:59 +02:00
if ( st - > ts_bufferedmeasure ) {
/*
* Last measurement is always discarded , since it can
* be erroneous .
* Always report previous measurement
*/
input_report_abs ( st - > ts_input , ABS_X , st - > ts_prev_absx ) ;
input_report_abs ( st - > ts_input , ABS_Y , st - > ts_prev_absy ) ;
input_report_key ( st - > ts_input , BTN_TOUCH , 1 ) ;
input_sync ( st - > ts_input ) ;
} else
st - > ts_bufferedmeasure = true ;
/* Now make new measurement */
st - > ts_prev_absx = at91_adc_readl ( st , AT91_ADC_CHAN ( st , 3 ) )
< < MAX_RLPOS_BITS ;
st - > ts_prev_absx / = at91_adc_readl ( st , AT91_ADC_CHAN ( st , 2 ) ) ;
st - > ts_prev_absy = at91_adc_readl ( st , AT91_ADC_CHAN ( st , 1 ) )
< < MAX_RLPOS_BITS ;
st - > ts_prev_absy / = at91_adc_readl ( st , AT91_ADC_CHAN ( st , 0 ) ) ;
}
return IRQ_HANDLED ;
}
static irqreturn_t at91_adc_9x5_interrupt ( int irq , void * private )
2013-10-08 04:48:00 +01:00
{
struct iio_dev * idev = private ;
struct at91_adc_state * st = iio_priv ( idev ) ;
u32 status = at91_adc_readl ( st , st - > registers - > status_register ) ;
const uint32_t ts_data_irq_mask =
AT91_ADC_IER_XRDY |
AT91_ADC_IER_YRDY |
AT91_ADC_IER_PRDY ;
2014-10-09 15:02:00 +01:00
if ( status & GENMASK ( st - > num_channels - 1 , 0 ) )
2013-10-08 04:48:00 +01:00
handle_adc_eoc_trigger ( irq , idev ) ;
if ( status & AT91_ADC_IER_PEN ) {
at91_adc_writel ( st , AT91_ADC_IDR , AT91_ADC_IER_PEN ) ;
at91_adc_writel ( st , AT91_ADC_IER , AT91_ADC_IER_NOPEN |
ts_data_irq_mask ) ;
/* Set up period trigger for sampling */
at91_adc_writel ( st , st - > registers - > trigger_register ,
AT91_ADC_TRGR_MOD_PERIOD_TRIG |
AT91_ADC_TRGR_TRGPER_ ( st - > ts_sample_period_val ) ) ;
} else if ( status & AT91_ADC_IER_NOPEN ) {
at91_adc_writel ( st , st - > registers - > trigger_register , 0 ) ;
at91_adc_writel ( st , AT91_ADC_IDR , AT91_ADC_IER_NOPEN |
ts_data_irq_mask ) ;
at91_adc_writel ( st , AT91_ADC_IER , AT91_ADC_IER_PEN ) ;
input_report_key ( st - > ts_input , BTN_TOUCH , 0 ) ;
input_sync ( st - > ts_input ) ;
} else if ( ( status & ts_data_irq_mask ) = = ts_data_irq_mask ) {
/* Now all touchscreen data is ready */
if ( status & AT91_ADC_ISR_PENS ) {
/* validate data by pen contact */
at91_ts_sample ( st ) ;
} else {
/* triggered by event that is no pen contact, just read
* them to clean the interrupt and discard all .
*/
at91_adc_readl ( st , AT91_ADC_TSXPOSR ) ;
at91_adc_readl ( st , AT91_ADC_TSYPOSR ) ;
at91_adc_readl ( st , AT91_ADC_TSPRESSR ) ;
}
}
2012-05-11 15:35:33 +02:00
return IRQ_HANDLED ;
}
static int at91_adc_channel_init ( struct iio_dev * idev )
{
struct at91_adc_state * st = iio_priv ( idev ) ;
struct iio_chan_spec * chan_array , * timestamp ;
int bit , idx = 0 ;
2013-10-08 04:48:00 +01:00
unsigned long rsvd_mask = 0 ;
/* If touchscreen is enable, then reserve the adc channels */
if ( st - > touchscreen_type = = ATMEL_ADC_TOUCHSCREEN_4WIRE )
rsvd_mask = CHAN_MASK_TOUCHSCREEN_4WIRE ;
else if ( st - > touchscreen_type = = ATMEL_ADC_TOUCHSCREEN_5WIRE )
rsvd_mask = CHAN_MASK_TOUCHSCREEN_5WIRE ;
/* set up the channel mask to reserve touchscreen channels */
st - > channels_mask & = ~ rsvd_mask ;
2012-05-11 15:35:33 +02:00
idev - > num_channels = bitmap_weight ( & st - > channels_mask ,
st - > num_channels ) + 1 ;
2012-10-29 08:25:00 +00:00
chan_array = devm_kzalloc ( & idev - > dev ,
( ( idev - > num_channels + 1 ) *
sizeof ( struct iio_chan_spec ) ) ,
GFP_KERNEL ) ;
2012-05-11 15:35:33 +02:00
if ( ! chan_array )
return - ENOMEM ;
for_each_set_bit ( bit , & st - > channels_mask , st - > num_channels ) {
struct iio_chan_spec * chan = chan_array + idx ;
chan - > type = IIO_VOLTAGE ;
chan - > indexed = 1 ;
chan - > channel = bit ;
chan - > scan_index = idx ;
chan - > scan_type . sign = ' u ' ;
2013-03-29 14:54:00 +00:00
chan - > scan_type . realbits = st - > res ;
2012-05-11 15:35:33 +02:00
chan - > scan_type . storagebits = 16 ;
2013-02-27 19:06:10 +00:00
chan - > info_mask_shared_by_type = BIT ( IIO_CHAN_INFO_SCALE ) ;
chan - > info_mask_separate = BIT ( IIO_CHAN_INFO_RAW ) ;
2012-05-11 15:35:33 +02:00
idx + + ;
}
timestamp = chan_array + idx ;
timestamp - > type = IIO_TIMESTAMP ;
timestamp - > channel = - 1 ;
timestamp - > scan_index = idx ;
timestamp - > scan_type . sign = ' s ' ;
timestamp - > scan_type . realbits = 64 ;
timestamp - > scan_type . storagebits = 64 ;
idev - > channels = chan_array ;
return idev - > num_channels ;
}
2014-11-06 09:13:00 +00:00
static int at91_adc_get_trigger_value_by_name ( struct iio_dev * idev ,
2012-05-11 15:35:33 +02:00
struct at91_adc_trigger * triggers ,
const char * trigger_name )
{
struct at91_adc_state * st = iio_priv ( idev ) ;
int i ;
for ( i = 0 ; i < st - > trigger_number ; i + + ) {
char * name = kasprintf ( GFP_KERNEL ,
" %s-dev%d-%s " ,
idev - > name ,
idev - > id ,
triggers [ i ] . name ) ;
if ( ! name )
return - ENOMEM ;
if ( strcmp ( trigger_name , name ) = = 0 ) {
kfree ( name ) ;
2014-11-06 09:13:00 +00:00
if ( triggers [ i ] . value = = 0 )
return - EINVAL ;
return triggers [ i ] . value ;
2012-05-11 15:35:33 +02:00
}
kfree ( name ) ;
}
2014-11-06 09:13:00 +00:00
return - EINVAL ;
2012-05-11 15:35:33 +02:00
}
static int at91_adc_configure_trigger ( struct iio_trigger * trig , bool state )
{
2013-03-25 08:58:00 +00:00
struct iio_dev * idev = iio_trigger_get_drvdata ( trig ) ;
2012-05-11 15:35:33 +02:00
struct at91_adc_state * st = iio_priv ( idev ) ;
struct at91_adc_reg_desc * reg = st - > registers ;
u32 status = at91_adc_readl ( st , reg - > trigger_register ) ;
2014-11-06 09:13:00 +00:00
int value ;
2012-05-11 15:35:33 +02:00
u8 bit ;
value = at91_adc_get_trigger_value_by_name ( idev ,
st - > trigger_list ,
idev - > trig - > name ) ;
2014-11-06 09:13:00 +00:00
if ( value < 0 )
return value ;
2012-05-11 15:35:33 +02:00
if ( state ) {
st - > buffer = kmalloc ( idev - > scan_bytes , GFP_KERNEL ) ;
if ( st - > buffer = = NULL )
return - ENOMEM ;
at91_adc_writel ( st , reg - > trigger_register ,
status | value ) ;
2015-03-02 21:03:05 +02:00
for_each_set_bit ( bit , idev - > active_scan_mask ,
2012-05-11 15:35:33 +02:00
st - > num_channels ) {
struct iio_chan_spec const * chan = idev - > channels + bit ;
at91_adc_writel ( st , AT91_ADC_CHER ,
AT91_ADC_CH ( chan - > channel ) ) ;
}
at91_adc_writel ( st , AT91_ADC_IER , reg - > drdy_mask ) ;
} else {
at91_adc_writel ( st , AT91_ADC_IDR , reg - > drdy_mask ) ;
at91_adc_writel ( st , reg - > trigger_register ,
status & ~ value ) ;
2015-03-02 21:03:05 +02:00
for_each_set_bit ( bit , idev - > active_scan_mask ,
2012-05-11 15:35:33 +02:00
st - > num_channels ) {
struct iio_chan_spec const * chan = idev - > channels + bit ;
at91_adc_writel ( st , AT91_ADC_CHDR ,
AT91_ADC_CH ( chan - > channel ) ) ;
}
kfree ( st - > buffer ) ;
}
return 0 ;
}
static const struct iio_trigger_ops at91_adc_trigger_ops = {
. set_trigger_state = & at91_adc_configure_trigger ,
} ;
static struct iio_trigger * at91_adc_allocate_trigger ( struct iio_dev * idev ,
struct at91_adc_trigger * trigger )
{
struct iio_trigger * trig ;
int ret ;
trig = iio_trigger_alloc ( " %s-dev%d-%s " , idev - > name ,
idev - > id , trigger - > name ) ;
if ( trig = = NULL )
return NULL ;
trig - > dev . parent = idev - > dev . parent ;
2013-03-25 08:58:00 +00:00
iio_trigger_set_drvdata ( trig , idev ) ;
2012-05-11 15:35:33 +02:00
trig - > ops = & at91_adc_trigger_ops ;
ret = iio_trigger_register ( trig ) ;
if ( ret )
return NULL ;
return trig ;
}
static int at91_adc_trigger_init ( struct iio_dev * idev )
{
struct at91_adc_state * st = iio_priv ( idev ) ;
int i , ret ;
2012-10-29 08:25:00 +00:00
st - > trig = devm_kzalloc ( & idev - > dev ,
2013-09-19 22:42:00 +01:00
st - > trigger_number * sizeof ( * st - > trig ) ,
2012-10-29 08:25:00 +00:00
GFP_KERNEL ) ;
2012-05-11 15:35:33 +02:00
if ( st - > trig = = NULL ) {
ret = - ENOMEM ;
goto error_ret ;
}
for ( i = 0 ; i < st - > trigger_number ; i + + ) {
if ( st - > trigger_list [ i ] . is_external & & ! ( st - > use_external ) )
continue ;
st - > trig [ i ] = at91_adc_allocate_trigger ( idev ,
st - > trigger_list + i ) ;
if ( st - > trig [ i ] = = NULL ) {
dev_err ( & idev - > dev ,
" Could not allocate trigger %d \n " , i ) ;
ret = - ENOMEM ;
goto error_trigger ;
}
}
return 0 ;
error_trigger :
for ( i - - ; i > = 0 ; i - - ) {
iio_trigger_unregister ( st - > trig [ i ] ) ;
iio_trigger_free ( st - > trig [ i ] ) ;
}
error_ret :
return ret ;
}
static void at91_adc_trigger_remove ( struct iio_dev * idev )
{
struct at91_adc_state * st = iio_priv ( idev ) ;
int i ;
for ( i = 0 ; i < st - > trigger_number ; i + + ) {
iio_trigger_unregister ( st - > trig [ i ] ) ;
iio_trigger_free ( st - > trig [ i ] ) ;
}
}
static int at91_adc_buffer_init ( struct iio_dev * idev )
{
2012-06-18 18:33:49 +02:00
return iio_triggered_buffer_setup ( idev , & iio_pollfunc_store_time ,
& at91_adc_trigger_handler , NULL ) ;
2012-05-11 15:35:33 +02:00
}
static void at91_adc_buffer_remove ( struct iio_dev * idev )
{
2012-06-18 18:33:49 +02:00
iio_triggered_buffer_cleanup ( idev ) ;
2012-05-11 15:35:33 +02:00
}
static int at91_adc_read_raw ( struct iio_dev * idev ,
struct iio_chan_spec const * chan ,
int * val , int * val2 , long mask )
{
struct at91_adc_state * st = iio_priv ( idev ) ;
int ret ;
switch ( mask ) {
case IIO_CHAN_INFO_RAW :
mutex_lock ( & st - > lock ) ;
2014-10-09 15:02:00 +01:00
st - > chnb = chan - > channel ;
2012-05-11 15:35:33 +02:00
at91_adc_writel ( st , AT91_ADC_CHER ,
AT91_ADC_CH ( chan - > channel ) ) ;
2014-10-09 15:02:00 +01:00
at91_adc_writel ( st , AT91_ADC_IER , BIT ( chan - > channel ) ) ;
2012-05-11 15:35:33 +02:00
at91_adc_writel ( st , AT91_ADC_CR , AT91_ADC_START ) ;
ret = wait_event_interruptible_timeout ( st - > wq_data_avail ,
st - > done ,
msecs_to_jiffies ( 1000 ) ) ;
if ( ret = = 0 )
2012-06-26 10:43:05 +02:00
ret = - ETIMEDOUT ;
if ( ret < 0 ) {
mutex_unlock ( & st - > lock ) ;
2012-05-11 15:35:33 +02:00
return ret ;
2012-06-26 10:43:05 +02:00
}
2012-05-11 15:35:33 +02:00
* val = st - > last_value ;
at91_adc_writel ( st , AT91_ADC_CHDR ,
AT91_ADC_CH ( chan - > channel ) ) ;
2014-10-09 15:02:00 +01:00
at91_adc_writel ( st , AT91_ADC_IDR , BIT ( chan - > channel ) ) ;
2012-05-11 15:35:33 +02:00
st - > last_value = 0 ;
st - > done = false ;
mutex_unlock ( & st - > lock ) ;
return IIO_VAL_INT ;
case IIO_CHAN_INFO_SCALE :
2013-09-28 10:31:00 +01:00
* val = st - > vref_mv ;
* val2 = chan - > scan_type . realbits ;
return IIO_VAL_FRACTIONAL_LOG2 ;
2012-05-11 15:35:33 +02:00
default :
break ;
}
return - EINVAL ;
}
2013-03-29 14:54:00 +00:00
static int at91_adc_of_get_resolution ( struct at91_adc_state * st ,
struct platform_device * pdev )
{
struct iio_dev * idev = iio_priv_to_dev ( st ) ;
struct device_node * np = pdev - > dev . of_node ;
int count , i , ret = 0 ;
char * res_name , * s ;
u32 * resolutions ;
count = of_property_count_strings ( np , " atmel,adc-res-names " ) ;
if ( count < 2 ) {
dev_err ( & idev - > dev , " You must specified at least two resolution names for "
" adc-res-names property in the DT \n " ) ;
return count ;
}
2015-11-16 05:35:57 +05:30
resolutions = kmalloc_array ( count , sizeof ( * resolutions ) , GFP_KERNEL ) ;
2013-03-29 14:54:00 +00:00
if ( ! resolutions )
return - ENOMEM ;
if ( of_property_read_u32_array ( np , " atmel,adc-res " , resolutions , count ) ) {
dev_err ( & idev - > dev , " Missing adc-res property in the DT. \n " ) ;
ret = - ENODEV ;
goto ret ;
}
if ( of_property_read_string ( np , " atmel,adc-use-res " , ( const char * * ) & res_name ) )
res_name = " highres " ;
for ( i = 0 ; i < count ; i + + ) {
if ( of_property_read_string_index ( np , " atmel,adc-res-names " , i , ( const char * * ) & s ) )
continue ;
if ( strcmp ( res_name , s ) )
continue ;
st - > res = resolutions [ i ] ;
if ( ! strcmp ( res_name , " lowres " ) )
st - > low_res = true ;
else
st - > low_res = false ;
dev_info ( & idev - > dev , " Resolution used: %u bits \n " , st - > res ) ;
goto ret ;
}
dev_err ( & idev - > dev , " There is no resolution for %s \n " , res_name ) ;
ret :
kfree ( resolutions ) ;
return ret ;
}
2015-06-17 18:21:36 +02:00
static u32 calc_startup_ticks_9260 ( u32 startup_time , u32 adc_clk_khz )
2013-10-08 04:48:00 +01:00
{
/*
* Number of ticks needed to cover the startup time of the ADC
* as defined in the electrical characteristics of the board ,
* divided by 8. The formula thus is :
* Startup Time = ( ticks + 1 ) * 8 / ADC Clock
*/
return round_up ( ( startup_time * adc_clk_khz / 1000 ) - 1 , 8 ) / 8 ;
}
2015-06-17 18:21:36 +02:00
static u32 calc_startup_ticks_9x5 ( u32 startup_time , u32 adc_clk_khz )
2013-10-08 04:48:00 +01:00
{
/*
* For sama5d3x and at91sam9x5 , the formula changes to :
* Startup Time = < lookup_table_value > / ADC Clock
*/
2017-07-10 18:46:54 +01:00
static const int startup_lookup [ ] = {
2016-04-14 21:36:37 +02:00
0 , 8 , 16 , 24 ,
64 , 80 , 96 , 112 ,
2013-10-08 04:48:00 +01:00
512 , 576 , 640 , 704 ,
768 , 832 , 896 , 960
} ;
int i , size = ARRAY_SIZE ( startup_lookup ) ;
unsigned int ticks ;
ticks = startup_time * adc_clk_khz / 1000 ;
for ( i = 0 ; i < size ; i + + )
if ( ticks < startup_lookup [ i ] )
break ;
ticks = i ;
if ( ticks = = size )
/* Reach the end of lookup table */
ticks = size - 1 ;
return ticks ;
}
2013-08-27 12:28:00 +01:00
static const struct of_device_id at91_adc_dt_ids [ ] ;
2013-10-08 04:48:00 +01:00
static int at91_adc_probe_dt_ts ( struct device_node * node ,
struct at91_adc_state * st , struct device * dev )
{
int ret ;
u32 prop ;
ret = of_property_read_u32 ( node , " atmel,adc-ts-wires " , & prop ) ;
if ( ret ) {
dev_info ( dev , " ADC Touch screen is disabled. \n " ) ;
return 0 ;
}
switch ( prop ) {
case 4 :
case 5 :
st - > touchscreen_type = prop ;
break ;
default :
dev_err ( dev , " Unsupported number of touchscreen wires (%d). Should be 4 or 5. \n " , prop ) ;
return - EINVAL ;
}
2014-04-15 12:27:59 +02:00
if ( ! st - > caps - > has_tsmr )
return 0 ;
2013-10-08 04:48:00 +01:00
prop = 0 ;
of_property_read_u32 ( node , " atmel,adc-ts-pressure-threshold " , & prop ) ;
st - > ts_pressure_threshold = prop ;
if ( st - > ts_pressure_threshold ) {
return 0 ;
} else {
dev_err ( dev , " Invalid pressure threshold for the touchscreen \n " ) ;
return - EINVAL ;
}
}
2012-05-11 15:35:37 +02:00
static int at91_adc_probe_dt ( struct at91_adc_state * st ,
struct platform_device * pdev )
{
struct iio_dev * idev = iio_priv_to_dev ( st ) ;
struct device_node * node = pdev - > dev . of_node ;
struct device_node * trig_node ;
int i = 0 , ret ;
u32 prop ;
if ( ! node )
return - EINVAL ;
2013-08-27 12:28:00 +01:00
st - > caps = ( struct at91_adc_caps * )
of_match_device ( at91_adc_dt_ids , & pdev - > dev ) - > data ;
2012-05-11 15:35:37 +02:00
st - > use_external = of_property_read_bool ( node , " atmel,adc-use-external-triggers " ) ;
if ( of_property_read_u32 ( node , " atmel,adc-channels-used " , & prop ) ) {
dev_err ( & idev - > dev , " Missing adc-channels-used property in the DT. \n " ) ;
ret = - EINVAL ;
goto error_ret ;
}
st - > channels_mask = prop ;
2013-03-29 14:54:00 +00:00
st - > sleep_mode = of_property_read_bool ( node , " atmel,adc-sleep-mode " ) ;
2012-05-11 15:35:37 +02:00
if ( of_property_read_u32 ( node , " atmel,adc-startup-time " , & prop ) ) {
dev_err ( & idev - > dev , " Missing adc-startup-time property in the DT. \n " ) ;
ret = - EINVAL ;
goto error_ret ;
}
st - > startup_time = prop ;
2013-03-29 14:54:00 +00:00
prop = 0 ;
of_property_read_u32 ( node , " atmel,adc-sample-hold-time " , & prop ) ;
st - > sample_hold_time = prop ;
2012-05-11 15:35:37 +02:00
if ( of_property_read_u32 ( node , " atmel,adc-vref " , & prop ) ) {
dev_err ( & idev - > dev , " Missing adc-vref property in the DT. \n " ) ;
ret = - EINVAL ;
goto error_ret ;
}
st - > vref_mv = prop ;
2013-03-29 14:54:00 +00:00
ret = at91_adc_of_get_resolution ( st , pdev ) ;
if ( ret )
goto error_ret ;
2013-08-27 12:28:00 +01:00
st - > registers = & st - > caps - > registers ;
2013-10-08 04:48:00 +01:00
st - > num_channels = st - > caps - > num_channels ;
2012-05-11 15:35:37 +02:00
st - > trigger_number = of_get_child_count ( node ) ;
2012-10-29 08:25:00 +00:00
st - > trigger_list = devm_kzalloc ( & idev - > dev , st - > trigger_number *
sizeof ( struct at91_adc_trigger ) ,
GFP_KERNEL ) ;
2012-05-11 15:35:37 +02:00
if ( ! st - > trigger_list ) {
dev_err ( & idev - > dev , " Could not allocate trigger list memory. \n " ) ;
ret = - ENOMEM ;
goto error_ret ;
}
for_each_child_of_node ( node , trig_node ) {
struct at91_adc_trigger * trig = st - > trigger_list + i ;
const char * name ;
if ( of_property_read_string ( trig_node , " trigger-name " , & name ) ) {
dev_err ( & idev - > dev , " Missing trigger-name property in the DT. \n " ) ;
ret = - EINVAL ;
goto error_ret ;
}
2016-04-14 21:36:37 +02:00
trig - > name = name ;
2012-05-11 15:35:37 +02:00
if ( of_property_read_u32 ( trig_node , " trigger-value " , & prop ) ) {
dev_err ( & idev - > dev , " Missing trigger-value property in the DT. \n " ) ;
ret = - EINVAL ;
goto error_ret ;
}
2016-04-14 21:36:37 +02:00
trig - > value = prop ;
2012-05-11 15:35:37 +02:00
trig - > is_external = of_property_read_bool ( trig_node , " trigger-external " ) ;
i + + ;
}
2013-10-08 04:48:00 +01:00
/* Check if touchscreen is supported. */
if ( st - > caps - > has_ts )
return at91_adc_probe_dt_ts ( node , st , & idev - > dev ) ;
else
dev_info ( & idev - > dev , " not support touchscreen in the adc compatible string. \n " ) ;
2012-05-11 15:35:37 +02:00
return 0 ;
error_ret :
return ret ;
}
2012-05-11 15:35:33 +02:00
static int at91_adc_probe_pdata ( struct at91_adc_state * st ,
struct platform_device * pdev )
{
struct at91_adc_data * pdata = pdev - > dev . platform_data ;
if ( ! pdata )
return - EINVAL ;
2014-05-03 16:57:00 +01:00
st - > caps = ( struct at91_adc_caps * )
platform_get_device_id ( pdev ) - > driver_data ;
2012-05-11 15:35:33 +02:00
st - > use_external = pdata - > use_external_triggers ;
st - > vref_mv = pdata - > vref ;
st - > channels_mask = pdata - > channels_used ;
2014-05-03 16:57:00 +01:00
st - > num_channels = st - > caps - > num_channels ;
2012-05-11 15:35:33 +02:00
st - > startup_time = pdata - > startup_time ;
st - > trigger_number = pdata - > trigger_number ;
st - > trigger_list = pdata - > trigger_list ;
2014-05-03 16:57:00 +01:00
st - > registers = & st - > caps - > registers ;
2014-04-15 12:27:59 +02:00
st - > touchscreen_type = pdata - > touchscreen_type ;
2012-05-11 15:35:33 +02:00
return 0 ;
}
static const struct iio_info at91_adc_info = {
. read_raw = & at91_adc_read_raw ,
} ;
2013-10-08 04:48:00 +01:00
/* Touchscreen related functions */
static int atmel_ts_open ( struct input_dev * dev )
{
struct at91_adc_state * st = input_get_drvdata ( dev ) ;
2014-04-15 12:27:59 +02:00
if ( st - > caps - > has_tsmr )
at91_adc_writel ( st , AT91_ADC_IER , AT91_ADC_IER_PEN ) ;
else
at91_adc_writel ( st , AT91_ADC_IER , AT91RL_ADC_IER_PEN ) ;
2013-10-08 04:48:00 +01:00
return 0 ;
}
static void atmel_ts_close ( struct input_dev * dev )
{
struct at91_adc_state * st = input_get_drvdata ( dev ) ;
2014-04-15 12:27:59 +02:00
if ( st - > caps - > has_tsmr )
at91_adc_writel ( st , AT91_ADC_IDR , AT91_ADC_IER_PEN ) ;
else
at91_adc_writel ( st , AT91_ADC_IDR , AT91RL_ADC_IER_PEN ) ;
2013-10-08 04:48:00 +01:00
}
static int at91_ts_hw_init ( struct at91_adc_state * st , u32 adc_clk_khz )
{
2016-08-30 14:27:01 +02:00
struct iio_dev * idev = iio_priv_to_dev ( st ) ;
2014-04-15 12:27:59 +02:00
u32 reg = 0 ;
2016-08-30 14:27:01 +02:00
u32 tssctim = 0 ;
2013-10-08 04:48:00 +01:00
int i = 0 ;
/* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
* pen detect noise .
* The formula is : Pen Detect Debounce Time = ( 2 ^ pendbc ) / ADCClock
*/
2014-04-15 12:27:59 +02:00
st - > ts_pendbc = round_up ( TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz /
1000 , 1 ) ;
2013-10-08 04:48:00 +01:00
2014-04-15 12:27:59 +02:00
while ( st - > ts_pendbc > > + + i )
2013-10-08 04:48:00 +01:00
; /* Empty! Find the shift offset */
2014-04-15 12:27:59 +02:00
if ( abs ( st - > ts_pendbc - ( 1 < < i ) ) < abs ( st - > ts_pendbc - ( 1 < < ( i - 1 ) ) ) )
st - > ts_pendbc = i ;
2013-10-08 04:48:00 +01:00
else
2014-04-15 12:27:59 +02:00
st - > ts_pendbc = i - 1 ;
2013-10-08 04:48:00 +01:00
2014-04-15 12:27:59 +02:00
if ( ! st - > caps - > has_tsmr ) {
reg = at91_adc_readl ( st , AT91_ADC_MR ) ;
reg | = AT91_ADC_TSAMOD_TS_ONLY_MODE | AT91_ADC_PENDET ;
reg | = AT91_ADC_PENDBC_ ( st - > ts_pendbc ) & AT91_ADC_PENDBC ;
at91_adc_writel ( st , AT91_ADC_MR , reg ) ;
reg = AT91_ADC_TSR_SHTIM_ ( TOUCH_SHTIM ) & AT91_ADC_TSR_SHTIM ;
at91_adc_writel ( st , AT91_ADC_TSR , reg ) ;
st - > ts_sample_period_val = round_up ( ( TOUCH_SAMPLE_PERIOD_US_RL *
adc_clk_khz / 1000 ) - 1 , 1 ) ;
return 0 ;
2013-10-08 04:48:00 +01:00
}
2016-08-30 14:27:01 +02:00
/* Touchscreen Switches Closure time needed for allowing the value to
* stabilize .
* Switch Closure Time = ( TSSCTIM * 4 ) ADCClock periods
*/
tssctim = DIV_ROUND_UP ( TOUCH_SCTIM_US * adc_clk_khz / 1000 , 4 ) ;
dev_dbg ( & idev - > dev , " adc_clk at: %d KHz, tssctim at: %d \n " ,
adc_clk_khz , tssctim ) ;
2014-04-15 12:27:59 +02:00
if ( st - > touchscreen_type = = ATMEL_ADC_TOUCHSCREEN_4WIRE )
reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS ;
else
reg = AT91_ADC_TSMR_TSMODE_5WIRE ;
2016-08-30 14:27:01 +02:00
reg | = AT91_ADC_TSMR_SCTIM_ ( tssctim ) & AT91_ADC_TSMR_SCTIM ;
2014-04-15 12:27:59 +02:00
reg | = AT91_ADC_TSMR_TSAV_ ( st - > caps - > ts_filter_average )
& AT91_ADC_TSMR_TSAV ;
reg | = AT91_ADC_TSMR_PENDBC_ ( st - > ts_pendbc ) & AT91_ADC_TSMR_PENDBC ;
reg | = AT91_ADC_TSMR_NOTSDMA ;
reg | = AT91_ADC_TSMR_PENDET_ENA ;
reg | = 0x03 < < 8 ; /* TSFREQ, needs to be bigger than TSAV */
at91_adc_writel ( st , AT91_ADC_TSMR , reg ) ;
2013-10-08 04:48:00 +01:00
/* Change adc internal resistor value for better pen detection,
* default value is 100 kOhm .
* 0 = 200 kOhm , 1 = 150 kOhm , 2 = 100 kOhm , 3 = 50 kOhm
* option only available on ES2 and higher
*/
at91_adc_writel ( st , AT91_ADC_ACR , st - > caps - > ts_pen_detect_sensitivity
& AT91_ADC_ACR_PENDETSENS ) ;
2014-04-15 12:27:59 +02:00
/* Sample Period Time = (TRGPER + 1) / ADCClock */
2013-10-08 04:48:00 +01:00
st - > ts_sample_period_val = round_up ( ( TOUCH_SAMPLE_PERIOD_US *
adc_clk_khz / 1000 ) - 1 , 1 ) ;
return 0 ;
}
static int at91_ts_register ( struct at91_adc_state * st ,
struct platform_device * pdev )
{
struct input_dev * input ;
struct iio_dev * idev = iio_priv_to_dev ( st ) ;
int ret ;
input = input_allocate_device ( ) ;
if ( ! input ) {
dev_err ( & idev - > dev , " Failed to allocate TS device! \n " ) ;
return - ENOMEM ;
}
input - > name = DRIVER_NAME ;
input - > id . bustype = BUS_HOST ;
input - > dev . parent = & pdev - > dev ;
input - > open = atmel_ts_open ;
input - > close = atmel_ts_close ;
__set_bit ( EV_ABS , input - > evbit ) ;
__set_bit ( EV_KEY , input - > evbit ) ;
__set_bit ( BTN_TOUCH , input - > keybit ) ;
2014-04-15 12:27:59 +02:00
if ( st - > caps - > has_tsmr ) {
input_set_abs_params ( input , ABS_X , 0 , ( 1 < < MAX_POS_BITS ) - 1 ,
0 , 0 ) ;
input_set_abs_params ( input , ABS_Y , 0 , ( 1 < < MAX_POS_BITS ) - 1 ,
0 , 0 ) ;
input_set_abs_params ( input , ABS_PRESSURE , 0 , 0xffffff , 0 , 0 ) ;
} else {
if ( st - > touchscreen_type ! = ATMEL_ADC_TOUCHSCREEN_4WIRE ) {
dev_err ( & pdev - > dev ,
" This touchscreen controller only support 4 wires \n " ) ;
ret = - EINVAL ;
goto err ;
}
input_set_abs_params ( input , ABS_X , 0 , ( 1 < < MAX_RLPOS_BITS ) - 1 ,
0 , 0 ) ;
input_set_abs_params ( input , ABS_Y , 0 , ( 1 < < MAX_RLPOS_BITS ) - 1 ,
0 , 0 ) ;
}
2013-10-08 04:48:00 +01:00
st - > ts_input = input ;
input_set_drvdata ( input , st ) ;
ret = input_register_device ( input ) ;
if ( ret )
2014-04-15 12:27:59 +02:00
goto err ;
return ret ;
2013-10-08 04:48:00 +01:00
2014-04-15 12:27:59 +02:00
err :
input_free_device ( st - > ts_input ) ;
2013-10-08 04:48:00 +01:00
return ret ;
}
static void at91_ts_unregister ( struct at91_adc_state * st )
{
input_unregister_device ( st - > ts_input ) ;
}
2012-12-21 13:21:43 -08:00
static int at91_adc_probe ( struct platform_device * pdev )
2012-05-11 15:35:33 +02:00
{
2013-08-27 12:28:00 +01:00
unsigned int prsc , mstrclk , ticks , adc_clk , adc_clk_khz , shtim ;
2012-05-11 15:35:33 +02:00
int ret ;
struct iio_dev * idev ;
struct at91_adc_state * st ;
struct resource * res ;
2013-03-29 14:54:00 +00:00
u32 reg ;
2012-05-11 15:35:33 +02:00
2013-07-22 12:02:00 +01:00
idev = devm_iio_device_alloc ( & pdev - > dev , sizeof ( struct at91_adc_state ) ) ;
if ( ! idev )
return - ENOMEM ;
2012-05-11 15:35:33 +02:00
st = iio_priv ( idev ) ;
2012-05-11 15:35:37 +02:00
if ( pdev - > dev . of_node )
ret = at91_adc_probe_dt ( st , pdev ) ;
else
ret = at91_adc_probe_pdata ( st , pdev ) ;
2012-05-11 15:35:33 +02:00
if ( ret ) {
dev_err ( & pdev - > dev , " No platform data available. \n " ) ;
2013-07-22 12:02:00 +01:00
return - EINVAL ;
2012-05-11 15:35:33 +02:00
}
platform_set_drvdata ( pdev , idev ) ;
idev - > dev . parent = & pdev - > dev ;
idev - > name = dev_name ( & pdev - > dev ) ;
idev - > modes = INDIO_DIRECT_MODE ;
idev - > info = & at91_adc_info ;
st - > irq = platform_get_irq ( pdev , 0 ) ;
if ( st - > irq < 0 ) {
dev_err ( & pdev - > dev , " No IRQ ID is designated \n " ) ;
2013-07-22 12:02:00 +01:00
return - ENODEV ;
2012-05-11 15:35:33 +02:00
}
2012-07-31 14:09:00 +01:00
res = platform_get_resource ( pdev , IORESOURCE_MEM , 0 ) ;
2012-05-11 15:35:33 +02:00
2013-01-21 11:09:04 +01:00
st - > reg_base = devm_ioremap_resource ( & pdev - > dev , res ) ;
if ( IS_ERR ( st - > reg_base ) ) {
2013-07-22 12:02:00 +01:00
return PTR_ERR ( st - > reg_base ) ;
2012-05-11 15:35:33 +02:00
}
/*
* Disable all IRQs before setting up the handler
*/
at91_adc_writel ( st , AT91_ADC_CR , AT91_ADC_SWRST ) ;
at91_adc_writel ( st , AT91_ADC_IDR , 0xFFFFFFFF ) ;
2014-04-15 12:27:59 +02:00
if ( st - > caps - > has_tsmr )
ret = request_irq ( st - > irq , at91_adc_9x5_interrupt , 0 ,
pdev - > dev . driver - > name , idev ) ;
else
ret = request_irq ( st - > irq , at91_adc_rl_interrupt , 0 ,
pdev - > dev . driver - > name , idev ) ;
2012-05-11 15:35:33 +02:00
if ( ret ) {
dev_err ( & pdev - > dev , " Failed to allocate IRQ. \n " ) ;
2013-07-22 12:02:00 +01:00
return ret ;
2012-05-11 15:35:33 +02:00
}
2012-07-31 14:09:00 +01:00
st - > clk = devm_clk_get ( & pdev - > dev , " adc_clk " ) ;
2012-05-11 15:35:33 +02:00
if ( IS_ERR ( st - > clk ) ) {
dev_err ( & pdev - > dev , " Failed to get the clock. \n " ) ;
ret = PTR_ERR ( st - > clk ) ;
goto error_free_irq ;
}
2012-08-26 17:00:00 +01:00
ret = clk_prepare_enable ( st - > clk ) ;
2012-05-11 15:35:33 +02:00
if ( ret ) {
2012-08-26 17:00:00 +01:00
dev_err ( & pdev - > dev ,
" Could not prepare or enable the clock. \n " ) ;
2012-07-31 14:09:00 +01:00
goto error_free_irq ;
2012-05-11 15:35:33 +02:00
}
2012-07-31 14:09:00 +01:00
st - > adc_clk = devm_clk_get ( & pdev - > dev , " adc_op_clk " ) ;
2012-05-11 15:35:33 +02:00
if ( IS_ERR ( st - > adc_clk ) ) {
dev_err ( & pdev - > dev , " Failed to get the ADC clock. \n " ) ;
2012-08-25 21:57:09 +02:00
ret = PTR_ERR ( st - > adc_clk ) ;
2012-05-11 15:35:33 +02:00
goto error_disable_clk ;
}
2012-08-26 17:00:00 +01:00
ret = clk_prepare_enable ( st - > adc_clk ) ;
2012-05-11 15:35:33 +02:00
if ( ret ) {
2012-08-26 17:00:00 +01:00
dev_err ( & pdev - > dev ,
" Could not prepare or enable the ADC clock. \n " ) ;
2012-07-31 14:09:00 +01:00
goto error_disable_clk ;
2012-05-11 15:35:33 +02:00
}
/*
* Prescaler rate computation using the formula from the Atmel ' s
* datasheet : ADC Clock = MCK / ( ( Prescaler + 1 ) * 2 ) , ADC Clock being
* specified by the electrical characteristics of the board .
*/
mstrclk = clk_get_rate ( st - > clk ) ;
adc_clk = clk_get_rate ( st - > adc_clk ) ;
2013-08-27 12:28:00 +01:00
adc_clk_khz = adc_clk / 1000 ;
2013-10-08 04:48:00 +01:00
dev_dbg ( & pdev - > dev , " Master clock is set as: %d Hz, adc_clk should set as: %d Hz \n " ,
mstrclk , adc_clk ) ;
2012-05-11 15:35:33 +02:00
prsc = ( mstrclk / ( 2 * adc_clk ) ) - 1 ;
if ( ! st - > startup_time ) {
dev_err ( & pdev - > dev , " No startup time available. \n " ) ;
ret = - EINVAL ;
goto error_disable_adc_clk ;
}
2013-10-08 04:48:00 +01:00
ticks = ( * st - > caps - > calc_startup_ticks ) ( st - > startup_time , adc_clk_khz ) ;
2012-05-11 15:35:33 +02:00
2013-03-29 14:54:00 +00:00
/*
* a minimal Sample and Hold Time is necessary for the ADC to guarantee
* the best converted final value between two channels selection
* The formula thus is : Sample and Hold Time = ( shtim + 1 ) / ADCClock
*/
2014-03-03 18:07:00 +00:00
if ( st - > sample_hold_time > 0 )
shtim = round_up ( ( st - > sample_hold_time * adc_clk_khz / 1000 )
- 1 , 1 ) ;
else
shtim = 0 ;
2013-03-29 14:54:00 +00:00
2013-08-27 12:28:00 +01:00
reg = AT91_ADC_PRESCAL_ ( prsc ) & st - > registers - > mr_prescal_mask ;
reg | = AT91_ADC_STARTUP_ ( ticks ) & st - > registers - > mr_startup_mask ;
2013-03-29 14:54:00 +00:00
if ( st - > low_res )
2013-03-29 14:54:00 +00:00
reg | = AT91_ADC_LOWRES ;
if ( st - > sleep_mode )
reg | = AT91_ADC_SLEEP ;
2013-03-29 14:54:00 +00:00
reg | = AT91_ADC_SHTIM_ ( shtim ) & AT91_ADC_SHTIM ;
2013-03-29 14:54:00 +00:00
at91_adc_writel ( st , AT91_ADC_MR , reg ) ;
2012-05-11 15:35:33 +02:00
/* Setup the ADC channels available on the board */
ret = at91_adc_channel_init ( idev ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Couldn't initialize the channels. \n " ) ;
goto error_disable_adc_clk ;
}
init_waitqueue_head ( & st - > wq_data_avail ) ;
mutex_init ( & st - > lock ) ;
2013-10-08 04:48:00 +01:00
/*
* Since touch screen will set trigger register as period trigger . So
* when touch screen is enabled , then we have to disable hardware
* trigger for classic adc .
*/
if ( ! st - > touchscreen_type ) {
ret = at91_adc_buffer_init ( idev ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Couldn't initialize the buffer. \n " ) ;
goto error_disable_adc_clk ;
}
2012-05-11 15:35:33 +02:00
2013-10-08 04:48:00 +01:00
ret = at91_adc_trigger_init ( idev ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Couldn't setup the triggers. \n " ) ;
at91_adc_buffer_remove ( idev ) ;
goto error_disable_adc_clk ;
}
} else {
ret = at91_ts_register ( st , pdev ) ;
if ( ret )
goto error_disable_adc_clk ;
at91_ts_hw_init ( st , adc_clk_khz ) ;
2012-05-11 15:35:33 +02:00
}
ret = iio_device_register ( idev ) ;
if ( ret < 0 ) {
dev_err ( & pdev - > dev , " Couldn't register the device. \n " ) ;
2013-10-08 04:48:00 +01:00
goto error_iio_device_register ;
2012-05-11 15:35:33 +02:00
}
return 0 ;
2013-10-08 04:48:00 +01:00
error_iio_device_register :
if ( ! st - > touchscreen_type ) {
at91_adc_trigger_remove ( idev ) ;
at91_adc_buffer_remove ( idev ) ;
} else {
at91_ts_unregister ( st ) ;
}
2012-05-11 15:35:33 +02:00
error_disable_adc_clk :
2012-08-26 17:00:00 +01:00
clk_disable_unprepare ( st - > adc_clk ) ;
2012-05-11 15:35:33 +02:00
error_disable_clk :
2012-08-26 17:00:00 +01:00
clk_disable_unprepare ( st - > clk ) ;
2012-05-11 15:35:33 +02:00
error_free_irq :
free_irq ( st - > irq , idev ) ;
return ret ;
}
2012-12-21 13:21:43 -08:00
static int at91_adc_remove ( struct platform_device * pdev )
2012-05-11 15:35:33 +02:00
{
struct iio_dev * idev = platform_get_drvdata ( pdev ) ;
struct at91_adc_state * st = iio_priv ( idev ) ;
iio_device_unregister ( idev ) ;
2013-10-08 04:48:00 +01:00
if ( ! st - > touchscreen_type ) {
at91_adc_trigger_remove ( idev ) ;
at91_adc_buffer_remove ( idev ) ;
} else {
at91_ts_unregister ( st ) ;
}
2012-05-11 15:35:33 +02:00
clk_disable_unprepare ( st - > adc_clk ) ;
2012-08-26 17:00:00 +01:00
clk_disable_unprepare ( st - > clk ) ;
2012-05-11 15:35:33 +02:00
free_irq ( st - > irq , idev ) ;
return 0 ;
}
2016-11-02 17:21:48 +08:00
# ifdef CONFIG_PM_SLEEP
static int at91_adc_suspend ( struct device * dev )
{
struct iio_dev * idev = platform_get_drvdata ( to_platform_device ( dev ) ) ;
struct at91_adc_state * st = iio_priv ( idev ) ;
pinctrl_pm_select_sleep_state ( dev ) ;
clk_disable_unprepare ( st - > clk ) ;
return 0 ;
}
static int at91_adc_resume ( struct device * dev )
{
struct iio_dev * idev = platform_get_drvdata ( to_platform_device ( dev ) ) ;
struct at91_adc_state * st = iio_priv ( idev ) ;
clk_prepare_enable ( st - > clk ) ;
pinctrl_pm_select_default_state ( dev ) ;
return 0 ;
}
# endif
static SIMPLE_DEV_PM_OPS ( at91_adc_pm_ops , at91_adc_suspend , at91_adc_resume ) ;
2013-08-27 12:28:00 +01:00
static struct at91_adc_caps at91sam9260_caps = {
2013-10-08 04:48:00 +01:00
. calc_startup_ticks = calc_startup_ticks_9260 ,
2013-10-08 04:48:00 +01:00
. num_channels = 4 ,
2013-08-27 12:28:00 +01:00
. registers = {
. channel_base = AT91_ADC_CHR ( 0 ) ,
. drdy_mask = AT91_ADC_DRDY ,
. status_register = AT91_ADC_SR ,
. trigger_register = AT91_ADC_TRGR_9260 ,
2013-08-27 12:28:00 +01:00
. mr_prescal_mask = AT91_ADC_PRESCAL_9260 ,
. mr_startup_mask = AT91_ADC_STARTUP_9260 ,
2013-08-27 12:28:00 +01:00
} ,
} ;
2014-04-15 12:28:02 +02:00
static struct at91_adc_caps at91sam9rl_caps = {
. has_ts = true ,
. calc_startup_ticks = calc_startup_ticks_9260 , /* same as 9260 */
. num_channels = 6 ,
. registers = {
. channel_base = AT91_ADC_CHR ( 0 ) ,
. drdy_mask = AT91_ADC_DRDY ,
. status_register = AT91_ADC_SR ,
. trigger_register = AT91_ADC_TRGR_9G45 ,
. mr_prescal_mask = AT91_ADC_PRESCAL_9260 ,
. mr_startup_mask = AT91_ADC_STARTUP_9G45 ,
} ,
} ;
2013-08-27 12:28:00 +01:00
static struct at91_adc_caps at91sam9g45_caps = {
2013-10-08 04:48:00 +01:00
. has_ts = true ,
2013-10-08 04:48:00 +01:00
. calc_startup_ticks = calc_startup_ticks_9260 , /* same as 9260 */
2013-10-08 04:48:00 +01:00
. num_channels = 8 ,
2013-08-27 12:28:00 +01:00
. registers = {
. channel_base = AT91_ADC_CHR ( 0 ) ,
. drdy_mask = AT91_ADC_DRDY ,
. status_register = AT91_ADC_SR ,
. trigger_register = AT91_ADC_TRGR_9G45 ,
2013-08-27 12:28:00 +01:00
. mr_prescal_mask = AT91_ADC_PRESCAL_9G45 ,
. mr_startup_mask = AT91_ADC_STARTUP_9G45 ,
2013-08-27 12:28:00 +01:00
} ,
} ;
static struct at91_adc_caps at91sam9x5_caps = {
2013-10-08 04:48:00 +01:00
. has_ts = true ,
. has_tsmr = true ,
. ts_filter_average = 3 ,
. ts_pen_detect_sensitivity = 2 ,
2013-10-08 04:48:00 +01:00
. calc_startup_ticks = calc_startup_ticks_9x5 ,
2013-10-08 04:48:00 +01:00
. num_channels = 12 ,
2013-08-27 12:28:00 +01:00
. registers = {
. channel_base = AT91_ADC_CDR0_9X5 ,
. drdy_mask = AT91_ADC_SR_DRDY_9X5 ,
. status_register = AT91_ADC_SR_9X5 ,
. trigger_register = AT91_ADC_TRGR_9X5 ,
2013-08-27 12:28:00 +01:00
/* prescal mask is same as 9G45 */
. mr_prescal_mask = AT91_ADC_PRESCAL_9G45 ,
. mr_startup_mask = AT91_ADC_STARTUP_9X5 ,
2013-08-27 12:28:00 +01:00
} ,
} ;
2012-05-11 15:35:37 +02:00
static const struct of_device_id at91_adc_dt_ids [ ] = {
2013-08-27 12:28:00 +01:00
{ . compatible = " atmel,at91sam9260-adc " , . data = & at91sam9260_caps } ,
2014-04-15 12:28:02 +02:00
{ . compatible = " atmel,at91sam9rl-adc " , . data = & at91sam9rl_caps } ,
2013-08-27 12:28:00 +01:00
{ . compatible = " atmel,at91sam9g45-adc " , . data = & at91sam9g45_caps } ,
{ . compatible = " atmel,at91sam9x5-adc " , . data = & at91sam9x5_caps } ,
2012-05-11 15:35:37 +02:00
{ } ,
} ;
MODULE_DEVICE_TABLE ( of , at91_adc_dt_ids ) ;
2014-05-03 16:57:00 +01:00
static const struct platform_device_id at91_adc_ids [ ] = {
{
. name = " at91sam9260-adc " ,
. driver_data = ( unsigned long ) & at91sam9260_caps ,
2014-04-15 12:28:02 +02:00
} , {
. name = " at91sam9rl-adc " ,
. driver_data = ( unsigned long ) & at91sam9rl_caps ,
2014-05-03 16:57:00 +01:00
} , {
. name = " at91sam9g45-adc " ,
. driver_data = ( unsigned long ) & at91sam9g45_caps ,
} , {
. name = " at91sam9x5-adc " ,
. driver_data = ( unsigned long ) & at91sam9x5_caps ,
} , {
/* terminator */
}
} ;
MODULE_DEVICE_TABLE ( platform , at91_adc_ids ) ;
2012-05-11 15:35:37 +02:00
2012-05-11 15:35:33 +02:00
static struct platform_driver at91_adc_driver = {
. probe = at91_adc_probe ,
2012-12-21 13:21:43 -08:00
. remove = at91_adc_remove ,
2014-05-03 16:57:00 +01:00
. id_table = at91_adc_ids ,
2012-05-11 15:35:33 +02:00
. driver = {
2013-10-08 04:48:00 +01:00
. name = DRIVER_NAME ,
2012-05-11 15:35:37 +02:00
. of_match_table = of_match_ptr ( at91_adc_dt_ids ) ,
2016-11-02 17:21:48 +08:00
. pm = & at91_adc_pm_ops ,
2012-05-11 15:35:33 +02:00
} ,
} ;
module_platform_driver ( at91_adc_driver ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_DESCRIPTION ( " Atmel AT91 ADC Driver " ) ;
MODULE_AUTHOR ( " Maxime Ripard <maxime.ripard@free-electrons.com> " ) ;