diff --git a/arch/arm/src/sama5/Kconfig b/arch/arm/src/sama5/Kconfig
index 855945f42c..26e00dd240 100644
--- a/arch/arm/src/sama5/Kconfig
+++ b/arch/arm/src/sama5/Kconfig
@@ -830,6 +830,674 @@ endif # SAMA5_OHCI || SAMA5_EHCI
 endmenu # USB High Speed Host Controller driver (HCD) options
 endif # SAMA5_UHPHS
 
+if SAMA5_ADC
+menu "ADC configuration"
+
+config SAMA5_ADC_HAVE_CHAN
+	bool
+	default n
+
+menu "ADC Channel selection"
+
+config SAMA5_ADC_CHAN0
+	bool "Channel 0"
+	default n
+	depends on !SAMA5_TSD
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 0
+
+config SAMA5_ADC_CHAN1
+	bool "Channel 1"
+	default n
+	depends on !SAMA5_TSD
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 1
+
+config SAMA5_ADC_CHAN2
+	bool "Channel 2"
+	default n
+	depends on !SAMA5_TSD
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 2
+
+config SAMA5_ADC_CHAN3
+	bool "Channel 3"
+	default n
+	depends on !SAMA5_TSD
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 3
+
+config SAMA5_ADC_CHAN4
+	bool "Channel 4"
+	default n
+	depends on !SAMA5_TSD || !SAMA5_TSD_5WIRE
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 4
+
+config SAMA5_ADC_CHAN5
+	bool "Channel 5"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 5
+
+config SAMA5_ADC_CHAN6
+	bool "Channel 6"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 6
+
+config SAMA5_ADC_CHAN7
+	bool "Channel 7"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 7
+
+config SAMA5_ADC_CHAN8
+	bool "Channel 8"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 8
+
+config SAMA5_ADC_CHAN9
+	bool "Channel 9"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 9
+
+config SAMA5_ADC_CHAN10
+	bool "Channel 10"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 10
+
+config SAMA5_ADC_CHAN11
+	bool "Channel 11"
+	default n
+	select SAMA5_ADC_HAVE_CHAN
+	---help---
+		Enable ADC sampling on ADC channel 11
+
+endmenu # ADC Channel selection
+
+if SAMA5_ADC_HAVE_CHAN
+
+config SAMA5_ADC_DMA
+	bool "DMA Support"
+	default n
+	---help---
+		Enable DMA transfers of converted data.  This option is only
+		useful if you have numerous DMA channels enabled.  The end result
+		is that there will be one DMA interrupt per conversion sequence vs.
+		one interrupt per conversion.
+
+config SAMA5_ADC_AUTOCALIB
+	bool "ADC auto-calibration"
+	default n
+	---help---
+		Perform ADC auto-calibration during the ADC initialization sequence
+
+config SAMA5_ADC_SEQUENCER
+	bool "ADC sequencer"
+	default n
+	---help---
+		Enable the sequencer to perform ADC conversions.  Recommended if you
+		enable several ADC channels.
+
+config SAMA5_ADC_ANARCH
+	bool "Analog changes"
+	default n
+	---help---
+		This option allows you to select different gain, offset, and single
+		vs. differential modes for each channel.
+
+if SAMA5_ADC_ANARCH
+
+menu "Channel gain"
+
+config SAMA5_ADC_GAIN0
+	int "Channel 0 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN0
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN1
+	int "Channel 1 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN1
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN2
+	int "Channel 2 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN2
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN3
+	int "Channel 3 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN3
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN4
+	int "Channel 4 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN4
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN5
+	int "Channel 5 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN5
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN6
+	int "Channel 6 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN6
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN7
+	int "Channel 7 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN7
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN8
+	int "Channel 8 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN8
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN9
+	int "Channel 9 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN9
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN10
+	int "Channel 10 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN10
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+config SAMA5_ADC_GAIN11
+	int "Channel 11 gain"
+	default 0
+	depends on SAMA5_ADC_CHAN11
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channel is configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channel is configured for
+		differential mode.
+
+endmenu # Channel gain
+
+menu "Channel offsets"
+
+config SAMA5_ADC_OFFSET0
+	bool "Channel 0 offset"
+	default n
+	depends on SAMA5_ADC_CHAN0
+	---help---
+		Center the channel 0 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET1
+	bool "Channel 1 offset"
+	default n
+	depends on SAMA5_ADC_CHAN1
+	---help---
+		Center the channel 1 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET2
+	bool "Channel 2 offset"
+	default n
+	depends on SAMA5_ADC_CHAN2
+	---help---
+		Center the channel 2 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET3
+	bool "Channel 3 offset"
+	default n
+	depends on SAMA5_ADC_CHAN3
+	---help---
+		Center the channel 3 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET4
+	bool "Channel 4 offset"
+	default n
+	depends on SAMA5_ADC_CHAN4
+	---help---
+		Center the channel 4 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET5
+	bool "Channel 5 offset"
+	default n
+	depends on SAMA5_ADC_CHAN5
+	---help---
+		Center the channel 5 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET6
+	bool "Channel 6 offset"
+	default n
+	depends on SAMA5_ADC_CHAN6
+	---help---
+		Center the channel 6 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET7
+	bool "Channel 7 offset"
+	default n
+	depends on SAMA5_ADC_CHAN7
+	---help---
+		Center the channel 7 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET8
+	bool "Channel 8 offset"
+	default n
+	depends on SAMA5_ADC_CHAN8
+	---help---
+		Center the channel 8 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET9
+	bool "Channel 9 offset"
+	default n
+	depends on SAMA5_ADC_CHAN9
+	---help---
+		Center the channel 9 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET10
+	bool "Channel 10 offset"
+	default n
+	depends on SAMA5_ADC_CHAN10
+	---help---
+		Center the channel 10 analog signal on Vrefin/2 before the gain
+		scaling.
+
+config SAMA5_ADC_OFFSET11
+	bool "Channel 11 offset"
+	default n
+	depends on SAMA5_ADC_CHAN11
+	---help---
+		Center the channel 11 analog signal on Vrefin/2 before the gain
+		scaling.
+
+endmenu # Channel offsets
+
+menu "Channel differential mode"
+
+config SAMA5_ADC_DIFFMODE0
+	bool "Channel 0 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN0
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 0
+
+config SAMA5_ADC_DIFFMODE1
+	bool "Channel 1 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN1
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 1
+
+config SAMA5_ADC_DIFFMODE2
+	bool "Channel 2 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN2
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 2
+
+config SAMA5_ADC_DIFFMODE3
+	bool "Channel 3 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN3
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 3
+
+config SAMA5_ADC_DIFFMODE4
+	bool "Channel 4 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN4
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 4
+
+config SAMA5_ADC_DIFFMODE5
+	bool "Channel 5 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN5
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 5
+
+config SAMA5_ADC_DIFFMODE6
+	bool "Channel 6 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN6
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 6
+
+config SAMA5_ADC_DIFFMODE7
+	bool "Channel 7 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN7
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 7
+
+config SAMA5_ADC_DIFFMODE8
+	bool "Channel 8 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN8
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 8
+
+config SAMA5_ADC_DIFFMODE9
+	bool "Channel 9 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN9
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 9
+
+config SAMA5_ADC_DIFFMODE10
+	bool "Channel 10 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN10
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 10
+
+config SAMA5_ADC_DIFFMODE11
+	bool "Channel 11 differential mode"
+	default n
+	depends on SAMA5_ADC_CHAN11
+	---help---
+		Selects differential (vs. single-ended mode) for ADC channel 11
+
+endmenu # Differential mode
+endif # SAMA5_ADC_ANARCH
+
+if !SAMA5_ADC_ANARCH
+
+config SAMA5_ADC_GAIN
+	int "Analog gain"
+	depends on SAMA5_ADC_CHAN0
+	range 0 3
+	---help---
+		Valid gain settings are {0, 1, 2, 3} which may be interpreted as
+		either {1, 1, 2, 4} if the channels are configured for single ended
+		mode or as {0.5, 1, 2, 2} if the channels are configured for
+		differential mode.
+
+config SAMA5_ADC_OFFSET
+	bool "Offset"
+	default n
+	---help---
+		Center the analog signal on Vrefin/2 before the gain scaling.
+
+config SAMA5_ADC_DIFFMODE
+	bool "Differential mode"
+	default n
+	---help---
+		Selects differential (vs. single-ended mode)
+
+endif # !SAMA5_ADC_ANARCH
+
+menu "ADC Trigger Selection"
+
+choice
+	prompt "ADC trigger mode"
+	default SAMA5_ADC_SWTRIG
+	---help---
+		Select the event that will trigger the A-to-D conversion sequence.
+
+config SAMA5_ADC_SWTRIG
+	bool "Software trigger"
+	---help---
+		A-to-D Conversion is initiated only by sofware via an ioctl()
+
+config SAMA5_ADC_ADTRG
+	bool "External trigger via the ADTRG pin"
+	---help---
+		A-to-D Conversion is initiated an event on the ADTRG pin.
+
+config SAMA5_ADC_TIOATRIG
+	bool "TC0 ouput A trigger"
+	---help---
+		A-to-D Conversion is initiated the A output from one of
+		Timer/Counter 0 channels.
+
+endchoice # Trigger mode
+
+choice
+	prompt "ADTRG edge"
+	default SAMA5_ADC_ADTRG_BOTH
+	depends on SAMA5_ADC_ADTRG
+
+config SAMA5_ADC_ADTRG_RISING
+	bool "Rising edge"
+	---help---
+		Trigger A-to-D conversion on the rising edge of the ADTRG signal.
+
+config SAMA5_ADC_ADTRG_FALLING
+	bool "Falling edge"
+	---help---
+		Trigger A-to-D conversion on the falling edge of the ADTRG signal.
+
+config SAMA5_ADC_ADTRG_BOTH
+	bool "Both edges"
+	---help---
+		Trigger A-to-D conversion on both edges of the ADTRG signal
+
+endchoice # ADTRG edge
+
+if SAMA5_ADC_TIOATRIG
+
+choice
+	prompt "TC0 channel"
+	default SAMA5_ADC_TIOA0TRIG
+
+config SAMA5_ADC_TIOA0TRIG
+	bool "TC0 Channel 0 Output A"
+	---help---
+		A-to-D conversion is triggered by the TC0 channel 0 output A signal.
+		This output must be enabled independently in the Timer/Counter
+		driver configuration for this to work.
+
+config SAMA5_ADC_TIOA1TRIG
+	bool "TC0 Channel 1 Output A"
+	---help---
+		A-to-D conversion is triggered by the TC0 channel 1 output A signal.
+		This output must be enabled independently in the Timer/Counter
+		driver configuration for this to work.
+
+config SAMA5_ADC_TIOA2TRIG
+	bool "TC0 Channel 2 Output A"
+	---help---
+		A-to-D conversion is triggered by the TC0 channel 2 output A signal.
+		This output must be enabled independently in the Timer/Counter
+		driver configuration for this to work.
+
+endchoice # TC0 channel
+
+choice
+	prompt "TIOAx edge"
+	default SAMA5_ADC_TIOA_BOTH
+	depends on SAMA5_ADC_ADTRG
+
+config SAMA5_ADC_TIOA_RISING
+	bool "Rising edge"
+	---help---
+		Trigger A-to-D conversion on the rising edge of the TIOAx signal.
+
+config SAMA5_ADC_TIOA_FALLING
+	bool "Falling edge"
+	---help---
+		Trigger A-to-D conversion on the falling edge of the TIOAx signal.
+
+config SAMA5_ADC_TIOA_BOTH
+	bool "Both edges"
+	---help---
+		Trigger A-to-D conversion on both edges of the TIOAx signal
+
+endchoice # ADTRG edge
+endif # SAMA5_ADC_TIOATRIG
+endmenu # ADC Trigger Selection
+endif # SAMA5_ADC_HAVE_CHAN
+
+config SAMA5_ADC_REGDEBUG
+	bool "Enable register-level ADC/touchscreen debug"
+	default n
+	depends on DEBUG
+	---help---
+		Enable very low register-level debug output.
+
+endmenu # ADC Configuration
+
+menu "Touchscreen configuration"
+
+config SAMA5_TSD
+	bool "Touchscreen support"
+	default n
+	select INPUT
+	---help---
+		Configure the ADC to support a touchscreen
+
+if SAMA5_TSD
+
+choice
+	prompt "Touchscreen interface"
+	default SAMA5_TSD_4WIRE
+	---help---
+		Select the type of physical interface to the touchscreen
+
+config SAMA5_TSD_4WIRE
+	bool "4-wire interface (with pressure)"
+
+config SAMA5_TSD_4WIRENPM
+	bool "4-wire interface (without pressure)"
+
+config SAMA5_TSD_5WIRE
+	bool "5-wire interface"
+
+endchoice # Touchscreen interface
+
+config SAMA5_TSD_SWAPXY
+	bool "Swap X/Y"
+	default n
+	---help---
+		Reverse the meaning of X and Y to handle different LCD orientations.
+
+config SAMA5_TSD_THRESHX
+	int "X threshold"
+	default 12
+	---help---
+		New touch positions will only be reported when the X or Y data
+		changes by these thresholds. This trades reduces data rate for some
+		loss in dragging accuracy.  For 12-bit values so the raw ranges are
+		0-4095. So for example, if your display is 320x240, then THRESHX=13
+		and THRESHY=17 would correspond to one pixel.  Default: 12
+
+config SAMA5_TSD_THRESHY
+	int "Y threshold"
+	default 12
+	---help---
+		New touch positions will only be reported when the X or Y data
+		changes by these thresholds. This trades reduces data rate for some
+		loss in dragging accuracy.  For 12-bit values so the raw ranges are
+		0-4095. So for example, if your display is 320x240, then THRESHX=13
+		and THRESHY=17 would correspond to one pixel.  Default: 12
+
+config SAMA_TSD_RXP
+	int "X-panel resistance"
+	default 6
+	depends on SAMA5_TSD_4WIRE
+	---help---
+		The method to measure the pressure (Rp) applied to the touchscreen is
+		based on the known resistance of the X-Panel resistance (Rxp).
+
+config SAMA5_TSD_NPOLLWAITERS
+	int "Number poll waiters"
+	default 4
+	depends on !DISABLE_POLL
+	---help---
+		Maximum number of threads that can be waiting on poll()
+
+endif # SAMA5_TSD
+endmenu # Touchscreen Configuration
+endif # SAMA5_ADC
+
 menu "External Memory Configuration"
 
 config SAMA5_DDRCS
diff --git a/arch/arm/src/sama5/Make.defs b/arch/arm/src/sama5/Make.defs
index c7e2fb5f50..94036c4db0 100644
--- a/arch/arm/src/sama5/Make.defs
+++ b/arch/arm/src/sama5/Make.defs
@@ -132,6 +132,14 @@ ifeq ($(CONFIG_SAMA5_UDPHS),y)
 CHIP_CSRCS += sam_udphs.c
 endif
 
+ifeq ($(CONFIG_USBHOST_TRACE),y)
+CHIP_CSRCS += sam_usbhost.c
+else
+ifeq ($(CONFIG_DEBUG_USB),y)
+CHIP_CSRCS += sam_usbhost.c
+endif
+endif
+
 ifeq ($(CONFIG_SAMA5_HSMCI0),y)
 CHIP_CSRCS += sam_hsmci.c
 else
@@ -166,10 +174,10 @@ endif
 endif
 endif
 
-ifeq ($(CONFIG_USBHOST_TRACE),y)
-CHIP_CSRCS += sam_usbhost.c
+ifeq ($(CONFIG_SAMA5_ADC),y)
+CHIP_CSRCS += sam_adc.c
 else
-ifeq ($(CONFIG_DEBUG_USB),y)
-CHIP_CSRCS += sam_usbhost.c
+ifeq ($(CONFIG_SAMA5_TSD),y)
+CHIP_CSRCS += sam_tsd.c
 endif
 endif
diff --git a/arch/arm/src/sama5/sam_adc.c b/arch/arm/src/sama5/sam_adc.c
index 8b4d408a06..d14108d65b 100644
--- a/arch/arm/src/sama5/sam_adc.c
+++ b/arch/arm/src/sama5/sam_adc.c
@@ -70,6 +70,7 @@
 #include "chip/sam_adc.h"
 #include "chip/sam_pmc.h"
 #include "sam_dmac.h"
+#include "sam_tsd.h"
 #include "sam_adc.h"
 
 #if defined(CONFIG_SAMA5_ADC)
@@ -209,9 +210,9 @@
 /* If we are supporting the analog chang feature, then sure that there
  * is a gain setting for each enabled channel.
  *
- * Valid gain settings are {1, 2, 3, 4} which may be interpreted as
+ * Valid gain settings are {0, 1, 2, 3} which may be interpreted as
  * either {1, 1, 2, 4} if the DIFFx bit in COR register is zero or as 
- * {0.5, 1, 2, 2} if the DIFFx bit is zet.
+ * {0.5, 1, 2, 2} if the DIFFx bit is set.
  */
 
 #ifdef CONFIG_SAMA5_ADC_ANARCH
@@ -283,7 +284,7 @@
  * available if the touch screen is enabled
  */
 
-#ifdef CONFIG_SAMA5_TOUCHSCREEN
+#ifdef CONFIG_SAMA5_TSD
 #  ifdef CONFIG_SAMA5_TSD_5WIRE
 #    SAMA5_ADC_CHALL  (ADC_CHALL & ~TSD_5WIRE_ALL)
 #  else
@@ -362,18 +363,20 @@
 
 struct sam_adc_s
 {
-  sem_t exclsem;        /* Supports exclusive access to the ADC interface */
+  sem_t exclsem;         /* Supports exclusive access to the ADC interface */
+  bool initialized;      /* The ADC driver is already initialized */
 
 #ifdef SAMA5_ADC_HAVE_CHANNELS
 #ifdef CONFIG_SAMA5_ADC_DMA
-  volatile bool odd;    /* Odd buffer is in use */
-  volatile bool ready;  /* Worker has completed the last set of samples */
+  volatile bool odd;     /* Odd buffer is in use */
+  volatile bool ready;   /* Worker has completed the last set of samples */
+  volatile bool enabled; /* DMA data transfer is enabled */
 #endif
-  struct adc_dev_s dev; /* The external via of the ADC device */
-  uint32_t pending;     /* Pending EOC events */
-  struct work_s work;   /* Supports the interrupt handling "bottom half" */
+  struct adc_dev_s dev;  /* The external via of the ADC device */
+  uint32_t pending;      /* Pending EOC events */
+  struct work_s work;    /* Supports the interrupt handling "bottom half" */
 #ifdef CONFIG_SAMA5_ADC_DMA
-  DMA_HANDLE dma;       /* Handle for DMA channel */
+  DMA_HANDLE dma;        /* Handle for DMA channel */
 #endif
 
   /* DMA sample data buffer */
@@ -387,10 +390,10 @@ struct sam_adc_s
   /* Debug stuff */
 
 #ifdef CONFIG_SAMA5_ADC_REGDEBUG
-   bool wrlast;         /* Last was a write */
-   uintptr_t addrlast;  /* Last address */
-   uint32_t vallast;    /* Last value */
-   int ntimes;          /* Number of times */
+   bool wrlast;          /* Last was a write */
+   uintptr_t addrlast;   /* Last address */
+   uint32_t vallast;     /* Last value */
+   int ntimes;           /* Number of times */
 #endif
 };
 
@@ -576,30 +579,35 @@ static void sam_adc_dmadone(void *arg)
 
   ASSERT(priv != NULL && !priv->ready);
 
-  /* Select the completed DMA buffer */
+  /* If the DMA is disabled, just ignore the data */
 
-  buffer = priv->odd ? priv->evenbuf : priv->oddbuf;
+  if (!priv->enabled)
+    {
+      /* Select the completed DMA buffer */
 
-  /* Invalidate the DMA buffer so that we are guaranteed to reload the
-   * newly DMAed data from RAM.
-   */
+      buffer = priv->odd ? priv->evenbuf : priv->oddbuf;
 
-  cp15_invalidate_dcache((uintptr_t)buffer,
-                         (uintptr_t)buffer + SAMA5_NCHANNELS * sizeof(uint32_t));
+      /* Invalidate the DMA buffer so that we are guaranteed to reload the
+       * newly DMAed data from RAM.
+       */
 
-  /* Process each sample */
+      cp15_invalidate_dcache((uintptr_t)buffer,
+                             (uintptr_t)buffer + SAMA5_NCHANNELS * sizeof(uint32_t));
 
-  for (i = 0; i < SAMA5_NCHANNELS; i++, buffer++)
-   {
-     /* Get the sample and the channel number */
+      /* Process each sample */
 
-     chan   = (int)((*buffer & ADC_LCDR_CHANB_MASK) >> ADC_LCDR_CHANB_SHIFT);
-     sample = (uint16_t)((*buffer & ADC_LCDR_DATA_MASK) >> ADC_LCDR_DATA_SHIFT);
+      for (i = 0; i < SAMA5_NCHANNELS; i++, buffer++)
+        {
+          /* Get the sample and the channel number */
 
-     /* And give the sample data to the ADC upper half */
+          chan   = (int)((*buffer & ADC_LCDR_CHANB_MASK) >> ADC_LCDR_CHANB_SHIFT);
+          sample = (uint16_t)((*buffer & ADC_LCDR_DATA_MASK) >> ADC_LCDR_DATA_SHIFT);
 
-     (void)adc_receive(&priv->dev, chan, sample);
-   }
+           /* And give the sample data to the ADC upper half */
+
+           (void)adc_receive(&priv->dev, chan, sample);
+        }
+    }
 
   /* We are ready to handle the next sample sequence */
 
@@ -624,7 +632,7 @@ static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result)
 
   /* Check of the bottom half is keeping up with us */
 
-  if (priv->ready)
+  if (priv->ready && priv->enabled)
     {
       /* Toggle to the next buffer.  Note that the toggle only occurs if
        * the bottom half is ready to accept more data.  Otherwise, we
@@ -640,7 +648,7 @@ static void sam_adc_dmacallback(DMA_HANDLE handle, void *arg, int result)
       ret = work_queue(HPWORK, &priv->work, sam_adc_dmadone, priv, 0);
       if (ret != 0)
         {
-          illdbg("ERROR: Failed to queue work: %d\n", ret);
+          alldbg("ERROR: Failed to queue work: %d\n", ret);
         }
     }
 
@@ -692,16 +700,9 @@ static int sam_adc_dmasetup(FAR struct sam_adc_s *priv, FAR uint8_t *buffer,
 
   sam_dmarxsetup(priv->dma, paddr, maddr, buflen);
 
-  /* Enable DMA handshaking */
-#warning Missing logic
-
   /* Start the DMA */
 
   sam_dmastart(priv->dma, sam_adc_dmacallback, priv);
-
-  /* Configure DMA-related interrupts */
-#warning Missing loic
-
   return OK;
 }
 #endif
@@ -797,7 +798,7 @@ static int sam_adc_interrupt(int irq, void *context)
 
   /* Handle pending touchscreen interrupts */
 
-#ifdef CONFIG_SAMA5_TOUCHSCREEN
+#ifdef CONFIG_SAMA5_TSD
   if ((pending & ADC_TSD_INTS) != 0)
     {
       /* Let the touchscreen handle its interrupts */
@@ -833,7 +834,7 @@ static int sam_adc_interrupt(int irq, void *context)
       ret = work_queue(HPWORK, &priv->work, sam_adc_endconversion, priv, 0);
       if (ret != 0)
         {
-          illdbg("ERROR: Failed to queue work: %d\n", ret);
+          alldbg("ERROR: Failed to queue work: %d\n", ret);
         }
 
       pending &= ~ADC_INT_EOCALL;
@@ -867,6 +868,10 @@ static void sam_adc_reset(struct adc_dev_s *dev)
    * touchscreen configuration.
    */
 
+  /* Stop any DMA */
+
+  dma_stop(priv->dma);
+
   /* Disable all EOC interrupts */
 
   sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_EOCALL);
@@ -886,8 +891,18 @@ static void sam_adc_reset(struct adc_dev_s *dev)
   sam_adc_putreg(priv, SAM_CGR_MR, 0);
   sam_adc_putreg(priv, SAM_COR_MR, 0);
 
-  /* trigger mode, etc */
-#warning Missing logic
+#ifndef CONFIG_SAMA5_ADC_SWTRIG
+  /* Select software trigger (i.e., basically no trigger) */
+
+  regval  = sam_adc_getreg(priv->dev, SAM_ADC_MR);
+  regval &= ~ADC_MR_TRGSEL_MASK;
+  sam_adc_putreg(priv->dev, SAM_ADC_MR, regval);
+
+  regval  = sam_adc_getreg(priv, SAM_ADC_TRGR);
+  regval &= ~ADC_TRGR_TRGMOD_MASK;
+  regval |= ADC_TRGR_TRGMOD_NO_TRIGGER;
+  sam_adc_putreg(priv, SAM_ADC_TRGR, regval);
+#endif
 }
 
 /****************************************************************************
@@ -943,7 +958,10 @@ static int sam_adc_setup(struct adc_dev_s *dev)
 #ifdef CONFIG_SAMA5_ADC_DMA
   /* Configure for DMA transfer */
 
-  priv->odd = false;
+  priv->odd     = false;
+  priv->ready   = true;
+  priv->enabled = false;
+
   sam_adc_dmasetup(priv->dma, (void *)priv->evenbuf, SAMA5_NCHANNELS);
 #else
   /* Enable end-of-conversion interrupts for all enabled channels. */
@@ -994,6 +1012,12 @@ static void sam_adc_rxint(struct adc_dev_s *dev, bool enable)
 {
   struct sam_adc_s *priv = (struct sam_adc_s *)dev->ad_priv;
 
+#ifdef CONFIG_SAMA5_ADC_DMA
+  /* We don't stop the DMA when RX is disabled, we just stop the data transfer */
+
+  priv->enabled = enable;
+
+#else
   /* Are we enabling or disabling? */
 
   if (enable)
@@ -1008,6 +1032,7 @@ static void sam_adc_rxint(struct adc_dev_s *dev, bool enable)
 
       sam_adc_putreg32(priv, SAM_ADC_IDR, ADC_INT_EOCALL);
     }
+#endif
 }
 
 /****************************************************************************
@@ -1103,7 +1128,7 @@ static void sam_adc_trigger(struct sam_adc_s *priv)
   regval |= ADC_MR_TRGSEL_TIOA0;   /* Timer/counter 0 channel 0 output A */
 #elif defined(CONFIG_SAMA5_ADC_TIOA1TRIG)
   regval |= ADC_MR_TRGSEL_TIOA1;   /* Timer/counter 0 channel 1 output A */
-#elif defined(CONFIG_SAMA5_ADC_TIOA0TRIG)
+#elif defined(CONFIG_SAMA5_ADC_TIOA2TRIG)
   regval |= ADC_MR_TRGSEL_TIOA2;   /* Timer/counter 0 channel 2 output A */
 #else
 #  error Timer/counter for trigger not defined
@@ -1173,7 +1198,7 @@ static void sam_adc_offset(struct sam_adc_s *priv)
   uint32_t regval = 0;
 
 #ifdef CONFIG_SAMA5_ADC_ANARCH
-  /* Set the offset for each enabled channel.  This xenters the analog signal
+  /* Set the offset for each enabled channel.  This centers the analog signal
    * on Vrefin/2 before the gain scaling. The Offset applied is: (G-1)Vrefin/2
    * where G is the gain applied. The default is no offset.
    */
@@ -1257,7 +1282,7 @@ static void sam_adc_offset(struct sam_adc_s *priv)
 #endif
 
 #else
-  /* Set offset and differentila mode only on channel 0.  This will be
+  /* Set offset and differential mode only on channel 0.  This will be
    * used for all channel.
    */
 
@@ -1588,124 +1613,137 @@ static void sam_adc_channels(truct sam_adc_s *priv)
 
 struct adc_dev_s *sam_adc_initialize(void)
 {
-  /* Disable ADC peripheral clock */
+  struct sam_adc_s *priv = &g_adcpriv;
 
-  sam_adc_disableclk();
+  /* Have we already been initialzed?  If yes, than just hand out the
+   * interface one more time.
+   */
 
-  /* Configure ADC pins */
+  if (!priv->initialized)
+    {
+      /* Disable ADC peripheral clock */
+
+      sam_adc_disableclk();
+
+      /* Configure ADC pins */
 
 #ifdef CONFIG_SAMA5_ADC_CHAN0
-  sam_configpio(PIO_ADC_AD0);
+      sam_configpio(PIO_ADC_AD0);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN1
-  sam_configpio(PIO_ADC_AD1);
+      sam_configpio(PIO_ADC_AD1);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN2
-  sam_configpio(PIO_ADC_AD2);
+      sam_configpio(PIO_ADC_AD2);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN3
-  sam_configpio(PIO_ADC_AD3);
+      sam_configpio(PIO_ADC_AD3);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN4
-  sam_configpio(PIO_ADC_AD4);
+      sam_configpio(PIO_ADC_AD4);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN5
-  sam_configpio(PIO_ADC_AD5);
+      sam_configpio(PIO_ADC_AD5);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN6
-  sam_configpio(PIO_ADC_AD6);
+      sam_configpio(PIO_ADC_AD6);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN7
-  sam_configpio(PIO_ADC_AD7);
+      sam_configpio(PIO_ADC_AD7);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN8
-  sam_configpio(PIO_ADC_AD8);
+      sam_configpio(PIO_ADC_AD8);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN9
-  sam_configpio(PIO_ADC_AD9);
+      sam_configpio(PIO_ADC_AD9);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN10
-  sam_configpio(PIO_ADC_AD10);
+      sam_configpio(PIO_ADC_AD10);
 #endif
 #ifdef CONFIG_SAMA5_ADC_CHAN11
-  sam_configpio(PIO_ADC_AD11);
+      sam_configpio(PIO_ADC_AD11);
 #endif
 
 #ifdef CONFIG_SAMA5_ADC_ADTRG
-  sam_configpio(PIO_ADC_TRG);
+      sam_configpio(PIO_ADC_TRG);
 #endif
 
-  /* Initialize the ADC device data structure */
+      /* Initialize the ADC device data structure */
 
-  sem_init(&priv->exclsem,  0, 1);
+      sem_init(&priv->exclsem,  0, 1);
 
 #ifdef CONFIG_SAMA5_ADC_DMA
-  /* Allocate a DMA channel */
+      /* Allocate a DMA channel */
 
-  priv->dma = sam_dmachannel(dmac, DMA_FLAGS);
-  DEBUGASSERT(priv->dma);
+      priv->dma = sam_dmachannel(dmac, DMA_FLAGS);
+      DEBUGASSERT(priv->dma);
 #endif
 
-  /* Set the maximum ADC peripheral clock frequency */
+      /* Set the maximum ADC peripheral clock frequency */
 
-  regval = PMC_PCR_PID(SAM_PID_ADC) | PMC_PCR_CMD | ADC_PCR_DIV | PMC_PCR_EN;
-  sam_adc_putreg(priv, SAM_PMC_PCR, regval);
+      regval = PMC_PCR_PID(SAM_PID_ADC) | PMC_PCR_CMD | ADC_PCR_DIV | PMC_PCR_EN;
+      sam_adc_putreg(priv, SAM_PMC_PCR, regval);
 
-  /* Enable the ADC peripheral clock*/
+      /* Enable the ADC peripheral clock*/
 
-  sam_adc_enableclk();
+      sam_adc_enableclk();
 
-  /* Reset the ADC controller */
+      /* Reset the ADC controller */
 
-  sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_SWRST);
+      sam_adc_putreg(priv, SAM_ADC_CR, ADC_CR_SWRST);
 
-  /* Reset Mode Register */
+      /* Reset Mode Register */
 
-  sam_adc_putreg(priv, SAM_ADC_MR, 0);
+      sam_adc_putreg(priv, SAM_ADC_MR, 0);
 
-  /* Set the MCK clock prescaler: ADCClock = MCK / ((PRESCAL+1)*2) */
+      /* Set the MCK clock prescaler: ADCClock = MCK / ((PRESCAL+1)*2) */
 
-  regval  = sam_adc_getreg(priv, SAM_ADC_MR);
-  regval &= ~ADC_MR_PRESCAL_MASK;
-  regval |=  ADC_MR_PRESCAL(BOARD_ADC_PRESCAL);
-  sam_adc_putreg(priv, SAM_ADC_MR, regval);
+      regval  = sam_adc_getreg(priv, SAM_ADC_MR);
+      regval &= ~ADC_MR_PRESCAL_MASK;
+      regval |=  ADC_MR_PRESCAL(BOARD_ADC_PRESCAL);
+      sam_adc_putreg(priv, SAM_ADC_MR, regval);
 
-  /* Formula:
-   *     Startup  Time = startup value / ADCClock
-   *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
-   *     Tracking Time = (TRACKTIM + 1) / ADCClock
-   *     Settling Time = settling value / ADCClock
-   * For example, ADC clock = 6MHz (166.7 ns)
-   *     Startup time = 512 / 6MHz = 85.3 us
-   *     Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns
-   *     Tracking Time = (0 + 1) / 6MHz = 166.7 ns
-   *     Settling Time = 3 / 6MHz = 500 ns
-   */
+      /* Formula:
+       *     Startup  Time = startup value / ADCClock
+       *     Transfer Time = (TRANSFER * 2 + 3) / ADCClock
+       *     Tracking Time = (TRACKTIM + 1) / ADCClock
+       *     Settling Time = settling value / ADCClock
+       * For example, ADC clock = 6MHz (166.7 ns)
+       *     Startup time = 512 / 6MHz = 85.3 us
+       *     Transfer Time = (1 * 2 + 3) / 6MHz = 833.3 ns
+       *     Tracking Time = (0 + 1) / 6MHz = 166.7 ns
+       *     Settling Time = 3 / 6MHz = 500 ns
+       */
 
-  /* Set ADC timing */
+      /* Set ADC timing */
 
-  regval  = sam_adc_getreg(priv, SAM_ADC_MR);
-  regval &= ~(ADC_MR_STARTUP_MASK | ADC_MR_TRACKTIM_MASK | ADC_MR_SETTLING_MASK);
-  regval |= ADC_MR_STARTUP_SUT512 | ADC_MR_TRACKTIM(0) | ADC_MR_SETTLING_AST17;
-  sam_adc_puttreg(priv, SAM_ADC_MR, regval);
+      regval  = sam_adc_getreg(priv, SAM_ADC_MR);
+      regval &= ~(ADC_MR_STARTUP_MASK | ADC_MR_TRACKTIM_MASK | ADC_MR_SETTLING_MASK);
+      regval |= ADC_MR_STARTUP_SUT512 | ADC_MR_TRACKTIM(0) | ADC_MR_SETTLING_AST17;
+      sam_adc_puttreg(priv, SAM_ADC_MR, regval);
 
-  /* Attach the ADC interrupt */
+      /* Attach the ADC interrupt */
 
-  ret = irq_attach(SAM_IRQ_ADC, sam_adc_interrupt);
-  if (ret < 0)
-    {
-      adbg("ERROR: Failed to attach IRQ %d: %d\n", SAM_IRQ_ADC, ret);
-      return ret;
+      ret = irq_attach(SAM_IRQ_ADC, sam_adc_interrupt);
+      if (ret < 0)
+        {
+          adbg("ERROR: Failed to attach IRQ %d: %d\n", SAM_IRQ_ADC, ret);
+          return NULL;
+        }
+
+      /* Disable all ADC interrupts at the source */
+
+      sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_ALL);
+
+      /* Enable the ADC interrupt at the AIC */
+
+      up_enable_irq(SAM_IRQ_ADC);
+
+      /* Now we are initialized */
+
+      priv->intialized = true;
     }
 
-  /* Disable all ADC interrupts at the source */
-
-  sam_adc_putreg(priv, SAM_ADC_IDR, ADC_INT_ALL);
-
-  /* Enable the ADC interrupt at the AIC */
-
-  up_enable_irq(SAM_IRQ_ADC);
-
   /* Return a pointer to the device structure */
 
   return &g_adcdev;
diff --git a/arch/arm/src/sama5/sam_adc.h b/arch/arm/src/sama5/sam_adc.h
index 2a9e001083..a01321c3b7 100644
--- a/arch/arm/src/sama5/sam_adc.h
+++ b/arch/arm/src/sama5/sam_adc.h
@@ -62,12 +62,12 @@
  * support is enabled.
  */
 
-#ifdef CONFIG_SAMA5_TOUCHSCREEN
+#ifdef CONFIG_SAMA5_TSD
 #  undef CONFIG_SAMA5_ADC_CHAN0
 #  undef CONFIG_SAMA5_ADC_CHAN1
 #  undef CONFIG_SAMA5_ADC_CHAN2
 #  undef CONFIG_SAMA5_ADC_CHAN3
-#  ifdef CONFIG_SAMA5_TOUCHSCREEN_5WIRE
+#  ifdef CONFIG_SAMA5_TSD_5WIRE
 #    undef CONFIG_SAMA5_ADC_CHAN4
 #  endif
 #endif
@@ -84,7 +84,7 @@
     defined(CONFIG_SAMA5_ADC_CHAN8) || defined(CONFIG_SAMA5_ADC_CHAN9) || \
     defined(CONFIG_SAMA5_ADC_CHAN10) || defined(CONFIG_SAMA5_ADC_CHAN11)
 #  define SAMA5_ADC_HAVE_CHANNELS 1
-#elif !defined(CONFIG_SAMA5_TOUCHSCREEN)
+#elif !defined(CONFIG_SAMA5_TSD)
 #  error "No ADC channels nor touchscreen"
 #endif
 
diff --git a/arch/arm/src/sama5/sam_touchscreen.c b/arch/arm/src/sama5/sam_tsd.c
similarity index 99%
rename from arch/arm/src/sama5/sam_touchscreen.c
rename to arch/arm/src/sama5/sam_tsd.c
index 8b3db2818c..6459c35bc3 100644
--- a/arch/arm/src/sama5/sam_touchscreen.c
+++ b/arch/arm/src/sama5/sam_tsd.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/src/sama5/sam_touchsreen.c
+ * arch/arm/src/sama5/sam_tsd.c
  *
  *   Copyright (C) 2013 Gregory Nutt. All rights reserved.
  *   Authors: Gregory Nutt <gnutt@nuttx.org>
@@ -65,9 +65,9 @@
 
 #include <nuttx/input/touchscreen.h>
 
-#include "sam_touchscreen.h"
+#include "sam_tsd.h"
 
-#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_SAMA5_TOUCHSCREEN)
+#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_SAMA5_TSD)
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -929,7 +929,7 @@ static int sam_tsd_close(struct file *filep)
   FAR struct watchdog_upperhalf_s *priv = inode->i_private;
   int ret;
 
-  wdvdbg("crefs: %d\n", priv->crefs);
+  ivdbg("crefs: %d\n", priv->crefs);
 
   /* Get exclusive access to the device structures */
 
@@ -1780,4 +1780,4 @@ void sam_tsd_interrupt(uint32_t pending)
   return ret;
 }
 
-#endif /* CONFIG_SAMA5_ADC && CONFIG_SAMA5_TOUCHSCREEN */
+#endif /* CONFIG_SAMA5_ADC && CONFIG_SAMA5_TSD */
diff --git a/arch/arm/src/sama5/sam_touchscreen.h b/arch/arm/src/sama5/sam_tsd.h
similarity index 93%
rename from arch/arm/src/sama5/sam_touchscreen.h
rename to arch/arm/src/sama5/sam_tsd.h
index 4e293382e5..1752c1cf31 100644
--- a/arch/arm/src/sama5/sam_touchscreen.h
+++ b/arch/arm/src/sama5/sam_tsd.h
@@ -1,5 +1,5 @@
 /****************************************************************************
- * arch/arm/src/sama5/sam_adc.h
+ * arch/arm/src/sama5/sam_tsd.h
  *
  *   Copyright (C) 2013 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
@@ -33,8 +33,8 @@
  *
  ****************************************************************************/
 
-#ifndef __ARCH_ARM_SRC_SAMA5_SAM_ADC_H
-#define __ARCH_ARM_SRC_SAMA5_SAM_ADC_H
+#ifndef __ARCH_ARM_SRC_SAMA5_SAM_TSD_H
+#define __ARCH_ARM_SRC_SAMA5_SAM_TSD_H
 
 /****************************************************************************
  * Included Files
@@ -43,7 +43,7 @@
 #include <nuttx/config.h>
 #include "chip/sam_adc.h"
 
-#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_SAMA5_TOUCHSCREEN)
+#if defined(CONFIG_SAMA5_ADC) && defined(CONFIG_SAMA5_TSD)
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -119,5 +119,5 @@ void sam_tsd_interrupt(uint32_t pending);
 }
 #endif
 
-#endif /* CONFIG_SAMA5_ADC && CONFIG_SAMA5_TOUCHSCREEN */
-#endif /* __ARCH_ARM_SRC_SAMA5_SAM_ADC_H */
+#endif /* CONFIG_SAMA5_ADC && CONFIG_SAMA5_TSD */
+#endif /* __ARCH_ARM_SRC_SAMA5_SAM_TSD_H */
diff --git a/configs/sama5d3x-ek/Kconfig b/configs/sama5d3x-ek/Kconfig
index d5a6695575..9f3b4124b7 100644
--- a/configs/sama5d3x-ek/Kconfig
+++ b/configs/sama5d3x-ek/Kconfig
@@ -42,6 +42,14 @@ config SAMA5_NOR_START
 		option:  If SAMA5_NOR_START is defined, then it will not wait but
 		will, instead, immediately start the program in NOR FLASH.
 
+config SAMA5_TSD_DEVMINOR
+	int "Touchscreen device minor"
+	default 0
+	depends on SAMA5_TSD
+	---help---
+		This touchscreen will be register as /dev/inputN where the value of
+		N is provided by this configuration setting.
+
 config SAMA5_AT25_AUTOMOUNT
 	bool "AT25 serial FLASH auto-mount"
 	default n
diff --git a/configs/sama5d3x-ek/README.txt b/configs/sama5d3x-ek/README.txt
index 98a374dbd3..88bc957462 100644
--- a/configs/sama5d3x-ek/README.txt
+++ b/configs/sama5d3x-ek/README.txt
@@ -1836,7 +1836,7 @@ Configurations
          nsh> cat /mnt/at24/atest.txt
          This is a test
 
-    13. I2C Tool. NuttX supports an I2C tool at apps/system/i2c that can be
+    14. I2C Tool. NuttX supports an I2C tool at apps/system/i2c that can be
         used to peek and poke I2C devices.  That tool cal be enabled by
         setting the following:
 
@@ -1910,7 +1910,7 @@ Configurations
         Address 0x1a is the WM8904.  Address 0x39 is the SIL9022A. I am
         not sure what is at address 0x3d and 0x60
 
-    14. Networking support via the can be added to NSH be selecting the
+    15. Networking support via the can be added to NSH be selecting the
         following configuration options.  The SAMA5D3x supports two different
         Ethernet MAC peripherals:  (1) The 10/100Base-T EMAC peripheral and
         and (2) the 10/100/1000Base-T GMAC peripheral.  Only the SAMA5D31
@@ -2083,7 +2083,38 @@ Configurations
           This delay will be especially long if the board is not connected to
           a network.
 
+    16. You can enable the touchscreen by modifying the configuration
+        in the following ways:
+
+        System Type:
+          CONFIG_SAMA5_ADC=y                     : ADC support is required
+          CONFIG_SAMA5_TSD=y                     : Enabled touchcreen device support
+          SAMA5_TSD_4WIRE=y                      : 4-Wire interface with pressure
+
+        You might want to tinker with the SWAPXY and THRESHX and THRESHY
+        settings to get the result that you want.
+
+        Drivers:
+          CONFIG_INPUT=y                         : (automatically selected)
+
+        Board Selection:
+           CONFIG_SAMA5_TSD_DEVMINOR=0           : Register as /dev/input0
+
+        Library Support:
+          CONFIG_SCHED_WORKQUEUE=y               : Work queue support required
+
+        These options may also be applied to enable a built-in touchscreen
+        test application:
+
+        Applicaton Configuration:
+          CONFIG_EXAMPLES_TOUCHSCREEN=y          : Enable the touchscreen built-int test
+          CONFIG_EXAMPLES_TOUCHSCREEN_MINOR=0    : To match the board selection
+          CONFIG_EXAMPLES_TOUCHSCREEN_DEVPATH="/dev/input0"
+
+        Defaults should be okay for all related settings.
+
     STATUS:
+
       PCK FREQUENCY
       2013-7-19:  This configuration (as do the others) run at 396MHz.
         The SAMA5D3 can run at 536MHz.  I still need to figure out the
diff --git a/configs/sama5d3x-ek/nsh/defconfig b/configs/sama5d3x-ek/nsh/defconfig
index ebdc5650a5..174d911837 100644
--- a/configs/sama5d3x-ek/nsh/defconfig
+++ b/configs/sama5d3x-ek/nsh/defconfig
@@ -43,6 +43,7 @@ CONFIG_RAW_BINARY=y
 # Debug Options
 #
 # CONFIG_DEBUG is not set
+CONFIG_ARCH_HAVE_STACKCHECK=y
 # CONFIG_DEBUG_SYMBOLS is not set
 
 #
@@ -503,7 +504,6 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024
 #
 # CONFIG_EXAMPLES_BUTTONS is not set
 # CONFIG_EXAMPLES_CAN is not set
-# CONFIG_SYSTEM_COMPOSITE is not set
 # CONFIG_EXAMPLES_CXXTEST is not set
 # CONFIG_EXAMPLES_DHCPD is not set
 # CONFIG_EXAMPLES_ELF is not set
@@ -551,7 +551,6 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
 # CONFIG_EXAMPLES_UDP is not set
 # CONFIG_EXAMPLES_UIP is not set
 # CONFIG_EXAMPLES_USBSERIAL is not set
-# CONFIG_SYSTEM_USBMSC is not set
 # CONFIG_EXAMPLES_USBTERM is not set
 # CONFIG_EXAMPLES_WATCHDOG is not set
 
@@ -669,6 +668,14 @@ CONFIG_NSH_CONSOLE=y
 # System NSH Add-Ons
 #
 
+#
+# USB CDC/ACM Device Commands
+#
+
+#
+# USB Composite Device Commands
+#
+
 #
 # Custom Free Memory Command
 #
@@ -722,6 +729,14 @@ CONFIG_READLINE_ECHO=y
 # USB Monitor
 #
 
+#
+# Stack Monitor
+#
+
+#
+# USB Mass Storage Device Commands
+#
+
 #
 # Zmodem Commands
 #
diff --git a/configs/sama5d3x-ek/src/Makefile b/configs/sama5d3x-ek/src/Makefile
index b931a8ae07..37fce7939a 100644
--- a/configs/sama5d3x-ek/src/Makefile
+++ b/configs/sama5d3x-ek/src/Makefile
@@ -114,6 +114,10 @@ ifeq ($(CONFIG_ARCH_FPU),y)
 CSRCS += sam_ostest.c
 endif
 
+ifeq ($(CONFIG_SAMA5_TSD),y)
+CSRCS += sam_touchscreen.c
+endif
+
 ifeq ($(CONFIG_ARCH_LEDS),y)
 CSRCS += sam_autoleds.c
 else
diff --git a/configs/sama5d3x-ek/src/sam_touchscreen.c b/configs/sama5d3x-ek/src/sam_touchscreen.c
new file mode 100644
index 0000000000..94763a69a8
--- /dev/null
+++ b/configs/sama5d3x-ek/src/sam_touchscreen.c
@@ -0,0 +1,163 @@
+/************************************************************************************
+ * configs/sama5d3-ek/src/sam_touchscreen.c
+ *
+ *   Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <debug.h>
+
+#include "sam_adc.h"
+#include "sam_tsd.h"
+#include "sama5d3x-ek.h"
+
+#ifdef CONFIG_SAMA5_TSD
+
+/****************************************************************************
+ * Pre-Processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_INPUT
+#  error "Touchscreen support requires CONFIG_INPUT"
+#endif
+
+#ifndef CONFIG_SAMA5_TSD_DEVMINOR
+#  define CONFIG_SAMA5_TSD_DEVMINOR 0
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arch_tcinitialize
+ *
+ * Description:
+ *   Each board that supports a touchscreen device must provide this
+ *   function.  This function is called by application-specific, setup logic
+ *   to configure the touchscreen device.  This function will register the
+ *   driver as /dev/inputN where N is the minor device number.
+ *
+ * Input Parameters:
+ *   minor - The input device minor number
+ *
+ * Returned Value:
+ *   Zero is returned on success.  Otherwise, a negated errno value is
+ *   returned to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int arch_tcinitialize(int minor)
+{
+  struct sam_adc_s *adc;
+  static bool initialized = false;
+  FAR struct spi_dev_s *dev;
+  int ret;
+
+  idbg("initialized:%d minor:%d\n", initialized, minor);
+  DEBUGASSERT(minor == 0);
+
+  /* Since there is no uninitialized logic, this initialization can be
+   * performed only one time.
+   */
+
+  if (!initialized)
+    {
+      /* Initialize the ADC driver */
+
+      adc = sam_adcinitialize();
+      if (!adc)
+        {
+          idbg("ERROR: Failed to initialize the ADC driver\n");
+          return -ENODEV;
+        }
+
+      /* Initialize and register the SPI touchscreen device */
+
+      ret = sam_tsd_register(adc, CONFIG_SAMA5_TSD_DEVMINOR);
+      if (ret < 0)
+        {
+          idbg("ERROR: Failed to register touchscreen device /dev/input%d: %d\n",
+               CONFIG_SAMA5_TSD_DEVMINOR, ret);
+          return -ENODEV;
+        }
+
+      initialized = true;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: arch_tcuninitialize
+ *
+ * Description:
+ *   Each board that supports a touchscreen device must provide this function.
+ *   This function is called by application-specific, setup logic to
+ *   uninitialize the touchscreen device.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None.
+ *
+ ****************************************************************************/
+
+void arch_tcuninitialize(void)
+{
+  /* No support for un-initializing the touchscreen  yet */
+}
+
+#endif /* CONFIG_INPUT_ADS7843E */