@@ -74,6 +64,21 @@
A.2 C Header File Structure
+
+
+
+
+
+
+
+
+ NuttX C Coding Standard
+
+ Last Updated: February 5, 2019
+
+
+
+
@@ -2984,5 +2989,8 @@ Each is preceded by a function header similar to the above.
Ending with the header file idempotence #endif.
+
+
+
diff --git a/Documentation/NuttXDemandPaging.html b/Documentation/NuttXDemandPaging.html
index e3a682c8b2d..b18e97480ac 100644
--- a/Documentation/NuttXDemandPaging.html
+++ b/Documentation/NuttXDemandPaging.html
@@ -1,6 +1,7 @@
On-Demand Paging
+
diff --git a/Documentation/NuttXNxFlat.html b/Documentation/NuttXNxFlat.html
index 5fe5c24455c..4e44e45fce3 100644
--- a/Documentation/NuttXNxFlat.html
+++ b/Documentation/NuttXNxFlat.html
@@ -1,6 +1,7 @@
NXFLAT
+
diff --git a/Documentation/NuttxPortingGuide.html b/Documentation/NuttxPortingGuide.html
index dedb90c32ce..7746ee3c5ce 100644
--- a/Documentation/NuttxPortingGuide.html
+++ b/Documentation/NuttxPortingGuide.html
@@ -2,22 +2,13 @@
NuttX Porting Guide
+
-
-
-
-
-
-
- NuttX RTOS Porting Guide
-
- Last Updated: February 18, 2019
-
-
-
-
+
+
+
@@ -238,6 +229,22 @@
Appendix A: NuttX Configuration Settings
Appendix B: Trademarks
+
+
+
+
+
+
+
+
+
+ NuttX RTOS Porting Guide
+
+ Last Updated: May 25, 2019
+
+
+
+
@@ -481,7 +488,7 @@
Configuration Files .
- The NuttX configuration consists of logic in processor architecture directories, chip/SoC directories, and board configuration directories.
+ The NuttX configuration consists of logic in processor architecture directories, chip/SoC directories, and board configuration directories.
The complete configuration is specified by several settings in the NuttX configuration file.
@@ -1773,7 +1780,7 @@ The specific environmental definitions are unique for each board but should incl
This strict layering is enforced in the NuttX build system by controlling the compiler include paths: Higher level code can never include header files from either; of the platform-specific source directories; microcontroller-specific code can never include header files from the board-specific source directories. The board-specific directories are, then, at the bottom of the layered hierarchy.
- An exception to these inclusion restrictions is the platform-specific include/ . These are made available to higher level OS logic. The microcontroller-specific include directory will be linked at include/arch/chip and, hence, can be included like #include <arch/chip/chip.h.
+ An exception to these inclusion restrictions is the platform-specific include/ . These are made available to higher level OS logic. The microcontroller-specific include directory will be linked at include/arch/chip and, hence, can be included like #include <arch/hardware/chip.h.
Similarly, the board-specific include directory will be linked at include/arch/board and, hence, can be included like #include <arch/board/board.h.
@@ -2176,10 +2183,6 @@ The specific environmental definitions are unique for each board but should incl
handler now.
-
- This API is NOT required if CONFIG_DISABLE_SIGNALS
- is defined.
-
Function Prototype : void up_allocate_heap(FAR void **heap_start, size_t *heap_size);
@@ -5168,7 +5171,7 @@ void iob_dump(FAR const char *msg, FAR struct iob_s *iob, unsigned int len,
Examples :
- arch/arm/src/chip/lm_serial.c, arch/arm/src/lpc214x/lpc214x_serial.c, arch/z16/src/z16f/z16f_serial.c, etc.
+ arch/arm/src/stm32/stm32_serial.c, arch/arm/src/lpc214x/lpc214x_serial.c, arch/z16/src/z16f/z16f_serial.c, etc.
@@ -5201,7 +5204,7 @@ void iob_dump(FAR const char *msg, FAR struct iob_s *iob, unsigned int len,
The controller-specific, "upper half" touchscreen drivers reside in the directory drivers/input.
"Lower Half" Drivers .
- Platform-specific touchscreen drivers reside in either: (1) The arch/<architecture> /src/<chip> directory for the processor architectures that have build in touchscreen controllers or (2) the configs/<board> /src/ directory for boards that use an external touchscreen controller chip.
+ Platform-specific touchscreen drivers reside in either: (1) The arch/<architecture> /src/<hardware> directory for the processor architectures that have build in touchscreen controllers or (2) the configs/<board> /src/ directory for boards that use an external touchscreen controller chip.
@@ -5226,7 +5229,7 @@ void iob_dump(FAR const char *msg, FAR struct iob_s *iob, unsigned int len,
Common analog logic and share-able analog drivers reside in the drivers/analog/.
- Platform-specific drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> analog peripheral devices.
+ Platform-specific drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> analog peripheral devices.
@@ -5312,7 +5315,7 @@ void iob_dump(FAR const char *msg, FAR struct iob_s *iob, unsigned int len,
The generic, "upper half" PWM driver resides at drivers/pwm.c.
"Lower Half" Drivers .
- Platform-specific PWM drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> PWM peripheral devices.
+ Platform-specific PWM drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> PWM peripheral devices.
@@ -5343,7 +5346,7 @@ void iob_dump(FAR const char *msg, FAR struct iob_s *iob, unsigned int len,
The generic, "upper half" CAN driver resides at drivers/can.c.
"Lower Half" Drivers .
- Platform-specific CAN drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> CAN peripheral devices.
+ Platform-specific CAN drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> CAN peripheral devices.
@@ -5411,7 +5414,7 @@ for (i = 0; i <= nread - CAN_MSGLEN(0); i += msglen)
The generic, "upper half" Quadrature Encoder driver resides at drivers/sensors/qencoder.c.
"Lower Half" Drivers .
- Platform-specific Quadrature Encoder drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> Quadrature Encoder peripheral devices.
+ Platform-specific Quadrature Encoder drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> Quadrature Encoder peripheral devices.
@@ -5440,7 +5443,7 @@ for (i = 0; i <= nread - CAN_MSGLEN(0); i += msglen)
The generic, "upper half" timer driver resides at drivers/timers/timer.c.
"Lower Half" Drivers .
- Platform-specific timer drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> timer peripheral devices.
+ Platform-specific timer drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> timer peripheral devices.
@@ -5469,7 +5472,7 @@ for (i = 0; i <= nread - CAN_MSGLEN(0); i += msglen)
The generic, "upper half" RTC driver resides at drivers/timers/rtc.c.
"Lower Half" Drivers .
- Platform-specific RTC drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> RTC peripheral devices.
+ Platform-specific RTC drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> RTC peripheral devices.
@@ -5498,7 +5501,7 @@ for (i = 0; i <= nread - CAN_MSGLEN(0); i += msglen)
The generic, "upper half" watchdog timer driver resides at drivers/timers/watchdog.c.
"Lower Half" Drivers .
- Platform-specific watchdog timer drivers reside in arch/<architecture> /src/<chip> directory for the specific processor <architecture> and for the specific <chip> watchdog timer peripheral devices.
+ Platform-specific watchdog timer drivers reside in arch/<architecture> /src/<hardware> directory for the specific processor <architecture> and for the specific <chip> watchdog timer peripheral devices.
@@ -6470,7 +6473,7 @@ int kbd_decode(FAR struct lib_instream_s *stream, FAR struct kbd_getstate_s *sta
#include <syslog.h>
int syslog(int priority, FAR const IPTR char *format, ...);
-int vsyslog(int priority, FAR const IPTR char *src, va_list ap);
+void vsyslog(int priority, FAR const IPTR char *src, va_list ap);
Description:
syslog() generates a log message. The priority argument is formed by ORing the facility and the level values (see include/syslog.h). The remaining arguments are a format, as in printf() and any arguments to the format.
@@ -7301,6 +7304,9 @@ void (*notify)(FAR struct pm_callback_s *cb, int domain, enum pm_state_e pmstate
standard as a development guideline only.
+
+
+
diff --git a/Documentation/NuttxUserGuide.html b/Documentation/NuttxUserGuide.html
index e6bab2cf571..2b0167d0e75 100644
--- a/Documentation/NuttxUserGuide.html
+++ b/Documentation/NuttxUserGuide.html
@@ -3,6 +3,7 @@
NuttX Users Manual
+
@@ -1476,9 +1477,8 @@ int posix_spawnattr_getschedpolicy(FAR const posix_spawnattr_t *attr, FAR int *p
#include <spawn.h>
-#ifndef CONFIG_DISABLE_SIGNALS
+
int posix_spawnattr_getsigmask(FAR const posix_spawnattr_t *attr, FAR sigset_t *sigmask);
-#endif
Description:
@@ -1598,9 +1598,8 @@ int posix_spawnattr_setschedpolicy(FAR posix_spawnattr_t *attr, int policy);
#include <spawn.h>
-#ifndef CONFIG_DISABLE_SIGNALS
+
int posix_spawnattr_setsigmask(FAR posix_spawnattr_t *attr, FAR const sigset_t *sigmask);
-#endif
Description:
@@ -8618,14 +8617,7 @@ interface of the same name.
Configuration Settings .
- In order to use the poll() API, the following must be defined
- in your NuttX configuration file:
-
-
- CONFIG_DISABLE_POLL NOT defined
-
-
- In order to use the select with TCP/IP sockets test, you must also have the following additional things
+ In order to use the select with TCP/IP sockets test, you must have the following things
selected in your NuttX configuration file:
@@ -29,9 +29,13 @@ nuttx/
|- arch/
| |
| |- arm/
- | | |- src
- | | |-
lpc214x/README.txt
- | | `-
stm32l4/README.txt
+ | | `- src
+ | | |- common
+ | | | `-
README_lwl_console.txt
+ | | |- lpc214x
+ | | | `-
README.txt
+ | | `- stm32l4
+ | | `-
stm32l4/README.txt
| |- renesas/
| | |- include/
| | | `-
README.txt
@@ -63,6 +67,8 @@ nuttx/
| | `-
README.txt
| |- avr32dev1/
| | `-
README.txt
+ | |- axoloti/
+ | | `-
README.txt
| |- b-l475e-iot01a/
| | `-
README.txt
| |- bambino-200e/
@@ -153,6 +159,8 @@ nuttx/
| | `-
README.txt
| |- lpcxpresso-lpc54628/
| | `-
README.txt
+ | |- makerlisp/
+ | | `-
README.txt \
| |- maple/
| | `-
README.txt \
| |- max32660-evsys/
@@ -286,6 +294,8 @@ nuttx/
| | `-
README.txt
| |- skp16c26/
| | `-
README.txt
+ | |- spresense/
+ | | `-
README.txt
| |- stm3210e-eval/
| | |-
RIDE/README.txt
| | `-
README.txt
diff --git a/Documentation/UsbTrace.html b/Documentation/UsbTrace.html
index 4794d524dff..2b26986e7f9 100644
--- a/Documentation/UsbTrace.html
+++ b/Documentation/UsbTrace.html
@@ -1,6 +1,7 @@
NuttX USB Trace Capability
+
diff --git a/Documentation/style.css b/Documentation/style.css
new file mode 100644
index 00000000000..70ee0ed10f5
--- /dev/null
+++ b/Documentation/style.css
@@ -0,0 +1,84 @@
+body
+{
+ background: none;
+ font-family: sans-serif;
+ height: 100%;
+}
+
+a
+{
+ color: #dd2f2f;
+ text-decoration: none;
+}
+
+a:hover
+{
+ text-decoration: underline;
+}
+
+code
+{
+ font-family: "Bitstream Vera Sans Mono";
+ color: #2b4893;
+ background: #f4f4f4;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+}
+
+pre
+{
+ font-family: "Bitstream Vera Sans Mono";
+ background: #f4f4f4;
+ padding: 1em;
+}
+
+.container
+{
+ overflow-x: hidden;
+}
+
+.toc
+{
+ top: 0;
+ left: 0;
+ float: left;
+ width: 22%;
+ font-size: 80%;
+ overflow-y: scroll;
+ height: 100%;
+ position: fixed;
+}
+
+.toc tbody
+{
+ font-size: 80%;
+}
+
+.toc .toc_table
+{
+ margin-left: 1em;
+}
+
+.toc ul
+{
+ padding-left: 1.5em;
+}
+
+.toc > ul
+{
+ padding-left: 1.0em;
+}
+
+.toc h1
+{
+ padding-left: 0.5em;
+ padding-top: 0.5em;
+}
+
+.main
+{
+ padding-left: 1em;
+ padding-right: 1em;
+ width: 75%;
+ float: right;
+}
diff --git a/README.txt b/README.txt
index 57263368aac..d4e4acb15e8 100644
--- a/README.txt
+++ b/README.txt
@@ -1707,8 +1707,12 @@ nuttx/
| |
| |- arm/
| | `- src
- | | |- lpc214x/README.txt
- | | `- stm32l4/README.txt
+ | | |- common
+ | | | `- README_lwl_console.txt
+ | | |- lpc214x
+ | | | `-README.txt
+ | | `- stm32l4
+ | | `- README.txt
| |- renesas/
| | |- include/
| | | `-README.txt
@@ -1738,6 +1742,8 @@ nuttx/
| | `- README.txt
| |- avr32dev1/
| | `- README.txt
+ | |- axoloti/
+ | | `- README.txt
| |- b-l475e-iot01a/
| | `- README.txt
| |- bambino-200e/
@@ -1827,6 +1833,8 @@ nuttx/
| | `- README.txt
| |- lpcxpresso-lpc54628/
| | `- README.txt
+ | |- makerlisp/
+ | | `- README.txt
| |- maple/
| | `- README.txt
| |- max32660-evsys/
@@ -1959,6 +1967,8 @@ nuttx/
| | `- README.txt
| |- skp16c26/
| | `- README.txt
+ | |- spresense/
+ | | `- README.txt
| |- stm3210e-eval/
| | |- RIDE/README.txt
| | `- README.txt
diff --git a/ReleaseNotes b/ReleaseNotes
index 15f94603192..119f1dfd2b2 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -11321,7 +11321,7 @@ Additional new features and extended functionality:
Mateusz Szafoni.
- Nucleo-144: Added USB OTG device to Nucleo-144. From David Sidrane.
- Nucleo-144: Added bbsram test to Nucleo-144. From David Sidrane.
- - STM32F4 Disovery: add CAN support for STM32F4 Discovery. From
+ - STM32F4 Disovery: Add CAN support for STM32F4 Discovery. From
Matthias Renner.
- STM32F4 Disovery: added a canard configuration files. From
Matthias Renner.
@@ -12253,7 +12253,7 @@ detailed bugfix information):
dirlinks target only sets up the directory links but does not try
to run all of the context setup; the compiler is never invoked; no
code is autogenerated and things work.
- - CXXFLAGS: add -fcheck-new whenever -fno-exceptions is used. From
+ - CXXFLAGS: Add -fcheck-new whenever -fno-exceptions is used. From
Beat Kng.
* Tools
@@ -12798,7 +12798,7 @@ detailed bugfix information):
- ARMv7-R: Remove the redundant update on SCTLR. mpu_control() is
invoking cp15_wrsctlr() around SCTLR update redundantly. From Heesub
Shin.
- - ARMv7-R: add new Kconfig entries for d/i-cache. Unlike in ARMv7-A/M,
+ - ARMv7-R: Add new Kconfig entries for D/I-cache. Unlike in ARMv7-A/M,
Kconfig entries for data and instruction caches are currently missing
in ARMv7-R. This change adds those missing Kconfig entries. Actual
implmenetation for those functions will be added in the subsequent
@@ -13247,7 +13247,7 @@ Additional new features and extended functionality:
- Olimex STM32 P407: Add a NSH protected build configuration; Enable
procfs/ in all configurations.
- Olimex STM32 P407: Add support for on-board microSD slot.
- - STM32F429i Discovery: add support for the L3GD20 driver. From
+ - STM32F429i Discovery: Add support for the L3GD20 driver. From
raiden00.
- STM32F103 Minimum: Add support to QEncoder on STM32F103 Minimum
board. From Alan Carvalho de Assis.
@@ -14679,7 +14679,7 @@ Additional new features and extended functionality:
dynamic configuration. From Frank Benkert.
- Franks' change remained on a branch until all issues were resolved.
the current version in Master is complete and ready for use.
- - power: battery_charger: add ioctl for charging input current. From
+ - power: battery_charger: Add ioctl for charging input current. From
Juha Niskanen.
- SMPS driver: Add generic upper-half driver for SMPS. From Mateusz
Szafoni.
@@ -14695,7 +14695,7 @@ Additional new features and extended functionality:
- HC-SR04 Driver: Add support to HC-SR04 distance sensor. From Alan
Carvalho de Assis.
- COMP Driver: Add poll support. From Pekka Ervasti.
- - BQ2429X Driver: add driver for TI BQ2429X battery charger. From Juha
+ - BQ2429X Driver: Add driver for TI BQ2429X battery charger. From Juha
Niskanen.
- ADC Driver: Add poll support. From Juha Niskanen.
- BCH Driver: Add poll support. From Jussi Kivilinna.
@@ -14901,7 +14901,7 @@ Additional new features and extended functionality:
- B-L475E-IOT01A: Add support for the SPSRGF/Spirit1 radio module. Add
a configuration for testing sprit radio.
- B-L475E-IOT01A: Add configurations to support a star topology.
- - B-L475E-IOT01A: add basic support for external Macronix QuadSPI flash
+ - B-L475E-IOT01A: Add basic support for external Macronix QuadSPI flash
memory. From Simon Piriou.
- B-L475E-IOT01A: Enable UDP broadcast test in the spirit-starhub
configuration.
@@ -15024,7 +15024,7 @@ Additional new features and extended functionality:
- examples/pf_ieee802154: Add for testing PF_IEEE802154 sockets. Add
PANID to command line options; Cannot bind to address zero... There is
no counterpart to INADDR_ANY for these radios (not now at least).
- - examples/dac: add DAC example. From Juha Niskanen.
+ - examples/dac: Add DAC example. From Juha Niskanen.
* Network Utilities: apps/netutils:
@@ -16134,7 +16134,7 @@ Additional new features and extended functionality:
- apps/examples/obd2: Add OBD2 example application. From Alan
Carvalho de Assis.
- apps/examples/userfs: Add a test case for verifying UserFS.
- - apps/examples/smps: add SMPS driver example. From Mateusz Szafoni.
+ - apps/examples/smps: Add SMPS driver example. From Mateusz Szafoni.
- apps/examples/pdcurses: Bring in pdcurses demos and make them
conform to the NuttX coding style.
- apps/examples/pdcurses: Add a very simple example that just shows
@@ -19122,7 +19122,7 @@ Additional new features and extended functionality:
* Test Utilities: apps/testing:
- - testing/unity: add Unity - unit testing library from
+ - testing/unity: Add Unity - unit testing library from
ThrowTheSwitch.org. From Mateusz Szafoni.
Bugfixes. Only the most critical bugfixes are listed here (see the
@@ -22881,3 +22881,613 @@ detailed bugfix information):
- apps/tools/mksymtab.sh: 'export LC_ALL=C' to get the traditional
sort order From anchao.
+
+NuttX-7.30 Release Notes
+------------------------
+
+The 130th release of NuttX, Version 7.30, was made on May 19, 2019,
+and is available for download from the Bitbucket.org website. Note
+that release consists of two tarballs: nuttx-7.30.tar.gz and
+apps-7.30.tar.gz. These are available from:
+
+ https://bitbucket.org/nuttx/nuttx/downloads
+ https://bitbucket.org/nuttx/apps/downloads
+
+Both may be needed (see the top-level nuttx/README.txt file for build
+information).
+
+Additional new features and extended functionality:
+
+ * Core OS:
+
+ - pthreads: Added non-standard pthread_get_stackaddr_np() and
+ pthread_get_stacksize_np(). From Joao Matos.
+ - boardctl(): Add a command to start the VNC server. From Gregory
+ Nutt.
+ - Signals: Remove references to CONFIG_DISABLE_SIGNALS in many
+ files. Signals can no longer be disabled. From Gregory Nutt.
+
+ * Wireless/Wireless Drivers:
+
+ - NRF24L01: Add support for "multicast" TX mode - no waiting for ACK
+ (needs to be enabled with fcntl SETTXPAYLOADNOACK) From Leif Jakob.
+
+ * Graphics/Display Drivers:
+
+ - NX Graphics: Add new server->client callback to notify the window
+ client of server events. Remove the old 'blocked' callback and just
+ make it one case of an 'event' callback. From Gregory Nutt.
+ - NX Graphics: Implement new interfaces nx_synch() and nxtk_synch().
+ This are used to synchronize the NX server with the window client.
+ Currently most of the logic is equivalent to nx_block() and
+ nxtk_block(), but with slightly different semantics. They are
+ separate now because they are likely to diverge in the future.
+ From Gregory Nutt.
+ - NX Graphics: Add support for modal windows. From Gregory Nutt.
+ - NX Graphics: Implement a software cursor. The cursor behaves
+ like a "sprite", always at the top of the display with a
+ transparent background. Includes new NX interfaces to show/hide
+ the cursor, set the cursor image, and to move the cursor position.
+ From Gregory Nutt.
+ - NX Graphics: Added support for hiding windows. This features is
+ needed by Twm4Nx: When a window is iconified, the icon should
+ appear on the background and the window should disappear (i.e., be
+ hidden). The windows needs to remain healthy and to be updated in
+ all ways, but it cannot affect the display content. Conversely,
+ when the icon is clicked, the icon needs to be hidden on the
+ background and the window needs to be restored in its current
+ state (which may be different than the state of the window at the
+ time it was iconified. From Gregory Nutt.
+ - NX Graphics: Windows can now be created in the hidden state.
+ This can be used to clean up initial window presentation which may
+ involve several steps. This makes those steps all invisible until
+ nx[tk]_setvisibility() is called to make the windows visible.
+ From Gregory Nutt.
+ - NX Graphics: Add new NX interfaces to query if a window is hidden
+ or not. From Gregory Nutt.
+ - NxTerm IOCTLs: Replace specific interfaces between boardctl and
+ nxterm with a generalized IOCTL interface. From Gregory Nutt.
+ - NxTerm: Add a new IOCTL that can be used to inform NxTerm that
+ the size of a window has changed. From Gregory Nutt.
+
+ * Other Common Device Drivers:
+
+ - CAN Upper Half: Support multiple readers of the same port From
+ Valmantas Paliksa.
+ - MAX7456: Adds a read-only (for now) /dev/osd0/CM interface for
+ obtaining the chip's onboard NVM character map data. Use seek()
+ to position the cursor over a desired subset of bytes, or request
+ a large read to obtain the entire EEPROM memory contents. Values
+ are returned in binary form. Use hexdump, etc. to format them for
+ viewing. From Bill Gatliff.
+ - Serial Upper Half: The upper half serial driver configuration
+ CONFIG_SERIAL_DMA used to enable DMA on both RX and TX streams.
+ This was replaced with CONFIG_SERIAL_RXDMA and CONFIG_SERIAKL_TXDMA
+ which will permit supporting DMA on only one or both streams.
+ From Gregory Nutt.
+ - FUSB303: Add FUSB303 driver From Juha Niskanen.
+
+ * Microchip PIC32MZ Drivers:
+
+ - PIC32MZ GPIO: Adds support for edge detect mode. Slew Rate was
+ also added for completeness. From Abdelatif Guettouche.
+
+ * Microchip/Atmel SAMv7 Boards
+
+ - SAME70-xplained: Add a configuration for test Twm4Nx using VNC.
+ From Gregory Nutt.
+
+ * Microchip LPCxx Drivers:
+
+ - LPC17xx Ethernet: Added support for KSZ8081RNA PHY to LPC17xx
+ Ethernet driver. From jjlange.
+ - LPC17xx Ethernet: Added support for Ethernet PHY ioctl() on
+ LPC17xx. From jjlange.
+
+ * NXP i.MX RT:
+
+ - .i.MXRT1020: Gets imx1020 family support started. It is pretty
+ similar, but subtly different, to 1050/60 (less PLLs, less GPIO
+ banks, differently numbered ports etc. etc.).
+
+ Moved each of the imxrt family-specific files into its own
+ subdirectory to tidy things up a bit, and remove the vast majority
+ of ifdefs from the mainline code.
+
+ From Dave Marples.
+
+ * NXP LPC54xx Drivers
+
+ - LPC54xx USB FS Host: Bring in the USB FS OHCI driver from LPC17.
+ This is a quick'n'dirty port from LPC17 that I hope finish
+ sometime later. Currently, it is missing hardware clocking setup
+ and is not even hooked into the build system yet. From Gregory
+ Nutt.
+
+ * NXP LPC54xx Boards
+
+ - LPCXpresso-LPC54628: Add a Twm4Nx configuration. From Gregory Nutt.
+
+ * Sony CXD56xx
+
+ - CXD56xx: Add initial CXD56xx chip driver sources. From Nobuto
+ Kobayashi.
+
+ * Sony CXD56xx Spresense Board
+
+ - Spresense: Add Spresense board support. This is not the full
+ Spresense BSP from Sony, only the barebones logic to present an
+ NSH console. From Nobuto Kobayashi.
+
+ * STMicro STM32:
+
+ - STM32F7 Clocking: Add support for using the HSE in bypass mode,
+ configured by board.h From Anthony Merlino.
+ - STM32F7 Clocking: Added support for TICKLESS mode. From Valmantas
+ Paliksa.
+ - STM32H7 Backup Domain: Add backup domain control registers. From
+ Jukka Laitinen.
+ - STM32H7 Clocking: Set the STM32H7 default HSI pre-divider to 4.
+ The I2C driver currently assumes HSI clock to be 16MHz. From Jukka
+ Laitinen.
+ - STM32H7 Memorymap.: Add the STM32H7 SYSTEM_UID and DEBUGMCU_BASE
+ register definitions. From Jukka Laitinen.
+ - STM32L071x: Add support for STM32L071x. From Mateusz Szafoni.
+
+ * STMicro STM32 Drivers:
+
+ - STM32 OTGHS Host: Allow VBUS monitoring for the OTG_HS host
+ driver. From Jason Harris.
+ - STM32F0/L0 ADC: Initial ADC support for the STM32 M0 From Mateusz
+ Szafoni.
+ - STM32F0/LO I2C: Port STM32F7 I2C to STM32F0/L0, From Mateusz Szafoni.
+ - STM32F1 FLASH: As noted by Matias N, the FLASH base address used
+ was incorrect. It was using the address of the FLASH data, not
+ the address of the FLASH registers. From Gregory Nutt.
+ - STM32F3 I2C: Port STM32F7 I2C to STM32F3. From Mateusz Szafoni.
+ - STM32F7 Ethernet.c: Auto-generate Ethernet MAC address from
+ device unique ID. From Valmantas Paliksa.
+ - STM32F7 FLASH: Add flash block mapping support for progmem. From
+ Valmantas Paliksa.
+ - STM32F7 FMC: Updated stm32_fmc.h with more FMC definitions. From
+ Joao Matos.
+ - STM32F7 GPIO: Adds additional pin alternate function for SPI2.
+ From Anthony Merlino.
+ - STM32F7 PWM: Ported the PWM from F4 to F7. From Eduard Niesner.
+ - STM32F7 SDMMC: Support bypassing the input clock divider on the
+ SDMMC interface. This enables using the full clock speed provided
+ to the SDMMC interface with no dividing. From Anthony Merlino.
+ - STM32F7 SPI: Add SPI DMA threshold configuration. From Valmantas
+ Paliksa.
+ - STM32F7 UID: Add UID access. From Valmantas Paliksa.
+ - STM32F7 USB: USB High speed for STM32F7 series From Ramtin Amin.
+ - STM32H7 Ethernet: Add stm32h7 Ethernet driver. This is the
+ initial push for the Ethernet driver. The driver has been tested
+ to be working on a nucleo board. This is still WIP, it doesn't
+ for example do MAC filtering on HW level, but just receives all
+ Ethernet packets. From Jukka Laitinen.
+ - STM32H7 GPIO: Add the GPIO_ETH_RMII_RXD1 pinmap definition for
+ STM32H7. From Jukka Laitinen.
+ - STM32H7 SDMMC: Add STM32H7 SDMMC driver. It is mostly copied
+ from STM32F7, with modified register addresses and bits, and IDMA
+ dded. This is still WIP; it only works with IDMA. From Jukka
+ Laitinen.
+ - STM32H7 Timers: Add timer devices driver for STM32H7. This i
+ mostly a forklift from stm32f7 with some h7 specific
+ modifications. From Jukka Laitinen.
+ - STM32L0 AES: Add support for AES for L0. From Mateusz Szafoni.
+ - STM32L0 RND: Add support for RND. From Mateusz Szafoni.
+ - STM32L0 HSI48: Add support for HS148 for L0. Move HSI48 enable
+ from stm32_usbdev.c to stm32xx_rcc.c From Mateusz Szafoni.
+ - STM32L4 USB FS Device: Add USB FS device support. From Juha
+ Niskanen.
+ - STM32L4 HSI48: Port HSI48 from STM32F0/L0 From Juha Niskanen.
+ - STM32L4 CRS: Port CRS from STM32F0/L0 From Juha Niskanen.
+
+ * STMicro STM32 Boards:
+
+ - B-L072Z-LRWAN1: Add ADC example. From Mateusz Szafoni.
+ - B-L072Z-LRWAN1: Add nxlines_oled example (ssd1306). Add support
+ for the I2C tool From Mateusz Szafoni.
+ - Nucleo-144: Added STM32_RCC_DCKCFGR2_DSISRC definition to board.h.
+ From Joao Matos.
+ - Nucleo-144: Mount sysfs for ifconfig for f767-netnsh/defconfig.
+ Even if ifconfig is working to set IP, it will not work to display
+ NICs (without args) From Phil Coval.
+ - Nucleo-144: Add basic PWM support to nucleo-144 board. More PWMs
+ and multi channels support may be investigated and added later.
+ Tested on Nucleo-F767ZI. From Phil Coval.
+ - Nucleo-F303ZE: Add nxlines_oled example (ssd1306) From Mateusz
+ Szafoni.
+ - Nucleo-H743ZI: Enable the FPU. From Jason Harris.
+ - Nucleo-H743ZI: Add support for I2C devices: ssd1306, pca9635,
+ i2ctools From Mateusz Szafoni.
+ - Nucleo-H743ZI: Add default clock configuration for SDMMC for
+ Nucleo-H743ZI's board.h. From Jukka Laitinen.
+ - Nucleo-H743ZI: Add the input clock frequency definitions in
+ board.h for all the drivers. Assumes internal clock source for
+ all the timers. From Jukka Laitinen.
+ - STM32F4 Discovery: Keep c++ global constructor symbols From
+ Masayuki Ishikawa.
+ - Nucleo-L073RZ: Add MFRC522 support From Mateusz Szafoni.
+ - OmnibusF4: Add boardctl() reset logic. From Bill Gatliff.
+ - OmnibusF4: Add board_ioctl() which is needed only if
+ CONFIG_BOARDCTL_IOCTL=y is selected; Update NSH configuration
+ to enable board IOCTLs and DFU mode reset. From Bill Gatliff.
+ - STM32L Discovery: Add support for board_late_initialize(), Move
+ common initialization logic out of board_app_initialize() into new
+ file stm32_bringup.c From Gregory Nutt.
+ - STM32F103-Minimum: Add PROCFS automount support From Alan
+ Carvalho de Assis.
+
+ * Libraries/Header Files:
+
+ - include/alloca.h: Add alloca.h. Included limited implementation
+ of alloc() that is only available for GCC versions 3 and above.
+ From Joao Matos.
+ - include/cxx/cstdlib: Add std::random() From Gregory Nutt.
+
+ * apps/ General:
+
+ - Many locations: Remove references to CONFIG_DISABLE_SIGNALS.
+ Signals can no longer be disabled. From Gregory Nutt.
+
+ * Examples/Tests: apps/examples:
+
+ - apps/examples/fb: Add some awareness of overlays to
+ apps/examples/fb From Matthew Koch.
+ - apps/examples/lvgldemo. Update to Littlevgl 5.3. From Matthew
+ Koch.
+ - apps/examples/pwfb: Extend example to verify software cursors.
+ From Gregory Nutt.
+ - apps/examples/pwfb: Add options to reduce the number of windows.
+ This is helpful during debug to reduce the complexity. From
+ Gregory Nutt.
+
+ * Network Utilities: apps/netutils:
+
+ - apps/netutils/cjson: Support for the current version of cJSON.
+ From Mateusz Szafoni.
+ - apps/netutils/libcurl4nx: This is an initial commit libcurl4nx.
+ It is not complete yet, but I still wish to commit the unfinished
+ bits to describe the roadmap, and because it is already usable. It
+ will be updated and fixed in the future weeks and months, certainly
+ including POST support and later, SSL. From Sebastien Lorquet.
+ - apps/netutils/netinit. This commit removes the private network
+ initialization logic from NSH and puts in a common location at
+ apps/netutils/netinit. Now that netork initialization logic can be
+ used by applications that do not include NSH. From Gregory Nutt.
+ - apps/netutils/netlib: Add a more flexible version of
+ netlib_parsehttpurl(). This one can parse any URL, and is
+ extensible so future improvements keep the same API. From Sebastien
+ Lorquet.
+
+ * System Utilities: apps/system
+
+ - apps/system/spi: I needed a small test tool for spi in the style of
+ the I2C tool, but I didn't see one so I've hacked one out of the I2C
+ tool source. From Dave Marples.
+
+ * Graphics: apps/graphics:
+
+ - apps/graphics/twm4nx. This release introduces Twm4Nx. Twm4Nx is a
+ "port" of TWM, Tab Window Manager (or Tom's Window Manager) version
+ 1.0.10 to NuttX NX windows server. No, a port is not the right
+ word. It is are-design of TWM from the inside out to work with the
+ NuttX NX server and NXWidgets. The name Twm4Nx reflects this
+ legacy. But Twm4Nx is more a homage to TWM than a port of TWM.
+
+ The original TWM was based on X11 which provides a rich set of
+ features. TWM provided titlebars, shaped windows, several forms of
+ icon management, user-defined macro functions, click-to-type and
+ pointer-driven keyboard focus, graphic contexts, and user-specified
+ key and pointer button bindings, etc.
+
+ Twm4Nx, on the other hand is based on the NuttX NX server which
+ provides comparatively minimal support. Additional drawing support
+ comes from the NuttX NxWidgets library (which necessitated a
+ conversion to C++).
+
+ Twm4Nx is greatly stripped down and targeted on small embedded systems
+ with minimal resources. For example, no assumption is made about the
+ availability of a file system; no .twmrc file is used.
+
+ The state of the "port" is available in
+ apps/graphics/twm4mx/README.txt. To summarize: The port is fully
+ functional but probably only at an alpha release level. The only
+ missing critical feature is built-in touchscreen calibration.
+
+ - apps/graphics/littlevgl. Update to Littlevgl 5.3. From Matthew
+ Koch.
+ - apps/graphics/nxglyphs: Put all NxWidgets and NxWM glyphs into a
+ common directory where they can eventually be shared. Decouple
+ from nxwidgets and nxwm so that they can be used elsewhere.
+ Creates include/graphics/nxglyphs.h From Gregory Nutt.
+ - apps/graphics/nxglyphs: Add some new cursor bitmap images. From
+ Gregory Nutt.
+ - apps/graphics/nxglyphs: Add mkcursor.c. Will auto-generate
+ cursor image header file from Gimp C output. From Gregory Nutt.
+ - apps/graphics/nxglyphs: Add 16x16 cursor images. 30x30 are kind
+ of large on small displays. From Gregory Nutt.
+ - apps/graphics/nxglyphs: Add a new resize cursor image. From
+ Gregory Nutt.
+ - apps/graphics/nxwm: Separate NxWidgets and NxWM into separate
+ directories. Remove old, common NxWidgets directory. From
+ Gregory Nutt.
+ - apps/graphics/nxwm: Move the NxWM unit test main() to apps/nxwm.
+ It is no longer a unit test, but the main startup entry point for
+ NxWM. From Gregory Nutt.
+ - apps/graphics/nxwidgets: Update NX window clients so that they
+ use the new 'event' callback (vs. the obsoleted 'blocked' callback).
+ From Gregory Nutt.
+ - apps/graphics/nxwidgets: Add a synchronize method to every window.
+ This is a wrapper arounc nx[tk]_sync and permits C++ applications
+ to synchronize with the NX server. From Gregory Nutt.
+ - apps/graphics/nxwidgets: Add support for modal windows. From
+ Gregory Nutt.
+ - apps/graphics/nxwidgets: Add cursor control methods to the
+ CNxServer class. From Gregory Nutt.
+ - apps/graphics/nxwidgets: Add a method to CButtonArray that will
+ allow us to dynamically resize the array (at the cost of losing all
+ button labels). From Gregory Nutt.
+ - apps/graphics/nxwidgets: Fix a possible deadlock condition when
+ waiting for window geometry data that will never come. Fixed by
+ re-requesting geometry data if we don't already have it. From
+ Gregory Nutt.
+ - apps/graphics/nxwidgets: Add handshake to
+ CWidgetControl::getWindowHandle() to avoid returning a NULL
+ handle. From Gregory Nutt.
+ - apps/graphics/nxwidgets: CNxTkWindow, CNxWindow, CNxServer: Add
+ support to create RAM backed windows. From Gregory Nutt.
+ - apps/graphics/nxwidgets: Add methods to all windows to query if a
+ window is visible or hidden. From Gregory Nutt.
+
+Bugfixes. Only the most critical bugfixes are listed here (see the
+ChangeLog for the complete list of bugfixes and for additional, more
+detailed bugfix information):
+
+ * Core OS:
+
+ - Clock Initialization: A recent change broke Tickless mode for all
+ architectures. The original change was intended to handle the
+ case where up_timer_gettime may not start from zero case. The
+ side effect is that this changed to order of initialization of
+ clocking, breaking Tickless mode:: After this change the tickless
+ timer structures are used before they are initialized in
+ clock_inittime(). The commit has been reverted.
+ - pthread Stack Attribute: Fixed pthread_attr_get/setstacksize
+ param type to size_t. From Joao Matos.
+ - Signals: The abnormal termination signal handler was just calling
+ exit() conditionally when, for example, Ctrl-C is sent to a task.
+ The abnormal termination handler must obey the rules of cancellation
+ points: If cancelation is disabled, then the abnormal termination
+ logic must wait for cancelation to be re-enabled; If cancellation
+ is deferred then the abnormal termination logic may have to wait
+ for the victim task to enter or exit a cancellation point. From
+ Gregory Nutt.
+ - Syscall: Added support for munmap() syscall. From Joao Matos.
+ - Syscall: Fix a warning due to inconsistencies in return type in
+ syscall.csv. From Gregory Nutt.
+ - Syscall: Correct an error syscall.csv. Error occurred when
+ creating the munmap() proxy if CONFIG_FS_RAMMAP is not defined.
+ From Gregory Nutt.
+
+ * File System/Block and MTD Drivers:
+
+ - fs/littlefs/lfs.c: Fix lfs_format bug. In superblock disk root-
+ block assignment, the second must be root[1]. From YanLin Zhu.
+
+ * Networking/Network Drivers:
+
+ - getsockname(): Fix addrlen check in socket debug features.
+ Getsockname() checked erroneously a pointer agains 0, where the
+ intention was to dereference the pointer and to check the length.
+ This causes also a compilation failure if the code is compiled
+ with CONFIG_DEBUG_FEATURES and with -Werror flag set. From Jukka
+ Laitinen.
+ - Network Locking: net_lock() and net_restorelock() now return a
+ value. That values is the standard zero on success; negated errn
+ value on failure. This return value is only needed for
+ -ECANCELED. That cancellation indication needs to ripple all the
+ way back to the highest levels where the cancellation can be acted
+ on. This commit only adds the return value; it does not add
+ checking for the return values of net_lock() and net_restorelock()
+ at higher levels. That is required too. From Gregory Nutt.
+ - PHY Notification Driver: Change sprintf to strncpy in phy_notify.
+ On some platforms, the sprintf doesn't accept a const char* as a
+ format argument. From Jukka Laitinen.
+ - 6LoWPAN HC06: Correct an endian-ness problem in HC06 decompression.
+ From Ivan Ucherdzhiev.
+
+ * Wireless/Wireless Drivers:
+
+ - NRF24L01: Don't block in read if file descriptor is O_NONBLOCK.
+ From Leif Jakob.
+
+ * Graphics/Display Drivers:
+
+ - NX Graphics: Fix an error in coordinate system usage. Expected
+ rectangle in device coordinate frame, but was passing the
+ rectangle in window-relative coordinate frame. From Gregory Nutt.
+ - NX Graphics: Fix an oversight in the implementation of per-window
+ framebuffers. It is true that redraw callbacks can be suppressed
+ for all cases ... EXCEPT ONE: When the window is resized to a
+ larger size, then the newly exposed territory must be drawn for
+ the first time. From Gregory Nutt.
+ - NxTK: Fix an error in handling mouse events for framed windows.
+ When drawing, NX may report mouse positions outside of the Window.
+ The is only for NX windows, but the outside-the-side positions were
+ being discarded by nxtk_events(). From Gregory Nutt.
+ - NxTK: Refuse to open a toolbar of height zero or less. From
+ Gregory Nutt.
+ - Nxglib: Correct bogus logic in nxgl_interesting(). From Gregory
+ Nutt.
+ - VNC Server: Fix an error in color conversion. From Gregory Nutt.
+
+ * Common Drivers:
+
+ - APDS9960: Initial state of allocated structure was not being set.
+ Noted by Leif Jacob. From Gregory Nutt.
+ - MFRC522: In mfrc522_read uid.sak must be different from 0x04 not
+ as before from 0x00. SAK == 0x00 is a valid PICC type. Add
+ interface to read MIFARE Ultralight data From Mateusz Szafoni.
+ - Power: Fix build for battery gauge From Tom Kopriva.
+ - Syslog: In syslog buffered mode, avoid IOB alloc lock-up with
+ heavy network activity. This change alters the buffered syslog
+ logic to use 'iob_tryalloc' instead of blocking 'iob_alloc' to
+ avoid syslog printing from getting stuck when all IOBs are
+ depleted by network activity. An issue was seen when large
+ incoming TCP transfer uses free IOB buffers and processing
+ threads try to use syslog which then block at iob_alloc. From
+ Jussi Kivilinna.
+ - USB CDC/ACM Device: This fixes a problem where the host sent a
+ "get descriptor" message of type "standard" with a recipient of
+ type "interface". Since the composite driver would only pass
+ messages to the child interfaces when a message was not
+ "standard", this message was not handled. I changed the condition
+ so that the composite driver checks not only if this is a
+ "standard" message but if it is also directed to the device.
+ Otherwise, the handling is delegated to the children of the
+ composite device. From Matias N.
+ - USB HID: The usbhid_descriptor_s struct defined in hid.h included
+ some optional fields that should not be hard-defined as part of
+ that structure. An arbitrary number of optional entries could be
+ included in the descriptor, but that is not properly represented.
+ No code on NuttX currently depends on the structure definition
+ with an optional descriptor so it is safe to remove. From Matias N.
+ - USB MSC Device: Correct typo "const const" to "const".
+ arch/arm/src/stm32/stm32_i2s.c: In debug assertions, it on a
+ sample rate of 0, but based on other code comments this value
+ implies disabling the i2s master clock. From Jason Harris.
+ - Zerocross Driver: Fix some errors when debug assertions are
+ enabled. From Matous Pokorny.
+ - User Leds: Fix ledset validity check in ULEDIOC_SETALL ioctl.
+ From Jussi Kivilinna.
+
+ * Architecture Common:
+
+ - All board interfaces (those starting with board_) must be defined
+ in board-specific logic. Otherwise, they cannot be customized for
+ specialized usage by different boards. The board_reset()
+ interface was defined in architecture-specific logic that only
+ called up_systemreset(). That is useless! This change removes
+ the board_reset() implementation from the architecture-specific
+ code and re-implements it in the src/ directory of each board that
+ has CONFIG_BOARDCTL_RESET enabled. That is the correct functional
+ partitioning. From Gregory Nutt.
+ - Start-up: Remove dependency on CONFIG_ARCH_FPU for inclusion of
+ nvic.h in all other *_start.c files. From Gregory Nutt.
+ - Architecture initialization: up_initialize() needs to know about
+ ramlog_consoleinit() From Jason Harris.
+
+ * Microchip PIC32MZ Drivers:
+
+ - PIC32MZ GPIO: Corrects the gpioirq when mismatch mode is
+ selected. From Abdelatif Guettouche.
+
+ * ARMv7-A:
+
+ - ARMv7-A Build: Fix 'cc1: warning: switch -mcpu=cortex-a7 conflicts
+ with -march=armv7-a switch' From Xiang Xiao.
+
+ * Nordic NRFxx
+
+ - NRF52: Fix compiler error in nrf52832_errdata.c when following
+ C89. From Erik Englund.
+
+ * STMicro STM32:
+
+ - STM32 Configuration: It seems one option in the timer configuration
+ was lost at some point. From Matias N.
+ - STM32 start-up: Inclusion of nvic.h should not be conditioned on
+ CONFIG_ARCH_FPU. From Mateusz Szafoni.
+ - STM32H7 Clocking: Fixes for STM32H7 RCC definitions. From Jukka
+ Laitinen.
+
+ * STMicro STM32 Drivers:
+
+ - STM32F0/L USART: A few fixes for USART. From Mateusz Szafoni.
+ - STM32F1/F30 FLASH: RCC register access should not be offset by
+ FLASH register base. From Matias N.
+ - STM32F7 CAN: CAN fixes. From Valmantas Paliksa.
+ - STM32F7 I2C: I2C Interrupt storm fix. I2C track bad state. Now
+ we track bad state and so the SW reset only when it occurs. From
+ David Sidrane.
+ - STM32F7 OTG: Fixes some macros related to OTGFS/OTGHS preventing
+ OTGHS from working. From Anthony Merlino.
+ - STM32F7 OTG Device: Correct hard-coded FIFO size that is wrong
+ for OTG FS. From Ramtin Amin.
+ - STM32F7 QSPI: Fix QuadSPI interrupts. This commit essentially
+ replaces wrongly named configuration variable STM32F7_QSPI_INTERRUPTS
+ into CONFIG_STM32F7_QSPI_INTERRUPTS. Also fixes some getreg/
+ putreg where register addresses were used instead of register
+ offsets From Pierre-Olivier Vauboin.
+ - STM32H7 I2C: Fix I2C4 compilation for STM32H7. From Jukka
+ Laitinen.
+ - STM32H7 UART: Fix compilation for UART7, UART8 and I2C4s. From
+ Jukka Laitinen.
+ - STM32L4 USB Device: Add missing PWR USBV enable, correct two USB
+ register bits From Juha Niskanen.
+
+ * STMicro STM32 Boards:
+
+ - STM32F103-Minimum: USB reset was not working appropriately since
+ the pin connected to D+ was incorrectly defined and the pullup/down
+ logic was reversed. From Matias N.
+ - Nucleo-l476RG: Fix some errors in GPIO logic when debug assertions
+ are enabled. From Matous Pokorny.
+ - Nucleo-L476RG: Add missing files of BMP180 example for Nucleo-L476RG.
+ From Fabian Justi.
+ - STM32F103-Minimum GPIO: Fix some errors when debug assertions are
+ enabled. From Matous Pokorny.
+ - STM32L4 PWM: Fix register addr, en_bit and resetbit for pwm timers.
+ From Fabian Justi.
+ - STM32F746G-DISCO: I2C1 config on stm32f746g-disco. Typo in
+ stm32f7/stm32_i2c.c From Matthew Koch.
+
+ * C Library/Header Files:
+
+ - include/limits.h: Remove the duplicate TMP_MAX definitions. The
+ standard requires that TMP_MAX defines be in stdio.h. From
+ Xiang Xiao.
+ - include/sys/select.h: Fix compiler error when
+ CONFIG_NSOCKET_DESCRIPTORS is undefined. From Xiang Xiao.
+ - include/signal.h: Add commented out definition of the si_addr
+ field. From Joao Matos.
+ - include/unistd.h: Fixed R_OK/X_OK definitions to match POSIX.
+ From Joao Matos.
+
+ - libs/libc/locale: Improved error handling in setlocale(). From Joao
+ Matos.
+ - libs/libc: Fixed return code in uname(). From Joao Matos.
+ - libs/libc/stdio: Restore support for printing NULL string as
+ "(null)". Legacy printf supported printing "(null)" in place for
+ NULL string: printf("null: %s\n", NULL); => null: (null). This
+ commit restores this functionality for new printf library. From
+ Jussi Kivilinna.
+
+ * Examples: apps/examples:
+
+ - apps/examples/pca9635/pca9635_main.c: fix compilation error. From
+ Mateusz Szafoni.
+
+ * Graphics Utilities: apps/graphics:
+
+ - Various graphics apps (and apps/examples): If CONFIG_VNCSERVER=y,
+ don't call vnc_default_fbinitialize() directly. That is a violation
+ of the portable POSIX interface. Instead, call
+ boardctl(BOARDIOC_VNC_START);. From Gregory Nutt.
+ - apps/graphics/nxwidgets: CWidgetControl::handleLeftClick now
+ returns a value to indicate if the click was actually processed or
+ not. CWidgetControl::pollMouseEvents: Correct return value. From
+ Gregory Nutt.
+ - apps/graphics/nxwidgets/: NXWidgets::CNxWidgets: Fix some issues
+ with returned values. On setting the widget size or position, it was
+ returning false if there was no change in size or position. Many
+ places in the code were treating the false return value as an error.
+ From Gregory Nutt.
+
+ * System Utilities: apps/system:
+
+ - apps/system/nxplayer: Fix some logical errors from recent commits.
+ They broke the build of the nxplayer as a library vs. a task.
diff --git a/TODO b/TODO
index b9a845141b2..67587d1ab78 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-NuttX TODO List (Last updated March 18, 2019)
+NuttX TODO List (Last updated April 29, 2019)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This file summarizes known NuttX bugs, limitations, inconsistencies with
@@ -31,7 +31,7 @@ nuttx/:
apps/ and other Add-Ons:
- (2) Network Utilities (apps/netutils/)
+ (1) Network Utilities (apps/netutils/)
(1) NuttShell (NSH) (apps/nshlib)
(1) System libraries apps/system (apps/system)
(1) Modbus (apps/modbus)
@@ -560,7 +560,7 @@ o SMP
This would also be an essential part of a high priority,
nested interrupt implementation (unrelated).
Status: Open
- Priority: Low. There are no know issues with the current non-maskable
+ Priority: Low. There are no known issues with the current non-maskable
SGI implementation. This change would, however, lead to
simplification in the design and permit commonality with
other, non-GIC implementations.
@@ -2720,14 +2720,6 @@ o Network Utilities (apps/netutils/)
Status: Open
Priority: Medium
- Title: NETWORK MONITOR NOT GENERALLY AVAILABLE
- Description: The NSH network management logic has general applicability
- but is currently useful only because it is embedded in the NSH
- module. It should be moved to apps/system or, better,
- apps/netutils.
- Status: Open
- Priority: Low
-
o NuttShell (NSH) (apps/nshlib)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4342c2946c3..1a0e67c6881 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -317,6 +317,12 @@ config ARCH_CHIP_STM32L0
---help---
STMicro STM32L0 architectures (ARM Cortex-M0).
+config ARCH_CHIP_STM32G0
+ bool "STMicro STM32 G0"
+ select ARCH_CORTEXM0
+ ---help---
+ STMicro STM32G0 architectures (ARM Cortex-M0).
+
config ARCH_CHIP_STM32F7
bool "STMicro STM32 F7"
select ARCH_CORTEXM7
@@ -328,6 +334,8 @@ config ARCH_CHIP_STM32F7
select ARCH_HAVE_SPI_BITORDER
select ARM_HAVE_MPU_UNIFIED
select ARMV7M_HAVE_STACKCHECK
+ select ARCH_HAVE_TICKLESS
+ select ARCH_HAVE_TIMEKEEPING
---help---
STMicro STM32 architectures (ARM Cortex-M7).
@@ -400,6 +408,18 @@ config ARCH_CHIP_XMC4
---help---
Infineon XMC4xxx(ARM Cortex-M4) architectures
+config ARCH_CHIP_CXD56XX
+ bool "Sony CXD56xx"
+ select ARCH_CORTEXM4
+ select ARCH_HAVE_MPU
+ select ARM_HAVE_MPU_UNIFIED
+ select ARCH_HAVE_FPU
+ select ARCH_HAVE_HEAPCHECK
+ select ARCH_HAVE_MULTICPU
+ select ARCH_HAVE_SDIO if MMCSD
+ ---help---
+ Sony CXD56XX (ARM Cortex-M4) architectures
+
endchoice
config ARCH_ARM7TDMI
@@ -663,13 +683,14 @@ config ARCH_CHIP
default "sam34" if ARCH_CHIP_SAM34
default "samv7" if ARCH_CHIP_SAMV7
default "stm32" if ARCH_CHIP_STM32
- default "stm32f0l0" if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0
+ default "stm32f0l0g0" if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0
default "stm32f7" if ARCH_CHIP_STM32F7
default "stm32h7" if ARCH_CHIP_STM32H7
default "stm32l4" if ARCH_CHIP_STM32L4
default "str71x" if ARCH_CHIP_STR71X
default "tms570" if ARCH_CHIP_TMS570
default "xmc4" if ARCH_CHIP_XMC4
+ default "cxd56xx" if ARCH_CHIP_CXD56XX
config ARCH_HAVE_TRUSTZONE
bool
@@ -792,6 +813,19 @@ config ARM_SEMIHOSTING_HOSTFS
---help---
Mount HostFS through semihosting.
+config ARM_LWL_CONSOLE
+ bool "Lightweight Link Console Support"
+ default n
+ depends on DEV_CONSOLE && ARCH_CHIP_STM32
+ ---help---
+ Use the lightweight link console which provides console over a
+ debug channel by means of shared memory. A terminal application
+ for openocd as the debugger is available in tools/ocdconsole.py.
+
+ Currently only available for STM32 architectures, but easily
+ added to other ARM architectures be addd up_low_console.c to the
+ architecture Make.defs file.
+
if ARCH_CORTEXM0
source arch/arm/src/armv6-m/Kconfig
endif
@@ -894,8 +928,8 @@ endif
if ARCH_CHIP_STM32
source arch/arm/src/stm32/Kconfig
endif
-if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0
-source arch/arm/src/stm32f0l0/Kconfig
+if ARCH_CHIP_STM32F0 || ARCH_CHIP_STM32L0 || ARCH_CHIP_STM32G0
+source arch/arm/src/stm32f0l0g0/Kconfig
endif
if ARCH_CHIP_STM32F7
source arch/arm/src/stm32f7/Kconfig
@@ -915,5 +949,8 @@ endif
if ARCH_CHIP_XMC4
source arch/arm/src/xmc4/Kconfig
endif
+if ARCH_CHIP_CXD56XX
+source arch/arm/src/cxd56xx/Kconfig
+endif
endif # ARCH_ARM
diff --git a/arch/arm/include/arm/irq.h b/arch/arm/include/arm/irq.h
index a369ad58882..a124c74e733 100644
--- a/arch/arm/include/arm/irq.h
+++ b/arch/arm/include/arm/irq.h
@@ -138,7 +138,6 @@
#ifndef __ASSEMBLY__
struct xcptcontext
{
-#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
@@ -156,7 +155,6 @@ struct xcptcontext
uint32_t saved_pc;
uint32_t saved_cpsr;
-#endif
/* Register save area */
diff --git a/arch/arm/include/armv6-m/irq.h b/arch/arm/include/armv6-m/irq.h
index 1ac545d1ded..338f24ada97 100644
--- a/arch/arm/include/armv6-m/irq.h
+++ b/arch/arm/include/armv6-m/irq.h
@@ -164,7 +164,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
-#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
@@ -191,8 +190,6 @@ struct xcptcontext
*/
uint32_t sigreturn;
-
-# endif
#endif
#ifdef CONFIG_LIB_SYSCALL
diff --git a/arch/arm/include/armv7-a/irq.h b/arch/arm/include/armv7-a/irq.h
index 837a1acb074..f0dc452006b 100644
--- a/arch/arm/include/armv7-a/irq.h
+++ b/arch/arm/include/armv7-a/irq.h
@@ -229,7 +229,6 @@ struct xcpt_syscall_s
#ifndef __ASSEMBLY__
struct xcptcontext
{
-#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there are pending signals
* to be processed.
*/
@@ -247,14 +246,13 @@ struct xcptcontext
uint32_t saved_pc;
uint32_t saved_cpsr;
-# ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_BUILD_KERNEL
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
uint32_t sigreturn;
-# endif
#endif
/* Register save area */
@@ -302,11 +300,9 @@ struct xcptcontext
FAR uint32_t *ustkptr; /* Saved user stack pointer */
FAR uint32_t *kstack; /* Allocate base of the (aligned) kernel stack */
-#ifndef CONFIG_DISABLE_SIGNALS
FAR uint32_t *kstkptr; /* Saved kernel stack pointer */
#endif
#endif
-#endif
};
#endif
diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h
index 6b07c94622c..53698d6e98f 100644
--- a/arch/arm/include/armv7-m/irq.h
+++ b/arch/arm/include/armv7-m/irq.h
@@ -119,7 +119,6 @@ struct xcpt_syscall_s
struct xcptcontext
{
-#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there
* are pending signals to be processed.
*/
@@ -151,7 +150,6 @@ struct xcptcontext
uint32_t sigreturn;
-# endif
#endif
#ifdef CONFIG_LIB_SYSCALL
diff --git a/arch/arm/include/armv7-r/irq.h b/arch/arm/include/armv7-r/irq.h
index 3d9e739b1b6..0d80c0b7794 100644
--- a/arch/arm/include/armv7-r/irq.h
+++ b/arch/arm/include/armv7-r/irq.h
@@ -229,7 +229,6 @@ struct xcpt_syscall_s
#ifndef __ASSEMBLY__
struct xcptcontext
{
-#ifndef CONFIG_DISABLE_SIGNALS
/* The following function pointer is non-zero if there are pending signals
* to be processed.
*/
@@ -247,14 +246,12 @@ struct xcptcontext
uint32_t saved_pc;
uint32_t saved_cpsr;
-# ifdef CONFIG_BUILD_KERNEL
+#ifdef CONFIG_BUILD_KERNEL
/* This is the saved address to use when returning from a user-space
* signal handler.
*/
uint32_t sigreturn;
-
-# endif
#endif
/* Register save area */
@@ -302,11 +299,9 @@ struct xcptcontext
FAR uint32_t *ustkptr; /* Saved user stack pointer */
FAR uint32_t *kstack; /* Allocate base of the (aligned) kernel stack */
-#ifndef CONFIG_DISABLE_SIGNALS
FAR uint32_t *kstkptr; /* Saved kernel stack pointer */
#endif
#endif
-#endif
};
#endif
diff --git a/arch/arm/include/cxd56xx/chip.h b/arch/arm/include/cxd56xx/chip.h
new file mode 100644
index 00000000000..9a790817d2f
--- /dev/null
+++ b/arch/arm/include/cxd56xx/chip.h
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ * arch/arm/include/cxd56xx/chip.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H
+#define __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define CXD56M4_SYSH_PRIORITY_MIN 0xe0 /* All bits[7:5] set is minimum priority */
+#define CXD56M4_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
+#define CXD56M4_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
+#define CXD56M4_SYSH_PRIORITY_STEP 0x20 /* Steps between priorities */
+
+#define NVIC_SYSH_PRIORITY_MIN CXD56M4_SYSH_PRIORITY_MIN
+#define NVIC_SYSH_PRIORITY_DEFAULT CXD56M4_SYSH_PRIORITY_DEFAULT
+#define NVIC_SYSH_PRIORITY_MAX CXD56M4_SYSH_PRIORITY_MAX
+#define NVIC_SYSH_PRIORITY_STEP CXD56M4_SYSH_PRIORITY_STEP
+
+/* If CONFIG_ARMV7M_USEBASEPRI is selected, then interrupts will be disabled
+ * by setting the BASEPRI register to NVIC_SYSH_DISABLE_PRIORITY so that most
+ * interrupts will not have execution priority. SVCall must have execution
+ * priority in all cases.
+ *
+ * In the normal cases, interrupts are not nest-able and all interrupts run
+ * at an execution priority between NVIC_SYSH_PRIORITY_MIN and
+ * NVIC_SYSH_PRIORITY_MAX (with NVIC_SYSH_PRIORITY_MAX reserved for SVCall).
+ *
+ * If, in addition, CONFIG_ARCH_HIPRI_INTERRUPT is defined, then special
+ * high priority interrupts are supported. These are not "nested" in the
+ * normal sense of the word. These high priority interrupts can interrupt
+ * normal processing but execute outside of OS (although they can "get back
+ * into the game" via a PendSV interrupt).
+ *
+ * In the normal course of things, interrupts must occasionally be disabled
+ * using the up_irq_save() inline function to prevent contention in use of
+ * resources that may be shared between interrupt level and non-interrupt
+ * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT,
+ * do we disable all interrupts (except SVCall), or do we only disable the
+ * "normal" interrupts. Since the high priority interrupts cannot interact
+ * with the OS, you may want to permit the high priority interrupts even if
+ * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be
+ * used to select either behavior:
+ *
+ * ----------------------------+--------------+----------------------------
+ * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES
+ * ----------------------------+--------------+--------------+-------------
+ * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO
+ * ----------------------------+--------------+--------------+-------------
+ * | | | SVCall
+ * | SVCall | SVCall | HIGH
+ * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL
+ * | | MAXNORMAL |
+ * ----------------------------+--------------+--------------+-------------
+ */
+
+#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL)
+# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP)
+# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
+# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY
+# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
+#else
+# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP)
+# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX
+# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY
+# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H */
diff --git a/arch/arm/include/cxd56xx/irq.h b/arch/arm/include/cxd56xx/irq.h
new file mode 100644
index 00000000000..7b20667d800
--- /dev/null
+++ b/arch/arm/include/cxd56xx/irq.h
@@ -0,0 +1,272 @@
+/****************************************************************************
+ * arch/arm/include/cxd56xx/irq.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* This file should never be included directed but, rather,
+ * only indirectly through nuttx/irq.h
+ */
+
+#ifndef __ARCH_ARM_INCLUDE_CXD56XX_IRQ_H
+#define __ARCH_ARM_INCLUDE_CXD56XX_IRQ_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+# include
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* IRQ numbers. The IRQ number corresponds vector number and hence map
+ * directly to bits in the NVIC. This does, however, waste several words of
+ * memory in the IRQ to handle mapping tables.
+ */
+
+/* Processor Exceptions (vectors 0-15) */
+
+#define CXD56_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG) */
+ /* Vector 0: Reset stack pointer value */
+ /* Vector 1: Reset (not handler as an IRQ) */
+#define CXD56_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
+#define CXD56_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
+#define CXD56_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
+#define CXD56_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
+#define CXD56_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
+#define CXD56_IRQ_SIGNVALUE (7) /* Vector 7: Sign value */
+#define CXD56_IRQ_SVCALL (11) /* Vector 11: SVC call */
+#define CXD56_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
+ /* Vector 13: Reserved */
+#define CXD56_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
+#define CXD56_IRQ_SYSTICK (15) /* Vector 15: System tick */
+#define CXD56_IRQ_EXTINT (16) /* Vector 16: Vector number of the first external interrupt */
+
+/* Cortex-M4 External interrupts (vectors >= 16) */
+
+#define CXD56_IRQ_PMU (CXD56_IRQ_EXTINT+0) /**< PMU IRQ number */
+#define CXD56_IRQ_CRG (CXD56_IRQ_EXTINT+1) /**< CRG IRQ number */
+#define CXD56_IRQ_HVDD (CXD56_IRQ_EXTINT+2) /**< HVDD IRQ number */
+#define CXD56_IRQ_LP (CXD56_IRQ_EXTINT+3) /**< LP IRQ number */
+#define CXD56_IRQ_RTC0_A0 (CXD56_IRQ_EXTINT+4) /**< RTC0_A0 IRQ number */
+#define CXD56_IRQ_RTC0_A1 (CXD56_IRQ_EXTINT+5) /**< RTC0_A1 IRQ number */
+#define CXD56_IRQ_RTC0_A2 (CXD56_IRQ_EXTINT+6) /**< RTC0_A2 IRQ number */
+#define CXD56_IRQ_RTC1_A0 (CXD56_IRQ_EXTINT+7) /**< RTC1_A0 IRQ number */
+#define CXD56_IRQ_RTC1_A1 (CXD56_IRQ_EXTINT+8) /**< RTC1_A1 IRQ number */
+#define CXD56_IRQ_RTC1_A2 (CXD56_IRQ_EXTINT+9) /**< RTC1_A2 IRQ number */
+#define CXD56_IRQ_RTC_INT (CXD56_IRQ_EXTINT+10) /**< RTC_INT IRQ number */
+#define CXD56_IRQ_UART1 (CXD56_IRQ_EXTINT+11) /**< UART1 IRQ number */
+#define CXD56_IRQ_UART0 (CXD56_IRQ_EXTINT+12) /**< UART0 IRQ number */
+#define CXD56_IRQ_HOSTIF_0 (CXD56_IRQ_EXTINT+13) /**< HOSTIF_0 IRQ number */
+#define CXD56_IRQ_HOSTIF_1 (CXD56_IRQ_EXTINT+14) /**< HOSTIF_1 IRQ number */
+#define CXD56_IRQ_HOSTIF_2 (CXD56_IRQ_EXTINT+15) /**< HOSTIF_2 IRQ number */
+#define CXD56_IRQ_SCU_SPI (CXD56_IRQ_EXTINT+16) /**< SCU_0 SPI IRQ number */
+#define CXD56_IRQ_SCU_I2C0 (CXD56_IRQ_EXTINT+17) /**< SCU_1 I2C1 IRQ number */
+#define CXD56_IRQ_SCU_I2C1 (CXD56_IRQ_EXTINT+18) /**< SCU_2 I2C2 IRQ number */
+#define CXD56_IRQ_SCU_3 (CXD56_IRQ_EXTINT+19) /**< SCU_3 SCU IRQ number */
+#define CXD56_IRQ_EXDEVICE_0 (CXD56_IRQ_EXTINT+20) /**< EXDEVICE_0 IRQ number */
+#define CXD56_IRQ_EXDEVICE_1 (CXD56_IRQ_EXTINT+21) /**< EXDEVICE_1 IRQ number */
+#define CXD56_IRQ_EXDEVICE_2 (CXD56_IRQ_EXTINT+22) /**< EXDEVICE_2 IRQ number */
+#define CXD56_IRQ_EXDEVICE_3 (CXD56_IRQ_EXTINT+23) /**< EXDEVICE_3 IRQ number */
+#define CXD56_IRQ_EXDEVICE_4 (CXD56_IRQ_EXTINT+24) /**< EXDEVICE_4 IRQ number */
+#define CXD56_IRQ_EXDEVICE_5 (CXD56_IRQ_EXTINT+25) /**< EXDEVICE_5 IRQ number */
+#define CXD56_IRQ_EXDEVICE_6 (CXD56_IRQ_EXTINT+26) /**< EXDEVICE_6 IRQ number */
+#define CXD56_IRQ_EXDEVICE_7 (CXD56_IRQ_EXTINT+27) /**< EXDEVICE_7 IRQ number */
+#define CXD56_IRQ_EXDEVICE_8 (CXD56_IRQ_EXTINT+28) /**< EXDEVICE_8 IRQ number */
+#define CXD56_IRQ_EXDEVICE_9 (CXD56_IRQ_EXTINT+29) /**< EXDEVICE_9 IRQ number */
+#define CXD56_IRQ_EXDEVICE_10 (CXD56_IRQ_EXTINT+30) /**< EXDEVICE_10 IRQ number */
+#define CXD56_IRQ_EXDEVICE_11 (CXD56_IRQ_EXTINT+31) /**< EXDEVICE_11 IRQ number */
+#define CXD56_IRQ_DMA_A_0 (CXD56_IRQ_EXTINT+32) /**< DMA_A_0 IRQ number */
+#define CXD56_IRQ_DMA_A_1 (CXD56_IRQ_EXTINT+33) /**< DMA_A_1 IRQ number */
+#define CXD56_IRQ_DMA_A_2 (CXD56_IRQ_EXTINT+34) /**< DMA_A_2 IRQ number */
+#define CXD56_IRQ_DMA_A_3 (CXD56_IRQ_EXTINT+35) /**< DMA_A_3 IRQ number */
+#define CXD56_IRQ_DMA_A_4 (CXD56_IRQ_EXTINT+36) /**< DMA_A_4 IRQ number */
+#define CXD56_IRQ_DMA_A_5 (CXD56_IRQ_EXTINT+37) /**< DMA_A_5 IRQ number */
+#define CXD56_IRQ_DMA_A_6 (CXD56_IRQ_EXTINT+38) /**< DMA_A_6 IRQ number */
+#define CXD56_IRQ_DMA_A_7 (CXD56_IRQ_EXTINT+39) /**< DMA_A_7 IRQ number */
+#define CXD56_IRQ_DMA_A_8 (CXD56_IRQ_EXTINT+40) /**< DMA_A_8 IRQ number */
+#define CXD56_IRQ_DMA_A_9 (CXD56_IRQ_EXTINT+41) /**< DMA_A_9 IRQ number */
+#define CXD56_IRQ_DMA_A_10 (CXD56_IRQ_EXTINT+42) /**< DMA_A_10 IRQ number */
+#define CXD56_IRQ_DMA_A_11 (CXD56_IRQ_EXTINT+43) /**< DMA_A_11 IRQ number */
+#define CXD56_IRQ_DMA_A_12 (CXD56_IRQ_EXTINT+44) /**< DMA_A_12 IRQ number */
+#define CXD56_IRQ_DMA_A_13 (CXD56_IRQ_EXTINT+45) /**< DMA_A_13 IRQ number */
+#define CXD56_IRQ_DMA_A_14 (CXD56_IRQ_EXTINT+46) /**< DMA_A_14 IRQ number */
+#define CXD56_IRQ_DMA_A_15 (CXD56_IRQ_EXTINT+47) /**< DMA_A_15 IRQ number */
+#define CXD56_IRQ_DMA_A_16 (CXD56_IRQ_EXTINT+48) /**< DMA_A_16 IRQ number */
+#define CXD56_IRQ_DMA_A_17 (CXD56_IRQ_EXTINT+49) /**< DMA_A_17 IRQ number */
+#define CXD56_IRQ_DMA_A_18 (CXD56_IRQ_EXTINT+50) /**< DMA_A_18 IRQ number */
+#define CXD56_IRQ_DMA_A_19 (CXD56_IRQ_EXTINT+51) /**< DMA_A_19 IRQ number */
+#define CXD56_IRQ_DMA_A_20 (CXD56_IRQ_EXTINT+52) /**< DMA_A_20 IRQ number */
+#define CXD56_IRQ_DMA_A_21 (CXD56_IRQ_EXTINT+53) /**< DMA_A_21 IRQ number */
+#define CXD56_IRQ_DMA_A_22 (CXD56_IRQ_EXTINT+54) /**< DMA_A_22 IRQ number */
+#define CXD56_IRQ_DMA_A_23 (CXD56_IRQ_EXTINT+55) /**< DMA_A_23 IRQ number */
+#define CXD56_IRQ_DMA_A_24 (CXD56_IRQ_EXTINT+56) /**< DMA_A_24 IRQ number */
+#define CXD56_IRQ_DMA_A_25 (CXD56_IRQ_EXTINT+57) /**< DMA_A_25 IRQ number */
+#define CXD56_IRQ_DMA_A_26 (CXD56_IRQ_EXTINT+58) /**< DMA_A_26 IRQ number */
+#define CXD56_IRQ_DMA_A_27 (CXD56_IRQ_EXTINT+59) /**< DMA_A_27 IRQ number */
+#define CXD56_IRQ_DMA_A_28 (CXD56_IRQ_EXTINT+60) /**< DMA_A_28 IRQ number */
+#define CXD56_IRQ_DMA_A_29 (CXD56_IRQ_EXTINT+61) /**< DMA_A_29 IRQ number */
+#define CXD56_IRQ_DMA_A_30 (CXD56_IRQ_EXTINT+62) /**< DMA_A_30 IRQ number */
+#define CXD56_IRQ_DMA_A_31 (CXD56_IRQ_EXTINT+63) /**< DMA_A_31 IRQ number */
+#define CXD56_IRQ_DMA_B_0 (CXD56_IRQ_EXTINT+64) /**< DMA_B_0 IRQ number */
+#define CXD56_IRQ_DMA_B_1 (CXD56_IRQ_EXTINT+65) /**< DMA_B_1 IRQ number */
+#define CXD56_IRQ_DMA_C_0 (CXD56_IRQ_EXTINT+66) /**< DMA_C_0 IRQ number */
+#define CXD56_IRQ_DMA_C_1 (CXD56_IRQ_EXTINT+67) /**< DMA_C_1 IRQ number */
+#define CXD56_IRQ_DMA_D_0 (CXD56_IRQ_EXTINT+68) /**< DMA_D_0 IRQ number */
+#define CXD56_IRQ_DMA_D_1 (CXD56_IRQ_EXTINT+69) /**< DMA_D_1 IRQ number */
+#define CXD56_IRQ_SAKE_NSEC (CXD56_IRQ_EXTINT+70) /**< SAKE_NSEC IRQ number */
+#define CXD56_IRQ_SAKE_SEC (CXD56_IRQ_EXTINT+71) /**< SAKE_SEC IRQ number */
+#define CXD56_IRQ_USB_VBUS (CXD56_IRQ_EXTINT+72) /**< USB_VBUS IRQ number */
+#define CXD56_IRQ_USB_VBUSN (CXD56_IRQ_EXTINT+73) /**< USB_VBUSN IRQ number */
+#define CXD56_IRQ_SPIM (CXD56_IRQ_EXTINT+74) /**< SPI0 IRQ number */
+#define CXD56_IRQ_I2CM (CXD56_IRQ_EXTINT+75) /**< I2C0 IRQ number */
+#define CXD56_IRQ_DEBUG0 (CXD56_IRQ_EXTINT+76) /**< DEBUG0 IRQ number */
+#define CXD56_IRQ_DEBUG1 (CXD56_IRQ_EXTINT+77) /**< DEBUG1 IRQ number */
+#define CXD56_IRQ_FIFO_TO (CXD56_IRQ_EXTINT+78) /**< FIFO_TO IRQ number */
+#define CXD56_IRQ_FIFO_FROM (CXD56_IRQ_EXTINT+79) /**< FIFO_FROM IRQ number */
+#define CXD56_IRQ_SPH0 (CXD56_IRQ_EXTINT+80) /**< SPH0 IRQ number */
+#define CXD56_IRQ_SPH1 (CXD56_IRQ_EXTINT+81) /**< SPH1 IRQ number */
+#define CXD56_IRQ_SPH2 (CXD56_IRQ_EXTINT+82) /**< SPH2 IRQ number */
+#define CXD56_IRQ_SPH3 (CXD56_IRQ_EXTINT+83) /**< SPH3 IRQ number */
+#define CXD56_IRQ_SPH4 (CXD56_IRQ_EXTINT+84) /**< SPH4 IRQ number */
+#define CXD56_IRQ_SPH5 (CXD56_IRQ_EXTINT+85) /**< SPH5 IRQ number */
+#define CXD56_IRQ_SPH6 (CXD56_IRQ_EXTINT+86) /**< SPH6 IRQ number */
+#define CXD56_IRQ_SPH7 (CXD56_IRQ_EXTINT+87) /**< SPH7 IRQ number */
+#define CXD56_IRQ_SPH8 (CXD56_IRQ_EXTINT+88) /**< SPH8 IRQ number */
+#define CXD56_IRQ_SPH9 (CXD56_IRQ_EXTINT+89) /**< SPH9 IRQ number */
+#define CXD56_IRQ_SPH10 (CXD56_IRQ_EXTINT+90) /**< SPH10 IRQ number */
+#define CXD56_IRQ_SPH11 (CXD56_IRQ_EXTINT+91) /**< SPH11 IRQ number */
+#define CXD56_IRQ_SPH12 (CXD56_IRQ_EXTINT+92) /**< SPH12 IRQ number */
+#define CXD56_IRQ_SPH13 (CXD56_IRQ_EXTINT+93) /**< SPH13 IRQ number */
+#define CXD56_IRQ_SPH14 (CXD56_IRQ_EXTINT+94) /**< SPH14 IRQ number */
+#define CXD56_IRQ_SPH15 (CXD56_IRQ_EXTINT+95) /**< SPH15 IRQ number */
+#define CXD56_IRQ_SW_INT (CXD56_IRQ_EXTINT+96) /**< SW_INT IRQ number */
+#define CXD56_IRQ_TIMER0 (CXD56_IRQ_EXTINT+97) /**< TIMER0 IRQ number */
+#define CXD56_IRQ_TIMER1 (CXD56_IRQ_EXTINT+98) /**< TIMER1 IRQ number */
+#define CXD56_IRQ_TIMER2 (CXD56_IRQ_EXTINT+99) /**< TIMER2 IRQ number */
+#define CXD56_IRQ_WDT_INT (CXD56_IRQ_EXTINT+100) /**< WDT_INT IRQ number */
+#define CXD56_IRQ_WDT_RES (CXD56_IRQ_EXTINT+101) /**< WDT_RES IRQ number */
+#define CXD56_IRQ_AUDIO_0 (CXD56_IRQ_EXTINT+102) /**< AUDIO_0(MIC) IRQ number */
+#define CXD56_IRQ_AUDIO_1 (CXD56_IRQ_EXTINT+103) /**< AUDIO_1(I2S1) IRQ number */
+#define CXD56_IRQ_AUDIO_2 (CXD56_IRQ_EXTINT+104) /**< AUDIO_2(I2S2) IRQ number */
+#define CXD56_IRQ_AUDIO_3 (CXD56_IRQ_EXTINT+105) /**< AUDIO_3(CODEC) IRQ number */
+#define CXD56_IRQ_GE2D (CXD56_IRQ_EXTINT+106) /**< APP_IMG 2D Graphics Engine IRQ number */
+#define CXD56_IRQ_ROT (CXD56_IRQ_EXTINT+107) /**< APP_IMG_ROTation IRQ number */
+#define CXD56_IRQ_CISIF (CXD56_IRQ_EXTINT+108) /**< APP_IMG CISIF IRQ number */
+#define CXD56_IRQ_IMG_WSPI (CXD56_IRQ_EXTINT+109) /**< APP_IMG WSSP IRQ number */
+#define CXD56_IRQ_IDMAC (CXD56_IRQ_EXTINT+110) /**< APP_IMG DMAC IRQ number */
+#define CXD56_IRQ_APP_UART (CXD56_IRQ_EXTINT+111) /**< APP_IMG UART IRQ number */
+#define CXD56_IRQ_VSYNC (CXD56_IRQ_EXTINT+112) /**< APP_IMG VSYNC IRQ number */
+#define CXD56_IRQ_IMG_SPI (CXD56_IRQ_EXTINT+113) /**< APP_IMG SSP IRQ number */
+#define CXD56_IRQ_EMMC (CXD56_IRQ_EXTINT+114) /**< APP_PER EMMC IRQ number */
+#define CXD56_IRQ_SDIO (CXD56_IRQ_EXTINT+115) /**< APP_PER SDIO IRQ number */
+#define CXD56_IRQ_USB_INT (CXD56_IRQ_EXTINT+116) /**< APP_PER USB_INT IRQ number */
+#define CXD56_IRQ_USB_SYS (CXD56_IRQ_EXTINT+117) /**< APP_PER USB_SYS IRQ number */
+#define CXD56_IRQ_APP_DMAC0 (CXD56_IRQ_EXTINT+118) /**< APP_DMAC0 IRQ number */
+#define CXD56_IRQ_APP_DMAC1 (CXD56_IRQ_EXTINT+119) /**< APP_DMAC1 IRQ number */
+#define CXD56_IRQ_APP_SAKE_NSEC (CXD56_IRQ_EXTINT+120) /**< APP_SAKE_NSEC IRQ number */
+#define CXD56_IRQ_APP_SAKE_SEC (CXD56_IRQ_EXTINT+121) /**< APP_SAKE_SEC IRQ number */
+#define CXD56_IRQ_SKDMAC_0 (CXD56_IRQ_EXTINT+122) /**< APP_SAKE_DMAC_0 IRQ number */
+#define CXD56_IRQ_SKDMAC_1 (CXD56_IRQ_EXTINT+123) /**< APP_SAKE_DMAC_1 IRQ number */
+#define CXD56_IRQ_APP_PPB (CXD56_IRQ_EXTINT+124) /**< reserved */
+#define CXD56_IRQ_GPS_OR (CXD56_IRQ_EXTINT+125) /**< GNSS_OR IRQ number */
+#define CXD56_IRQ_SFC (CXD56_IRQ_EXTINT+126) /**< SFC IRQ number */
+#define CXD56_IRQ_PMIC (CXD56_IRQ_EXTINT+127) /**< PMIC IRQ number */
+
+#define CXD56_IRQ_NEXTINT (128)
+#define CXD56_IRQ_NIRQS (CXD56_IRQ_EXTINT+CXD56_IRQ_NEXTINT)
+
+/* Total number of IRQ numbers (This will need to be revisited if/when the
+ * Cortex-M0 is supported)
+ */
+
+#define NR_VECTORS CXD56_IRQ_NIRQS
+#define NR_IRQS CXD56_IRQ_NIRQS
+
+/* Cortex-M0 External interrupts (vectors >= 16) */
+
+#if 0
+# define CXD56M0_IRQ_NIRQS (CXD56_IRQ_EXTINT + CXD56M0_IRQ_NEXTINT)
+#endif
+
+/* Total number of IRQ numbers (This will need to be revisited if/when the
+ * Cortex-M0 is supported)
+ */
+
+#if 0
+# define NR_VECTORS CXD56M0_IRQ_NIRQS
+# define NR_IRQS CXD56M0_IRQ_NIRQS
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+typedef void (*vic_vector_t)(uint32_t *regs);
+#endif
+
+/****************************************************************************
+ * Inline functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_CXD56XX_IRQ_H */
+
diff --git a/arch/arm/include/cxd56xx/pin.h b/arch/arm/include/cxd56xx/pin.h
new file mode 100644
index 00000000000..f309745507d
--- /dev/null
+++ b/arch/arm/include/cxd56xx/pin.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+ * arch/arm/include/cxd56xx/pin.h
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_INCLUDE_CXD56XX_PIN_H
+#define __ARCH_ARM_INCLUDE_CXD56XX_PIN_H
+
+/****************************************************************************
+ * Included Files
+ ***************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Pin number Definitions */
+
+#define PIN_RTC_CLK_IN (0)
+
+/* SYS GPIO: system power domain GPIOs */
+
+#define PIN_I2C4_BCK (1)
+#define PIN_I2C4_BDT (2)
+#define PIN_PMIC_INT (3)
+#define PIN_RTC_IRQ_OUT (4)
+#define PIN_AP_CLK (5)
+#define PIN_GNSS_1PPS_OUT (6)
+#define PIN_SPI0_CS_X (17)
+#define PIN_SPI0_SCK (18)
+#define PIN_SPI0_MOSI (19)
+#define PIN_SPI0_MISO (20)
+#define PIN_SPI1_CS_X (21)
+#define PIN_SPI1_SCK (22)
+#define PIN_SPI1_IO0 (23)
+#define PIN_SPI1_IO1 (24)
+#define PIN_SPI1_IO2 (25)
+#define PIN_SPI1_IO3 (26)
+#define PIN_SPI2_CS_X (27)
+#define PIN_SPI2_SCK (28)
+#define PIN_SPI2_MOSI (29)
+#define PIN_SPI2_MISO (30)
+#define PIN_HIF_IRQ_OUT (31)
+#define PIN_HIF_GPIO0 (32)
+#define PIN_SEN_IRQ_IN (37)
+#define PIN_SPI3_CS0_X (38)
+#define PIN_SPI3_CS1_X (39)
+#define PIN_SPI3_CS2_X (40)
+#define PIN_SPI3_SCK (41)
+#define PIN_SPI3_MOSI (42)
+#define PIN_SPI3_MISO (43)
+#define PIN_I2C0_BCK (44)
+#define PIN_I2C0_BDT (45)
+#define PIN_PWM0 (46)
+#define PIN_PWM1 (47)
+#define PIN_PWM2 (48)
+#define PIN_PWM3 (49)
+
+/* APP GPIO: application power domain GPIOs */
+
+#define PIN_IS_CLK (56)
+#define PIN_IS_VSYNC (57)
+#define PIN_IS_HSYNC (58)
+#define PIN_IS_DATA0 (59)
+#define PIN_IS_DATA1 (60)
+#define PIN_IS_DATA2 (61)
+#define PIN_IS_DATA3 (62)
+#define PIN_IS_DATA4 (63)
+#define PIN_IS_DATA5 (64)
+#define PIN_IS_DATA6 (65)
+#define PIN_IS_DATA7 (66)
+#define PIN_UART2_TXD (67)
+#define PIN_UART2_RXD (68)
+#define PIN_UART2_CTS (69)
+#define PIN_UART2_RTS (70)
+#define PIN_SPI4_CS_X (71)
+#define PIN_SPI4_SCK (72)
+#define PIN_SPI4_MOSI (73)
+#define PIN_SPI4_MISO (74)
+#define PIN_EMMC_CLK (75)
+#define PIN_SPI5_SCK (PIN_EMMC_CLK)
+#define PIN_EMMC_CMD (76)
+#define PIN_SPI5_CS_X (PIN_EMMC_CMD)
+#define PIN_EMMC_DATA0 (77)
+#define PIN_SPI5_MOSI (PIN_EMMC_DATA0)
+#define PIN_EMMC_DATA1 (78)
+#define PIN_SPI5_MISO (PIN_EMMC_DATA1)
+#define PIN_EMMC_DATA2 (79)
+#define PIN_EMMC_DATA3 (80)
+#define PIN_SDIO_CLK (81)
+#define PIN_SDIO_CMD (82)
+#define PIN_SDIO_DATA0 (83)
+#define PIN_SDIO_DATA1 (84)
+#define PIN_SDIO_DATA2 (85)
+#define PIN_SDIO_DATA3 (86)
+#define PIN_SDIO_CD (87)
+#define PIN_SDIO_WP (88)
+#define PIN_SDIO_CMDDIR (89)
+#define PIN_SDIO_DIR0 (90)
+#define PIN_SDIO_DIR1_3 (91)
+#define PIN_SDIO_CLKI (92)
+#define PIN_I2S0_BCK (93)
+#define PIN_I2S0_LRCK (94)
+#define PIN_I2S0_DATA_IN (95)
+#define PIN_I2S0_DATA_OUT (96)
+#define PIN_I2S1_BCK (97)
+#define PIN_I2S1_LRCK (98)
+#define PIN_I2S1_DATA_IN (99)
+#define PIN_I2S1_DATA_OUT (100)
+#define PIN_MCLK (101)
+#define PIN_PDM_CLK (102)
+#define PIN_PDM_IN (103)
+#define PIN_PDM_OUT (104)
+#define PIN_USB_VBUSINT (105)
+
+#endif /* __ARCH_ARM_INCLUDE_CXD56XX_PIN_H */
diff --git a/arch/arm/include/cxd56xx/pm.h b/arch/arm/include/cxd56xx/pm.h
new file mode 100644
index 00000000000..50b05271023
--- /dev/null
+++ b/arch/arm/include/cxd56xx/pm.h
@@ -0,0 +1,391 @@
+/****************************************************************************
+ * arch/arm/include/cxd56xx/pm.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+/**
+ * @file pm.h
+ */
+
+#ifndef __ARCH_ARM_INCLUDE_CXD56XX_PM_H
+#define __ARCH_ARM_INCLUDE_CXD56XX_PM_H
+
+/*-----------------------------------------------------------------------------
+ * include files
+ *---------------------------------------------------------------------------*/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Boot Cause definitions */
+
+#define PM_BOOT_POR_NORMAL (0x00000000ul) /** Power On Reset like as battery attached */
+#define PM_BOOT_POR_DEADBATT (0x00000001ul) /** Battery charged from DeadBattery state */
+#define PM_BOOT_WDT_REBOOT (0x00000002ul) /** System WDT expired or Explicitly Self Reboot */
+#define PM_BOOT_WDT_RESET (0x00000004ul) /** Chip WDT expired (might be used in HV-only system) */
+#define PM_BOOT_DEEP_WKUPL (0x00000008ul) /** In DeepSleep state, Detected WKUPL signal */
+#define PM_BOOT_DEEP_WKUPS (0x00000010ul) /** In DeepSleep state, Detected WKUPS signal */
+#define PM_BOOT_DEEP_RTC (0x00000020ul) /** In DeepSleep state, RTC Alarm expired */
+#define PM_BOOT_DEEP_USB_ATTACH (0x00000040ul) /** In DeepSleep state, USB Connected */
+#define PM_BOOT_DEEP_OTHERS (0x00000080ul) /** In DeepSleep state, Reserved others cause occurred */
+#define PM_BOOT_COLD_SCU_INT (0x00000100ul) /** In ColdSleep state, Detected SCU Interrupt */
+#define PM_BOOT_COLD_RTC (0x00001e00ul) /** In ColdSleep state, RTC Alarm Interrupt */
+#define PM_BOOT_COLD_RTC_ALM0 (0x00000200ul) /** In ColdSleep state, RTC Alarm0 expired */
+#define PM_BOOT_COLD_RTC_ALM1 (0x00000400ul) /** In ColdSleep state, RTC Alarm1 expired */
+#define PM_BOOT_COLD_RTC_ALM2 (0x00000800ul) /** In ColdSleep state, RTC Alarm2 expired */
+#define PM_BOOT_COLD_RTC_ALMERR (0x00001000ul) /** In ColdSleep state, RTC Alarm Error occurred */
+#define PM_BOOT_COLD_GPIO (0x0fff0000ul) /** In ColdSleep state, Detected GPIO interrupt */
+#define PM_BOOT_COLD_SEN_INT (0x10000000ul) /** In ColdSleep state, Detected SEN_INT Interrupt */
+#define PM_BOOT_COLD_PMIC_INT (0x20000000ul) /** In ColdSleep state, Detected PMIC Interrupt */
+#define PM_BOOT_COLD_USB_DETACH (0x40000000ul) /** In ColdSleep state, USB Disconnected */
+#define PM_BOOT_COLD_USB_ATTACH (0x80000000ul) /** In ColdSleep state, USB Connected */
+
+/* SRAM power status definitions */
+
+#define PMCMD_RAM_OFF 0 /* Power off */
+#define PMCMD_RAM_RET 1 /* Retention */
+#define PMCMD_RAM_ON 3 /* Power on */
+
+/* FrequencyLock request flag definitions */
+
+#define PM_CPUFREQLOCK_FLAG_HV (0x0001) /* request HV */
+#define PM_CPUFREQLOCK_FLAG_LV (0x4000) /* request LV */
+
+/* FrequencyLock identifier tag helper macro function */
+
+#define PM_CPUFREQLOCK_TAG(prefix1, prefix2, num) \
+ (((prefix1) << 24) + ((prefix2) << 16) + (num))
+
+/* FrequencyLock initializer macro function */
+
+# define PM_CPUFREQLOCK_INIT(_tag, _flag) \
+{ \
+ .count = 0, \
+ .info = _tag, \
+ .flag = _flag, \
+}
+
+/* WakeLock identifier tag helper macro function */
+
+#define PM_CPUWAKELOCK_TAG(prefix1, prefix2, num) \
+ (((prefix1) << 24) + ((prefix2) << 16) + (num))
+
+/* WakeLock initializer macro function */
+
+#define PM_CPUWAKELOCK_INIT(_tag) \
+{ \
+ .count = 0, \
+ .info = _tag, \
+}
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/* slee mode definitions */
+
+enum pm_sleepmode_e
+{
+ PM_SLEEP_DEEP,
+ PM_SLEEP_COLD,
+};
+
+/* FreqLock structure */
+
+struct pm_cpu_freqlock_s
+{
+ struct sq_entry_s sq_entry;
+ int count;
+ uint32_t info;
+ int flag;
+};
+
+/* WakeLock structure */
+
+struct pm_cpu_wakelock_s
+{
+ struct sq_entry_s sq_entry;
+ int count;
+ uint32_t info;
+};
+
+/* Definitions for pmic notify */
+
+enum pmic_notify_e
+{
+ PMIC_NOTIFY_ALARM = 0,
+ PMIC_NOTIFY_WKUPS,
+ PMIC_NOTIFY_WKUPL,
+ PMIC_NOTIFY_LOWBATT,
+ PMIC_NOTIFY_MAX
+};
+
+/* callback function for pmic notify */
+
+typedef void (*pmic_notify_t)(void *arg);
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Name: up_pmstatdump
+ *
+ * Description:
+ * Print architecture specific power status
+ *
+ ****************************************************************************/
+
+int up_pmramctrl(int cmd, uintptr_t addr, size_t size);
+
+#ifdef CONFIG_DEBUG_PM
+/****************************************************************************
+ * Name: up_pmstatdump
+ *
+ * Description:
+ * Print architecture specific power status
+ *
+ ****************************************************************************/
+
+void up_pmstatdump(void);
+#else
+# define up_pmstatdump()
+#endif
+
+/****************************************************************************
+ * Name: up_pm_acquire_freqlock
+ *
+ * Description:
+ * Acquire the specified freqlock. If the higher freqlock is acquired, the
+ * system can clockup until it is released.
+ *
+ * Parameter:
+ * lock - the pointer of a wakelock variable
+ *
+ ****************************************************************************/
+
+void up_pm_acquire_freqlock(struct pm_cpu_freqlock_s *lock);
+
+/****************************************************************************
+ * Name: up_pm_release_freqlock
+ *
+ * Description:
+ * Release the specified freqlock. If the freqlock are released, the system
+ * can drop to the lower clock mode for power saving.
+ *
+ * Parameter:
+ * lock - the pointer of a freqlock variable
+ *
+ ****************************************************************************/
+
+void up_pm_release_freqlock(struct pm_cpu_freqlock_s *lock);
+
+/****************************************************************************
+ * Name: up_pm_get_freqlock_count
+ *
+ * Description:
+ * Get the locked count of the specified freqlock
+ *
+ * Parameter:
+ * lock - the pointer of a freqlock variable
+ *
+ * Return:
+ * the locked count of the specified freqlock
+ *
+ ****************************************************************************/
+
+int up_pm_get_freqlock_count(struct pm_cpu_freqlock_s *lock);
+
+/****************************************************************************
+ * Name: up_pm_acquire_wakelock
+ *
+ * Description:
+ * Acquire the specified wakelock. If any wakelock is acquired, CPU can't
+ * enter to the hot sleep state.
+ *
+ * Parameter:
+ * lock - the pointer of a wakelock variable
+ *
+ ****************************************************************************/
+
+void up_pm_acquire_wakelock(struct pm_cpu_wakelock_s *lock);
+
+/****************************************************************************
+ * Name: up_pm_release_wakelock
+ *
+ * Description:
+ * Release the specified wakelock. If all of the wakelock are released,
+ * CPU can enter to the hot sleep state.
+ *
+ * Parameter:
+ * lock - the pointer of a wakelock variable
+ *
+ ****************************************************************************/
+
+void up_pm_release_wakelock(struct pm_cpu_wakelock_s *lock);
+
+/****************************************************************************
+ * Name: up_pm_count_acquire_wakelock
+ *
+ * Description:
+ * Count the total number of wakelock
+ *
+ * Return:
+ * the total number of wakelock
+ *
+ ****************************************************************************/
+
+int up_pm_count_acquire_wakelock(void);
+
+/****************************************************************************
+ * Name: up_pm_get_bootcause
+ *
+ * Description:
+ * Get the system boot cause. This boot cause indicates the cause why the
+ * system is launched from the state of power-off, deep sleep or cold sleep.
+ * Each boot cause is defined as PM_BOOT_XXX.
+ *
+ * Return:
+ * Boot cause
+ *
+ ****************************************************************************/
+
+uint32_t up_pm_get_bootcause(void);
+
+/****************************************************************************
+ * Name: up_pm_get_bootmask
+ *
+ * Description:
+ * Get the system boot mask. This boot mask indicates whether the specified
+ * bit is enabled or not as the boot cause. If a bit of boot mask is set,
+ * the boot cause is enabled. Each boot mask is defined as PM_BOOT_XXX.
+ *
+ * Return:
+ * Boot mask
+ *
+ ****************************************************************************/
+
+uint32_t up_pm_get_bootmask(void);
+
+/****************************************************************************
+ * Name: up_pm_set_bootmask
+ *
+ * Description:
+ * Enable the boot cause of the specified bit.
+ *
+ * Parameter:
+ * mask - OR of Boot mask definied as PM_BOOT_XXX
+ *
+ * Return:
+ * Updated boot mask
+ *
+ ****************************************************************************/
+
+uint32_t up_pm_set_bootmask(uint32_t mask);
+
+/****************************************************************************
+ * Name: up_pm_clr_bootmask
+ *
+ * Description:
+ * Disable the boot cause of the specified bit.
+ *
+ * Parameter:
+ * mask - OR of Boot mask definied as PM_BOOT_XXX
+ *
+ * Return:
+ * Updated boot mask
+ *
+ ****************************************************************************/
+
+uint32_t up_pm_clr_bootmask(uint32_t mask);
+
+/****************************************************************************
+ * Name: up_pm_sleep
+ *
+ * Description:
+ * Enter sleep mode. This function never returns.
+ *
+ * Parameter:
+ * mode - PM_SLEEP_DEEP or PM_SLEEP_COLD
+ *
+ ****************************************************************************/
+
+int up_pm_sleep(enum pm_sleepmode_e mode);
+
+/****************************************************************************
+ * Name: up_pm_reboot
+ *
+ * Description:
+ * System reboot. This function never returns.
+ *
+ ****************************************************************************/
+
+int up_pm_reboot(void);
+
+/****************************************************************************
+ * Name: up_pmic_set_notify
+ *
+ * Description:
+ * Register a callback for pmic interrupt
+ *
+ * Input Parameter:
+ * kind - A kind of pmic interrupt defined as pmic_notify_e
+ * cb - A callback function for a kind of pmic interrupt
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_PMIC_INT
+int up_pmic_set_notify(int kind, pmic_notify_t cb);
+#else
+# define up_pmic_set_notify(kind, cb)
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_CXD56XX_PM_H */
diff --git a/arch/arm/include/cxd56xx/usbdev.h b/arch/arm/include/cxd56xx/usbdev.h
new file mode 100644
index 00000000000..f44e75487bf
--- /dev/null
+++ b/arch/arm/include/cxd56xx/usbdev.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+ * arch/arm/include/cxd56xx/usbdev.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_INCLUDE_CXD56XX_USBDEV_H
+#define __ARCH_ARM_INCLUDE_CXD56XX_USBDEV_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/* BOARDIOC_USBDEV_SETNOTIFYSIG signal value ************************************************/
+
+#define USBDEV_STATE_DETACH 0
+#define USBDEV_STATE_ATTACH 1
+
+/*
+ * The BOARDIOC_USBDEV_SETNOTIFYSIG signal output the VBUS connection state
+ * and supply current value to the signal handler argument (sival_int).
+ *
+ * Please use the following macros.
+ *
+ * - USBDEV_CONNECTED : Get VBUS connection state.
+ * - USBDEV_POWER_CURRENT : Get VBUS supply current.
+ */
+
+#define USBDEV_CONNECTED(x) (0xffff & ((x)>>16))
+#define USBDEV_POWER_CURRENT(x) (0xffff & (x))
+
+#endif /* __ARCH_ARM_INCLUDE_CXD56XX_USBDEV_H */
diff --git a/arch/arm/include/imxrt/chip.h b/arch/arm/include/imxrt/chip.h
index b2942107806..34faf216dc4 100644
--- a/arch/arm/include/imxrt/chip.h
+++ b/arch/arm/include/imxrt/chip.h
@@ -1,4 +1,4 @@
-/************************************************************************************
+/*****************************************************************************
* arch/arm/include/imxrt/chip.h
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
@@ -32,27 +32,42 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ************************************************************************************/
+ *****************************************************************************/
#ifndef __ARCH_ARM_INCLUDE_IMXRT_CHIP_H
#define __ARCH_ARM_INCLUDE_IMXRT_CHIP_H
-/************************************************************************************
+/*****************************************************************************
* Included Files
- ************************************************************************************/
+ *****************************************************************************/
#include
-/************************************************************************************
+/*****************************************************************************
* Pre-processor Definitions
- ************************************************************************************/
+ *****************************************************************************/
/* Get customizations for each supported chip */
-#if defined(CONFIG_ARCH_CHIP_MIMXRT1051DVL6A) || \
- defined(CONFIG_ARCH_CHIP_MIMXRT1051CVL5A) || \
- defined(CONFIG_ARCH_CHIP_MIMXRT1052DVL6A) || \
- defined(CONFIG_ARCH_CHIP_MIMXRT1052CVL5A)
+#if defined(CONFIG_ARCH_CHIP_MIMXRT1021CAG4A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1021CAF4A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1021DAF5A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1021DAG5A)
+
+/* MIMXRT1021CAG4A - 144 pin, 400MHz Industrial
+ * MIMXRT1021CAF4A - 100 pin, 400MHz Industrial
+ * MIMXRT1021DAF5A - 100 pin, 500MHz Consumer
+ * MIMXRT1021DAG5A - 144 pin, 500MHz Consumer
+ */
+
+# define IMXRT_OCRAM_SIZE (256 * 1024) /* 256Kb OCRAM */
+# define IMXRT_GPIO_NPORTS 5 /* Five total ports */
+ /* but 4 doesn't exist */
+
+#elif defined(CONFIG_ARCH_CHIP_MIMXRT1051DVL6A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1051CVL5A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1052DVL6A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1052CVL5A)
/* MIMXRT1051CVL5A - Industrial, Reduced Features, 528MHz
* MIMXRT1051DVL6A - Consumer, Reduced Features, 600MHz
* MIMXRT1052CVL5A - Industrial, Full Feature, 528MHz
@@ -63,9 +78,9 @@
# define IMXRT_GPIO_NPORTS 5 /* Five total ports */
#elif defined(CONFIG_ARCH_CHIP_MIMXRT1061DVL6A) || \
- defined(CONFIG_ARCH_CHIP_MIMXRT1061CVL5A) || \
- defined(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) || \
- defined(CONFIG_ARCH_CHIP_MIMXRT1062CVL5A)
+ defined(CONFIG_ARCH_CHIP_MIMXRT1061CVL5A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1062DVL6A) || \
+ defined(CONFIG_ARCH_CHIP_MIMXRT1062CVL5A)
/* MIMXRT1061CVL5A - Industrial, Reduced Features, 528MHz
* MIMXRT1061DVL6A - Consumer, Reduced Features, 600MHz
* MIMXRT1062CVL5A - Industrial, Full Feature, 528MHz
@@ -78,27 +93,28 @@
# error "Unknown i.MX RT chip type"
#endif
-/* NVIC priority levels *************************************************************/
-/* Each priority field holds an 8-bit priority value, 0-15. The lower the value, the
- * greater the priority of the corresponding interrupt. The i.MX RT processor
- * implements only bits[7:4] of each field, bits[3:0] read as zero and ignore writes.
+/* NVIC priority levels ******************************************************
+/* Each priority field holds an 8-bit priority value, 0-15. The lower the
+ * value, the greater the priority of the corresponding interrupt. The i.MX
+ * RT processor implements only bits[7:4] of each field, bits[3:0] read as
+ * zero and ignore writes.
*/
-#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits[7:4] set is minimum priority */
+#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits[7:4] set is min pri */
#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
-#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Two bits of interrupt priority used */
+#define NVIC_SYSH_PRIORITY_STEP 0x40 /* Two bits of interrupt pri used */
-/************************************************************************************
+/*****************************************************************************
* Public Types
- ************************************************************************************/
+ *****************************************************************************/
-/************************************************************************************
+/*****************************************************************************
* Public Data
- ************************************************************************************/
+ *****************************************************************************/
-/************************************************************************************
+/*****************************************************************************
* Public Functions
- ************************************************************************************/
+ *****************************************************************************/
#endif /* __ARCH_ARM_INCLUDE_IMXRT_CHIP_H */
diff --git a/arch/arm/include/imxrt/imxrt102x_irq.h b/arch/arm/include/imxrt/imxrt102x_irq.h
new file mode 100644
index 00000000000..98cf25460b6
--- /dev/null
+++ b/arch/arm/include/imxrt/imxrt102x_irq.h
@@ -0,0 +1,469 @@
+/****************************************************************************************
+ * arch/arm/include/imxrt/imxrt105x_irq.h
+ *
+ * Copyright (C) 2018 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ * Dave Marples
+ *
+ * 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.
+ *
+ ****************************************************************************************/
+
+/* This file should never be included directed but, rather, only indirectly through
+ * nuttx/irq.h
+ */
+
+#ifndef __ARCH_ARM_INCLUDE_IMXRT_IMXRT102X_IRQ_H
+#define __ARCH_ARM_INCLUDE_IMXRT_IMXRT102X_IRQ_H
+
+/****************************************************************************************
+ * Included Files
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************/
+
+/* External interrupts (priority levels >= 256) *****************************************/
+
+#define IMXRT_IRQ_EDMA0_16 (IMXRT_IRQ_EXTINT + 0) /* eDMA Channel 0/16 Transfer Complete */
+#define IMXRT_IRQ_EDMA1_17 (IMXRT_IRQ_EXTINT + 1) /* eDMA Channel 1/17 Transfer Complete */
+#define IMXRT_IRQ_EDMA2_18 (IMXRT_IRQ_EXTINT + 2) /* eDMA Channel 2/18 Transfer Complete */
+#define IMXRT_IRQ_EDMA3_19 (IMXRT_IRQ_EXTINT + 3) /* eDMA Channel 3/19 Transfer Complete */
+#define IMXRT_IRQ_EDMA4_20 (IMXRT_IRQ_EXTINT + 4) /* eDMA Channel 4/20 Transfer Complete */
+#define IMXRT_IRQ_EDMA5_21 (IMXRT_IRQ_EXTINT + 5) /* eDMA Channel 5/21 Transfer Complete */
+#define IMXRT_IRQ_EDMA6_22 (IMXRT_IRQ_EXTINT + 6) /* eDMA Channel 6/22 Transfer Complete */
+#define IMXRT_IRQ_EDMA7_23 (IMXRT_IRQ_EXTINT + 7) /* eDMA Channel 7/23 Transfer Complete */
+#define IMXRT_IRQ_EDMA8_24 (IMXRT_IRQ_EXTINT + 8) /* eDMA Channel 8/24 Transfer Complete */
+#define IMXRT_IRQ_EDMA9_25 (IMXRT_IRQ_EXTINT + 9) /* eDMA Channel 9/25 Transfer Complete */
+#define IMXRT_IRQ_EDMA10_26 (IMXRT_IRQ_EXTINT + 10) /* eDMA Channel 10/26 Transfer Complete */
+#define IMXRT_IRQ_EDMA11_27 (IMXRT_IRQ_EXTINT + 11) /* eDMA Channel 11/27 Transfer Complete */
+#define IMXRT_IRQ_EDMA12_28 (IMXRT_IRQ_EXTINT + 12) /* eDMA Channel 12/28 Transfer Complete */
+#define IMXRT_IRQ_EDMA13_29 (IMXRT_IRQ_EXTINT + 13) /* eDMA Channel 13/29 Transfer Complete */
+#define IMXRT_IRQ_EDMA14_30 (IMXRT_IRQ_EXTINT + 14) /* eDMA Channel 14/30 Transfer Complete */
+#define IMXRT_IRQ_EDMA15_31 (IMXRT_IRQ_EXTINT + 15) /* eDMA Channel 15/31 Transfer Complete */
+#define IMXRT_IRQ_EDMA_ERROR (IMXRT_IRQ_EXTINT + 16) /* Error Interrupt, Channels 0-15 / 16-31 */
+#define IMXRT_IRQ_CM70 (IMXRT_IRQ_EXTINT + 17) /* CTI trigger outputs (internal: CTIIRQ[0]) */
+#define IMXRT_IRQ_CM71 (IMXRT_IRQ_EXTINT + 18) /* CTI trigger outputs (internal: CTIIRQ[1]) */
+#define IMXRT_IRQ_CM7CP (IMXRT_IRQ_EXTINT + 19) /* CorePlatform exception IRQ */
+#define IMXRT_IRQ_LPUART1 (IMXRT_IRQ_EXTINT + 20) /* UART1 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART2 (IMXRT_IRQ_EXTINT + 21) /* UART2 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART3 (IMXRT_IRQ_EXTINT + 22) /* UART3 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART4 (IMXRT_IRQ_EXTINT + 23) /* UART4 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART5 (IMXRT_IRQ_EXTINT + 24) /* UART5 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART6 (IMXRT_IRQ_EXTINT + 25) /* UART6 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART7 (IMXRT_IRQ_EXTINT + 26) /* UART7 TX/RX interrupt */
+#define IMXRT_IRQ_LPUART8 (IMXRT_IRQ_EXTINT + 27) /* UART8 TX/RX interrupt */
+#define IMXRT_IRQ_LPI2C1 (IMXRT_IRQ_EXTINT + 28) /* I2C1 Interrupt */
+#define IMXRT_IRQ_LPI2C2 (IMXRT_IRQ_EXTINT + 29) /* I2C2 Interrupt */
+#define IMXRT_IRQ_LPI2C3 (IMXRT_IRQ_EXTINT + 30) /* I2C3 Interrupt */
+#define IMXRT_IRQ_LPI2C4 (IMXRT_IRQ_EXTINT + 31) /* I2C4 Interrupt */
+#define IMXRT_IRQ_LPSPI1 (IMXRT_IRQ_EXTINT + 32) /* LPSPI1 interrupt */
+#define IMXRT_IRQ_LPSPI2 (IMXRT_IRQ_EXTINT + 33) /* LPSPI2 interrupt */
+#define IMXRT_IRQ_LPSPI3 (IMXRT_IRQ_EXTINT + 34) /* LPSPI3 interrupt */
+#define IMXRT_IRQ_LPSPI4 (IMXRT_IRQ_EXTINT + 35) /* LPSPI4 interrupt */
+#define IMXRT_IRQ_CAN1 (IMXRT_IRQ_EXTINT + 36) /* CAN1 interrupt */
+#define IMXRT_IRQ_CAN2 (IMXRT_IRQ_EXTINT + 37) /* CAN2 interrupt */
+#define IMXRT_IRQ_CM7FR (IMXRT_IRQ_EXTINT + 38) /* FlexRAM address fault */
+#define IMXRT_IRQ_KPP (IMXRT_IRQ_EXTINT + 39) /* Keypad Interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 40) RESERVED */
+#define IMXRT_IRQ_GPRIRQ (IMXRT_IRQ_EXTINT + 41) /* Notify cores on exception while boot */
+/* RESERVED (IMXRT_IRQ_EXTINT + 42) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 43) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 44) RESERVED */
+#define IMXRT_IRQ_WDOG2 (IMXRT_IRQ_EXTINT + 45) /* Watchdog Timer reset */
+#define IMXRT_IRQ_SNVS (IMXRT_IRQ_EXTINT + 46) /* SNVS Functional Interrupt */
+#define IMXRT_IRQ_SNVSSEC (IMXRT_IRQ_EXTINT + 47) /* SNVS Security Interrupt */
+#define IMXRT_IRQ_SNVSSB (IMXRT_IRQ_EXTINT + 48) /* ON-OFF short button press */
+#define IMXRT_IRQ_CSU (IMXRT_IRQ_EXTINT + 49) /* CSU Interrupt Request 1 */
+#define IMXRT_IRQ_DCP (IMXRT_IRQ_EXTINT + 50) /* DCP channel/CRC interrupts (channel != 0) */
+#define IMXRT_IRQ_DCP0 (IMXRT_IRQ_EXTINT + 51) /* DCP channel 0 interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 52) RESERVED */
+#define IMXRT_IRQ_TRNG (IMXRT_IRQ_EXTINT + 53) /* TRNG Interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 54) RESERVED */
+#define IMXRT_IRQ_BEE (IMXRT_IRQ_EXTINT + 55) /* BEE IRQ */
+#define IMXRT_IRQ_SAI1 (IMXRT_IRQ_EXTINT + 56) /* SAI1 interrupt (RX/TX) */
+#define IMXRT_IRQ_SAI2 (IMXRT_IRQ_EXTINT + 57) /* SAI2 interrupt (RX/TX) */
+#define IMXRT_IRQ_SAI3RX (IMXRT_IRQ_EXTINT + 58) /* SAI3 RX interrupt (RX/TX) */
+#define IMXRT_IRQ_SAI3TX (IMXRT_IRQ_EXTINT + 59) /* SAI3 TX interrupt (RX/TX) */
+#define IMXRT_IRQ_SPDIF (IMXRT_IRQ_EXTINT + 60) /* SPDIF interrupt */
+#define IMXRT_IRQ_PMU (IMXRT_IRQ_EXTINT + 61) /* Brown-out event 1.1, 2.5 or 3.0 regulators */
+/* RESERVED (IMXRT_IRQ_EXTINT + 62) RESERVED */
+#define IMXRT_IRQ_TEMP (IMXRT_IRQ_EXTINT + 63) /* Temperature Monitor */
+#define IMXRT_IRQ_TEMPPANIC (IMXRT_IRQ_EXTINT + 64) /* TempSensor panic */
+#define IMXRT_IRQ_USBPHY0 (IMXRT_IRQ_EXTINT + 65) /* USBPHY (UTMI0) interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 66) RESERVED */
+#define IMXRT_IRQ_ADC1 (IMXRT_IRQ_EXTINT + 67) /* ADC1 interrupt */
+#define IMXRT_IRQ_ADC2 (IMXRT_IRQ_EXTINT + 68) /* ADC2 interrupt */
+#define IMXRT_IRQ_DCDC (IMXRT_IRQ_EXTINT + 69) /* DCDC interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 70) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 71) RESERVED */
+#define IMXRT_IRQ_GPIO1_0 (IMXRT_IRQ_EXTINT + 72) /* GPIO1 INT0 interrupt */
+#define IMXRT_IRQ_GPIO1_1 (IMXRT_IRQ_EXTINT + 73) /* GPIO1 INT1 interrupt */
+#define IMXRT_IRQ_GPIO1_2 (IMXRT_IRQ_EXTINT + 74) /* GPIO1 INT2 interrupt */
+#define IMXRT_IRQ_GPIO1_3 (IMXRT_IRQ_EXTINT + 75) /* GPIO1 INT3 interrupt */
+#define IMXRT_IRQ_GPIO1_4 (IMXRT_IRQ_EXTINT + 76) /* GPIO1 INT4 interrupt */
+#define IMXRT_IRQ_GPIO1_5 (IMXRT_IRQ_EXTINT + 77) /* GPIO1 INT5 interrupt */
+#define IMXRT_IRQ_GPIO1_6 (IMXRT_IRQ_EXTINT + 78) /* GPIO1 INT6 interrupt */
+#define IMXRT_IRQ_GPIO1_7 (IMXRT_IRQ_EXTINT + 79) /* GPIO1 INT7 interrupt */
+#define IMXRT_IRQ_GPIO1_0_15 (IMXRT_IRQ_EXTINT + 80) /* GPIO1 INT0-15 interrupt */
+#define IMXRT_IRQ_GPIO1_16_31 (IMXRT_IRQ_EXTINT + 81) /* GPIO1 INT16-31 interrupt */
+#define IMXRT_IRQ_GPIO2_0_15 (IMXRT_IRQ_EXTINT + 82) /* GPIO2 INT0-15 interrupt */
+#define IMXRT_IRQ_GPIO2_16_31 (IMXRT_IRQ_EXTINT + 83) /* GPIO2 INT16-31 interrupt */
+#define IMXRT_IRQ_GPIO3_0_15 (IMXRT_IRQ_EXTINT + 84) /* GPIO3 INT0-15 interrupt */
+#define IMXRT_IRQ_GPIO3_16_31 (IMXRT_IRQ_EXTINT + 85) /* GPIO3 INT16-31 interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 86) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 87) RESERVED */
+#define IMXRT_IRQ_GPIO5_0_15 (IMXRT_IRQ_EXTINT + 88) /* GPIO5 INT0-15 interrupt */
+#define IMXRT_IRQ_GPIO5_16_31 (IMXRT_IRQ_EXTINT + 89) /* GPIO5 INT16-31 interrupt */
+#define IMXRT_IRQ_FLEXIO1 (IMXRT_IRQ_EXTINT + 90) /* FlexIO Interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 91) RESERVED */
+#define IMXRT_IRQ_WDOG1 (IMXRT_IRQ_EXTINT + 92) /* Watchdog Timer reset */
+#define IMXRT_IRQ_RTWDOG (IMXRT_IRQ_EXTINT + 93) /* Watchdog Timer reset */
+#define IMXRT_IRQ_EWM (IMXRT_IRQ_EXTINT + 94) /* EWM interrupt */
+#define IMXRT_IRQ_CCM_1 (IMXRT_IRQ_EXTINT + 95) /* CCM interrupt 1 */
+#define IMXRT_IRQ_CCM_2 (IMXRT_IRQ_EXTINT + 96) /* CCM interrupt 2 */
+#define IMXRT_IRQ_GPC (IMXRT_IRQ_EXTINT + 97) /* GPC interrupt 1 */
+#define IMXRT_IRQ_SRC (IMXRT_IRQ_EXTINT + 98) /* SRC interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 99) RESERVED */
+#define IMXRT_IRQ_GPT1 (IMXRT_IRQ_EXTINT + 100) /* GPT1 interrupt */
+#define IMXRT_IRQ_GPT2 (IMXRT_IRQ_EXTINT + 101) /* GPT2 interrupt */
+#define IMXRT_IRQ_FLEXPWM1_0 (IMXRT_IRQ_EXTINT + 102) /* FLEXPWM1 capture/compare/reload 0 interrupt */
+#define IMXRT_IRQ_FLEXPWM1_1 (IMXRT_IRQ_EXTINT + 103) /* FLEXPWM1 capture/compare/reload 1 interrupt */
+#define IMXRT_IRQ_FLEXPWM1_2 (IMXRT_IRQ_EXTINT + 104) /* FLEXPWM1 capture/compare/reload 2 interrupt */
+#define IMXRT_IRQ_FLEXPWM1_3 (IMXRT_IRQ_EXTINT + 105) /* FLEXPWM1 capture/compare/reload 3 interrupt */
+#define IMXRT_IRQ_FLEXPWM1_F (IMXRT_IRQ_EXTINT + 106) /* FLEXPWM1 fault interrupt OR reload error */
+/* RESERVED (IMXRT_IRQ_EXTINT + 107) RESERVED */
+#define IMXRT_IRQ_FLEXSPI (IMXRT_IRQ_EXTINT + 108) /* FlexSPI interrupt */
+#define IMXRT_IRQ_SEMC (IMXRT_IRQ_EXTINT + 109) /* SEMC interrupt */
+#define IMXRT_IRQ_USDHC1 (IMXRT_IRQ_EXTINT + 110) /* USDHC1 interrupt */
+#define IMXRT_IRQ_USDHC2 (IMXRT_IRQ_EXTINT + 111) /* USDHC2 interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 112) RESERVED */
+#define IMXRT_IRQ_USBOTG1 (IMXRT_IRQ_EXTINT + 113) /* USBO2 USB OTG1 interrupt */
+#define IMXRT_IRQ_ENET (IMXRT_IRQ_EXTINT + 114) /* ENET MAC 0 interrupt */
+#define IMXRT_IRQ_ENET1588 (IMXRT_IRQ_EXTINT + 115) /* ENET MAC 0 1588 Timer Interrupt */
+#define IMXRT_IRQ_XBAR1_0_1 (IMXRT_IRQ_EXTINT + 116) /* XBAR1 interrupt 0/1 */
+#define IMXRT_IRQ_XBAR1_2_3 (IMXRT_IRQ_EXTINT + 117) /* XBAR1 interrupt 2/3 */
+#define IMXRT_IRQ_ADCETC_0 (IMXRT_IRQ_EXTINT + 118) /* ADC_ETC interrupt 0 */
+#define IMXRT_IRQ_ADCETC_1 (IMXRT_IRQ_EXTINT + 119) /* ADC_ETC interrupt 1 */
+#define IMXRT_IRQ_ADCETC_2 (IMXRT_IRQ_EXTINT + 120) /* ADC_ETC interrupt 2 */
+#define IMXRT_IRQ_ADCETC_ERR (IMXRT_IRQ_EXTINT + 121) /* ADC_ETC error interrupt */
+#define IMXRT_IRQ_PIT (IMXRT_IRQ_EXTINT + 122) /* PIT interrupt */
+#define IMXRT_IRQ_ACMP1 (IMXRT_IRQ_EXTINT + 123) /* ACMP1 interrupt */
+#define IMXRT_IRQ_ACMP2 (IMXRT_IRQ_EXTINT + 124) /* ACMP2 interrupt */
+#define IMXRT_IRQ_ACMP3 (IMXRT_IRQ_EXTINT + 125) /* ACMP3 interrupt */
+#define IMXRT_IRQ_ACMP4 (IMXRT_IRQ_EXTINT + 126) /* ACMP4 interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 127) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 128) RESERVED */
+#define IMXRT_IRQ_ENC1 (IMXRT_IRQ_EXTINT + 129) /* ENC1 interrupt */
+#define IMXRT_IRQ_ENC2 (IMXRT_IRQ_EXTINT + 130) /* ENC2 interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 131) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 132) RESERVED */
+#define IMXRT_IRQ_QTIMER1 (IMXRT_IRQ_EXTINT + 133) /* QTIMER1 timer 0-3 interrupt */
+#define IMXRT_IRQ_QTIMER2 (IMXRT_IRQ_EXTINT + 134) /* QTIMER2 timer 0-3 interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 135) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 136) RESERVED */
+#define IMXRT_IRQ_FLEXPWM2_0 (IMXRT_IRQ_EXTINT + 137) /* FLEXPWM2 capture/compare/reload 0 interrupt */
+#define IMXRT_IRQ_FLEXPWM2_1 (IMXRT_IRQ_EXTINT + 138) /* FLEXPWM2 capture/compare/reload 1 interrupt */
+#define IMXRT_IRQ_FLEXPWM2_2 (IMXRT_IRQ_EXTINT + 139) /* FLEXPWM2 capture/compare/reload 1 interrupt */
+#define IMXRT_IRQ_FLEXPWM2_3 (IMXRT_IRQ_EXTINT + 140) /* FLEXPWM2 capture/compare/reload 3 interrupt */
+#define IMXRT_IRQ_FLEXPWM2_F (IMXRT_IRQ_EXTINT + 141) /* FLEXPWM2 fault interrupt */
+/* RESERVED (IMXRT_IRQ_EXTINT + 142) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 143) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 144) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 146) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 147) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 148) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 149) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 150) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 151) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 152) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 153) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 154) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 155) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 156) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 157) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 158) RESERVED */
+/* RESERVED (IMXRT_IRQ_EXTINT + 159) RESERVED */
+
+#define IMXRT_IRQ_NEXTINT 160
+
+/* GPIO second level interrupt **********************************************************/
+
+#define IMXRT_GPIO_IRQ_FIRST (IMXRT_IRQ_EXTINT + IMXRT_IRQ_NEXTINT)
+#define _IMXRT_GPIO1_0_15_BASE IMXRT_GPIO_IRQ_FIRST
+
+#ifdef CONFIG_IMXRT_GPIO1_0_15_IRQ
+ /* GPIO1 has dedicated interrupts for pins 0-7
+ * REVISIT: I am assuming that you really cannot use the dedicated and the multiplex
+ * interrupts concurrently.
+ */
+
+# define IMXRT_IRQ_GPIO1_0 (_IMXRT_GPIO1_0_15_BASE + 0) /* GPIO1 pin 0 interrupt */
+# define IMXRT_IRQ_GPIO1_1 (_IMXRT_GPIO1_0_15_BASE + 1) /* GPIO1 pin 1 interrupt */
+# define IMXRT_IRQ_GPIO1_2 (_IMXRT_GPIO1_0_15_BASE + 2) /* GPIO1 pin 2 interrupt */
+# define IMXRT_IRQ_GPIO1_3 (_IMXRT_GPIO1_0_15_BASE + 3) /* GPIO1 pin 3 interrupt */
+# define IMXRT_IRQ_GPIO1_4 (_IMXRT_GPIO1_0_15_BASE + 4) /* GPIO1 pin 4 interrupt */
+# define IMXRT_IRQ_GPIO1_5 (_IMXRT_GPIO1_0_15_BASE + 5) /* GPIO1 pin 5 interrupt */
+# define IMXRT_IRQ_GPIO1_6 (_IMXRT_GPIO1_0_15_BASE + 6) /* GPIO1 pin 6 interrupt */
+# define IMXRT_IRQ_GPIO1_7 (_IMXRT_GPIO1_0_15_BASE + 7) /* GPIO1 pin 7 interrupt */
+# define IMXRT_IRQ_GPIO1_8 (_IMXRT_GPIO1_0_15_BASE + 8) /* GPIO1 pin 8 interrupt */
+# define IMXRT_IRQ_GPIO1_9 (_IMXRT_GPIO1_0_15_BASE + 9) /* GPIO1 pin 9 interrupt */
+# define IMXRT_IRQ_GPIO1_10 (_IMXRT_GPIO1_0_15_BASE + 10) /* GPIO1 pin 10 interrupt */
+# define IMXRT_IRQ_GPIO1_11 (_IMXRT_GPIO1_0_15_BASE + 11) /* GPIO1 pin 11 interrupt */
+# define IMXRT_IRQ_GPIO1_12 (_IMXRT_GPIO1_0_15_BASE + 12) /* GPIO1 pin 12 interrupt */
+# define IMXRT_IRQ_GPIO1_13 (_IMXRT_GPIO1_0_15_BASE + 13) /* GPIO1 pin 13 interrupt */
+# define IMXRT_IRQ_GPIO1_14 (_IMXRT_GPIO1_0_15_BASE + 14) /* GPIO1 pin 14 interrupt */
+# define IMXRT_IRQ_GPIO1_15 (_IMXRT_GPIO1_0_15_BASE + 15) /* GPIO1 pin 15 interrupt */
+
+# define _IMXRT_GPIO1_8_15_NIRQS 16
+# define _IMXRT_GPIO1_16_31_BASE (_IMXRT_GPIO1_0_15_BASE + _IMXRT_GPIO1_8_15_NIRQS)
+#else
+# define _IMXRT_GPIO1_8_15_NIRQS 0
+# define _IMXRT_GPIO1_16_31_BASE _IMXRT_GPIO1_0_15_BASE
+#endif
+
+#ifdef CONFIG_IMXRT_GPIO1_16_31_IRQ
+# define IMXRT_IRQ_GPIO1_16 (_IMXRT_GPIO1_16_31_BASE + 0) /* GPIO1 pin 16 interrupt */
+# define IMXRT_IRQ_GPIO1_17 (_IMXRT_GPIO1_16_31_BASE + 1) /* GPIO1 pin 17 interrupt */
+# define IMXRT_IRQ_GPIO1_18 (_IMXRT_GPIO1_16_31_BASE + 2) /* GPIO1 pin 18 interrupt */
+# define IMXRT_IRQ_GPIO1_19 (_IMXRT_GPIO1_16_31_BASE + 3) /* GPIO1 pin 19 interrupt */
+# define IMXRT_IRQ_GPIO1_20 (_IMXRT_GPIO1_16_31_BASE + 4) /* GPIO1 pin 10 interrupt */
+# define IMXRT_IRQ_GPIO1_21 (_IMXRT_GPIO1_16_31_BASE + 5) /* GPIO1 pin 21 interrupt */
+# define IMXRT_IRQ_GPIO1_22 (_IMXRT_GPIO1_16_31_BASE + 6) /* GPIO1 pin 22 interrupt */
+# define IMXRT_IRQ_GPIO1_23 (_IMXRT_GPIO1_16_31_BASE + 7) /* GPIO1 pin 23 interrupt */
+# define IMXRT_IRQ_GPIO1_24 (_IMXRT_GPIO1_16_31_BASE + 8) /* GPIO1 pin 24 interrupt */
+# define IMXRT_IRQ_GPIO1_25 (_IMXRT_GPIO1_16_31_BASE + 9) /* GPIO1 pin 25 interrupt */
+# define IMXRT_IRQ_GPIO1_26 (_IMXRT_GPIO1_16_31_BASE + 10) /* GPIO1 pin 26 interrupt */
+# define IMXRT_IRQ_GPIO1_27 (_IMXRT_GPIO1_16_31_BASE + 11) /* GPIO1 pin 27 interrupt */
+# define IMXRT_IRQ_GPIO1_28 (_IMXRT_GPIO1_16_31_BASE + 12) /* GPIO1 pin 28 interrupt */
+# define IMXRT_IRQ_GPIO1_29 (_IMXRT_GPIO1_16_31_BASE + 13) /* GPIO1 pin 29 interrupt */
+# define IMXRT_IRQ_GPIO1_30 (_IMXRT_GPIO1_16_31_BASE + 14) /* GPIO1 pin 30 interrupt */
+# define IMXRT_IRQ_GPIO1_31 (_IMXRT_GPIO1_16_31_BASE + 15) /* GPIO1 pin 31 interrupt */
+
+# define _IMXRT_GPIO1_16_31_NIRQS 16
+# define _IMXRT_GPIO2_0_15_BASE (_IMXRT_GPIO1_16_31_BASE + _IMXRT_GPIO1_16_31_NIRQS)
+# define IMXRT_GPIO1_NIRQS (_IMXRT_GPIO1_8_15_NIRQS + _IMXRT_GPIO1_16_31_NIRQS)
+#else
+# define _IMXRT_GPIO2_0_15_BASE _IMXRT_GPIO1_16_31_BASE
+# define IMXRT_GPIO1_NIRQS _IMXRT_GPIO1_8_15_NIRQS
+#endif
+
+#ifdef CONFIG_IMXRT_GPIO2_0_15_IRQ
+# define IMXRT_IRQ_GPIO2_0 (_IMXRT_GPIO2_0_15_BASE + 0) /* GPIO2 pin 0 interrupt */
+# define IMXRT_IRQ_GPIO2_1 (_IMXRT_GPIO2_0_15_BASE + 1) /* GPIO2 pin 1 interrupt */
+# define IMXRT_IRQ_GPIO2_2 (_IMXRT_GPIO2_0_15_BASE + 2) /* GPIO2 pin 2 interrupt */
+# define IMXRT_IRQ_GPIO2_3 (_IMXRT_GPIO2_0_15_BASE + 3) /* GPIO2 pin 3 interrupt */
+# define IMXRT_IRQ_GPIO2_4 (_IMXRT_GPIO2_0_15_BASE + 4) /* GPIO2 pin 4 interrupt */
+# define IMXRT_IRQ_GPIO2_5 (_IMXRT_GPIO2_0_15_BASE + 5) /* GPIO2 pin 5 interrupt */
+# define IMXRT_IRQ_GPIO2_6 (_IMXRT_GPIO2_0_15_BASE + 6) /* GPIO2 pin 6 interrupt */
+# define IMXRT_IRQ_GPIO2_7 (_IMXRT_GPIO2_0_15_BASE + 7) /* GPIO2 pin 7 interrupt */
+# define IMXRT_IRQ_GPIO2_8 (_IMXRT_GPIO2_0_15_BASE + 8) /* GPIO2 pin 8 interrupt */
+# define IMXRT_IRQ_GPIO2_9 (_IMXRT_GPIO2_0_15_BASE + 9) /* GPIO2 pin 9 interrupt */
+# define IMXRT_IRQ_GPIO2_10 (_IMXRT_GPIO2_0_15_BASE + 10) /* GPIO2 pin 10 interrupt */
+# define IMXRT_IRQ_GPIO2_11 (_IMXRT_GPIO2_0_15_BASE + 11) /* GPIO2 pin 11 interrupt */
+# define IMXRT_IRQ_GPIO2_12 (_IMXRT_GPIO2_0_15_BASE + 12) /* GPIO2 pin 12 interrupt */
+# define IMXRT_IRQ_GPIO2_13 (_IMXRT_GPIO2_0_15_BASE + 13) /* GPIO2 pin 13 interrupt */
+# define IMXRT_IRQ_GPIO2_14 (_IMXRT_GPIO2_0_15_BASE + 14) /* GPIO2 pin 14 interrupt */
+# define IMXRT_IRQ_GPIO2_15 (_IMXRT_GPIO2_0_15_BASE + 15) /* GPIO2 pin 15 interrupt */
+
+# define _IMXRT_GPIO2_0_15_NIRQS 16
+# define _IMXRT_GPIO2_16_31_BASE (_IMXRT_GPIO2_0_15_BASE + _IMXRT_GPIO2_0_15_NIRQS)
+#else
+# define _IMXRT_GPIO2_0_15_NIRQS 0
+# define _IMXRT_GPIO2_16_31_BASE _IMXRT_GPIO2_0_15_BASE
+#endif
+
+#ifdef CONFIG_IMXRT_GPIO2_16_31_IRQ
+# define IMXRT_IRQ_GPIO2_16 (_IMXRT_GPIO2_16_31_BASE + 0) /* GPIO2 pin 16 interrupt */
+# define IMXRT_IRQ_GPIO2_17 (_IMXRT_GPIO2_16_31_BASE + 1) /* GPIO2 pin 17 interrupt */
+# define IMXRT_IRQ_GPIO2_18 (_IMXRT_GPIO2_16_31_BASE + 2) /* GPIO2 pin 18 interrupt */
+# define IMXRT_IRQ_GPIO2_19 (_IMXRT_GPIO2_16_31_BASE + 3) /* GPIO2 pin 19 interrupt */
+# define IMXRT_IRQ_GPIO2_20 (_IMXRT_GPIO2_16_31_BASE + 4) /* GPIO2 pin 20 interrupt */
+# define IMXRT_IRQ_GPIO2_21 (_IMXRT_GPIO2_16_31_BASE + 5) /* GPIO2 pin 21 interrupt */
+# define IMXRT_IRQ_GPIO2_22 (_IMXRT_GPIO2_16_31_BASE + 6) /* GPIO2 pin 22 interrupt */
+# define IMXRT_IRQ_GPIO2_23 (_IMXRT_GPIO2_16_31_BASE + 7) /* GPIO2 pin 23 interrupt */
+# define IMXRT_IRQ_GPIO2_24 (_IMXRT_GPIO2_16_31_BASE + 8) /* GPIO2 pin 24 interrupt */
+# define IMXRT_IRQ_GPIO2_25 (_IMXRT_GPIO2_16_31_BASE + 9) /* GPIO2 pin 25 interrupt */
+# define IMXRT_IRQ_GPIO2_26 (_IMXRT_GPIO2_16_31_BASE + 10) /* GPIO2 pin 26 interrupt */
+# define IMXRT_IRQ_GPIO2_27 (_IMXRT_GPIO2_16_31_BASE + 11) /* GPIO2 pin 27 interrupt */
+# define IMXRT_IRQ_GPIO2_28 (_IMXRT_GPIO2_16_31_BASE + 12) /* GPIO2 pin 28 interrupt */
+# define IMXRT_IRQ_GPIO2_29 (_IMXRT_GPIO2_16_31_BASE + 13) /* GPIO2 pin 29 interrupt */
+# define IMXRT_IRQ_GPIO2_30 (_IMXRT_GPIO2_16_31_BASE + 14) /* GPIO2 pin 30 interrupt */
+# define IMXRT_IRQ_GPIO2_31 (_IMXRT_GPIO2_16_31_BASE + 15) /* GPIO2 pin 31 interrupt */
+
+# define _IMXRT_GPIO2_16_31_NIRQS 16
+# define _IMXRT_GPIO3_0_15_BASE (_IMXRT_GPIO2_16_31_BASE + _IMXRT_GPIO2_16_31_NIRQS)
+# define IMXRT_GPIO2_NIRQS (_IMXRT_GPIO2_0_15_NIRQS + _IMXRT_GPIO2_16_31_NIRQS)
+#else
+# define _IMXRT_GPIO3_0_15_BASE _IMXRT_GPIO2_16_31_BASE
+# define IMXRT_GPIO2_NIRQS _IMXRT_GPIO2_0_15_NIRQS
+#endif
+
+#ifdef CONFIG_IMXRT_GPIO3_0_15_IRQ
+# define IMXRT_IRQ_GPIO3_0 (_IMXRT_GPIO3_0_15_BASE + 0) /* GPIO3 pin 0 interrupt */
+# define IMXRT_IRQ_GPIO3_1 (_IMXRT_GPIO3_0_15_BASE + 1) /* GPIO3 pin 1 interrupt */
+# define IMXRT_IRQ_GPIO3_2 (_IMXRT_GPIO3_0_15_BASE + 2) /* GPIO3 pin 2 interrupt */
+# define IMXRT_IRQ_GPIO3_3 (_IMXRT_GPIO3_0_15_BASE + 3) /* GPIO3 pin 3 interrupt */
+# define IMXRT_IRQ_GPIO3_4 (_IMXRT_GPIO3_0_15_BASE + 4) /* GPIO3 pin 4 interrupt */
+# define IMXRT_IRQ_GPIO3_5 (_IMXRT_GPIO3_0_15_BASE + 5) /* GPIO3 pin 5 interrupt */
+# define IMXRT_IRQ_GPIO3_6 (_IMXRT_GPIO3_0_15_BASE + 6) /* GPIO3 pin 6 interrupt */
+# define IMXRT_IRQ_GPIO3_7 (_IMXRT_GPIO3_0_15_BASE + 7) /* GPIO3 pin 7 interrupt */
+# define IMXRT_IRQ_GPIO3_8 (_IMXRT_GPIO3_0_15_BASE + 8) /* GPIO3 pin 8 interrupt */
+# define IMXRT_IRQ_GPIO3_9 (_IMXRT_GPIO3_0_15_BASE + 9) /* GPIO3 pin 9 interrupt */
+# define IMXRT_IRQ_GPIO3_10 (_IMXRT_GPIO3_0_15_BASE + 10) /* GPIO3 pin 10 interrupt */
+# define IMXRT_IRQ_GPIO3_11 (_IMXRT_GPIO3_0_15_BASE + 11) /* GPIO3 pin 11 interrupt */
+# define IMXRT_IRQ_GPIO3_12 (_IMXRT_GPIO3_0_15_BASE + 12) /* GPIO3 pin 12 interrupt */
+# define IMXRT_IRQ_GPIO3_13 (_IMXRT_GPIO3_0_15_BASE + 13) /* GPIO3 pin 13 interrupt */
+# define IMXRT_IRQ_GPIO3_14 (_IMXRT_GPIO3_0_15_BASE + 14) /* GPIO3 pin 14 interrupt */
+# define IMXRT_IRQ_GPIO3_15 (_IMXRT_GPIO3_0_15_BASE + 15) /* GPIO3 pin 15 interrupt */
+
+# define _IMXRT_GPIO3_0_15_NIRQS 16
+# define _IMXRT_GPIO3_16_31_BASE (_IMXRT_GPIO3_0_15_BASE + _IMXRT_GPIO3_0_15_NIRQS)
+#else
+# define _IMXRT_GPIO3_0_15_NIRQS 0
+# define _IMXRT_GPIO3_16_31_BASE _IMXRT_GPIO3_0_15_BASE
+#endif
+
+#ifdef CONFIG_IMXRT_GPIO3_16_31_IRQ
+# define IMXRT_IRQ_GPIO3_16 (_IMXRT_GPIO3_16_31_BASE + 0) /* GPIO3 pin 16 interrupt */
+# define IMXRT_IRQ_GPIO3_17 (_IMXRT_GPIO3_16_31_BASE + 1) /* GPIO3 pin 17 interrupt */
+# define IMXRT_IRQ_GPIO3_18 (_IMXRT_GPIO3_16_31_BASE + 2) /* GPIO3 pin 18 interrupt */
+# define IMXRT_IRQ_GPIO3_19 (_IMXRT_GPIO3_16_31_BASE + 3) /* GPIO3 pin 19 interrupt */
+# define IMXRT_IRQ_GPIO3_20 (_IMXRT_GPIO3_16_31_BASE + 4) /* GPIO3 pin 20 interrupt */
+# define IMXRT_IRQ_GPIO3_21 (_IMXRT_GPIO3_16_31_BASE + 5) /* GPIO3 pin 21 interrupt */
+# define IMXRT_IRQ_GPIO3_22 (_IMXRT_GPIO3_16_31_BASE + 6) /* GPIO3 pin 22 interrupt */
+# define IMXRT_IRQ_GPIO3_23 (_IMXRT_GPIO3_16_31_BASE + 7) /* GPIO3 pin 23 interrupt */
+# define IMXRT_IRQ_GPIO3_24 (_IMXRT_GPIO3_16_31_BASE + 8) /* GPIO3 pin 24 interrupt */
+# define IMXRT_IRQ_GPIO3_25 (_IMXRT_GPIO3_16_31_BASE + 9) /* GPIO3 pin 25 interrupt */
+# define IMXRT_IRQ_GPIO3_26 (_IMXRT_GPIO3_16_31_BASE + 10) /* GPIO3 pin 26 interrupt */
+# define IMXRT_IRQ_GPIO3_27 (_IMXRT_GPIO3_16_31_BASE + 11) /* GPIO3 pin 27 interrupt */
+# define IMXRT_IRQ_GPIO3_28 (_IMXRT_GPIO3_16_31_BASE + 12) /* GPIO3 pin 28 interrupt */
+# define IMXRT_IRQ_GPIO3_29 (_IMXRT_GPIO3_16_31_BASE + 13) /* GPIO3 pin 29 interrupt */
+# define IMXRT_IRQ_GPIO3_30 (_IMXRT_GPIO3_16_31_BASE + 14) /* GPIO3 pin 30 interrupt */
+# define IMXRT_IRQ_GPIO3_31 (_IMXRT_GPIO3_16_31_BASE + 15) /* GPIO3 pin 31 interrupt */
+
+# define _IMXRT_GPIO3_16_31_NIRQS 16
+# define _IMXRT_GPIO5_0_15_BASE (_IMXRT_GPIO3_16_31_BASE + _IMXRT_GPIO3_16_31_NIRQS)
+# define IMXRT_GPIO3_NIRQS (_IMXRT_GPIO3_0_15_NIRQS + _IMXRT_GPIO3_16_31_NIRQS)
+#else
+# define _IMXRT_GPIO5_0_15_BASE _IMXRT_GPIO3_16_31_BASE
+# define IMXRT_GPIO3_NIRQS _IMXRT_GPIO3_0_15_NIRQS
+#endif
+
+/* There is no GPIO4 on this chip */
+
+#ifdef CONFIG_IMXRT_GPIO5_0_15_IRQ
+# define IMXRT_IRQ_GPIO5_0 (_IMXRT_GPIO5_0_15_BASE + 0) /* GPIO5 pin 0 interrupt */
+# define IMXRT_IRQ_GPIO5_1 (_IMXRT_GPIO5_0_15_BASE + 1) /* GPIO5 pin 1 interrupt */
+# define IMXRT_IRQ_GPIO5_2 (_IMXRT_GPIO5_0_15_BASE + 2) /* GPIO5 pin 2 interrupt */
+# define IMXRT_IRQ_GPIO5_3 (_IMXRT_GPIO5_0_15_BASE + 3) /* GPIO5 pin 3 interrupt */
+# define IMXRT_IRQ_GPIO5_4 (_IMXRT_GPIO5_0_15_BASE + 4) /* GPIO5 pin 4 interrupt */
+# define IMXRT_IRQ_GPIO5_5 (_IMXRT_GPIO5_0_15_BASE + 5) /* GPIO5 pin 5 interrupt */
+# define IMXRT_IRQ_GPIO5_6 (_IMXRT_GPIO5_0_15_BASE + 6) /* GPIO5 pin 6 interrupt */
+# define IMXRT_IRQ_GPIO5_7 (_IMXRT_GPIO5_0_15_BASE + 7) /* GPIO5 pin 7 interrupt */
+# define IMXRT_IRQ_GPIO5_8 (_IMXRT_GPIO5_0_15_BASE + 8) /* GPIO5 pin 8 interrupt */
+# define IMXRT_IRQ_GPIO5_9 (_IMXRT_GPIO5_0_15_BASE + 9) /* GPIO5 pin 9 interrupt */
+# define IMXRT_IRQ_GPIO5_10 (_IMXRT_GPIO5_0_15_BASE + 10) /* GPIO5 pin 10 interrupt */
+# define IMXRT_IRQ_GPIO5_11 (_IMXRT_GPIO5_0_15_BASE + 11) /* GPIO5 pin 11 interrupt */
+# define IMXRT_IRQ_GPIO5_12 (_IMXRT_GPIO5_0_15_BASE + 12) /* GPIO5 pin 12 interrupt */
+# define IMXRT_IRQ_GPIO5_13 (_IMXRT_GPIO5_0_15_BASE + 13) /* GPIO5 pin 13 interrupt */
+# define IMXRT_IRQ_GPIO5_14 (_IMXRT_GPIO5_0_15_BASE + 14) /* GPIO5 pin 14 interrupt */
+# define IMXRT_IRQ_GPIO5_15 (_IMXRT_GPIO5_0_15_BASE + 15) /* GPIO5 pin 15 interrupt */
+
+# define _IMXRT_GPIO5_0_15_NIRQS 16
+# define _IMXRT_GPIO5_16_31_BASE (_IMXRT_GPIO5_0_15_BASE + _IMXRT_GPIO5_0_15_NIRQS)
+#else
+# define _IMXRT_GPIO5_0_15_NIRQS 0
+# define _IMXRT_GPIO5_16_31_BASE _IMXRT_GPIO5_0_15_BASE
+#endif
+
+#ifdef CONFIG_IMXRT_GPIO5_16_31_IRQ
+# define IMXRT_IRQ_GPIO5_16 (_IMXRT_GPIO5_16_31_BASE + 0) /* GPIO5 pin 16 interrupt */
+# define IMXRT_IRQ_GPIO5_17 (_IMXRT_GPIO5_16_31_BASE + 1) /* GPIO5 pin 17 interrupt */
+# define IMXRT_IRQ_GPIO5_18 (_IMXRT_GPIO5_16_31_BASE + 2) /* GPIO5 pin 18 interrupt */
+# define IMXRT_IRQ_GPIO5_19 (_IMXRT_GPIO5_16_31_BASE + 3) /* GPIO5 pin 19 interrupt */
+# define IMXRT_IRQ_GPIO5_20 (_IMXRT_GPIO5_16_31_BASE + 4) /* GPIO5 pin 20 interrupt */
+# define IMXRT_IRQ_GPIO5_21 (_IMXRT_GPIO5_16_31_BASE + 5) /* GPIO5 pin 21 interrupt */
+# define IMXRT_IRQ_GPIO5_22 (_IMXRT_GPIO5_16_31_BASE + 6) /* GPIO5 pin 22 interrupt */
+# define IMXRT_IRQ_GPIO5_23 (_IMXRT_GPIO5_16_31_BASE + 7) /* GPIO5 pin 23 interrupt */
+# define IMXRT_IRQ_GPIO5_24 (_IMXRT_GPIO5_16_31_BASE + 8) /* GPIO5 pin 24 interrupt */
+# define IMXRT_IRQ_GPIO5_25 (_IMXRT_GPIO5_16_31_BASE + 9) /* GPIO5 pin 25 interrupt */
+# define IMXRT_IRQ_GPIO5_26 (_IMXRT_GPIO5_16_31_BASE + 10) /* GPIO5 pin 26 interrupt */
+# define IMXRT_IRQ_GPIO5_27 (_IMXRT_GPIO5_16_31_BASE + 11) /* GPIO5 pin 27 interrupt */
+# define IMXRT_IRQ_GPIO5_28 (_IMXRT_GPIO5_16_31_BASE + 12) /* GPIO5 pin 28 interrupt */
+# define IMXRT_IRQ_GPIO5_29 (_IMXRT_GPIO5_16_31_BASE + 13) /* GPIO5 pin 29 interrupt */
+# define IMXRT_IRQ_GPIO5_30 (_IMXRT_GPIO5_16_31_BASE + 14) /* GPIO5 pin 30 interrupt */
+# define IMXRT_IRQ_GPIO5_31 (_IMXRT_GPIO5_16_31_BASE + 15) /* GPIO5 pin 31 interrupt */
+
+# define _IMXRT_GPIO5_16_31_NIRQS 16
+# define IMXRT_GPIO5_NIRQS (_IMXRT_GPIO5_0_15_NIRQS + _IMXRT_GPIO5_16_31_NIRQS)
+#else
+# define IMXRT_GPIO5_NIRQS _IMXRT_GPIO5_0_15_NIRQS
+#endif
+
+#define IMXRT_GPIO_NIRQS (IMXRT_GPIO1_NIRQS + IMXRT_GPIO2_NIRQS + \
+ IMXRT_GPIO3_NIRQS + IMXRT_GPIO5_NIRQS)
+#define IMXRT_GPIO_IRQ_LAST (_IMXRT_GPIO1_0_15_BASE + IMXRT_GPIO_NIRQS)
+
+/* Total number of IRQ numbers **********************************************************/
+
+#define NR_IRQS (IMXRT_IRQ_EXTINT + IMXRT_IRQ_NEXTINT + IMXRT_GPIO_NIRQS)
+
+/****************************************************************************************
+ * Public Types
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Inline functions
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Data
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_IMXRT_IMXRT102X_IRQ_H */
diff --git a/arch/arm/include/imxrt/irq.h b/arch/arm/include/imxrt/irq.h
index 72bca14fabe..0773511b2f5 100644
--- a/arch/arm/include/imxrt/irq.h
+++ b/arch/arm/include/imxrt/irq.h
@@ -1,4 +1,4 @@
-/****************************************************************************************
+/****************************************************************************
* arch/arm/include/imxrt/irq.h
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
@@ -32,53 +32,61 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
- ****************************************************************************************/
+ ****************************************************************************/
-/* This file should never be included directed but, rather, only indirectly through
- * nuttx/irq.h
+/* This file should never be included directed but, rather, only indirectly
+ * through nuttx/irq.h
*/
#ifndef __ARCH_ARM_INCLUDE_IMXRT_IRQ_H
#define __ARCH_ARM_INCLUDE_IMXRT_IRQ_H
-/****************************************************************************************
+/*****************************************************************************
* Included Files
- ****************************************************************************************/
+ *****************************************************************************/
#include
#include
-/****************************************************************************************
+/*****************************************************************************
* Pre-processor Definitions
- ****************************************************************************************/
+ *****************************************************************************/
-/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to
- * bits in the NVIC. This does, however, waste several words of memory in the IRQ
- * to handle mapping tables.
+/* IRQ numbers. The IRQ number corresponds vector number and hence map
+ * directly to bits in the NVIC. This does, however, waste several words
+ * of memory in the IRQ to handle mapping tables.
*/
/* Common Processor Exceptions (vectors 0-15) */
-#define IMXRT_IRQ_RESERVED (0) /* Reserved vector (only used with CONFIG_DEBUG_FEATURES) */
+#define IMXRT_IRQ_RESERVED (0) /* Reserved vector .. only used with
+ CONFIG_DEBUG_FEATURES */
+
/* Vector 0: Reset stack pointer value */
- /* Vector 1: Reset (not handler as an IRQ) */
-#define IMXRT_IRQ_NMI (2) /* Vector 2: Non-Maskable Interrupt (NMI) */
+
+ /* Vector 1: Reset (not handled by IRQ) */
+
+#define IMXRT_IRQ_NMI (2) /* Vector 2: Non-Maskable Int (NMI) */
#define IMXRT_IRQ_HARDFAULT (3) /* Vector 3: Hard fault */
#define IMXRT_IRQ_MEMFAULT (4) /* Vector 4: Memory management (MPU) */
#define IMXRT_IRQ_BUSFAULT (5) /* Vector 5: Bus fault */
#define IMXRT_IRQ_USAGEFAULT (6) /* Vector 6: Usage fault */
/* Vectors 7-10: Reserved */
+
#define IMXRT_IRQ_SVCALL (11) /* Vector 11: SVC call */
#define IMXRT_IRQ_DBGMONITOR (12) /* Vector 12: Debug Monitor */
/* Vector 13: Reserved */
-#define IMXRT_IRQ_PENDSV (14) /* Vector 14: Pendable system service request */
+
+#define IMXRT_IRQ_PENDSV (14) /* Vector 14: Pendable SSR */
#define IMXRT_IRQ_SYSTICK (15) /* Vector 15: System tick */
/* Chip-Specific External interrupts */
-#define IMXRT_IRQ_EXTINT (16) /* Vector number of the first external interrupt */
+#define IMXRT_IRQ_EXTINT (16) /* Vector number of the first ext int */
-#if defined(CONFIG_ARCH_FAMILY_IMXRT105x)
+#if defined(CONFIG_ARCH_FAMILY_IMXRT102x)
+# include
+#elif defined(CONFIG_ARCH_FAMILY_IMXRT105x)
# include
#elif defined(CONFIG_ARCH_FAMILY_IMXRT106x)
# include
@@ -86,15 +94,15 @@
# error Unrecognized i.MX RT architecture
#endif
-/****************************************************************************************
+/****************************************************************************
* Public Types
- ****************************************************************************************/
+ ****************************************************************************/
#ifndef __ASSEMBLY__
-/****************************************************************************************
+/****************************************************************************
* Public Data
- ****************************************************************************************/
+ ****************************************************************************/
#ifdef __cplusplus
#define EXTERN extern "C"
@@ -104,9 +112,9 @@ extern "C"
#define EXTERN extern
#endif
-/****************************************************************************************
+/****************************************************************************
* Public Function Prototypes
- ****************************************************************************************/
+ ****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
diff --git a/arch/arm/include/stm32f0l0/chip.h b/arch/arm/include/stm32f0l0g0/chip.h
similarity index 71%
rename from arch/arm/include/stm32f0l0/chip.h
rename to arch/arm/include/stm32f0l0g0/chip.h
index f5d6c3b6c38..b05fc7eb281 100644
--- a/arch/arm/include/stm32f0l0/chip.h
+++ b/arch/arm/include/stm32f0l0g0/chip.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/include/stm32f0l0/chip.h
+ * arch/arm/include/stm32f0l0g0/chip.h
*
* Copyright (C) 2017-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -34,8 +34,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_INCLUDE_STM32F0L0_CHIP_H
-#define __ARCH_ARM_INCLUDE_STM32F0L0_CHIP_H
+#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_CHIP_H
+#define __ARCH_ARM_INCLUDE_STM32F0L0G0_CHIP_H
/************************************************************************************
* Included Files
@@ -57,12 +57,13 @@
# define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */
# define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */
# define STM32_NI2C 2 /* Two I2C modules */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
# define STM32_NUSART 2 /* Two USARTs modules */
# define STM32_NCAN 0 /* No CAN controllers */
# define STM32_NUSBDEV 1 /* One USB full-speed device controller */
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */
-# define STM32_NDAC 1 /* One DAC module */
-# define STM32_NDACCHAN 1 /* One DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 1 /* One DAC channel */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCAP 13 /* Capacitive sensing channels (14 on UFQFPN32)) */
# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-F */
@@ -83,16 +84,14 @@
# define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */
# define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */
# define STM32_NI2C 2 /* Two I2C modules */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
# define STM32_NUSART 4 /* Four USARTs module */
# define STM32_NCAN 1 /* One CAN controller */
# define STM32_NUSBDEV 1 /* One USB full-speed device controller */
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 1 /* One HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit module */
-# define STM32_NADCCHAN 10 /* Ten external channels */
-# define STM32_NADCINT 3 /* Three internal channels */
-# define STM32_NDAC 1 /* One DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channel */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCAP 17 /* Capacitive sensing channels */
# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-F */
@@ -113,16 +112,14 @@
# define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */
# define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */
# define STM32_NI2C 2 /* Two I2C modules */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
# define STM32_NUSART 4 /* Four USARTs module */
# define STM32_NCAN 1 /* One CAN controller */
# define STM32_NUSBDEV 1 /* One USB full-speed device controller */
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 1 /* One HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit module */
-# define STM32_NADCCHAN 16 /* 16 external channels */
-# define STM32_NADCINT 3 /* Three internal channels */
-# define STM32_NDAC 1 /* One DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channel */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCAP 18 /* Capacitive sensing channels */
# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-F */
@@ -143,16 +140,14 @@
# define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */
# define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */
# define STM32_NI2C 2 /* Two I2C modules */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
# define STM32_NUSART 4 /* Four USARTs module */
# define STM32_NCAN 1 /* One CAN controller */
# define STM32_NUSBDEV 1 /* One USB full-speed device controller */
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 1 /* One HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit module */
-# define STM32_NADCCHAN 16 /* 16 external channels */
-# define STM32_NADCINT 3 /* Three internal channels */
-# define STM32_NDAC 1 /* One DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channel */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCAP 24 /* Capacitive sensing channels */
# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-F */
@@ -173,16 +168,14 @@
# define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */
# define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */
# define STM32_NI2C 2 /* Two I2C modules */
+# define STM32_NDMA 2 /* DMA1, DMA2 */
# define STM32_NUSART 6 /* Six USARTs modules */
# define STM32_NCAN 1 /* One CAN controller */
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 1 /* One HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit module */
-# define STM32_NADCCHAN 10 /* 10 external channels */
-# define STM32_NADCINT 3 /* Three internal channels */
-# define STM32_NDAC 1 /* One DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channel */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCAP 17 /* Capacitive sensing channels */
# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-F */
@@ -204,16 +197,14 @@
# define STM32_NSPI 2 /* Two SPI modules (SPI or I2S) */
# define STM32_NI2S 2 /* Two I2S modules (SPI or I2S) */
# define STM32_NI2C 2 /* Two I2C modules */
+# define STM32_NDMA 2 /* DMA1, DMA2 */
# define STM32_NUSART 8 /* Eight USARTs modules */
# define STM32_NCAN 1 /* One CAN controller */
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 0 /* No USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 1 /* One HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit module */
-# define STM32_NADCCHAN 16 /* 16 external channels */
-# define STM32_NADCINT 3 /* Three internal channels */
-# define STM32_NDAC 1 /* One DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channel */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# if defined(CONFIG_ARCH_CHIP_STM32F091VB) || defined(CONFIG_ARCH_CHIP_STM32F091VC)
# define STM32_NCAP 24 /* Capacitive sensing channels */
@@ -222,10 +213,44 @@
# endif
# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-F */
+#elif defined(CONFIG_ARCH_CHIP_STM32G071EB) || defined(CONFIG_ARCH_CHIP_STM32G071G8) || \
+ defined(CONFIG_ARCH_CHIP_STM32G071GB) || defined(CONFIG_ARCH_CHIP_STM32G071G8XN) || \
+ defined(CONFIG_ARCH_CHIP_STM32G071GBXN) || defined(CONFIG_ARCH_CHIP_STM32G071K8) || \
+ defined(CONFIG_ARCH_CHIP_STM32G071KB) || defined(CONFIG_ARCH_CHIP_STM32G071K8XN) || \
+ defined(CONFIG_ARCH_CHIP_STM32G071KBXN) || defined(CONFIG_ARCH_CHIP_STM32G071C8) || \
+ defined(CONFIG_ARCH_CHIP_STM32G071CB) || defined(CONFIG_ARCH_CHIP_STM32G071R8) || \
+ defined(CONFIG_ARCH_CHIP_STM32G071RB)
+
+# define STM32_NATIM 1 /* One advanced timer TIM1 */
+# define STM32_NGTIM16 4 /* 16-bit general up/down timers TIM2-3
+ * (with DMA) and TIM21-22 without DMA */
+# define STM32_NGTIM32 0 /* No 32-bit general up/down timers */
+# define STM32_NBTIM 2 /* Two basic timers: TIM6, TIM7 with DMA */
+ /* Two LPTIMER */
+# define STM32_NSPI 2 /* Two SPI modules SPI1-2 */
+# define STM32_NI2C 2 /* Two I2C (2 with SMBus/PMBus) */
+# define STM32_NDMA 1 /* One DMA1, 7-channels */
+# define STM32_NUSART 4 /* Four USART modules, USART1-4 */
+ /* One LPUART */
+# define STM32_NCAN 0 /* No CAN controllers */
+# define STM32_NLCD 0 /* No LCD */
+# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
+# define STM32_NUSBOTG 0 /* No USB OTG */
+# define STM32_NCEC 1 /* One HDMI-CEC controller */
+# define STM32_NADC 1 /* (1) ADC1, 12-channels */
+
+# define STM32_NDAC 2 /* Two DAC channels */
+# define STM32_NCOMP 2 /* Two Analog Comparators */
+# define STM32_NCRC 0 /* No CRC module */
+# define STM32_NRNG 0 /* No Random number generator (RNG) */
+# define STM32_NCAP 0 /* No Capacitive sensing channels */
+# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-E, H */
+
/* STM32L EnergyLite Line ***********************************************************/
-
-/* STM32L03XX - With LCD
- * STM32L02XX - No LCD
+
+/* STM32L073XX - With LCD
+ * STM32L072XX - No LCD
+ * STM32L071XX - Access line, no LCD
*
* STM32L0XXX8 - 64KB FLASH, 20KB SRAM, 3KB EEPROM
* STM32L0XXXB - 128KB FLASH, 20KB SRAM, 6KB EEPROM
@@ -236,6 +261,87 @@
* STM32L0XXVX - 100-pins
*/
+#elif defined(CONFIG_ARCH_CHIP_STM32L071K8)
+# define STM32_NATIM 0 /* No advanced timers */
+# define STM32_NGTIM16 4 /* 16-bit general up/down timers TIM2-3
+ * (with DMA) and TIM21-22 without DMA */
+# define STM32_NGTIM32 0 /* No 32-bit general up/down timers */
+# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */
+ /* 1 LPTIMER */
+# define STM32_NSPI 1 /* 1 SPI modules SPI1 */
+# define STM32_NI2S 0 /* 0 I2S module */
+# define STM32_NI2C 2 /* 2 I2C */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
+# define STM32_NUSART 3 /* 3 USART modules, USART1-3 */
+ /* 1 LPUART */
+# define STM32_NCAN 0 /* 0 CAN controllers */
+# define STM32_NLCD 0 /* 0 LCD */
+# define STM32_NUSBDEV 0 /* 0 USB full-speed device controller */
+# define STM32_NUSBOTG 0 /* 0 USB OTG FS/HS (only USB 2.0 device) */
+# define STM32_NCEC 0 /* 0 HDMI-CEC controller */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 0 /* 0 DAC channel */
+# define STM32_NCOMP 2 /* 2 Analog Comparators */
+# define STM32_NCRC 0 /* 0 CRC module */
+# define STM32_NRNG 0 /* 0 Random number generator (RNG) */
+# define STM32_NCAP 0 /* 0 Capacitive sensing channels */
+# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-E, H */
+
+#elif defined(CONFIG_ARCH_CHIP_STM32L071C8) || defined(CONFIG_ARCH_CHIP_STM32L071V8) || \
+ defined(CONFIG_ARCH_CHIP_STM32L071CB) || defined(CONFIG_ARCH_CHIP_STM32L071VB) || \
+ defined(CONFIG_ARCH_CHIP_STM32L071RB) || defined(CONFIG_ARCH_CHIP_STM32L071CZ) || \
+ defined(CONFIG_ARCH_CHIP_STM32L071VZ) || defined(CONFIG_ARCH_CHIP_STM32L071RZ)
+# define STM32_NATIM 0 /* 0 advanced timers */
+# define STM32_NGTIM16 4 /* 16-bit general up/down timers TIM2-3
+ * (with DMA) and TIM21-22 without DMA */
+# define STM32_NGTIM32 0 /* 0 32-bit general up/down timers */
+# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */
+ /* 1 LPTIMER */
+# define STM32_NSPI 2 /* 2 SPI modules SPI1-2 */
+# define STM32_NI2S 1 /* 1 I2S module */
+# define STM32_NI2C 3 /* 3 I2C */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
+# define STM32_NUSART 4 /* 4 USART modules, USART1-4 */
+ /* 1 LPUART */
+# define STM32_NCAN 0 /* 0 CAN controllers */
+# define STM32_NLCD 0 /* 0 LCD */
+# define STM32_NUSBDEV 0 /* 0 USB full-speed device controller */
+# define STM32_NUSBOTG 0 /* 0 USB OTG FS/HS (only USB 2.0 device) */
+# define STM32_NCEC 0 /* 0 HDMI-CEC controller */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 0 /* 0 DAC channel */
+# define STM32_NCOMP 2 /* 2 Analog Comparators */
+# define STM32_NCRC 0 /* 0 CRC module */
+# define STM32_NRNG 0 /* 0 Random number generator (RNG) */
+# define STM32_NCAP 0 /* 0 Capacitive sensing channels */
+# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-E, H */
+
+#elif defined(CONFIG_ARCH_CHIP_STM32L071KB) || defined(CONFIG_ARCH_CHIP_STM32L071KZ)
+# define STM32_NATIM 0 /* 0 advanced timers */
+# define STM32_NGTIM16 4 /* 16-bit general up/down timers TIM2-3
+ * (with DMA) and TIM21-22 without DMA */
+# define STM32_NGTIM32 0 /* 0 32-bit general up/down timers */
+# define STM32_NBTIM 2 /* 2 basic timers: TIM6, TIM7 with DMA */
+ /* 1 LPTIMER */
+# define STM32_NSPI 1 /* 1 SPI modules SPI1 */
+# define STM32_NI2S 0 /* 0 I2S module */
+# define STM32_NI2C 3 /* 3 I2C */
+# define STM32_NDMA 1 /* 1 DMA1, 7-channels */
+# define STM32_NUSART 4 /* 4 USART modules, USART1-4 */
+ /* 1 LPUART */
+# define STM32_NCAN 0 /* 0 CAN controllers */
+# define STM32_NLCD 0 /* 0 LCD */
+# define STM32_NUSBDEV 0 /* 0 USB full-speed device controller */
+# define STM32_NUSBOTG 0 /* 0 USB OTG FS/HS (only USB 2.0 device) */
+# define STM32_NCEC 0 /* 0 HDMI-CEC controller */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 0 /* 0 DAC channel */
+# define STM32_NCOMP 2 /* 2 Analog Comparators */
+# define STM32_NCRC 0 /* 0 CRC module */
+# define STM32_NRNG 0 /* 0 Random number generator (RNG) */
+# define STM32_NCAP 0 /* 0 Capacitive sensing channels */
+# define STM32_NPORTS 6 /* Six GPIO ports, GPIOA-E, H */
+
#elif defined(CONFIG_ARCH_CHIP_STM32L072V8) || defined(CONFIG_ARCH_CHIP_STM32L072VB) || \
defined(CONFIG_ARCH_CHIP_STM32L072VZ)
# define STM32_NATIM 0 /* No advanced timers */
@@ -255,11 +361,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit ADC module */
-# define STM32_NADCCHAN 14 /* 14 channels */
-# define STM32_NADCINT 0 /* ? internal channels vs external? */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -283,9 +386,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC 1 /* (1) ADC1, 14-channels */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -310,11 +412,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit ADC module */
-# define STM32_NADCCHAN 14 /* 14 channels */
-# define STM32_NADCINT 0 /* ? internal channels vs external? */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -339,11 +438,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit ADC module */
-# define STM32_NADCCHAN 14 /* 14 channels */
-# define STM32_NADCINT 0 /* ? internal channels vs external? */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -369,11 +465,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit ADC module */
-# define STM32_NADCCHAN 14 /* 14 channels */
-# define STM32_NADCINT 0 /* ? internal channels vs external? */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -398,11 +491,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit ADC module */
-# define STM32_NADCCHAN 14 /* 14 channels */
-# define STM32_NADCINT 0 /* ? internal channels vs external? */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -427,11 +517,8 @@
# define STM32_NUSBDEV 0 /* No USB full-speed device controller */
# define STM32_NUSBOTG 1 /* One USB OTG FS/HS (only USB 2.0 device) */
# define STM32_NCEC 0 /* No HDMI-CEC controller */
-# define STM32_NADC12 1 /* One 12-bit ADC module */
-# define STM32_NADCCHAN 14 /* 14 channels */
-# define STM32_NADCINT 0 /* ? internal channels vs external? */
-# define STM32_NDAC 2 /* Two DAC module */
-# define STM32_NDACCHAN 2 /* Two DAC channels */
+# define STM32_NADC 1 /* One 12-bit module */
+# define STM32_NDAC 2 /* Two DAC channels */
# define STM32_NCOMP 2 /* Two Analog Comparators */
# define STM32_NCRC 1 /* One CRC module */
# define STM32_NRNG 1 /* One Random number generator (RNG) */
@@ -465,4 +552,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_INCLUDE_STM32F0L0_CHIP_H */
+#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_CHIP_H */
diff --git a/arch/arm/include/stm32f0l0/irq.h b/arch/arm/include/stm32f0l0g0/irq.h
similarity index 93%
rename from arch/arm/include/stm32f0l0/irq.h
rename to arch/arm/include/stm32f0l0g0/irq.h
index f168747afde..61c63c4f805 100644
--- a/arch/arm/include/stm32f0l0/irq.h
+++ b/arch/arm/include/stm32f0l0g0/irq.h
@@ -38,8 +38,8 @@
* through nuttx/irq.h
*/
-#ifndef __ARCH_ARM_INCLUDE_STM32F0L0_IRQ_H
-#define __ARCH_ARM_INCLUDE_STM32F0L0_IRQ_H
+#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F0L0G0_IRQ_H
/****************************************************************************
* Included Files
@@ -48,7 +48,7 @@
#ifndef __ASSEMBLY__
# include
#endif
-#include
+#include
/****************************************************************************
* Pre-processor Definitions
@@ -79,9 +79,11 @@
/* Include MCU-specific external interrupt definitions */
#if defined(CONFIG_ARCH_CHIP_STM32F0)
-# include
+# include
#elif defined(CONFIG_ARCH_CHIP_STM32L0)
-# include
+# include
+#elif defined(CONFIG_ARCH_CHIP_STM32G0)
+# include
#else
# error Unrecognized STM32 Cortex M0 family
#endif
@@ -117,4 +119,4 @@ extern "C"
#endif
#endif /* __ASSEMBLY__ */
-#endif /* __ARCH_ARM_INCLUDE_STM32F0L0_IRQ_H */
+#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_IRQ_H */
diff --git a/arch/arm/include/stm32f0l0/stm32f0_irq.h b/arch/arm/include/stm32f0l0g0/stm32f0_irq.h
similarity index 56%
rename from arch/arm/include/stm32f0l0/stm32f0_irq.h
rename to arch/arm/include/stm32f0l0g0/stm32f0_irq.h
index 52ad609a938..3ba8a1eef0a 100644
--- a/arch/arm/include/stm32f0l0/stm32f0_irq.h
+++ b/arch/arm/include/stm32f0l0g0/stm32f0_irq.h
@@ -1,5 +1,5 @@
/****************************************************************************
- * arch/arm/include/stm32f0l0/stm32f0_irq.h
+ * arch/arm/include/stm32f0l0g0/stm32f0_irq.h
*
* Copyright (C) 2017 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -38,8 +38,8 @@
* through nuttx/irq.h
*/
-#ifndef __ARCH_ARM_INCLUDE_STM32F0L0_STM32F0_IRQ_H
-#define __ARCH_ARM_INCLUDE_STM32F0L0_STM32F0_IRQ_H
+#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32F0_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32F0_IRQ_H
/****************************************************************************
* Included Files
@@ -47,7 +47,7 @@
#include
#include
-#include
+#include
/****************************************************************************
* Pre-processor Definitions
@@ -58,7 +58,7 @@
* to handle mapping tables.
*
* Processor Exceptions (vectors 0-15). These common definitions can be found
- * in nuttx/arch/arm/include/stm32f0l0/irq.h
+ * in nuttx/arch/arm/include/stm32f0l0g0/irq.h
*/
#define STM32_IRQ_WWDG (STM32_IRQ_EXTINT + 0) /* 0: WWDG */
@@ -70,29 +70,46 @@
#define STM32_IRQ_EXTI2_3 (STM32_IRQ_EXTINT + 6) /* 6: EXTI2_3 */
#define STM32_IRQ_EXTI4_15 (STM32_IRQ_EXTINT + 7) /* 7: EXTI4_15 */
#define STM32_IRQ_TSC (STM32_IRQ_EXTINT + 8) /* 8: TSC */
-#define STM32_IRQ_DMA_CH1 (STM32_IRQ_EXTINT + 9) /* 9: DMA_CH1 */
-#define STM32_IRQ_DMA_CH23 (STM32_IRQ_EXTINT + 10) /* 0: DMA_CH2_3 and DMA2_CH1_2 */
-#define STM32_IRQ_DMA_CH4567 (STM32_IRQ_EXTINT + 11) /* 1: DMA_CH4_5_6_7 and DMA2_CH3_4_5 */
-#define STM32_IRQ_ADC_COMP (STM32_IRQ_EXTINT + 12) /* 2: ADC_COMP */
-#define STM32_IRQ_TIM1_BRK (STM32_IRQ_EXTINT + 13) /* 3: TIM1_BRK_UP_TRG_COM */
-#define STM32_IRQ_TIM1_CC (STM32_IRQ_EXTINT + 14) /* 4: TIM1_CC */
-#define STM32_IRQ_TIM2 (STM32_IRQ_EXTINT + 15) /* 5: TIM2 */
-#define STM32_IRQ_TIM3 (STM32_IRQ_EXTINT + 16) /* 6: TIM3 */
-#define STM32_IRQ_TIM6_DAC (STM32_IRQ_EXTINT + 17) /* 7: TIM6 and DAC */
-#define STM32_IRQ_TIM7 (STM32_IRQ_EXTINT + 18) /* 8: TIM7 */
-#define STM32_IRQ_TIM14 (STM32_IRQ_EXTINT + 19) /* 9: TIM14 */
-#define STM32_IRQ_TIM15 (STM32_IRQ_EXTINT + 20) /* 0: TIM15 */
-#define STM32_IRQ_TIM16 (STM32_IRQ_EXTINT + 21) /* 1: TIM16 */
-#define STM32_IRQ_TIM17 (STM32_IRQ_EXTINT + 22) /* 2: TIM17 */
-#define STM32_IRQ_I2C1 (STM32_IRQ_EXTINT + 23) /* 3: I2C1 */
-#define STM32_IRQ_I2C2 (STM32_IRQ_EXTINT + 24) /* 4: I2C2 */
-#define STM32_IRQ_SPI1 (STM32_IRQ_EXTINT + 25) /* 5: SPI1 */
-#define STM32_IRQ_SPI2 (STM32_IRQ_EXTINT + 26) /* 6: SPI2 */
-#define STM32_IRQ_USART1 (STM32_IRQ_EXTINT + 27) /* 7: USART1 */
-#define STM32_IRQ_USART2 (STM32_IRQ_EXTINT + 28) /* 8: USART2 */
-#define STM32_IRQ_USART345678 (STM32_IRQ_EXTINT + 29) /* 9: USART3_4_5_6_7_8 */
-#define STM32_IRQ_CEC_CAN (STM32_IRQ_EXTINT + 30) /* 0: HDMI CEC and CAN */
-#define STM32_IRQ_USB (STM32_IRQ_EXTINT + 31) /* 1: USB */
+#define STM32_IRQ_DMA1CH1 (STM32_IRQ_EXTINT + 9) /* 9: DMA1_CH1 */
+#define STM32_IRQ_DMA1CH2 (STM32_IRQ_EXTINT + 10) /* 10: DMA1_CH2 */
+#define STM32_IRQ_DMA1CH3 (STM32_IRQ_EXTINT + 10) /* 10: DMA1_CH3 */
+#define STM32_IRQ_DMA2CH1 (STM32_IRQ_EXTINT + 10) /* 10: DMA2_CH1 */
+#define STM32_IRQ_DMA2CH2 (STM32_IRQ_EXTINT + 10) /* 10: DMA2_CH2 */
+#define STM32_IRQ_DMA1CH4 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH4 */
+#define STM32_IRQ_DMA1CH5 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH5 */
+#define STM32_IRQ_DMA1CH6 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH6 */
+#define STM32_IRQ_DMA1CH7 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH7 */
+#define STM32_IRQ_DMA2CH3 (STM32_IRQ_EXTINT + 11) /* 11: DMA2_CH3 */
+#define STM32_IRQ_DMA2CH4 (STM32_IRQ_EXTINT + 11) /* 11: DMA2_CH4 */
+#define STM32_IRQ_DMA2CH5 (STM32_IRQ_EXTINT + 11) /* 11: DMA2_CH5 */
+#define STM32_IRQ_ADC (STM32_IRQ_EXTINT + 12) /* 12: ADC */
+#define STM32_IRQ_COMP (STM32_IRQ_EXTINT + 12) /* 12: COMP */
+#define STM32_IRQ_TIM1_BRK (STM32_IRQ_EXTINT + 13) /* 13: TIM1_BRK_UP_TRG_COM */
+#define STM32_IRQ_TIM1_CC (STM32_IRQ_EXTINT + 14) /* 14: TIM1_CC */
+#define STM32_IRQ_TIM2 (STM32_IRQ_EXTINT + 15) /* 15: TIM2 */
+#define STM32_IRQ_TIM3 (STM32_IRQ_EXTINT + 16) /* 16: TIM3 */
+#define STM32_IRQ_TIM6 (STM32_IRQ_EXTINT + 17) /* 17: TIM6 */
+#define STM32_IRQ_DAC (STM32_IRQ_EXTINT + 17) /* 17: DAC */
+#define STM32_IRQ_TIM7 (STM32_IRQ_EXTINT + 18) /* 18: TIM7 */
+#define STM32_IRQ_TIM14 (STM32_IRQ_EXTINT + 19) /* 19: TIM14 */
+#define STM32_IRQ_TIM15 (STM32_IRQ_EXTINT + 20) /* 20: TIM15 */
+#define STM32_IRQ_TIM16 (STM32_IRQ_EXTINT + 21) /* 21: TIM16 */
+#define STM32_IRQ_TIM17 (STM32_IRQ_EXTINT + 22) /* 22: TIM17 */
+#define STM32_IRQ_I2C1 (STM32_IRQ_EXTINT + 23) /* 23: I2C1 */
+#define STM32_IRQ_I2C2 (STM32_IRQ_EXTINT + 24) /* 24: I2C2 */
+#define STM32_IRQ_SPI1 (STM32_IRQ_EXTINT + 25) /* 25: SPI1 */
+#define STM32_IRQ_SPI2 (STM32_IRQ_EXTINT + 26) /* 26: SPI2 */
+#define STM32_IRQ_USART1 (STM32_IRQ_EXTINT + 27) /* 27: USART1 */
+#define STM32_IRQ_USART2 (STM32_IRQ_EXTINT + 28) /* 28: USART2 */
+#define STM32_IRQ_USART3 (STM32_IRQ_EXTINT + 29) /* 29: USART3 */
+#define STM32_IRQ_USART4 (STM32_IRQ_EXTINT + 29) /* 29: USART4 */
+#define STM32_IRQ_USART5 (STM32_IRQ_EXTINT + 29) /* 29: USART5 */
+#define STM32_IRQ_USART6 (STM32_IRQ_EXTINT + 29) /* 29: USART6 */
+#define STM32_IRQ_USART7 (STM32_IRQ_EXTINT + 29) /* 29: USART7 */
+#define STM32_IRQ_USART8 (STM32_IRQ_EXTINT + 29) /* 29: USART8 */
+#define STM32_IRQ_CEC (STM32_IRQ_EXTINT + 30) /* 30: HDMI CEC */
+#define STM32_IRQ_CAN (STM32_IRQ_EXTINT + 30) /* 30: HDMI CAN */
+#define STM32_IRQ_USB (STM32_IRQ_EXTINT + 31) /* 31: USB */
#define STM32_IRQ_NEXTINT (32) /* 32 external interrupts */
@@ -125,4 +142,4 @@ extern "C"
#endif
#endif /* __ASSEMBLY__ */
-#endif /* __ARCH_ARM_INCLUDE_STM32F0L0_STM32F0_IRQ_H */
+#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32F0_IRQ_H */
diff --git a/arch/arm/include/stm32f0l0g0/stm32g0_irq.h b/arch/arm/include/stm32f0l0g0/stm32g0_irq.h
new file mode 100644
index 00000000000..0b646f33d66
--- /dev/null
+++ b/arch/arm/include/stm32f0l0g0/stm32g0_irq.h
@@ -0,0 +1,142 @@
+/****************************************************************************************************
+ * arch/arm/include/stm32f0l0g0/stm32g0_irq.h
+ *
+ * Copyright (C) 2019 Gregory Nutt. All rights reserved.
+ * Author: Mateusz Szafoni
+ *
+ * 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.
+ *
+ ****************************************************************************************************/
+
+/* This file should never be included directed but, rather, only indirectly through nuttx/irq.h */
+
+#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32G0_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32G0_IRQ_H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+#include
+#include
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+
+/* IRQ numbers. The IRQ number corresponds vector number and hence map directly to
+ * bits in the NVIC. This does, however, waste several words of memory in the IRQ
+ * to handle mapping tables.
+ *
+ * Processor Exceptions (vectors 0-15). These common definitions can be found
+ * in nuttx/arch/arm/include/stm32f0l0g0/irq.h
+ */
+
+#define STM32_IRQ_WWDG (STM32_IRQ_EXTINT + 0) /* 0: Window Watchdog interrupt */
+#define STM32_IRQ_PVD (STM32_IRQ_EXTINT + 1) /* 1: PVD through EXTI Line detection interrupt */
+#define STM32_IRQ_RTC (STM32_IRQ_EXTINT + 2) /* 2: RTC */
+#define STM32_IRQ_FLASH (STM32_IRQ_EXTINT + 3) /* 3: Flash */
+#define STM32_IRQ_RCC (STM32_IRQ_EXTINT + 4) /* 4: RCC */
+#define STM32_IRQ_EXTI0_1 (STM32_IRQ_EXTINT + 5) /* 5: EXTI0_1 */
+#define STM32_IRQ_EXTI2_3 (STM32_IRQ_EXTINT + 6) /* 6: EXTI2_3 */
+#define STM32_IRQ_EXTI4_15 (STM32_IRQ_EXTINT + 7) /* 7: EXTI4_15 */
+#define STM32_IRQ_UCPD12 (STM32_IRQ_EXTINT + 8) /* 8: UCPD1_2 */
+#define STM32_IRQ_EXTI32_33 (STM32_IRQ_EXTINT + 8) /* 8: EXTI_32_33 */
+#define STM32_IRQ_DMA1CH1 (STM32_IRQ_EXTINT + 9) /* 9: DMA1_CH1 */
+#define STM32_IRQ_DMA1CH2 (STM32_IRQ_EXTINT + 10) /* 10: DMA1_CH2 */
+#define STM32_IRQ_DMA1CH3 (STM32_IRQ_EXTINT + 10) /* 10: DMA1_CH3 */
+#define STM32_IRQ_DMA1CH4 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH4 */
+#define STM32_IRQ_DMA1CH5 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH5 */
+#define STM32_IRQ_DMA1CH6 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH6 */
+#define STM32_IRQ_DMA1CH7 (STM32_IRQ_EXTINT + 11) /* 11: DMA1_CH7 */
+#define STM32_IRQ_DMAMUX (STM32_IRQ_EXTINT + 11) /* 11: DMAMUX */
+#define STM32_IRQ_ADC (STM32_IRQ_EXTINT + 12) /* 12: ADC */
+#define STM32_IRQ_EXTI17_18 (STM32_IRQ_EXTINT + 12) /* 12: EXTI_17_18 */
+#define STM32_IRQ_COMP (STM32_IRQ_EXTINT + 12) /* 12: COMP */
+#define STM32_IRQ_TIM1_BRK (STM32_IRQ_EXTINT + 13) /* 13: TIM1_BRK_UP_TRG_COM */
+#define STM32_IRQ_TIM1_CC (STM32_IRQ_EXTINT + 14) /* 14: TIM1_CC */
+#define STM32_IRQ_TIM2 (STM32_IRQ_EXTINT + 15) /* 15: TIM2 */
+#define STM32_IRQ_TIM3 (STM32_IRQ_EXTINT + 16) /* 16: TIM3 */
+#define STM32_IRQ_TIM6 (STM32_IRQ_EXTINT + 17) /* 17: TIM6 */
+#define STM32_IRQ_DAC (STM32_IRQ_EXTINT + 17) /* 17: DAC */
+#define STM32_IRQ_LPTIM1 (STM32_IRQ_EXTINT + 17) /* 17: LPTIM1 */
+#define STM32_IRQ_TIM7 (STM32_IRQ_EXTINT + 18) /* 18: TIM7 */
+#define STM32_IRQ_LPTIM2 (STM32_IRQ_EXTINT + 18) /* 18: LPTIM2 */
+#define STM32_IRQ_TIM14 (STM32_IRQ_EXTINT + 19) /* 19: TIM14 */
+#define STM32_IRQ_TIM15 (STM32_IRQ_EXTINT + 20) /* 20: TIM15 */
+#define STM32_IRQ_TIM16 (STM32_IRQ_EXTINT + 21) /* 21: TIM16 */
+#define STM32_IRQ_TIM17 (STM32_IRQ_EXTINT + 22) /* 22: TIM17 */
+#define STM32_IRQ_I2C1 (STM32_IRQ_EXTINT + 23) /* 23: I2C1 */
+#define STM32_IRQ_EXTI23 (STM32_IRQ_EXTINT + 23) /* 23: EXTI_23 */
+#define STM32_IRQ_I2C2 (STM32_IRQ_EXTINT + 24) /* 24: I2C2 */
+#define STM32_IRQ_SPI1 (STM32_IRQ_EXTINT + 25) /* 25: SPI1 */
+#define STM32_IRQ_SPI2 (STM32_IRQ_EXTINT + 26) /* 26: SPI2 */
+#define STM32_IRQ_USART1 (STM32_IRQ_EXTINT + 27) /* 27: USART1 */
+#define STM32_IRQ_EXTI25 (STM32_IRQ_EXTINT + 27) /* 27: EXTI_25 */
+#define STM32_IRQ_USART2 (STM32_IRQ_EXTINT + 28) /* 28: USART2 */
+#define STM32_IRQ_EXTI26 (STM32_IRQ_EXTINT + 28) /* 28: EXTI_26 */
+#define STM32_IRQ_USART3 (STM32_IRQ_EXTINT + 29) /* 29: USART3 */
+#define STM32_IRQ_USART4 (STM32_IRQ_EXTINT + 29) /* 29: USART4 */
+#define STM32_IRQ_LPUART1 (STM32_IRQ_EXTINT + 29) /* 29: LPUART1 */
+#define STM32_IRQ_EXTI28 (STM32_IRQ_EXTINT + 29) /* 29: EXTI_28 */
+#define STM32_IRQ_CEC (STM32_IRQ_EXTINT + 30) /* 30: HDMI CEC */
+#define STM32_IRQ_EXTI27 (STM32_IRQ_EXTINT + 30) /* 30: EXTI_27 */
+#define STM32_IRQ_AES (STM32_IRQ_EXTINT + 31) /* 31: AES */
+#define STM32_IRQ_RNG (STM32_IRQ_EXTINT + 31) /* 31: RNG */
+
+#define STM32_IRQ_NEXTINT (32)
+
+/****************************************************************************************************
+ * Public Types
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Public Data
+****************************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32G0_IRQ_H */
diff --git a/arch/arm/include/stm32f0l0/stm32l0_irq.h b/arch/arm/include/stm32f0l0g0/stm32l0_irq.h
similarity index 96%
rename from arch/arm/include/stm32f0l0/stm32l0_irq.h
rename to arch/arm/include/stm32f0l0g0/stm32l0_irq.h
index 704309bcc4c..236d10d3342 100644
--- a/arch/arm/include/stm32f0l0/stm32l0_irq.h
+++ b/arch/arm/include/stm32f0l0g0/stm32l0_irq.h
@@ -1,5 +1,5 @@
/****************************************************************************************************
- * arch/arm/include/stm32f0l0/stm32_irq.h
+ * arch/arm/include/stm32f0l0g0/stm32l0_irq.h
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Mateusz Szafoni
@@ -35,8 +35,8 @@
/* This file should never be included directed but, rather, only indirectly through nuttx/irq.h */
-#ifndef __ARCH_ARM_INCLUDE_STM32F0L0_STM32L0_IRQ_H
-#define __ARCH_ARM_INCLUDE_STM32F0L0_STM32L0_IRQ_H
+#ifndef __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32L0_IRQ_H
+#define __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32L0_IRQ_H
/****************************************************************************************************
* Included Files
@@ -44,7 +44,7 @@
#include
#include
-#include
+#include
/****************************************************************************************************
* Pre-processor Definitions
@@ -55,7 +55,7 @@
* to handle mapping tables.
*
* Processor Exceptions (vectors 0-15). These common definitions can be found
- * in nuttx/arch/arm/include/stm32f0l0/irq.h
+ * in nuttx/arch/arm/include/stm32f0l0g0/irq.h
*/
#define STM32_IRQ_WWDG (STM32_IRQ_EXTINT + 0) /* 0: Window Watchdog interrupt */
@@ -129,4 +129,4 @@ extern "C"
#endif
#endif
-#endif /* __ARCH_ARM_INCLUDE_STM32F0L0_STM32L0_IRQ_H */
+#endif /* __ARCH_ARM_INCLUDE_STM32F0L0G0_STM32L0_IRQ_H */
diff --git a/arch/arm/include/stm32h7/chip.h b/arch/arm/include/stm32h7/chip.h
index ab3e999dfcf..a1b7ffe5269 100644
--- a/arch/arm/include/stm32h7/chip.h
+++ b/arch/arm/include/stm32h7/chip.h
@@ -122,17 +122,21 @@
/* Diversification based on Family and package */
-// TODO:
-// #if defined(CONFIG_STM32F7_HAVE_FMC)
-// # define STM32F7_NFMC 1 /* Have FMC memory controller */
-// #else
-// # define STM32F7_NFMC 0 /* No FMC memory controller */
-// #endif
+#if defined(CONFIG_STM32H7_HAVE_ETHERNET)
+# define STM32H7_NETHERNET 1 /* 100/100 Ethernet MAC */
+#else
+# define STM32H7_NETHERNET 0 /* No 100/100 Ethernet MAC */
+#endif
-/* NVIC priority levels *************************************************************/
+#if defined(CONFIG_STM32F7_HAVE_FMC)
+# define STM32F7_NFMC 1 /* Have FMC memory controller */
+#else
+# define STM32F7_NFMC 0 /* No FMC memory controller */
+#endif
+
+/* NVIC priority levels **********************************************************o***/
/* 16 Programmable interrupt levels */
-// TODO: check this
#define NVIC_SYSH_PRIORITY_MIN 0xf0 /* All bits set in minimum priority */
#define NVIC_SYSH_PRIORITY_DEFAULT 0x80 /* Midpoint is the default */
#define NVIC_SYSH_PRIORITY_MAX 0x00 /* Zero is maximum priority */
diff --git a/arch/arm/src/a1x/a1x_irq.h b/arch/arm/src/a1x/a1x_irq.h
index ad0925707c5..d3633839f14 100644
--- a/arch/arm/src/a1x/a1x_irq.h
+++ b/arch/arm/src/a1x/a1x_irq.h
@@ -41,7 +41,7 @@
****************************************************************************/
#include
-#include "chip/a1x_intc.h"
+#include "hardware/a1x_intc.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/a1x/a1x_lowputc.c b/arch/arm/src/a1x/a1x_lowputc.c
index e3f682da880..9085aa122a9 100644
--- a/arch/arm/src/a1x/a1x_lowputc.c
+++ b/arch/arm/src/a1x/a1x_lowputc.c
@@ -48,7 +48,7 @@
#include "up_arch.h"
#include "a1x_config.h"
-#include "chip/a1x_uart.h"
+#include "hardware/a1x_uart.h"
#include "a1x_pio.h"
/****************************************************************************
diff --git a/arch/arm/src/a1x/a1x_pio.c b/arch/arm/src/a1x/a1x_pio.c
index 8016b007594..5c5ba699d25 100644
--- a/arch/arm/src/a1x/a1x_pio.c
+++ b/arch/arm/src/a1x/a1x_pio.c
@@ -53,7 +53,7 @@
#include "chip.h"
#include "a1x_pio.h"
-#include "chip/a1x_pio.h"
+#include "hardware/a1x_pio.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/a1x/a1x_pio.h b/arch/arm/src/a1x/a1x_pio.h
index de69d4c3e1b..46622824374 100644
--- a/arch/arm/src/a1x/a1x_pio.h
+++ b/arch/arm/src/a1x/a1x_pio.h
@@ -45,7 +45,7 @@
#include
#include
-#include "chip/a1x_pio.h"
+#include "hardware/a1x_pio.h"
/************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/a1x/a1x_serial.c b/arch/arm/src/a1x/a1x_serial.c
index 0107b4e248f..a77786604ee 100644
--- a/arch/arm/src/a1x/a1x_serial.c
+++ b/arch/arm/src/a1x/a1x_serial.c
@@ -62,7 +62,7 @@
#include "up_internal.h"
#include "chip.h"
-#include "chip/a1x_uart.h"
+#include "hardware/a1x_uart.h"
#include "a1x_pio.h"
#include "a1x_serial.h"
diff --git a/arch/arm/src/a1x/a1x_serial.h b/arch/arm/src/a1x/a1x_serial.h
index 47957ac12d4..ffef0794858 100644
--- a/arch/arm/src/a1x/a1x_serial.h
+++ b/arch/arm/src/a1x/a1x_serial.h
@@ -43,7 +43,7 @@
#include
#include
-#include "chip/a1x_uart.h"
+#include "hardware/a1x_uart.h"
#include "a1x_config.h"
#include "a1x_pio.h"
diff --git a/arch/arm/src/a1x/a1x_timerisr.c b/arch/arm/src/a1x/a1x_timerisr.c
index 978cfcdd58e..071389eedea 100644
--- a/arch/arm/src/a1x/a1x_timerisr.c
+++ b/arch/arm/src/a1x/a1x_timerisr.c
@@ -49,7 +49,7 @@
#include
#include "up_arch.h"
-#include "chip/a1x_timer.h"
+#include "hardware/a1x_timer.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/a1x/chip.h b/arch/arm/src/a1x/chip.h
index 31521e2d0a4..516536ba6d2 100644
--- a/arch/arm/src/a1x/chip.h
+++ b/arch/arm/src/a1x/chip.h
@@ -42,7 +42,7 @@
#include
-#include "chip/a1x_memorymap.h"
+#include "hardware/a1x_memorymap.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/a1x/chip/a10_memorymap.h b/arch/arm/src/a1x/hardware/a10_memorymap.h
similarity index 99%
rename from arch/arm/src/a1x/chip/a10_memorymap.h
rename to arch/arm/src/a1x/hardware/a10_memorymap.h
index a4e5d669c94..eee9cbca165 100644
--- a/arch/arm/src/a1x/chip/a10_memorymap.h
+++ b/arch/arm/src/a1x/hardware/a10_memorymap.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/a10_memorymap.h
+ * arch/arm/src/a1x/hardware/a10_memorymap.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A10_MEMORYMAP_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A10_MEMORYMAP_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A10_MEMORYMAP_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A10_MEMORYMAP_H
/************************************************************************************
* Included Files
@@ -615,4 +615,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A10_MEMORYMAP_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A10_MEMORYMAP_H */
diff --git a/arch/arm/src/a1x/chip/a10_piocfg.h b/arch/arm/src/a1x/hardware/a10_piocfg.h
similarity index 99%
rename from arch/arm/src/a1x/chip/a10_piocfg.h
rename to arch/arm/src/a1x/hardware/a10_piocfg.h
index 3ed6a652dbc..12fd23c7927 100644
--- a/arch/arm/src/a1x/chip/a10_piocfg.h
+++ b/arch/arm/src/a1x/hardware/a10_piocfg.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a10_piocfg.h
+ * arch/arm/src/a1x/hardware/a10_piocfg.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A10_PIOCFG_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A10_PIOCFG_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A10_PIOCFG_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A10_PIOCFG_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/a1x_memorymap.h"
+#include "hardware/a1x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -609,4 +609,4 @@
#define PIO_UART7_TX_1 (PIO_PERIPH3 | PIO_PORT_PIOI | PIO_PIN20)
#define PIO_UART7_TX_2 (PIO_PERIPH3 | PIO_PORT_PIOA | PIO_PIN14)
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A10_PIOCFG_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A10_PIOCFG_H */
diff --git a/arch/arm/src/a1x/chip/a1x_intc.h b/arch/arm/src/a1x/hardware/a1x_intc.h
similarity index 97%
rename from arch/arm/src/a1x/chip/a1x_intc.h
rename to arch/arm/src/a1x/hardware/a1x_intc.h
index 86bdc911c88..0c3cd0eb3d7 100644
--- a/arch/arm/src/a1x/chip/a1x_intc.h
+++ b/arch/arm/src/a1x/hardware/a1x_intc.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a1x_intc.h
+ * arch/arm/src/a1x/hardware/a1x_intc.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A1X_INTC_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A1X_INTC_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/a1x_memorymap.h"
+#include "hardware/a1x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -203,4 +203,4 @@
#define INTC_PRIO_MASK(n) (3 << INTC_PRIO_SHIFT(n))
# define INTC_PRIO(n,p) ((uint32_t)(p) << INTC_PRIO_SHIFT(n))
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_INTC_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A1X_INTC_H */
diff --git a/arch/arm/src/a1x/chip/a1x_memorymap.h b/arch/arm/src/a1x/hardware/a1x_memorymap.h
similarity index 89%
rename from arch/arm/src/a1x/chip/a1x_memorymap.h
rename to arch/arm/src/a1x/hardware/a1x_memorymap.h
index 154a1641ba4..b791115ac68 100644
--- a/arch/arm/src/a1x/chip/a1x_memorymap.h
+++ b/arch/arm/src/a1x/hardware/a1x_memorymap.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a1x_memorymap.h
+ * arch/arm/src/a1x/hardware/a1x_memorymap.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_MEMORYMAP_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A1X_MEMORYMAP_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A1X_MEMORYMAP_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A1X_MEMORYMAP_H
/************************************************************************************
* Included Files
@@ -44,9 +44,9 @@
#include
#if defined(CONFIG_ARCH_CHIP_A10)
-# include "chip/a10_memorymap.h"
+# include "hardware/a10_memorymap.h"
#else
# error Unrecognized A1X architecture
#endif
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_MEMORYMAP_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A1X_MEMORYMAP_H */
diff --git a/arch/arm/src/a1x/chip/a1x_pio.h b/arch/arm/src/a1x/hardware/a1x_pio.h
similarity index 97%
rename from arch/arm/src/a1x/chip/a1x_pio.h
rename to arch/arm/src/a1x/hardware/a1x_pio.h
index 48cc2bd9d78..ccb619e93f2 100644
--- a/arch/arm/src/a1x/chip/a1x_pio.h
+++ b/arch/arm/src/a1x/hardware/a1x_pio.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a1x_pio.h
+ * arch/arm/src/a1x/hardware/a1x_pio.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_PIO_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A1X_PIO_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A1X_PIO_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A1X_PIO_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/a1x_memorymap.h"
+#include "hardware/a1x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -217,4 +217,4 @@
/* SDRAM Pad Pull Register */
/* REVISIT: Missing register bit definitions */
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_PIO_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A1X_PIO_H */
diff --git a/arch/arm/src/a1x/chip/a1x_piocfg.h b/arch/arm/src/a1x/hardware/a1x_piocfg.h
similarity index 90%
rename from arch/arm/src/a1x/chip/a1x_piocfg.h
rename to arch/arm/src/a1x/hardware/a1x_piocfg.h
index 019eebf778d..d1fe6afe97f 100644
--- a/arch/arm/src/a1x/chip/a1x_piocfg.h
+++ b/arch/arm/src/a1x/hardware/a1x_piocfg.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a1x_piocfg.h
+ * arch/arm/src/a1x/hardware/a1x_piocfg.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_PIOCFG_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A1X_PIOCFG_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A1X_PIOCFG_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A1X_PIOCFG_H
/************************************************************************************
* Included Files
@@ -44,9 +44,9 @@
#include
#if defined(CONFIG_ARCH_CHIP_A10)
-# include "chip/a10_piocfg.h"
+# include "hardware/a10_piocfg.h"
#else
# error Unrecognized A1X architecture
#endif
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_PIOCFG_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A1X_PIOCFG_H */
diff --git a/arch/arm/src/a1x/chip/a1x_timer.h b/arch/arm/src/a1x/hardware/a1x_timer.h
similarity index 98%
rename from arch/arm/src/a1x/chip/a1x_timer.h
rename to arch/arm/src/a1x/hardware/a1x_timer.h
index afe3603057d..19f3745895d 100644
--- a/arch/arm/src/a1x/chip/a1x_timer.h
+++ b/arch/arm/src/a1x/hardware/a1x_timer.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a1x_timer.h
+ * arch/arm/src/a1x/hardware/a1x_timer.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_TIMER_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A1X_TIMER_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A1X_TIMER_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A1X_TIMER_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/a1x_memorymap.h"
+#include "hardware/a1x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -376,4 +376,4 @@
#define CPU_CFG_L2DCACHE_INVEN (1 << 0) /* Bit 0: Enable L2 data cache invalidation at reset */
#define CPU_CFG_L1DCACHE_INVAEN (1 << 1) /* Bit 1: Enable L1 data cache invalidation at reset */
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_TIMER_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A1X_TIMER_H */
diff --git a/arch/arm/src/a1x/chip/a1x_uart.h b/arch/arm/src/a1x/hardware/a1x_uart.h
similarity index 98%
rename from arch/arm/src/a1x/chip/a1x_uart.h
rename to arch/arm/src/a1x/hardware/a1x_uart.h
index 96f53a25056..199ad7ff1be 100644
--- a/arch/arm/src/a1x/chip/a1x_uart.h
+++ b/arch/arm/src/a1x/hardware/a1x_uart.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/a1x/chip/a1x_uart.h
+ * arch/arm/src/a1x/hardware/a1x_uart.h
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_A1X_CHIP_A1X_UART_H
-#define __ARCH_ARM_SRC_A1X_CHIP_A1X_UART_H
+#ifndef __ARCH_ARM_SRC_A1X_HARDWARE_A1X_UART_H
+#define __ARCH_ARM_SRC_A1X_HARDWARE_A1X_UART_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/a1x_memorymap.h"
+#include "hardware/a1x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -357,4 +357,4 @@
#define UART_HALT_SIR_TX_INVERT (1 << 4) /* Bit 4: SIR Transmit Pulse Polarity Invert */
#define UART_HALT_SIR_RX_INVERT (1 << 5) /* Bit 5: SIR Receiver Pulse Polarity Invert */
-#endif /* __ARCH_ARM_SRC_A1X_CHIP_A1X_UART_H */
+#endif /* __ARCH_ARM_SRC_A1X_HARDWARE_A1X_UART_H */
diff --git a/arch/arm/src/am335x/am335x_clockconfig.c b/arch/arm/src/am335x/am335x_clockconfig.c
index fbe5fe5b571..e719561c153 100644
--- a/arch/arm/src/am335x/am335x_clockconfig.c
+++ b/arch/arm/src/am335x/am335x_clockconfig.c
@@ -42,7 +42,7 @@
#include "up_arch.h"
#if 0
/* TODO: add clock register module */
-#include "chip/am335x_ccm.h"
+#include "hardware/am335x_ccm.h"
#endif
#include "am335x_config.h"
#include "am335x_clockconfig.h"
diff --git a/arch/arm/src/am335x/am335x_gpio.h b/arch/arm/src/am335x/am335x_gpio.h
index 033fde75098..b2f74107024 100644
--- a/arch/arm/src/am335x/am335x_gpio.h
+++ b/arch/arm/src/am335x/am335x_gpio.h
@@ -45,8 +45,8 @@
#include
#include
-#include "chip/am335x_control.h"
-#include "chip/am335x_gpio.h"
+#include "hardware/am335x_control.h"
+#include "hardware/am335x_gpio.h"
/************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/am335x_irq.h b/arch/arm/src/am335x/am335x_irq.h
index bad04939a84..091ade0b693 100644
--- a/arch/arm/src/am335x/am335x_irq.h
+++ b/arch/arm/src/am335x/am335x_irq.h
@@ -41,7 +41,7 @@
****************************************************************************/
#include
-#include "chip/am335x_intc.h"
+#include "hardware/am335x_intc.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/am335x_lowputc.c b/arch/arm/src/am335x/am335x_lowputc.c
index c1d3b9e51cb..7fe6d1757c0 100644
--- a/arch/arm/src/am335x/am335x_lowputc.c
+++ b/arch/arm/src/am335x/am335x_lowputc.c
@@ -50,7 +50,7 @@
#include "am335x_config.h"
#include "am335x_gpio.h"
#include "am335x_pinmux.h"
-#include "chip/am335x_uart.h"
+#include "hardware/am335x_uart.h"
/**************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/am335x_pinmux.h b/arch/arm/src/am335x/am335x_pinmux.h
index 0bb4766c9e8..70c5fa00671 100644
--- a/arch/arm/src/am335x/am335x_pinmux.h
+++ b/arch/arm/src/am335x/am335x_pinmux.h
@@ -42,8 +42,8 @@
#include
-#include "chip/am335x_control.h"
-#include "chip/am335x_pinmux.h"
+#include "hardware/am335x_control.h"
+#include "hardware/am335x_pinmux.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/am335x_serial.c b/arch/arm/src/am335x/am335x_serial.c
index a16c296deef..ba1e3eddcf9 100644
--- a/arch/arm/src/am335x/am335x_serial.c
+++ b/arch/arm/src/am335x/am335x_serial.c
@@ -62,8 +62,9 @@
#include "up_internal.h"
#include "chip.h"
-#include "chip/am335x_uart.h"
+#include "hardware/am335x_uart.h"
#include "am335x_gpio.h"
+#include "am335x_pinmux.h"
#include "am335x_serial.h"
/****************************************************************************
diff --git a/arch/arm/src/am335x/am335x_serial.h b/arch/arm/src/am335x/am335x_serial.h
index 304fd5794e9..7097582bb77 100644
--- a/arch/arm/src/am335x/am335x_serial.h
+++ b/arch/arm/src/am335x/am335x_serial.h
@@ -43,10 +43,10 @@
#include
#include
-#include "chip/am335x_uart.h"
+#include "hardware/am335x_uart.h"
#include "am335x_config.h"
-#include "chip/am335x_gpio.h"
+#include "hardware/am335x_gpio.h"
/************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/am335x_timerisr.c b/arch/arm/src/am335x/am335x_timerisr.c
index 9537252c2f8..f54d5709553 100644
--- a/arch/arm/src/am335x/am335x_timerisr.c
+++ b/arch/arm/src/am335x/am335x_timerisr.c
@@ -49,7 +49,7 @@
#include
#include "up_arch.h"
-#include "chip/am335x_timer.h"
+#include "hardware/am335x_timer.h"
/****************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/am335x_wdog.c b/arch/arm/src/am335x/am335x_wdog.c
index 05a783bbc67..7b0aec8ec2c 100644
--- a/arch/arm/src/am335x/am335x_wdog.c
+++ b/arch/arm/src/am335x/am335x_wdog.c
@@ -42,7 +42,7 @@
#include
#include "up_arch.h"
-#include "chip/am335x_wdog.h"
+#include "hardware/am335x_wdog.h"
/****************************************************************************
* Public Functions
diff --git a/arch/arm/src/am335x/am335x_wdog.h b/arch/arm/src/am335x/am335x_wdog.h
index 40a763f1425..4ad85784d57 100644
--- a/arch/arm/src/am335x/am335x_wdog.h
+++ b/arch/arm/src/am335x/am335x_wdog.h
@@ -49,7 +49,7 @@
#include "up_internal.h"
#include "chip.h"
-#include "chip/am335x_wdog.h"
+#include "hardware/am335x_wdog.h"
/****************************************************************************
* Public Types
diff --git a/arch/arm/src/am335x/chip.h b/arch/arm/src/am335x/chip.h
index 54465118ca3..f5f8a71fbf7 100644
--- a/arch/arm/src/am335x/chip.h
+++ b/arch/arm/src/am335x/chip.h
@@ -42,7 +42,7 @@
#include
-#include "chip/am335x_memorymap.h"
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/am335x/chip/am3358_memorymap.h b/arch/arm/src/am335x/hardware/am3358_memorymap.h
similarity index 99%
rename from arch/arm/src/am335x/chip/am3358_memorymap.h
rename to arch/arm/src/am335x/hardware/am3358_memorymap.h
index b103f57fbb8..50dda4f80d1 100644
--- a/arch/arm/src/am335x/chip/am3358_memorymap.h
+++ b/arch/arm/src/am335x/hardware/am3358_memorymap.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am3358_memorymap.h
+ * arch/arm/src/am335x/hardware/am3358_memorymap.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM3358_MEMORYMAP_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM3358_MEMORYMAP_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM3358_MEMORYMAP_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM3358_MEMORYMAP_H
/************************************************************************************
* Included Files
@@ -614,4 +614,4 @@
* Public Functions
************************************************************************************/
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM3358_MEMORYMAP_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM3358_MEMORYMAP_H */
diff --git a/arch/arm/src/am335x/chip/am3358_pinmux.h b/arch/arm/src/am335x/hardware/am3358_pinmux.h
similarity index 99%
rename from arch/arm/src/am335x/chip/am3358_pinmux.h
rename to arch/arm/src/am335x/hardware/am3358_pinmux.h
index 0ba6f464d60..ce398b56a7f 100644
--- a/arch/arm/src/am335x/chip/am3358_pinmux.h
+++ b/arch/arm/src/am335x/hardware/am3358_pinmux.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am3358_pinmux.h
+ * arch/arm/src/am335x/hardware/am3358_pinmux.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
****************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM3358_PINMUX_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM3358_PINMUX_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM3358_PINMUX_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM3358_PINMUX_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/am335x_memorymap.h"
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -859,4 +859,4 @@
#define GPIO_USB1_DRVVBUS (GPIO_PERIPH | GPIO_PADCTL(AM335X_PADCTL_USB1_DRVVBUS_INDEX) | PINMUX_MODE0)
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM3358_PINMUX_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM3358_PINMUX_H */
diff --git a/arch/arm/src/am335x/chip/am335x_control.h b/arch/arm/src/am335x/hardware/am335x_control.h
similarity index 99%
rename from arch/arm/src/am335x/chip/am335x_control.h
rename to arch/arm/src/am335x/hardware/am335x_control.h
index 2ae2615fc7f..44ae78be6f6 100644
--- a/arch/arm/src/am335x/chip/am335x_control.h
+++ b/arch/arm/src/am335x/hardware/am335x_control.h
@@ -1,5 +1,5 @@
/********************************************************************************************
- * arch/arm/src/am335x/chip/am335x_control.h
+ * arch/arm/src/am335x/hardware/am335x_control.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
********************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_CONTROL_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_CONTROL_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CONTROL_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CONTROL_H
/********************************************************************************************
* Included Files
********************************************************************************************/
#include
-#include
+#include "hardware/am335x_memorymap.h"
/********************************************************************************************
* Pre-processor Definitions
@@ -643,4 +643,4 @@
#define PADCTL_RXACTIVE (1 << 5) /* Bit 5: Receiver enabled */
#define PADCTL_SLEWCTRL (1 << 6) /* Bit 6: Select between faster or slower slew rate */
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_CONTROL_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CONTROL_H */
diff --git a/arch/arm/src/am335x/chip/am335x_gpio.h b/arch/arm/src/am335x/hardware/am335x_gpio.h
similarity index 98%
rename from arch/arm/src/am335x/chip/am335x_gpio.h
rename to arch/arm/src/am335x/hardware/am335x_gpio.h
index bcb38ca50a6..51944e5ffb2 100644
--- a/arch/arm/src/am335x/chip/am335x_gpio.h
+++ b/arch/arm/src/am335x/hardware/am335x_gpio.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/am335x_gpio.h
+ * arch/arm/src/am335x/hardware/am335x_gpio.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_GPIO_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_GPIO_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_GPIO_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_GPIO_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -241,4 +241,4 @@
#define GPIO_ICR_MASK(n) (3 << GPIO_ICR_SHIFT(n))
#define GPIO_ICR(i,n) ((uint32_t)(n) << GPIO_ICR_SHIFT(n))
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_GPIO_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_GPIO_H */
diff --git a/arch/arm/src/am335x/chip/am335x_intc.h b/arch/arm/src/am335x/hardware/am335x_intc.h
similarity index 98%
rename from arch/arm/src/am335x/chip/am335x_intc.h
rename to arch/arm/src/am335x/hardware/am335x_intc.h
index 2d6c36a8850..2521053d8ce 100644
--- a/arch/arm/src/am335x/chip/am335x_intc.h
+++ b/arch/arm/src/am335x/hardware/am335x_intc.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am335x_intc.h
+ * arch/arm/src/am335x/hardware/am335x_intc.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_INTC_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_INTC_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_INTC_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_INTC_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/am335x_memorymap.h"
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -268,4 +268,4 @@
#define INTC_ILR_PRIO_MASK (127) /* Bits 2..7: Interrupt Priority */
# define INTC_ILR_PRIO(p) (((p) & INTC_ILR_PRIO_MASK) << INTC_ILR_PRIO_SHIFT)
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_INTC_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_INTC_H */
diff --git a/arch/arm/src/am335x/chip/am335x_memorymap.h b/arch/arm/src/am335x/hardware/am335x_memorymap.h
similarity index 88%
rename from arch/arm/src/am335x/chip/am335x_memorymap.h
rename to arch/arm/src/am335x/hardware/am335x_memorymap.h
index 3460ada57b4..a46997c97dd 100644
--- a/arch/arm/src/am335x/chip/am335x_memorymap.h
+++ b/arch/arm/src/am335x/hardware/am335x_memorymap.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am335x_memorymap.h
+ * arch/arm/src/am335x/hardware/am335x_memorymap.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_MEMORYMAP_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_MEMORYMAP_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_MEMORYMAP_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_MEMORYMAP_H
/************************************************************************************
* Included Files
@@ -44,9 +44,9 @@
#include
#if defined(CONFIG_ARCH_CHIP_AM3358)
-# include "chip/am3358_memorymap.h"
+# include "hardware/am3358_memorymap.h"
#else
# error Unrecognized AM335X architecture
#endif
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_MEMORYMAP_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_MEMORYMAP_H */
diff --git a/arch/arm/src/am335x/chip/am335x_pinmux.h b/arch/arm/src/am335x/hardware/am335x_pinmux.h
similarity index 89%
rename from arch/arm/src/am335x/chip/am335x_pinmux.h
rename to arch/arm/src/am335x/hardware/am335x_pinmux.h
index 42d789dcc72..2b15ccebca0 100644
--- a/arch/arm/src/am335x/chip/am335x_pinmux.h
+++ b/arch/arm/src/am335x/hardware/am335x_pinmux.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am335x_pinmux.h
+ * arch/arm/src/am335x/hardware/am335x_pinmux.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,8 +33,8 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_PINMUX_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_PINMUX_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_PINMUX_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_PINMUX_H
/************************************************************************************
* Included Files
@@ -44,9 +44,9 @@
#include
#if defined(CONFIG_ARCH_CHIP_AM3358)
-# include "chip/am3358_pinmux.h"
+# include "hardware/am3358_pinmux.h"
#else
# error Unrecognized AM335X architecture
#endif
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_PINMUX_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_PINMUX_H */
diff --git a/arch/arm/src/am335x/chip/am335x_timer.h b/arch/arm/src/am335x/hardware/am335x_timer.h
similarity index 98%
rename from arch/arm/src/am335x/chip/am335x_timer.h
rename to arch/arm/src/am335x/hardware/am335x_timer.h
index cfec609516a..ff72b73aa5f 100644
--- a/arch/arm/src/am335x/chip/am335x_timer.h
+++ b/arch/arm/src/am335x/hardware/am335x_timer.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am335x_timer.h
+ * arch/arm/src/am335x/hardware/am335x_timer.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_TIMER_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_TIMER_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_TIMER_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_TIMER_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/am335x_memorymap.h"
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -213,4 +213,4 @@
#define TMR1MS_TOWR_MASK (0xffffff)
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_TIMER_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_TIMER_H */
diff --git a/arch/arm/src/am335x/chip/am335x_uart.h b/arch/arm/src/am335x/hardware/am335x_uart.h
similarity index 99%
rename from arch/arm/src/am335x/chip/am335x_uart.h
rename to arch/arm/src/am335x/hardware/am335x_uart.h
index 4a6255d266d..122b478b98e 100644
--- a/arch/arm/src/am335x/chip/am335x_uart.h
+++ b/arch/arm/src/am335x/hardware/am335x_uart.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am335x_uart.h
+ * arch/arm/src/am335x/hardware/am335x_uart.h
*
* Copyright (C) 2018 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_UART_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_UART_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_UART_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_UART_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/am335x_memorymap.h"
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -401,5 +401,5 @@
#define UART_EFR_AUTORTSEN (1 << 6) /* Bit 6: Enable Auto-RTS */
#define UART_EFR_AUTOCTSEN (1 << 7) /* Bit 7: Enable Auto-CTS */
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_UART_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_UART_H */
diff --git a/arch/arm/src/am335x/chip/am335x_wdog.h b/arch/arm/src/am335x/hardware/am335x_wdog.h
similarity index 96%
rename from arch/arm/src/am335x/chip/am335x_wdog.h
rename to arch/arm/src/am335x/hardware/am335x_wdog.h
index 2bedef07538..cd52b23395c 100644
--- a/arch/arm/src/am335x/chip/am335x_wdog.h
+++ b/arch/arm/src/am335x/hardware/am335x_wdog.h
@@ -1,5 +1,5 @@
/************************************************************************************
- * arch/arm/src/am335x/chip/am335x_wdog.h
+ * arch/arm/src/am335x/hardware/am335x_wdog.h
*
* Copyright (C) 2019 Petro Karashchenko. All rights reserved.
* Author: Petro Karashchenko
@@ -33,15 +33,15 @@
*
************************************************************************************/
-#ifndef __ARCH_ARM_SRC_AM335X_CHIP_AM335X_WDOG_H
-#define __ARCH_ARM_SRC_AM335X_CHIP_AM335X_WDOG_H
+#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_WDOG_H
+#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_WDOG_H
/************************************************************************************
* Included Files
************************************************************************************/
#include
-#include "chip/am335x_memorymap.h"
+#include "hardware/am335x_memorymap.h"
/************************************************************************************
* Pre-processor Definitions
@@ -129,5 +129,5 @@
#define WDT_WSPR_STOP_FEED_A (0x0000aaaa)
#define WDT_WSPR_STOP_FEED_B (0x00005555)
-#endif /* __ARCH_ARM_SRC_AM335X_CHIP_AM335X_WDOG_H */
+#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_WDOG_H */
diff --git a/arch/arm/src/arm/up_schedulesigaction.c b/arch/arm/src/arm/up_schedulesigaction.c
index f6f0c655e8f..5b731692eaf 100644
--- a/arch/arm/src/arm/up_schedulesigaction.c
+++ b/arch/arm/src/arm/up_schedulesigaction.c
@@ -51,8 +51,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -189,5 +187,3 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
leave_critical_section(flags);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/arm/up_sigdeliver.c b/arch/arm/src/arm/up_sigdeliver.c
index afc843b1e1a..19419e12240 100644
--- a/arch/arm/src/arm/up_sigdeliver.c
+++ b/arch/arm/src/arm/up_sigdeliver.c
@@ -53,8 +53,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -131,6 +129,3 @@ void up_sigdeliver(void)
board_autoled_off(LED_SIGNAL);
up_fullcontextrestore(regs);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
-
diff --git a/arch/arm/src/armv6-m/up_schedulesigaction.c b/arch/arm/src/armv6-m/up_schedulesigaction.c
index 5040582bacf..1636db6de68 100644
--- a/arch/arm/src/armv6-m/up_schedulesigaction.c
+++ b/arch/arm/src/armv6-m/up_schedulesigaction.c
@@ -52,20 +52,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -211,5 +197,3 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
leave_critical_section(flags);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv6-m/up_sigdeliver.c b/arch/arm/src/armv6-m/up_sigdeliver.c
index 1688019729a..834c16348c7 100644
--- a/arch/arm/src/armv6-m/up_sigdeliver.c
+++ b/arch/arm/src/armv6-m/up_sigdeliver.c
@@ -52,8 +52,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -141,5 +139,3 @@ void up_sigdeliver(void)
board_autoled_off(LED_SIGNAL);
up_fullcontextrestore(regs);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv6-m/up_signal_dispatch.c b/arch/arm/src/armv6-m/up_signal_dispatch.c
index 45446a2b5e4..f69702f953c 100644
--- a/arch/arm/src/armv6-m/up_signal_dispatch.c
+++ b/arch/arm/src/armv6-m/up_signal_dispatch.c
@@ -43,20 +43,8 @@
#include "svcall.h"
#include "up_internal.h"
-#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
- defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
+#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
+ defined(CONFIG_BUILD_KERNEL)
/****************************************************************************
* Public Functions
diff --git a/arch/arm/src/armv6-m/up_svcall.c b/arch/arm/src/armv6-m/up_svcall.c
index 98377230346..d2b5b9cf12e 100644
--- a/arch/arm/src/armv6-m/up_svcall.c
+++ b/arch/arm/src/armv6-m/up_svcall.c
@@ -351,7 +351,7 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
* R4 = ucontext
*/
-#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_PROTECTED
case SYS_signal_handler:
{
struct tcb_s *rtcb = sched_self();
@@ -389,7 +389,7 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
* R0 = SYS_signal_handler_return
*/
-#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_PROTECTED
case SYS_signal_handler_return:
{
struct tcb_s *rtcb = sched_self();
diff --git a/arch/arm/src/armv7-a/arm_schedulesigaction.c b/arch/arm/src/armv7-a/arm_schedulesigaction.c
index 1fc7f48c237..7a565365bfb 100644
--- a/arch/arm/src/armv7-a/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-a/arm_schedulesigaction.c
@@ -53,8 +53,6 @@
#include "irq/irq.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -384,5 +382,3 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
leave_critical_section(flags);
}
#endif /* CONFIG_SMP */
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv7-a/arm_sigdeliver.c b/arch/arm/src/armv7-a/arm_sigdeliver.c
index e1f500b1e98..25bd57358fb 100644
--- a/arch/arm/src/armv7-a/arm_sigdeliver.c
+++ b/arch/arm/src/armv7-a/arm_sigdeliver.c
@@ -53,8 +53,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -184,5 +182,3 @@ void up_sigdeliver(void)
board_autoled_off(LED_SIGNAL);
up_fullcontextrestore(regs);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv7-a/arm_signal_dispatch.c b/arch/arm/src/armv7-a/arm_signal_dispatch.c
index 1b461f5cb92..ec1eb56485f 100644
--- a/arch/arm/src/armv7-a/arm_signal_dispatch.c
+++ b/arch/arm/src/armv7-a/arm_signal_dispatch.c
@@ -44,8 +44,8 @@
#include "pgalloc.h"
#include "up_internal.h"
-#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
- defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS)
+#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
+ defined(CONFIG_BUILD_KERNEL)
/****************************************************************************
* Public Functions
@@ -104,4 +104,4 @@ void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
}
}
-#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL) && !CONFIG_DISABLE_SIGNALS */
+#endif /* CONFIG_BUILD_PROTECTED || CONFIG_BUILD_KERNEL */
diff --git a/arch/arm/src/armv7-a/arm_syscall.c b/arch/arm/src/armv7-a/arm_syscall.c
index 7b95e4935b3..00e4f43c6b9 100644
--- a/arch/arm/src/armv7-a/arm_syscall.c
+++ b/arch/arm/src/armv7-a/arm_syscall.c
@@ -312,7 +312,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
#endif
-#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_KERNEL
/* R0=SYS_signal_handler: This a user signal handler callback
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
@@ -372,7 +372,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
#endif
-#if defined(CONFIG_BUILD_KERNEL) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_KERNEL
/* R0=SYS_signal_handler_return: This a user signal handler callback
*
* void signal_handler_return(void);
diff --git a/arch/arm/src/armv7-a/crt0.c b/arch/arm/src/armv7-a/crt0.c
index f13148aa9b8..399ff8e2948 100644
--- a/arch/arm/src/armv7-a/crt0.c
+++ b/arch/arm/src/armv7-a/crt0.c
@@ -79,7 +79,6 @@ int main(int argc, char *argv[]);
*
****************************************************************************/
-#ifndef CONFIG_DISABLE_SIGNALS
static void sig_trampoline(void) naked_function;
static void sig_trampoline(void)
{
@@ -97,7 +96,6 @@ static void sig_trampoline(void)
" svc #0x900001\n" /* Return from the signal handler */
);
}
-#endif
/****************************************************************************
* Public Functions
@@ -127,13 +125,11 @@ void _start(int argc, FAR char *argv[])
{
int ret;
-#ifndef CONFIG_DISABLE_SIGNALS
/* Initialize the reserved area at the beginning of the .bss/.data region
* that is visible to the RTOS.
*/
ARCH_DATA_RESERVE->ar_sigtramp = (addrenv_sigtramp_t)sig_trampoline;
-#endif
/* Call C++ constructors */
/* Setup so that C++ destructors called on task exit */
diff --git a/arch/arm/src/armv7-m/up_schedulesigaction.c b/arch/arm/src/armv7-m/up_schedulesigaction.c
index df994c41fad..760f3b6c594 100644
--- a/arch/arm/src/armv7-m/up_schedulesigaction.c
+++ b/arch/arm/src/armv7-m/up_schedulesigaction.c
@@ -55,8 +55,6 @@
#include "irq/irq.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -448,5 +446,3 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
leave_critical_section(flags);
}
#endif /* CONFIG_SMP */
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv7-m/up_sigdeliver.c b/arch/arm/src/armv7-m/up_sigdeliver.c
index e79f569d3d0..66fa9b3530a 100644
--- a/arch/arm/src/armv7-m/up_sigdeliver.c
+++ b/arch/arm/src/armv7-m/up_sigdeliver.c
@@ -53,8 +53,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -198,5 +196,3 @@ void up_sigdeliver(void)
board_autoled_off(LED_SIGNAL);
up_fullcontextrestore(regs);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv7-m/up_signal_dispatch.c b/arch/arm/src/armv7-m/up_signal_dispatch.c
index 332d61252e0..54bc8e5cd51 100644
--- a/arch/arm/src/armv7-m/up_signal_dispatch.c
+++ b/arch/arm/src/armv7-m/up_signal_dispatch.c
@@ -43,8 +43,8 @@
#include "svcall.h"
#include "up_internal.h"
-#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
- defined(CONFIG_BUILD_KERNEL)) && !defined(CONFIG_DISABLE_SIGNALS)
+#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
+ defined(CONFIG_BUILD_KERNEL)
/****************************************************************************
* Public Functions
diff --git a/arch/arm/src/armv7-m/up_svcall.c b/arch/arm/src/armv7-m/up_svcall.c
index d549edc9590..c0e782cd2e0 100644
--- a/arch/arm/src/armv7-m/up_svcall.c
+++ b/arch/arm/src/armv7-m/up_svcall.c
@@ -351,7 +351,7 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
* R4 = ucontext
*/
-#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_PROTECTED
case SYS_signal_handler:
{
struct tcb_s *rtcb = sched_self();
@@ -389,7 +389,7 @@ int up_svcall(int irq, FAR void *context, FAR void *arg)
* R0 = SYS_signal_handler_return
*/
-#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_PROTECTED
case SYS_signal_handler_return:
{
struct tcb_s *rtcb = sched_self();
diff --git a/arch/arm/src/armv7-r/arm_schedulesigaction.c b/arch/arm/src/armv7-r/arm_schedulesigaction.c
index 3752cc0e7d1..f14901adcda 100644
--- a/arch/arm/src/armv7-r/arm_schedulesigaction.c
+++ b/arch/arm/src/armv7-r/arm_schedulesigaction.c
@@ -51,8 +51,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -196,5 +194,3 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
leave_critical_section(flags);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv7-r/arm_sigdeliver.c b/arch/arm/src/armv7-r/arm_sigdeliver.c
index 6f560d14ff4..e6002fe1166 100644
--- a/arch/arm/src/armv7-r/arm_sigdeliver.c
+++ b/arch/arm/src/armv7-r/arm_sigdeliver.c
@@ -52,8 +52,6 @@
#include "up_internal.h"
#include "up_arch.h"
-#ifndef CONFIG_DISABLE_SIGNALS
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -130,5 +128,3 @@ void up_sigdeliver(void)
board_autoled_off(LED_SIGNAL);
up_fullcontextrestore(regs);
}
-
-#endif /* !CONFIG_DISABLE_SIGNALS */
diff --git a/arch/arm/src/armv7-r/arm_signal_dispatch.c b/arch/arm/src/armv7-r/arm_signal_dispatch.c
index c09c1481b6c..2b4ed038691 100644
--- a/arch/arm/src/armv7-r/arm_signal_dispatch.c
+++ b/arch/arm/src/armv7-r/arm_signal_dispatch.c
@@ -44,20 +44,8 @@
#include "pgalloc.h"
#include "up_internal.h"
-#if ((defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
- defined(CONFIG_BUILD_PROTECTED)) && !defined(CONFIG_DISABLE_SIGNALS)
-
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
+#if (defined(CONFIG_BUILD_PROTECTED) && defined(__KERNEL__)) || \
+ defined(CONFIG_BUILD_PROTECTED)
/****************************************************************************
* Public Functions
@@ -116,4 +104,4 @@ void up_signal_dispatch(_sa_sigaction_t sighand, int signo,
}
}
-#endif /* (CONFIG_BUILD_PROTECTED || CONFIG_BUILD_PROTECTED) && !CONFIG_DISABLE_SIGNALS */
+#endif /* CONFIG_BUILD_PROTECTED || CONFIG_BUILD_PROTECTED */
diff --git a/arch/arm/src/armv7-r/arm_syscall.c b/arch/arm/src/armv7-r/arm_syscall.c
index 26168ce4b5c..3abc36df903 100644
--- a/arch/arm/src/armv7-r/arm_syscall.c
+++ b/arch/arm/src/armv7-r/arm_syscall.c
@@ -310,7 +310,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
#endif
-#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_PROTECTED
/* R0=SYS_signal_handler: This a user signal handler callback
*
* void signal_handler(_sa_sigaction_t sighand, int signo,
@@ -370,7 +370,7 @@ uint32_t *arm_syscall(uint32_t *regs)
break;
#endif
-#if defined(CONFIG_BUILD_PROTECTED) && !defined(CONFIG_DISABLE_SIGNALS)
+#ifdef CONFIG_BUILD_PROTECTED
/* R0=SYS_signal_handler_return: This a user signal handler callback
*
* void signal_handler_return(void);
diff --git a/arch/arm/src/common/README_lwl_console.txt b/arch/arm/src/common/README_lwl_console.txt
new file mode 100644
index 00000000000..3e2cd3dfa43
--- /dev/null
+++ b/arch/arm/src/common/README_lwl_console.txt
@@ -0,0 +1,59 @@
+The file up_lwl_console.c implements a 'Lightweight Link' protocol between
+a target and debugger for use when you need a console but the target doesn't
+have a spare serial port or other available resource. This implements a
+new console type which uses two words of memory for data exchange.
+
+It is not particularly efficient because of the various compromises that are
+made (polling in busy loops, mostly) but it works well enough to give you
+something where you previously had nothing...typically the case when you're
+bring up a new CPU, or when the hardware designer thought the softies could
+cope without a logging port. It has an advantage over semi-hosting in that
+it doesn't put the target into debug mode while it's running, so you've got
+some hope of maintaining real time semantics. To be clear, for output only
+use you'd be better off with SWO if you've got it available!
+
+There is a terminal program in python(*) for the host side in
+tools/ocdconsole.py for use with openocd...the NuttX side functionality is
+not dependent on a specific debugger, the only requirement on it being that
+the debugger can watch and modify a memory location on the target while it is executing.
+
+Typical use is;
+
+$ tools/ocdconsole.py
+==Link Activated
+
+NuttShell (NSH)
+nsh> help
+help usage: help [-v] []
+
+ ? echo exit hexdump ls mh sleep xd
+ cat exec help kill mb mw usleep
+nsh>
+
+On the target side it's transparent, and is just a console;
+
+nsh> ls /dev
+/dev:
+ console
+ null
+ ttyS0
+nsh> echo "Hello World" > /dev/console
+Hello World
+nsh>
+
+CPU load on the host is surprisingly low given that the polling loop is
+continuous (probably due to the fact that openocd is spending most of it's
+time waiting for messages to/from the debug port on the target). When not
+actively doing anything there's no load on the target, but waiting for input
+is done in a busy polled loop (so the thread is effectively busy-locked)
+and output busy-waits for the previous message to be collected before it
+sends the next one.
+
+For now I've only made it available on stm32, but it should only be a case
+of changing the Kconfig and Make.defs for other arm CPUs to make it
+available for them too. Moving beyond arm needs knowledge of the targets
+that I don't have.
+
+If anyone fancies extending this proof-of-concept to full Segger-RTT-style
+functionality then drop me a note, there are plenty of ways to improve
+performance.
diff --git a/arch/arm/src/common/up_initialize.c b/arch/arm/src/common/up_initialize.c
index 82669eace87..7c0d1dcc0ea 100644
--- a/arch/arm/src/common/up_initialize.c
+++ b/arch/arm/src/common/up_initialize.c
@@ -51,6 +51,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -203,7 +204,9 @@ void up_initialize(void)
* serial driver).
*/
-#if defined(CONFIG_DEV_LOWCONSOLE)
+#if defined (CONFIG_ARM_LWL_CONSOLE)
+ lwlconsole_init();
+#elif defined(CONFIG_DEV_LOWCONSOLE)
lowconsole_init();
#elif defined(CONFIG_CONSOLE_SYSLOG)
syslog_console_init();
@@ -258,9 +261,11 @@ void up_initialize(void)
(void)telnet_initialize();
#endif
+#if defined(CONFIG_USBDEV) || defined(CONFIG_USBHOST)
/* Initialize USB -- device and/or host */
up_usbinitialize();
+#endif
/* Initialize the L2 cache if present and selected */
diff --git a/arch/arm/src/common/up_internal.h b/arch/arm/src/common/up_internal.h
index 51ea73f4a4e..64290551729 100644
--- a/arch/arm/src/common/up_internal.h
+++ b/arch/arm/src/common/up_internal.h
@@ -63,7 +63,11 @@
# undef CONFIG_DEV_LOWCONSOLE
# undef CONFIG_RAMLOG_CONSOLE
#else
-# if defined(CONFIG_RAMLOG_CONSOLE)
+# if defined(CONFIG_ARM_LWL_CONSOLE)
+# undef USE_SERIALDRIVER
+# undef USE_EARLYSERIALINIT
+# undef CONFIG_DEV_LOWCONSOLE
+# elif defined(CONFIG_RAMLOG_CONSOLE)
# undef USE_SERIALDRIVER
# undef USE_EARLYSERIALINIT
# undef CONFIG_DEV_LOWCONSOLE
@@ -299,7 +303,7 @@ EXTERN uint32_t _eramfuncs; /* Copy destination end address in RAM */
****************************************************************************/
/****************************************************************************
- * Public Functions
+ * Public Function Prototypes
****************************************************************************/
#ifndef __ASSEMBLY__
@@ -449,10 +453,18 @@ void up_earlyserialinit(void);
# define up_earlyserialinit()
#endif
+#ifdef CONFIG_ARM_LWL_CONSOLE
+
+/* Defined in src/common/up_lwl_console.c */
+
+void lwlconsole_init(void);
+
+#elif defined(CONFIG_DEV_LOWCONSOLE)
+
/* Defined in drivers/lowconsole.c */
-#ifdef CONFIG_DEV_LOWCONSOLE
void lowconsole_init(void);
+
#else
# define lowconsole_init()
#endif
diff --git a/arch/arm/src/common/up_lwl_console.c b/arch/arm/src/common/up_lwl_console.c
new file mode 100644
index 00000000000..a915a3879f5
--- /dev/null
+++ b/arch/arm/src/common/up_lwl_console.c
@@ -0,0 +1,327 @@
+/****************************************************************************
+ * drivers/serial/lwlconsole.c
+ *
+ * Copyright (C) 2019 Gregory Nutt. All rights reserved.
+ * Author: Dave Marples
+ *
+ * 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
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Lightweight Link (lwl)
+ * ======================
+ *
+ * Lightweight bidirectional communication between target and debug host
+ * without any need for additional hardware.
+ *
+ * Works with openOCD and other debuggers that are capable of reading and
+ * writing memory while the target is running.
+ *
+ * Principle of operation is simple; An 'upword' of 32 bits communicates
+ * from the target to the host, a 'downword' of the same size runs in the
+ * opposite direction. These two words can be in any memory that is
+ * read/write access for both the target and the debug host. A simple ping
+ * pong handshake protocol over these words allows up/down link
+ * communication. On the upside no additional integration is needed. On
+ * the downside it may be necessary to feed lwl with cycles to poll for
+ * changes in the downword, depending on the use case.
+ *
+ * Bit configuration
+ * -----------------
+ *
+ * Downword (Host to target);
+ *
+ * A D U VV XXX
+ *
+ * A 31 1 - Service Active (Set by host)
+ * D 30 1 - Downsense (Toggled when there is data)
+ * U 29 1 - Upsense ack (Toggled to acknowledge receipt of uplink data)
+ * VV 28-27 2 - Valid Octets (Number of octets valid in the message)
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2 23-16 8 - Octet 2
+ * O1 15-08 8 - Octet 1
+ * O0 07-00 8 - Octet 0
+ *
+ * Upword (Target to Host);
+ *
+ * A 31 1 - Service Active (Set by device)
+ * D 30 1 - Downsense ack (Toggled to acknowledge receipt of downlink
+ * data)
+ * U 29 1 - Upsense (Toggled when there is data)
+ * VV 28-27 2 - Valid upword octets
+ * XXX 26-24 3 - Port in use (Type of the message)
+ * O2 23-16 8 - Octet 2
+ * O1 15-08 8 - Octet 1
+ * O0 07-00 8 - Octet 0
+ *
+ */
+
+/* Protocol bits */
+
+#define LWL_GETACTIVE(x) (((x) & (1 << 31)) != 0)
+#define LWL_ACTIVE(x) (((x)&1) << 31)
+
+#define LWL_DNSENSEBIT (1 << 30)
+#define LWL_DNSENSE(x) ((x)&LWL_DNSENSEBIT)
+#define LWL_UPSENSEBIT (1 << 29)
+#define LWL_UPSENSE(x) ((x)&LWL_UPSENSEBIT)
+#define LWL_SENSEMASK (3 << 29)
+
+#define LWL_GETOCTVAL(x) (((x) >> 27) & 3)
+#define LWL_OCTVAL(x) (((x)&3) << 27)
+#define LWL_GETPORT(x) (((x) >> 24) & 7)
+#define LWL_PORT(x) (((x)&7) << 24)
+
+#define LWL_PORT_CONSOLE 1
+#define ID_SIG 0x7216A318
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+ size_t buflen);
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+ size_t buflen);
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct
+{
+ uint32_t sig; /* Location signature */
+ volatile uint32_t downword; /* Host to Target word */
+ uint32_t upword; /* Target to Host word */
+} g_d =
+{
+ .sig = ID_SIG
+};
+
+static const struct file_operations g_consoleops =
+{
+ NULL, /* open */
+ NULL, /* close */
+ lwlconsole_read, /* read */
+ lwlconsole_write, /* write */
+ NULL, /* seek */
+ lwlconsole_ioctl, /* ioctl */
+ NULL /* poll */
+#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
+ ,
+ NULL /* unlink */
+#endif
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool linkactive(void)
+{
+ return (LWL_GETACTIVE(g_d.downword) != 0);
+}
+
+static bool writeword(uint32_t newupword)
+{
+ /* Check link is active */
+
+ if (!linkactive())
+ {
+ return false;
+ }
+
+ /* Spin waiting for previous data to be collected */
+
+ while (LWL_UPSENSE(g_d.downword) != LWL_UPSENSE(g_d.upword))
+ {
+ }
+
+ /* Load new data, toggling UPSENSE bit to show it is new */
+
+ g_d.upword = LWL_DNSENSE(g_d.upword) | newupword |
+ (LWL_UPSENSE(g_d.upword) ? 0 : LWL_UPSENSEBIT);
+
+ return true;
+}
+
+static bool write8bits(uint8_t port, uint8_t val)
+{
+ /* Prepare new word */
+
+ uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(1) |
+ LWL_PORT(port) | (val & 0xff);
+
+ return writeword(newupword);
+}
+
+static bool write16bits(uint8_t port, uint32_t val)
+{
+ /* Prepare new word */
+
+ uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(2) |
+ LWL_PORT(port) | (val & 0xffff);
+
+ return writeword(newupword);
+}
+
+static bool write24bits(uint8_t port, uint32_t val)
+{
+ /* Prepare new word */
+
+ uint32_t newupword = LWL_ACTIVE(true) | LWL_OCTVAL(3) |
+ LWL_PORT(port) | (val & 0xffffff);
+
+ return writeword(newupword);
+}
+
+static bool read8bits(uint8_t port, uint8_t * store)
+{
+ if (LWL_DNSENSE(g_d.downword) == LWL_DNSENSE(g_d.upword))
+ {
+ return false;
+ }
+
+ *store = g_d.downword & 255;
+
+ /* Flip the bit to indicate the datum is read */
+
+ g_d.upword = (g_d.upword & ~LWL_DNSENSEBIT) | LWL_DNSENSE(g_d.downword);
+
+ return true;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_ioctl
+ ****************************************************************************/
+
+static int lwlconsole_ioctl(struct file *filep, int cmd, unsigned long arg)
+{
+ return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_read
+ ****************************************************************************/
+
+static ssize_t lwlconsole_read(struct file *filep, char *buffer,
+ size_t buflen)
+{
+ if (buflen == 0 || !linkactive())
+ {
+ return 0;
+ }
+
+ while (!read8bits(LWL_PORT_CONSOLE, (uint8_t *) buffer))
+ {
+ }
+
+ return 1;
+}
+
+/****************************************************************************
+ * Name: lwlconsole_write
+ ****************************************************************************/
+
+static ssize_t lwlconsole_write(struct file *filep, const char *buffer,
+ size_t buflen)
+{
+ uint32_t oc = 0;
+
+ while (buflen)
+ {
+ switch (buflen)
+ {
+ case 0:
+ return oc;
+
+ case 1:
+ if (write8bits(LWL_PORT_CONSOLE, buffer[0]))
+ {
+ oc++;
+ buffer++;
+ buflen--;
+ }
+ break;
+
+ case 2:
+ if (write16bits(LWL_PORT_CONSOLE, buffer[0] | (buffer[1] << 8)))
+ {
+ oc += 2;
+ buffer += 2;
+ buflen -= 2;
+ }
+ break;
+
+ default:
+ if (write24bits(LWL_PORT_CONSOLE, buffer[0] |
+ (buffer[1] << 8) | (buffer[2] << 16)))
+ {
+ oc += 3;
+ buffer += 3;
+ buflen -= 3;
+ }
+ break;
+ }
+ }
+
+ return oc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lwlconsole_init
+ ****************************************************************************/
+
+void lwlconsole_init(void)
+{
+ g_d.upword = 0;
+ (void)register_driver("/dev/console", &g_consoleops, 0666, NULL);
+}
diff --git a/arch/arm/src/cxd56xx/Kconfig b/arch/arm/src/cxd56xx/Kconfig
new file mode 100644
index 00000000000..30740742731
--- /dev/null
+++ b/arch/arm/src/cxd56xx/Kconfig
@@ -0,0 +1,118 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+comment "CXD56xx Configuration Options"
+
+config CXD56_ARCH_OPTS
+ bool
+ default y
+ select ARCH_DMA
+ select SDIO_DMA if MMCSD
+
+menu "CXD56xx Package Configuration"
+
+choice
+ prompt "CXD56xx package selection"
+ default CXD56_FCBGA if !CXD56_100PIN
+ default CXD56_WLCSP if CXD56_100PIN
+
+config CXD56_FCBGA
+ bool "FCBGA 185 pin package"
+
+config CXD56_WLCSP
+ bool "WLCSP 100 pin package"
+
+endchoice
+endmenu
+
+comment "Basic Options"
+
+config CXD56_XOSC_CLOCK
+ int
+ default 26000000
+
+config CXD56_PMIC
+ bool
+ default y
+
+config CXD56_CPUFIFO
+ bool
+
+config CXD56_ICC
+ bool
+ default y
+
+menu "CXD56xx Peripheral Support"
+
+config CXD56_GPIO_IRQ
+ bool "GPIO interrupt"
+ default y
+ ---help---
+ Enable support for GPIO interrupts
+
+config CXD56_UART1
+ bool "UART1"
+ default y
+ select UART1_SERIALDRIVER
+ select ARCH_HAVE_SERIAL_TERMIOS
+ ---help---
+ UART interface in the communication subsystem. This doesn't have any
+ hardware flow control, and is mainly used for debug console.
+
+config CXD56_UART2
+ bool "UART2"
+ default n
+ select UART2_SERIALDRIVER
+ ---help---
+ UART interface with hardware flow control in the application subsystem.
+
+config CXD56_USBDEV
+ bool "USB"
+ default n
+ ---help---
+ Enables USB
+
+menuconfig CXD56_SDIO
+ bool "SDIO SD Card"
+ default n
+ select ARCH_HAVE_SDIO
+ select SDIO_BLOCKSETUP
+ select SCHED_WORKQUEUE
+ select SCHED_HPWORK
+
+if CXD56_SDIO
+
+config CXD56_SDIO_DMA
+ bool "Support DMA data transfers"
+ default y
+ select SDIO_DMA
+ ---help---
+ Support DMA data transfers.
+ Enable SD card DMA data transfers. This is marginally optional.
+ For most usages, SD accesses will cause data overruns if used without
+ DMA.
+
+config CXD56_SDIO_WIDTH_D1_ONLY
+ bool "Use D1 only"
+ default n
+ ---help---
+ Select 1-bit transfer mode. Default: 4-bit transfer mode.
+
+config CXD56_SDIO_DISABLE_CD_WP
+ bool "Disable the CD and WP pin for SDIO"
+ default y
+ ---help---
+ Disable the CD and WP pin for Embedded SDIO.If the CD pin is not disable,
+ the SDIO initialization will be failed.
+
+config CXD56_SDIO_ENABLE_MULTIFUNCTION
+ bool "Enable SDIO multi-function"
+ default n
+ ---help---
+ Support multi-function with SDIO interfaced peripheral other than SD Card.
+
+endif # SDIO Configuration
+
+endmenu
diff --git a/arch/arm/src/cxd56xx/Make.defs b/arch/arm/src/cxd56xx/Make.defs
new file mode 100644
index 00000000000..cbc488ef2bc
--- /dev/null
+++ b/arch/arm/src/cxd56xx/Make.defs
@@ -0,0 +1,103 @@
+############################################################################
+# arch/arm/src/cxd56xx/Make.defs
+#
+# Copyright 2018 Sony Semiconductor Solutions Corporation
+#
+# Copyright (C) 2012-2015 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt
+#
+# 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.
+#
+############################################################################
+
+HEAD_ASRC =
+
+CMN_ASRCS = up_saveusercontext.S up_fullcontextrestore.S up_switchcontext.S
+CMN_ASRCS += up_testset.S vfork.S
+
+CMN_CSRCS = up_assert.c up_blocktask.c up_copyfullstate.c
+CMN_CSRCS += up_createstack.c up_mdelay.c up_udelay.c up_exit.c
+CMN_CSRCS += up_initialize.c up_initialstate.c up_interruptcontext.c
+CMN_CSRCS += up_memfault.c up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c
+CMN_CSRCS += up_releasepending.c up_releasestack.c up_reprioritizertr.c
+CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c
+CMN_CSRCS += up_unblocktask.c up_usestack.c up_doirq.c up_hardfault.c
+CMN_CSRCS += up_svcall.c up_vfork.c
+
+ifeq ($(CONFIG_ARMV7M_LAZYFPU),y)
+CMN_ASRCS += up_lazyexception.S
+else
+CMN_ASRCS += up_exception.S
+endif
+CMN_CSRCS += up_vectors.c
+
+ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
+CMN_CSRCS += up_ramvec_initialize.c up_ramvec_attach.c
+endif
+
+ifeq ($(CONFIG_ARCH_MEMCPY),y)
+CMN_ASRCS += up_memcpy.S
+endif
+
+ifeq ($(CONFIG_BUILD_PROTECTED),y)
+CMN_CSRCS += up_mpu.c up_task_start.c up_pthread_start.c
+CMN_CSRCS += up_signal_dispatch.c
+CMN_UASRCS += up_signal_handler.S
+endif
+
+ifeq ($(CONFIG_STACK_COLORATION),y)
+CMN_CSRCS += up_checkstack.c
+endif
+
+ifeq ($(CONFIG_ARCH_FPU),y)
+CMN_ASRCS += up_fpu.S
+ifneq ($(CONFIG_ARMV7M_CMNVECTOR),y)
+CMN_CSRCS += up_copyarmstate.c
+else ifeq ($(CONFIG_ARMV7M_LAZYFPU),y)
+CMN_CSRCS += up_copyarmstate.c
+endif
+endif
+
+CHIP_CSRCS = cxd56_allocateheap.c cxd56_idle.c
+CHIP_CSRCS += cxd56_serial.c cxd56_uart.c cxd56_irq.c
+CHIP_CSRCS += cxd56_start.c
+CHIP_CSRCS += cxd56_timerisr.c
+CHIP_CSRCS += cxd56_pinconfig.c
+CHIP_CSRCS += cxd56_clock.c
+CHIP_CSRCS += cxd56_gpio.c
+CHIP_CSRCS += cxd56_pmic.c
+CHIP_CSRCS += cxd56_cpufifo.c
+CHIP_CSRCS += cxd56_icc.c
+
+ifeq ($(CONFIG_CXD56_GPIO_IRQ),y)
+CHIP_CSRCS += cxd56_gpioint.c
+endif
+
+ifeq ($(CONFIG_USBDEV),y)
+CHIP_CSRCS += cxd56_usbdev.c
+endif
diff --git a/arch/arm/src/cxd56xx/chip.h b/arch/arm/src/cxd56xx/chip.h
new file mode 100644
index 00000000000..0ccfe5ffda2
--- /dev/null
+++ b/arch/arm/src/cxd56xx/chip.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/chip.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CHIP_H
+#define __ARCH_ARM_SRC_CXD56XX_CHIP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/* Include the chip capabilities file */
+
+#include
+
+#define ARMV7M_PERIPHERAL_INTERRUPTS 128
+
+#include "hardware/cxd5602_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CHIP_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_allocateheap.c b/arch/arm/src/cxd56xx/cxd56_allocateheap.c
new file mode 100644
index 00000000000..606e2139bc7
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_allocateheap.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_allocateheap.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012-2013, 2015-2017 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include "chip.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* _sbss is the start of the BSS region (see the linker script) _ebss is the
+ * end of the BSS regsion (see the linker script). The idle task stack starts
+ * at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. The IDLE
+ * thread is the thread that the system boots on and, eventually, becomes the
+ * idle, do nothing task that runs only when there is nothing else to run.
+ * The heap continues from there until the configured end of memory.
+ * g_idle_topstack is the beginning of this heap region (not necessarily
+ * aligned).
+ */
+
+const uint32_t g_idle_topstack = (uint32_t)&_ebss +
+ CONFIG_IDLETHREAD_STACKSIZE;
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+/* Sanity check */
+
+#if (CONFIG_RAM_START < CXD56_RAM_BASE) || \
+ (CONFIG_RAM_START + CONFIG_RAM_SIZE > CXD56_RAM_BASE + CXD56_RAM_SIZE)
+# error Invalid memory configuration
+#endif
+
+#define MM_RAM_END CONFIG_RAM_END
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_heap_color
+ *
+ * Description:
+ * Set heap memory to a known, non-zero state to checking heap usage.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_HEAP_COLORATION
+static inline void up_heap_color(FAR void *start, size_t size)
+{
+ memset(start, HEAP_COLOR, size);
+}
+#else
+# define up_heap_color(start,size)
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_allocate_heap
+ *
+ * Description:
+ * This function will be called to dynamically set aside the heap region.
+ *
+ * For the kernel build (CONFIG_BUILD_PROTECTED=y) with both kernel- and
+ * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the
+ * size of the unprotected, user-space heap.
+ *
+ * If a protected kernel-space heap is provided, the kernel heap must be
+ * allocated (and protected) by an analogous up_allocate_kheap().
+ *
+ ****************************************************************************/
+
+void up_allocate_heap(FAR void **heap_start, size_t *heap_size)
+{
+ /* Start with the first SRAM region */
+
+ board_autoled_on(LED_HEAPALLOCATE);
+ *heap_start = (FAR void *)g_idle_topstack;
+ *heap_size = MM_RAM_END - g_idle_topstack;
+
+ /* Colorize the heap for debug */
+
+ up_heap_color(*heap_start, *heap_size);
+}
diff --git a/arch/arm/src/cxd56xx/cxd56_clock.c b/arch/arm/src/cxd56xx/cxd56_clock.c
new file mode 100644
index 00000000000..ecdc5c3b9b9
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_clock.c
@@ -0,0 +1,2357 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_clock.c
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include "up_arch.h"
+
+#include "chip.h"
+#include "hardware/cxd56_crg.h"
+#include "hardware/cxd5602_backupmem.h"
+#include "hardware/cxd5602_topreg.h"
+
+#include "cxd56_clock.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_PM
+# define pmerr(fmt, ...) logerr(fmt, ## __VA_ARGS__)
+# define pminfo(fmt, ...) loginfo(fmt, ## __VA_ARGS__)
+# define pmdbg(fmt, ...) logdebug(fmt, ## __VA_ARGS__)
+#else
+# define pmerr(fmt, ...)
+# define pminfo(fmt, ...)
+# define pmdbg(fmt, ...)
+#endif
+
+/* For enable_pwd, disable_pwd (digital domain) */
+
+#define PDID_SCU 0
+#define PDID_APP_DSP 9
+#define PDID_APP_SUB 10
+#define PDID_APP_AUD 14
+
+/* For enable_apwd, disable_apwd (analog domain) */
+
+#define APDID_RCOSC 0
+#define APDID_XOSC 1
+#define APDID_HPADC 12
+#define APDID_LPADC 13
+
+/* Compiler hint shortcut */
+
+#define __unused __attribute__((unused))
+
+#define ALIGNUP(v, a) (((v) + ((a) - 1)) & ~((a) - 1))
+#define TILESIZESHIT 17
+#define TILESIZE (1 << TILESIZESHIT)
+#define TILEALIGN(v) ALIGNUP(v, TILESIZE)
+#define TILEALIGNIDX(v) (((v) >> TILESIZESHIT) & 0xf)
+
+#ifndef CONFIG_CXD56_UART2_BASE_CLOCK_DIVIDER
+#define CONFIG_CXD56_UART2_BASE_CLOCK_DIVIDER 4
+#endif /* CONFIG_CXD56_UART2_BASE_CLOCK_DIVIDER */
+
+/*
+ * Flags for IMG device active
+ *
+ * This flags for fixed clock devices.
+ */
+
+#define FLAG_IMG_CISIF (1 << 0)
+#define FLAG_IMG_GE2D (1 << 1)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+enum clock_source {
+ RCOSC = 1,
+ RTC,
+ RCRTC,
+ XOSC,
+ SYSPLL,
+};
+
+struct scu_peripheral
+{
+ int8_t cken;
+ int8_t swreset;
+ int8_t crgintmask;
+ int8_t reserved;
+};
+
+struct power_domain
+{
+ uint8_t refs[16];
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void cxd56_img_clock_enable(void);
+static void cxd56_img_clock_disable(void);
+static void cxd56_scu_clock_ctrl(uint32_t block, uint32_t intr, int on);
+static void cxd56_scu_peri_clock_enable(FAR const struct scu_peripheral *p) __unused;
+static void cxd56_scu_peri_clock_disable(FAR const struct scu_peripheral *p) __unused;
+static void cxd56_scu_peri_clock_gating(FAR const struct scu_peripheral *p, int enable) __unused;
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct power_domain g_digital;
+static struct power_domain g_analog;
+
+/* Store calibrated RCOSC */
+
+static uint32_t rcosc_clock = 0;
+
+/* Save used IMG block devices */
+
+static uint32_t g_active_imgdevs = 0;
+
+/* Exclusive control */
+
+static sem_t g_clockexc = SEM_INITIALIZER(1);
+
+/* For peripherals inside SCU block
+ *
+ * Related registers are:
+ * cken : SCU_CKEN
+ * swreset : SWRESET_SCU
+ * crgintmask : CRG_INT_CLR0, CRG_INT_STAT_RAW0
+ *
+ * Each member values are indicated the number of bit in apropriate registers.
+ */
+
+#if defined(CONFIG_CXD56_SPI3)
+const struct scu_peripheral g_scuspi =
+{
+ .cken = 3,
+ .swreset = 8,
+ .crgintmask = 10,
+};
+#endif
+#if defined(CONFIG_CXD56_I2C0)
+const struct scu_peripheral g_scui2c0 =
+{
+ .cken = 1,
+ .swreset = 5,
+ .crgintmask = 11,
+};
+#endif
+#if defined(CONFIG_CXD56_I2C1)
+const struct scu_peripheral g_scui2c1 =
+{
+ .cken = 2,
+ .swreset = 6,
+ .crgintmask = 12,
+};
+#endif
+#if defined(CONFIG_CXD56_SCUSEQ)
+const struct scu_peripheral g_scuseq =
+{
+ .cken = 4,
+ .swreset = 7,
+ .crgintmask = 13,
+};
+#endif
+#if defined(CONFIG_CXD56_ADC)
+const struct scu_peripheral g_sculpadc =
+{
+ .cken = 6,
+ .swreset = 4,
+ .crgintmask = 17,
+};
+const struct scu_peripheral g_scuhpadc =
+{
+ .cken = 7,
+ .swreset = 2,
+ .crgintmask = 16,
+};
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void clock_semtake(sem_t *id)
+{
+ if (!up_interrupt_context())
+ {
+ sem_wait(id);
+ }
+}
+
+static void clock_semgive(sem_t *id)
+{
+ if (!up_interrupt_context())
+ {
+ sem_post(id);
+ }
+}
+
+static void busy_wait(int cnt)
+{
+ for (; cnt; cnt--)
+ {
+ getreg32(CXD56_TOPREG_CHIP_ID);
+ }
+}
+
+static void do_power_control(void)
+{
+ uint32_t stat;
+
+ putreg32(0xf1f, CXD56_TOPREG_PMU_INT_CLR);
+ putreg32(0xf1f, CXD56_TOPREG_PMU_INT_MASK);
+ putreg32(1, CXD56_TOPREG_PMU_PW_CTL);
+
+ do
+ {
+ stat = getreg32(CXD56_TOPREG_PMU_RAW_INT_STAT);
+ stat &= 0x1f;
+ }
+ while (stat == 0);
+
+ DEBUGASSERT(stat == 1);
+
+ putreg32(0xf1f, CXD56_TOPREG_PMU_INT_CLR);
+}
+
+static inline void release_pwd_reset(uint32_t domain)
+{
+ /* Reset acts only belows
+ * [ 0] SCU
+ * [ 6] SYSIOP_SUB
+ * [ 8] APP
+ * [12] GNSS_ITP
+ * [13] GNSS
+ */
+
+ if (domain & 0x3141)
+ {
+ /* Release power domain reset */
+
+ putreg32(domain | domain <<16, CXD56_TOPREG_PWD_RESET0);
+ }
+}
+
+static void enable_pwd(int pdid)
+{
+ uint32_t stat;
+ int domain = 1u << pdid;
+
+ stat = getreg32(CXD56_TOPREG_PWD_STAT);
+ if ((stat & domain) != domain)
+ {
+ putreg32((domain|(domain<<16)), CXD56_TOPREG_PWD_CTL);
+ do_power_control();
+ release_pwd_reset(domain);
+ }
+ g_digital.refs[pdid]++;
+}
+
+static void disable_pwd(int pdid)
+{
+ uint32_t stat;
+ int domain = 1u << pdid;
+
+ stat = getreg32(CXD56_TOPREG_PWD_STAT);
+ if (stat & domain)
+ {
+ g_digital.refs[pdid]--;
+ if (g_digital.refs[pdid] == 0)
+ {
+ putreg32(domain<<16, CXD56_TOPREG_PWD_CTL);
+ do_power_control();
+ }
+ }
+}
+
+static void enable_apwd(int apdid)
+{
+ uint32_t stat;
+ int domain = 1u << apdid;
+
+ stat = getreg32(CXD56_TOPREG_ANA_PW_STAT);
+ if ((stat & domain) != domain)
+ {
+ putreg32(domain|(domain<<16), CXD56_TOPREG_ANA_PW_CTL);
+ do_power_control();
+ }
+ g_analog.refs[apdid]++;
+}
+
+static void disable_apwd(int apdid)
+{
+ uint32_t stat;
+ int domain = 1u << apdid;
+
+ stat = getreg32(CXD56_TOPREG_ANA_PW_STAT);
+ if (stat & domain)
+ {
+ g_analog.refs[apdid]--;
+ if (g_analog.refs[apdid] == 0)
+ {
+ putreg32(domain<<16, CXD56_TOPREG_ANA_PW_CTL);
+ do_power_control();
+ }
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+/****************************************************************************
+ * Name: cxd56_rcosc_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_rcosc_enable(void)
+{
+ enable_apwd(APDID_RCOSC);
+}
+
+/****************************************************************************
+ * Name: cxd56_rcosc_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_rcosc_disable(void)
+{
+ disable_apwd(APDID_RCOSC);
+}
+
+/****************************************************************************
+ * Name: cxd56_xosc_enable
+ *
+ * Description:
+ * Enable XOSC (if needed)
+ *
+ ****************************************************************************/
+
+void cxd56_xosc_enable(void)
+{
+ enable_apwd(APDID_XOSC);
+}
+
+/****************************************************************************
+ * Name: cxd56_xosc_disable
+ *
+ * Description:
+ * Disable XOSC.
+ *
+ * CAUTION:
+ * This function is tentative. We need to consider that clock source control
+ * with other devices which XOSC is used.
+ *
+ ****************************************************************************/
+
+void cxd56_xosc_disable(void)
+{
+ disable_apwd(APDID_XOSC);
+}
+
+/****************************************************************************
+ * Name: cxd56_spif_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spif_clock_enable(void)
+{
+ uint32_t val, rst;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ if (val & CK_SFC)
+ {
+ return;
+ }
+
+ putreg32(val | CK_SFC, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+
+ busy_wait(10);
+
+ putreg32(val, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ rst = getreg32(CXD56_TOPREG_SWRESET_BUS);
+ putreg32(rst | XRST_SFC, CXD56_TOPREG_SWRESET_BUS);
+ putreg32(val | CK_SFC, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+}
+
+/****************************************************************************
+ * Name: cxd56_spif_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spif_clock_disable(void)
+{
+ uint32_t val, rst;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ if (!(val & CK_SFC))
+ {
+ return;
+ }
+
+ putreg32(val & ~CK_SFC, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ rst = getreg32(CXD56_TOPREG_SWRESET_BUS);
+ putreg32(rst & ~XRST_SFC, CXD56_TOPREG_SWRESET_BUS);
+}
+
+/****************************************************************************
+ * Name: cxd56_get_cpu_baseclk
+ *
+ * Description:
+ * Get CPU clock.
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_cpu_baseclk(void)
+{
+ uint32_t val;
+ int n, m;
+
+ val = getreg32(CXD56_CRG_GEAR_AHB);
+ n = (val >> 16) & 0x7f;
+ m = val & 0x7f;
+
+ if (n && m)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_cpu_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpu_clock_enable(int cpu)
+{
+ cxd56_cpulist_clock_enable(1 << cpu);
+}
+
+/****************************************************************************
+ * Name: cxd56_cpulist_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpulist_clock_enable(uint32_t cpus)
+{
+ uint32_t c, bits = (cpus & 0x3f) << 16;
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ putreg32(c | bits, CXD56_CRG_CK_GATE_AHB);
+}
+
+/****************************************************************************
+ * Name: cxd56_cpu_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpu_clock_disable(int cpu)
+{
+ cxd56_cpulist_clock_disable(1 << cpu);
+}
+
+/****************************************************************************
+ * Name: cxd56_cpulist_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpulist_clock_disable(uint32_t cpus)
+{
+ uint32_t c, bits = (cpus & 0x3f) << 16;
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ putreg32(c & ~bits, CXD56_CRG_CK_GATE_AHB);
+}
+
+/****************************************************************************
+ * Name: cxd56_cpu_reset
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpu_reset(int cpu)
+{
+ cxd56_cpulist_reset(1 << cpu);
+}
+
+/****************************************************************************
+ * Name: cxd56_cpulist_reset
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpulist_reset(uint32_t cpus)
+{
+ uint32_t c, r, bits = (cpus & 0x3f) << 16;
+
+ /* Reset assert */
+
+ r = getreg32(CXD56_CRG_RESET);
+ putreg32(r & ~bits, CXD56_CRG_RESET);
+
+ /* Temporary provide clock for perform reset */
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ putreg32(c | bits, CXD56_CRG_CK_GATE_AHB);
+ busy_wait(10);
+ putreg32(c, CXD56_CRG_CK_GATE_AHB);
+
+ /* Reset deassert */
+
+ putreg32(r | bits, CXD56_CRG_RESET);
+}
+
+/****************************************************************************
+ * Name: cxd56_usb_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_usb_clock_enable(void)
+{
+ uint32_t c, r;
+
+ enable_pwd(PDID_APP_SUB);
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ if (!(c & CK_GATE_USB))
+ {
+ r = getreg32(CXD56_CRG_RESET);
+ putreg32(r & ~XRS_USB, CXD56_CRG_RESET);
+ putreg32(c | CK_GATE_USB, CXD56_CRG_CK_GATE_AHB);
+ busy_wait(10);
+ putreg32(r | XRS_USB, CXD56_CRG_RESET);
+ putreg32(1, CXD56_TOPREG_USBPHY_CKEN);
+ putreg32(0x00010002, CXD56_CRG_GEAR_PER_USB);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_usb_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_usb_clock_disable(void)
+{
+ uint32_t c, r;
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ if (c & CK_GATE_USB)
+ {
+ putreg32(0, CXD56_CRG_GEAR_PER_USB);
+ putreg32(0, CXD56_TOPREG_USBPHY_CKEN);
+ putreg32(c & ~CK_GATE_USB, CXD56_CRG_CK_GATE_AHB);
+ r = getreg32(CXD56_CRG_RESET);
+ putreg32(r & ~XRS_USB, CXD56_CRG_RESET);
+ }
+
+ disable_pwd(PDID_APP_SUB);
+}
+
+/****************************************************************************
+ * Name: cxd56_emmc_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_emmc_clock_enable(uint32_t div, uint32_t driver, uint32_t sample)
+{
+ uint32_t c, r, g;
+
+ enable_pwd(PDID_APP_SUB);
+
+ c = getreg32(CXD56_CRG_CKEN_EMMC);
+ if (c == 7)
+ {
+ /* already enabled */
+
+ return;
+ }
+
+ r = getreg32(CXD56_CRG_RESET);
+ r = (r & ~XRS_MMC) | XRS_MMC_CRG;
+ putreg32(r, CXD56_CRG_RESET);
+
+ g = getreg32(CXD56_CRG_CK_GATE_AHB);
+ putreg32(g | CK_GATE_MMC, CXD56_CRG_CK_GATE_AHB);
+ putreg32(7, CXD56_CRG_CKEN_EMMC);
+
+ busy_wait(10);
+
+ putreg32(g & ~CK_GATE_MMC, CXD56_CRG_CK_GATE_AHB);
+ putreg32(0, CXD56_CRG_CKEN_EMMC);
+
+ r |= XRS_MMC;
+ putreg32(r, CXD56_CRG_RESET);
+
+ putreg32(g | CK_GATE_MMC, CXD56_CRG_CK_GATE_AHB);
+
+ /* T.B.D: This register located at eMMC controller */
+
+ *((volatile uint32_t *)0x4e201108) = (div << 30) |
+ ((driver & 0x7f) << 23) | ((sample & 0x7f) << 16);
+
+ putreg32(7, CXD56_CRG_CKEN_EMMC);
+}
+
+/****************************************************************************
+ * Name: cxd56_emmc_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_emmc_clock_disable(void)
+{
+ uint32_t c, r, g;
+
+ c = getreg32(CXD56_CRG_CKEN_EMMC);
+ if (c != 7)
+ {
+ return;
+ }
+
+ g = getreg32(CXD56_CRG_CK_GATE_AHB);
+ putreg32(g & ~CK_GATE_MMC, CXD56_CRG_CK_GATE_AHB);
+ putreg32(0, CXD56_CRG_CKEN_EMMC);
+
+ r = getreg32(CXD56_CRG_RESET);
+ putreg32(r & ~(XRS_MMC|XRS_MMC_CRG), CXD56_CRG_RESET);
+
+ disable_pwd(PDID_APP_SUB);
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_sdio_clock_enable(void)
+{
+ uint32_t c, r;
+
+ enable_pwd(PDID_APP_SUB);
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ if (!(c & CK_GATE_SDIO))
+ {
+ r = getreg32(CXD56_CRG_RESET);
+ putreg32(r & ~XRS_SDIO, CXD56_CRG_RESET);
+ putreg32(c | CK_GATE_SDIO, CXD56_CRG_CK_GATE_AHB);
+ putreg32(0x00010002, CXD56_CRG_GEAR_PER_SDIO);
+ busy_wait(10);
+ putreg32(r | XRS_SDIO, CXD56_CRG_RESET);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_sdio_clock_disable(void)
+{
+ uint32_t c, r;
+
+ c = getreg32(CXD56_CRG_CK_GATE_AHB);
+ if (c & CK_GATE_SDIO)
+ {
+ putreg32(0, CXD56_CRG_GEAR_PER_SDIO);
+ putreg32(c & ~CK_GATE_SDIO, CXD56_CRG_CK_GATE_AHB);
+ r = getreg32(CXD56_CRG_RESET);
+ putreg32(r & ~XRS_SDIO, CXD56_CRG_RESET);
+ }
+
+ disable_pwd(PDID_APP_SUB);
+}
+
+/****************************************************************************
+ * Name: cxd56_audio_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_audio_clock_enable(uint32_t clk, uint32_t div)
+{
+ enable_pwd(PDID_APP_AUD);
+
+ modifyreg32(CXD56_TOPREG_APP_CKSEL, AUD_MCLK_MASK, clk);
+ if (AUD_MCLK_XOSC == clk)
+ {
+ putreg32(div, CXD56_TOPREG_APP_DIV);
+ }
+
+ modifyreg32(CXD56_TOPREG_APP_CKEN, 0, APP_CKEN_MCLK);
+ modifyreg32(CXD56_CRG_RESET, 0, XRS_AUD);
+ modifyreg32(CXD56_CRG_CK_GATE_AHB, 0, CK_GATE_AUD);
+}
+
+/****************************************************************************
+ * Name: cxd56_audio_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_audio_clock_disable(void)
+{
+ modifyreg32(CXD56_CRG_RESET, XRS_AUD, 0);
+ modifyreg32(CXD56_CRG_CK_GATE_AHB, CK_GATE_AUD, 0);
+ modifyreg32(CXD56_TOPREG_APP_CKEN, APP_CKEN_MCLK, 0);
+
+ disable_pwd(PDID_APP_AUD);
+}
+
+/****************************************************************************
+ * Name: cxd56_audio_clock_is_enabled
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+bool cxd56_audio_clock_is_enabled(void)
+{
+ return (getreg32(CXD56_CRG_CK_GATE_AHB) & CK_GATE_AUD) == CK_GATE_AUD;
+}
+
+#if defined(CONFIG_CXD56_SPI0)
+/****************************************************************************
+ * Name: cxd56_spim_clock_enable
+ *
+ * Description:
+ * Enable SPI channel 0 device clock. This is a SYS domain peripheral.
+ * I expect SYSIOP_SUB power domain already enabled.
+ *
+ ****************************************************************************/
+
+static void cxd56_spim_clock_enable(void)
+{
+ uint32_t val, rst;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ if (val & CK_SPIM)
+ {
+ return;
+ }
+
+ putreg32(val | CK_SPIM | CK_COM_BRG | CK_AHB_BRG_COMIF, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+
+ busy_wait(10);
+
+ putreg32(val | CK_COM_BRG | CK_AHB_BRG_COMIF, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ rst = getreg32(CXD56_TOPREG_SWRESET_BUS);
+ putreg32(rst | XRST_SPIM, CXD56_TOPREG_SWRESET_BUS);
+ putreg32(val | CK_SPIM | CK_COM_BRG | CK_AHB_BRG_COMIF, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+}
+
+/****************************************************************************
+ * Name: cxd56_spim_clock_disable
+ *
+ * Description:
+ * Disable SPI channel 0 device clock.
+ *
+ ****************************************************************************/
+
+static void cxd56_spim_clock_disable(void)
+{
+ uint32_t val, rst, mask;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ if (!(val & CK_SPIM))
+ {
+ return;
+ }
+
+ mask = CK_SPIM;
+ if (!(val & (CK_UART1 | CK_I2CM)))
+ {
+ mask |= CK_COM_BRG | CK_AHB_BRG_COMIF;
+ }
+
+ putreg32(val & ~mask, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ rst = getreg32(CXD56_TOPREG_SWRESET_BUS);
+ putreg32(rst & ~XRST_SPIM, CXD56_TOPREG_SWRESET_BUS);
+}
+#endif
+
+#if defined(CONFIG_CXD56_SPI4)
+/****************************************************************************
+ * Name: cxd56_img_spi_clock_enable
+ *
+ * Description:
+ * Enable SPI channel 4 device clock.
+ * This is called IMG_SPI, located at APP domain and inside of IMG block.
+ *
+ ****************************************************************************/
+
+static void cxd56_img_spi_clock_enable(void)
+{
+ clock_semtake(&g_clockexc);
+ enable_pwd(PDID_APP_SUB);
+ cxd56_img_clock_enable();
+ putreg32(0x00010002, CXD56_CRG_GEAR_IMG_SPI);
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_spi_clock_disable
+ *
+ * Description:
+ * Disable SPI channel 4 device clock.
+ *
+ ****************************************************************************/
+
+static void cxd56_img_spi_clock_disable(void)
+{
+ clock_semtake(&g_clockexc);
+ putreg32(0, CXD56_CRG_GEAR_IMG_SPI);
+ cxd56_img_clock_disable();
+ disable_pwd(PDID_APP_SUB);
+ clock_semgive(&g_clockexc);
+}
+#endif
+
+#if defined(CONFIG_CXD56_SPI5)
+/****************************************************************************
+ * Name: cxd56_img_wspi_clock_enable
+ *
+ * Description:
+ * Enable SPI channel 5 device clock.
+ * This is called IMG_WSPI, located at APP domain and inside of IMG block.
+ *
+ ****************************************************************************/
+
+static void cxd56_img_wspi_clock_enable(void)
+{
+ clock_semtake(&g_clockexc);
+ enable_pwd(PDID_APP_SUB);
+ cxd56_img_clock_enable();
+ putreg32(0x00010004, CXD56_CRG_GEAR_IMG_WSPI);
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_wspi_clock_disable
+ *
+ * Description:
+ * Disable SPI channel 5 device clock.
+ *
+ ****************************************************************************/
+
+static void cxd56_img_wspi_clock_disable(void)
+{
+ clock_semtake(&g_clockexc);
+ putreg32(0, CXD56_CRG_GEAR_IMG_WSPI);
+ cxd56_img_clock_disable();
+ disable_pwd(PDID_APP_SUB);
+ clock_semgive(&g_clockexc);
+}
+#endif
+
+void cxd56_spi_clock_enable(int port)
+{
+#if defined(CONFIG_CXD56_SPI4)
+ if (port == 4)
+ {
+ cxd56_img_spi_clock_enable();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI5)
+ if (port == 5)
+ {
+ cxd56_img_wspi_clock_enable();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI0)
+ if (port == 0)
+ {
+ cxd56_spim_clock_enable();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI3)
+ if (port == 3)
+ {
+ cxd56_scu_peri_clock_enable(&g_scuspi);
+ }
+#endif
+}
+
+void cxd56_spi_clock_disable(int port)
+{
+#if defined(CONFIG_CXD56_SPI4)
+ if (port == 4)
+ {
+ cxd56_img_spi_clock_disable();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI5)
+ if (port == 5)
+ {
+ cxd56_img_wspi_clock_disable();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI0)
+ if (port == 0)
+ {
+ cxd56_spim_clock_disable();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI3)
+ if (port == 3)
+ {
+ cxd56_scu_peri_clock_disable(&g_scuspi);
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_gate_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_gate_enable(int port)
+{
+#if defined(CONFIG_CXD56_SPI3)
+ if (port == 3)
+ {
+ cxd56_scu_peri_clock_gating(&g_scuspi, 1);
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_gate_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_gate_disable(int port)
+{
+#if defined(CONFIG_CXD56_SPI3)
+ if (port == 3)
+ {
+ cxd56_scu_peri_clock_gating(&g_scuspi, 0);
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_gear_adjust
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_gear_adjust(int port, uint32_t maxfreq)
+{
+ uint32_t baseclock;
+ uint32_t gear;
+ uint32_t divisor;
+ uint32_t maxdivisor;
+ uint32_t addr;
+
+ if (maxfreq == 0)
+ {
+ return;
+ }
+
+#if defined(CONFIG_CXD56_SPI4)
+ if (port == 4)
+ {
+ maxdivisor = 0x7f;
+ addr = CXD56_CRG_GEAR_IMG_SPI;
+ }
+ else
+#endif
+#if defined(CONFIG_CXD56_SPI5)
+ if (port == 5)
+ {
+ maxdivisor = 0xf;
+ addr = CXD56_CRG_GEAR_IMG_WSPI;
+ }
+ else
+#endif
+ {
+ return;
+ }
+
+ clock_semtake(&g_clockexc);
+ baseclock = cxd56_get_appsmp_baseclock();
+ if (baseclock != 0)
+ {
+ divisor = baseclock / (maxfreq * 2);
+ if (baseclock % (maxfreq * 2))
+ {
+ divisor += 1;
+ }
+ if (divisor > maxdivisor)
+ {
+ divisor = maxdivisor;
+ }
+ gear = 0x00010000 | divisor;
+ putreg32(gear, addr);
+ }
+ clock_semgive(&g_clockexc);
+}
+
+#if defined(CONFIG_CXD56_I2C2)
+/****************************************************************************
+ * Name: cxd56_i2cm_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+static void cxd56_i2cm_clock_enable(void)
+{
+ uint32_t val, rst;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ if (val & CK_I2CM)
+ {
+ return;
+ }
+
+ putreg32(val | CK_I2CM | CK_COM_BRG | CK_AHB_BRG_COMIF, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+
+ busy_wait(10);
+
+ putreg32(val | CK_COM_BRG | CK_AHB_BRG_COMIF, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ rst = getreg32(CXD56_TOPREG_SWRESET_BUS);
+ putreg32(rst | XRST_I2CM, CXD56_TOPREG_SWRESET_BUS);
+ putreg32(val | CK_I2CM | CK_COM_BRG | CK_AHB_BRG_COMIF, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+}
+
+/****************************************************************************
+ * Name: cxd56_i2c0_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+static void cxd56_i2cm_clock_disable(void)
+{
+ uint32_t val, rst, mask;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ if (!(val & CK_I2CM))
+ {
+ return;
+ }
+
+ mask = CK_I2CM;
+ if (!(val & (CK_UART1 | CK_SPIM)))
+ {
+ mask |= CK_COM_BRG | CK_AHB_BRG_COMIF;
+ }
+
+ putreg32(val & ~mask, CXD56_TOPREG_SYSIOP_SUB_CKEN);
+ rst = getreg32(CXD56_TOPREG_SWRESET_BUS);
+ putreg32(rst & ~XRST_I2CM, CXD56_TOPREG_SWRESET_BUS);
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_i2c_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_enable(int port)
+{
+#if defined(CONFIG_CXD56_I2C0)
+ if (port == 0)
+ {
+ cxd56_scu_peri_clock_enable(&g_scui2c0);
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C1)
+ if (port == 1)
+ {
+ cxd56_scu_peri_clock_enable(&g_scui2c1);
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C2)
+ if (port == 2)
+ {
+ cxd56_i2cm_clock_enable();
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: cxd56_i2c1_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_disable(int port)
+{
+#if defined(CONFIG_CXD56_I2C0)
+ if (port == 0)
+ {
+ cxd56_scu_peri_clock_disable(&g_scui2c0);
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C1)
+ if (port == 1)
+ {
+ cxd56_scu_peri_clock_disable(&g_scui2c1);
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C2)
+ if (port == 2)
+ {
+ cxd56_i2cm_clock_disable();
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: cxd56_i2c_clock_gate_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_gate_enable(int port)
+{
+#if defined(CONFIG_CXD56_I2C0)
+ if (port == 0)
+ {
+ cxd56_scu_peri_clock_gating(&g_scui2c0, 1);
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C1)
+ if (port == 1)
+ {
+ cxd56_scu_peri_clock_gating(&g_scui2c1, 1);
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: cxd56_i2c_clock_gate_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_gate_disable(int port)
+{
+#if defined(CONFIG_CXD56_I2C0)
+ if (port == 0)
+ {
+ cxd56_scu_peri_clock_gating(&g_scui2c0, 0);
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C1)
+ if (port == 1)
+ {
+ cxd56_scu_peri_clock_gating(&g_scui2c1, 0);
+ }
+#endif
+}
+
+uint32_t cxd56_get_img_uart_baseclock(void)
+{
+ uint32_t val;
+ int n, m;
+
+ val = getreg32(CXD56_CRG_GEAR_IMG_UART);
+ n = (val >> 16) & 1;
+ m = val & 0x7f;
+
+ if (n && m)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_img_uart_clock_enable
+ *
+ * Description:
+ * Enable img uart clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_uart_clock_enable()
+{
+ uint32_t val = 0;
+
+ clock_semtake(&g_clockexc);
+
+ enable_pwd(PDID_APP_SUB);
+ cxd56_img_clock_enable();
+
+ val = getreg32(CXD56_CRG_GEAR_IMG_UART);
+ val |= (1UL << 16);
+#ifdef CONFIG_CXD56_UART2
+ val &= ~0x7f;
+ val |= CONFIG_CXD56_UART2_BASE_CLOCK_DIVIDER;
+#endif /* CONFIG_CXD56_UART2 */
+ putreg32(val, CXD56_CRG_GEAR_IMG_UART);
+
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_uart_clock_dsiable
+ *
+ * Description:
+ * Disable img uart clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_uart_clock_disable()
+{
+ uint32_t val = 0;
+
+ clock_semtake(&g_clockexc);
+
+ val = getreg32(CXD56_CRG_GEAR_IMG_UART);
+ val &= ~(1UL << 16);
+ putreg32(val, CXD56_CRG_GEAR_IMG_UART);
+
+ cxd56_img_clock_disable();
+ disable_pwd(PDID_APP_SUB);
+
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_cisif_clock_enable
+ *
+ * Description:
+ * Enable img cisif clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_cisif_clock_enable(void)
+{
+ clock_semtake(&g_clockexc);
+
+ enable_pwd(PDID_APP_SUB);
+ cxd56_img_clock_enable();
+ g_active_imgdevs |= FLAG_IMG_CISIF;
+
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_cisif_clock_disable
+ *
+ * Description:
+ * Disable img cisif clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_cisif_clock_disable(void)
+{
+ clock_semtake(&g_clockexc);
+
+ g_active_imgdevs &= ~FLAG_IMG_CISIF;
+ cxd56_img_clock_disable();
+ disable_pwd(PDID_APP_SUB);
+
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_ge2d_clock_enable
+ *
+ * Description:
+ * Enable img cisif clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_ge2d_clock_enable(void)
+{
+ clock_semtake(&g_clockexc);
+
+ enable_pwd(PDID_APP_SUB);
+ cxd56_img_clock_enable();
+ g_active_imgdevs |= FLAG_IMG_GE2D;
+
+ clock_semgive(&g_clockexc);
+}
+
+/****************************************************************************
+ * Name: cxd56_img_ge2d_clock_disable
+ *
+ * Description:
+ * Disable img cisif clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_ge2d_clock_disable(void)
+{
+ clock_semtake(&g_clockexc);
+
+ g_active_imgdevs &= ~FLAG_IMG_GE2D;
+ cxd56_img_clock_disable();
+ disable_pwd(PDID_APP_SUB);
+
+ clock_semgive(&g_clockexc);
+}
+
+static uint32_t cxd56_get_clock(enum clock_source cs)
+{
+ if (!rcosc_clock)
+ {
+ rcosc_clock = BKUP->rcosc_clock;
+ }
+
+ switch (cs)
+ {
+ case RCOSC:
+ return rcosc_clock;
+ case RTC:
+ return 32768;
+ case RCRTC:
+ return rcosc_clock / 250;
+ case XOSC:
+ return CONFIG_CXD56_XOSC_CLOCK;
+ case SYSPLL:
+ {
+ uint32_t ctrl, rc, fb;
+
+ ctrl = getreg32(CXD56_TOPREG_SYS_PLL_CTRL2);
+ rc = ctrl >> 30;
+ fb = (ctrl >> 27) & 0x7;
+
+ switch (rc)
+ {
+ case 0:
+ rc = 1;
+ break;
+ case 1:
+ rc = 2;
+ break;
+ case 3:
+ rc = 4;
+ break;
+ }
+
+ switch (fb)
+ {
+ case 0:
+ fb = 10;
+ break;
+ case 1:
+ fb = 12;
+ break;
+ case 2:
+ fb = 15;
+ break;
+ }
+
+ return CONFIG_CXD56_XOSC_CLOCK * fb / rc;
+ }
+ }
+
+ return 0;
+}
+
+uint32_t cxd56_get_sys_baseclock(void)
+{
+ uint32_t val;
+
+ val = getreg32(CXD56_TOPREG_CKSEL_ROOT);
+
+ switch ((val >> 22) & 0x3)
+ {
+ case 0:
+ return cxd56_get_clock(RCOSC);
+
+ case 1:
+ {
+ uint32_t div = ((val >> 10) & 0x3) + 1;
+
+ if (div == 4 && (val & (1<<2)))
+ {
+ div = 5;
+ }
+
+ return cxd56_get_clock(SYSPLL) / div;
+ }
+
+ case 2:
+ return cxd56_get_clock(XOSC);
+
+ case 3:
+ return cxd56_get_clock(RTC);
+ }
+
+ return 0;
+}
+
+uint32_t cxd56_get_scu_baseclock(void)
+{
+ uint32_t val;
+
+ val = getreg32(CXD56_TOPREG_CKSEL_SCU);
+
+ switch (val & 0x3)
+ {
+ case 0:
+ return cxd56_get_clock(RCOSC);
+
+ case 1:
+ return cxd56_get_clock(XOSC) / (((val >> 8) & 0x3) + 1);
+
+ case 2:
+ if (val & (1 << 4))
+ {
+ return cxd56_get_clock(RTC);
+ }
+ else
+ {
+ return cxd56_get_clock(RCRTC);
+ }
+ }
+
+ return 0;
+}
+
+uint32_t cxd56_get_appsmp_baseclock(void)
+{
+ uint32_t val = getreg32(CXD56_TOPREG_APP_CKSEL);
+
+ switch ((val >> 8) & 0x3)
+ {
+ case 0:
+ return cxd56_get_clock(RCOSC);
+
+ case 1:
+ {
+ uint32_t div = ((val >> 10) & 0x3) + 1;
+
+ if (div == 4 && (val & (1<<7)))
+ {
+ div = 5;
+ }
+
+ return cxd56_get_clock(SYSPLL) / div;
+ }
+
+ case 2:
+ return cxd56_get_clock(XOSC);
+
+ case 3:
+ return cxd56_get_clock(RTC);
+ }
+
+ return 0;
+}
+
+uint32_t cxd56_get_com_baseclock(void)
+{
+ uint32_t clock = cxd56_get_sys_baseclock();
+ uint32_t val = getreg32(CXD56_TOPREG_CKDIV_COM);
+
+ return clock / ((val & 0x1f) + 1);
+}
+
+uint32_t cxd56_get_sdio_baseclock(void)
+{
+ uint32_t val;
+ int n, m;
+
+ val = getreg32(CXD56_CRG_GEAR_PER_SDIO);
+ n = (val >> 16) & 1;
+ m = val & 0x3;
+
+ if (m != 0)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+uint32_t cxd56_get_img_spi_baseclock(void)
+{
+ uint32_t val;
+ int n, m;
+
+ val = getreg32(CXD56_CRG_GEAR_IMG_SPI);
+ n = (val >> 16) & 1;
+ m = val & 0x7f;
+
+ if (n && m)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+uint32_t cxd56_get_img_wspi_baseclock(void)
+{
+ uint32_t val;
+ int n, m;
+
+ val = getreg32(CXD56_CRG_GEAR_IMG_WSPI);
+ n = (val >> 16) & 1;
+ m = val & 0xf;
+
+ if (n && m)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+uint32_t cxd56_get_spi_baseclock(int port)
+{
+#if defined(CONFIG_CXD56_SPI4)
+ if (port == 4)
+ {
+ return cxd56_get_img_spi_baseclock();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI5)
+ if (port == 5)
+ {
+ return cxd56_get_img_wspi_baseclock();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI0)
+ if (port == 0)
+ {
+ return cxd56_get_com_baseclock();
+ }
+#endif
+#if defined(CONFIG_CXD56_SPI3)
+ if (port == 3)
+ {
+ return cxd56_get_scu_baseclock();
+ }
+#endif
+ return 0;
+}
+
+uint32_t cxd56_get_i2c_baseclock(int port)
+{
+#if defined(CONFIG_CXD56_I2C0)
+ if (port == 0)
+ {
+ return cxd56_get_scu_baseclock();
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C1)
+ if (port == 1)
+ {
+ return cxd56_get_scu_baseclock();
+ }
+#endif
+#if defined(CONFIG_CXD56_I2C2)
+ if (port == 2)
+ {
+ return cxd56_get_com_baseclock();
+ }
+#endif
+ return 0;
+}
+
+uint32_t cxd56_get_pwm_baseclock(void)
+{
+ return cxd56_get_scu_baseclock();
+}
+
+static void cxd56_img_clock_enable(void)
+{
+ uint32_t val;
+
+ val = getreg32(CXD56_CRG_CK_GATE_AHB);
+ if (val & CK_GATE_IMG)
+ {
+ return;
+ }
+
+ putreg32(val | CK_GATE_IMG, CXD56_CRG_CK_GATE_AHB);
+ val = getreg32(CXD56_CRG_RESET);
+ putreg32(val | XRS_IMG, CXD56_CRG_RESET);
+}
+
+static void cxd56_img_clock_disable(void)
+{
+ uint32_t val;
+
+ /* Check IMG block peripherals in use */
+
+ val = getreg32(CXD56_CRG_GEAR_IMG_UART) >> 16;
+ val |= getreg32(CXD56_CRG_GEAR_IMG_SPI) >> 16;
+ val |= getreg32(CXD56_CRG_GEAR_IMG_WSPI) >> 16;
+ val |= getreg32(CXD56_CRG_GEAR_N_IMG_VENB);
+
+ if (val || g_active_imgdevs)
+ {
+ return;
+ }
+
+ val = getreg32(CXD56_CRG_RESET);
+ putreg32(val & ~XRS_IMG, CXD56_CRG_RESET);
+ val = getreg32(CXD56_CRG_CK_GATE_AHB);
+ putreg32(val & ~CK_GATE_IMG, CXD56_CRG_CK_GATE_AHB);
+}
+
+static void cxd56_scu_clock_ctrl(uint32_t block, uint32_t intr, int on)
+{
+ uint32_t val, stat;
+ int retry = 10000;
+
+ putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0);
+
+ val = getreg32(CXD56_TOPREG_SCU_CKEN);
+ if (on)
+ {
+ if ((val & block) == block)
+ {
+ /* Already clock on */
+
+ return;
+ }
+ putreg32(val | block, CXD56_TOPREG_SCU_CKEN);
+ }
+ else
+ {
+ if ((val & block) == 0)
+ {
+ /* Already clock off */
+
+ return;
+ }
+ putreg32(val & ~block, CXD56_TOPREG_SCU_CKEN);
+ }
+
+ do
+ {
+ stat = getreg32(CXD56_TOPREG_CRG_INT_STAT_RAW0);
+ busy_wait(1000);
+ }
+ while (retry-- && !(stat & intr));
+
+ putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0);
+}
+
+static void cxd56_scu_clock_enable(void)
+{
+ uint32_t val, stat;
+ int retry = 1000;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_CKEN);
+ if (val & CKEN_BRG_SCU)
+ {
+ return;
+ }
+
+ /* SCU clock select default 0 (RCOSC) */
+
+#ifdef CONFIG_CXD56_SCU_32K
+ val = 2;
+#elif defined CONFIG_CXD56_SCU_XOSC
+ cxd56_xosc_enable();
+ val = 1 | ((CONFIG_CXD56_SCU_XOSC_DIV - 1) << 8);
+#else
+ cxd56_rcosc_enable();
+ val = 0;
+#endif
+#ifdef CONFIG_CXD56_SCU32K_RTC
+ val |= 1 << 4;
+#endif
+ putreg32(val, CXD56_TOPREG_CKSEL_SCU);
+
+ putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0);
+
+ /* Enable SYSIOP and SCU bridge */
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_CKEN);
+ putreg32(val | CKEN_BRG_SCU, CXD56_TOPREG_SYSIOP_CKEN);
+
+ /* Enable each blocks in SCU */
+
+ val = getreg32(CXD56_TOPREG_SCU_CKEN);
+ putreg32(val | SCU_SCU | SCU_SC | SCU_32K | SCU_SEQ, CXD56_TOPREG_SCU_CKEN);
+
+ do
+ {
+ stat = getreg32(CXD56_TOPREG_CRG_INT_STAT_RAW0);
+ busy_wait(1000);
+ }
+ while (retry-- &&
+ !(stat & (CRG_CK_SCU |
+ CRG_CK_SCU_SC |
+ CRG_CK_BRG_SCU |
+ CRG_CK_32K |
+ CRG_CK_SCU_SEQ)));
+
+ putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0);
+}
+
+void cxd56_scu_clock_disable(void)
+{
+ uint32_t val, stat;
+ int retry = 1000;
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_CKEN);
+ if (!(val & CKEN_BRG_SCU))
+ {
+ /* Already disabled */
+
+ return;
+ }
+
+ val = getreg32(CXD56_TOPREG_SWRESET_SCU);
+ putreg32(val & ~XRST_SCU_ISOP, CXD56_TOPREG_SWRESET_SCU);
+
+ up_udelay(1);
+
+ putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0);
+
+ /* Enable SYSIOP and SCU bridge */
+
+ val = getreg32(CXD56_TOPREG_SYSIOP_CKEN);
+ putreg32(val & ~CKEN_BRG_SCU, CXD56_TOPREG_SYSIOP_CKEN);
+
+ /* Enable each blocks in SCU */
+
+ val = getreg32(CXD56_TOPREG_SCU_CKEN);
+ putreg32(val & ~(SCU_SCU | SCU_SC | SCU_32K | SCU_SEQ), CXD56_TOPREG_SCU_CKEN);
+
+ do
+ {
+ stat = getreg32(CXD56_TOPREG_CRG_INT_STAT_RAW0);
+ busy_wait(1000);
+ }
+ while (retry-- &&
+ !(stat & (CRG_CK_SCU |
+ CRG_CK_SCU_SC |
+ CRG_CK_BRG_SCU |
+ CRG_CK_32K |
+ CRG_CK_SCU_SEQ)));
+
+ putreg32(0xffffffff, CXD56_TOPREG_CRG_INT_CLR0);
+}
+
+bool cxd56_scuseq_clock_is_enabled(void)
+{
+ uint32_t rst;
+
+ /* If SCU reset is already released, it assumes that the SCU sequencer is
+ * already in running.
+ */
+
+ rst = getreg32(CXD56_TOPREG_SWRESET_SCU);
+ if (rst & XRST_SCU_ISOP)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+int cxd56_scuseq_clock_enable(void)
+{
+ /* Enable SCU IRAM/DRAM & FIFO memory power.
+ * Actual power control will running at SCU power control.
+ */
+
+ putreg32(0x133f, CXD56_TOPREG_TOP_SCU_RAMMODE_SEL);
+
+ /* Up SCU power if needed */
+
+ enable_pwd(PDID_SCU);
+
+ cxd56_scu_clock_enable();
+
+ return OK;
+}
+
+void cxd56_scuseq_release_reset(void)
+{
+ uint32_t rst;
+
+ cxd56_scu_clock_ctrl(SCU_SEQ, CRG_CK_SCU_SEQ, 0);
+
+ rst = getreg32(CXD56_TOPREG_SWRESET_SCU);
+ putreg32(rst | XRST_SCU_ISOP, CXD56_TOPREG_SWRESET_SCU);
+
+ cxd56_scu_clock_ctrl(SCU_SEQ, CRG_CK_SCU_SEQ, 1);
+}
+
+void cxd56_scuseq_clock_disable(void)
+{
+ uint32_t rst;
+
+ cxd56_scu_clock_ctrl(SCU_SEQ, CRG_CK_SCU_SEQ, 0);
+
+ rst = getreg32(CXD56_TOPREG_SWRESET_SCU);
+ putreg32(rst & ~XRST_SCU_ISOP, CXD56_TOPREG_SWRESET_SCU);
+
+ /* Down SCU power if needed */
+
+ disable_pwd(PDID_SCU);
+}
+
+static void cxd56_scu_peri_clock_enable(FAR const struct scu_peripheral *p)
+{
+ uint32_t val, rst;
+ uint32_t cken = 1u << p->cken;
+ uint32_t crgintmask = 1u << p->crgintmask;
+ uint32_t swreset = 1u << p->swreset;
+
+ /* Up SCU power if needed */
+
+ enable_pwd(PDID_SCU);
+
+ cxd56_scu_clock_enable();
+
+ val = getreg32(CXD56_TOPREG_SCU_CKEN);
+ if (val & cken)
+ {
+ return;
+ }
+
+ cxd56_scu_clock_ctrl(cken, crgintmask, 1);
+ cxd56_scu_clock_ctrl(cken, crgintmask, 0);
+
+ rst = getreg32(CXD56_TOPREG_SWRESET_SCU);
+ putreg32(rst | swreset, CXD56_TOPREG_SWRESET_SCU);
+
+ cxd56_scu_clock_ctrl(cken, crgintmask, 1);
+}
+
+static void cxd56_scu_peri_clock_disable(FAR const struct scu_peripheral *p)
+{
+ uint32_t val, rst;
+ uint32_t cken = 1u << p->cken;
+ uint32_t crgintmask = 1u << p->crgintmask;
+ uint32_t swreset = 1u << p->swreset;
+
+ val = getreg32(CXD56_TOPREG_SCU_CKEN);
+ if (!(val & cken))
+ {
+ return;
+ }
+
+ cxd56_scu_clock_ctrl(cken, crgintmask, 0);
+
+ rst = getreg32(CXD56_TOPREG_SWRESET_SCU);
+ putreg32(rst & ~swreset, CXD56_TOPREG_SWRESET_SCU);
+
+ /* Down SCU power if needed */
+
+ disable_pwd(PDID_SCU);
+}
+
+static void cxd56_scu_peri_clock_gating(FAR const struct scu_peripheral *p, int enable)
+{
+ uint32_t cken = 1u << p->cken;
+
+ if (enable)
+ {
+ modifyreg32(CXD56_TOPREG_SCU_CKEN, cken, 0); /* clock stop */
+ }
+ else
+ {
+ modifyreg32(CXD56_TOPREG_SCU_CKEN, 0, cken); /* clock start */
+ }
+}
+
+void cxd56_udmac_clock_enable(void)
+{
+ uint32_t val;
+ val = getreg32(CXD56_TOPREG_SYSIOP_CKEN);
+ putreg32(val | CKEN_AHB_DMAC0, CXD56_TOPREG_SYSIOP_CKEN);
+}
+
+void cxd56_udmac_clock_disable(void)
+{
+ uint32_t val;
+ val = getreg32(CXD56_TOPREG_SYSIOP_CKEN);
+ putreg32(val & ~CKEN_AHB_DMAC0, CXD56_TOPREG_SYSIOP_CKEN);
+}
+
+void cxd56_lpadc_clock_enable(uint32_t div)
+{
+#if defined(CONFIG_CXD56_ADC)
+ uint32_t val;
+ uint32_t mask;
+
+ if (div > 4)
+ {
+ return;
+ }
+
+ enable_apwd(APDID_LPADC);
+
+ mask = 0x0000000f;
+ val = getreg32(CXD56_TOPREG_CKDIV_SCU) & ~mask;
+ val |= div;
+ putreg32(val, CXD56_TOPREG_CKDIV_SCU);
+
+ cxd56_scu_peri_clock_enable(&g_sculpadc);
+#endif
+}
+
+void cxd56_lpadc_clock_disable(void)
+{
+#if defined(CONFIG_CXD56_ADC)
+ cxd56_scu_peri_clock_disable(&g_sculpadc);
+
+ disable_apwd(APDID_LPADC);
+#endif
+}
+
+void cxd56_hpadc_clock_enable(uint32_t div)
+{
+#if defined(CONFIG_CXD56_ADC)
+ uint32_t val;
+ uint32_t mask;
+
+ if (div > 4)
+ {
+ return;
+ }
+
+ enable_apwd(APDID_HPADC);
+
+ mask = 0x000000f0;
+ val = getreg32(CXD56_TOPREG_CKDIV_SCU) & ~mask;
+ val |= (div << 4);
+ putreg32(val, CXD56_TOPREG_CKDIV_SCU);
+
+ mask = 0x00004000;
+ val = getreg32(CXD56_TOPREG_RCOSC_CTRL1) & ~mask;
+ putreg32(val, CXD56_TOPREG_RCOSC_CTRL1);
+
+ mask = 0x00020000;
+ val = getreg32(CXD56_TOPREG_XOSC_CTRL) & ~mask;
+ val |= mask;
+ putreg32(val, CXD56_TOPREG_XOSC_CTRL);
+
+ cxd56_scu_peri_clock_enable(&g_scuhpadc);
+#endif
+}
+
+void cxd56_hpadc_clock_disable(void)
+{
+#if defined(CONFIG_CXD56_ADC)
+ uint32_t val;
+ uint32_t mask;
+
+ mask = 0x00004000;
+ val = getreg32(CXD56_TOPREG_RCOSC_CTRL1) & ~mask;
+ val |= mask;
+ putreg32(val, CXD56_TOPREG_RCOSC_CTRL1);
+
+ mask = 0x00020000;
+ val = getreg32(CXD56_TOPREG_XOSC_CTRL) & ~mask;
+ putreg32(val, CXD56_TOPREG_XOSC_CTRL);
+
+ cxd56_scu_peri_clock_disable(&g_scuhpadc);
+
+ disable_apwd(APDID_HPADC);
+#endif
+}
+
+uint32_t cxd56_get_xosc_clock(void)
+{
+ return cxd56_get_clock(XOSC);
+}
+
+uint32_t cxd56_get_rcosc_clock(void)
+{
+ return cxd56_get_clock(RCOSC);
+}
+
+uint32_t cxd56_get_rtc_clock(void)
+{
+ return cxd56_get_clock(RTC);
+}
+
+uint32_t cxd56_get_syspll_clock(void)
+{
+ return cxd56_get_clock(SYSPLL);
+}
+
+uint32_t cxd56_get_sys_ahb_baseclock(void)
+{
+ uint32_t bus, ahb;
+
+ bus = getreg32(CXD56_TOPREG_CKDIV_CPU_DSP_BUS);
+ ahb = 1 << ((bus >> 16) & 0x7);
+ return cxd56_get_sys_baseclock() / ahb;
+}
+
+uint32_t cxd56_get_sys_apb_baseclock(void)
+{
+ uint32_t bus, apb;
+
+ bus = getreg32(CXD56_TOPREG_CKDIV_CPU_DSP_BUS);
+ apb = 1 << ((bus >> 24) & 0x3);
+ return cxd56_get_sys_ahb_baseclock() / apb;
+}
+
+uint32_t cxd56_get_sys_sfc_baseclock(void)
+{
+ uint32_t bus, sfchclk;
+
+ bus = getreg32(CXD56_TOPREG_CKDIV_CPU_DSP_BUS);
+ sfchclk = ((bus >> 28) & 0xf);
+ if (sfchclk <= 9)
+ {
+ return (cxd56_get_sys_baseclock() / ((sfchclk * 2) + 2));
+ }
+ else
+ {
+ return (cxd56_get_sys_baseclock() / ((1 << (sfchclk - 10)) * 32));
+ }
+}
+
+static uint32_t cxd56_get_suc32k_baseclock(void)
+{
+ uint32_t ckscu;
+
+ ckscu = getreg32(CXD56_TOPREG_CKSEL_SCU);
+
+ if (((ckscu >> 4) & 0x1) == 0)
+ {
+ return cxd56_get_clock(RCOSC) / 250;
+ }
+ else
+ {
+ return cxd56_get_clock(RTC);
+ }
+}
+
+uint32_t cxd56_get_hpadc_baseclock(void)
+{
+ uint32_t divscu;
+
+ divscu = getreg32(CXD56_TOPREG_CKDIV_SCU);
+ return cxd56_get_suc32k_baseclock() / (1 << ((divscu >> 4) & 0xf));
+}
+
+uint32_t cxd56_get_lpadc_baseclock(void)
+{
+ uint32_t divscu;
+
+ divscu = getreg32(CXD56_TOPREG_CKDIV_SCU);
+ return cxd56_get_suc32k_baseclock() / (1 << (divscu & 0xf));
+}
+
+uint32_t cxd56_get_pmui2c_baseclock(void)
+{
+ uint32_t ckpmu;
+
+ ckpmu = getreg32(CXD56_TOPREG_CKSEL_PMU);
+ switch (ckpmu & 0x3)
+ {
+ case 0:
+ return cxd56_get_sys_apb_baseclock();
+ break;
+ case 1:
+ return cxd56_get_clock(RTC);
+ break;
+ case 2:
+ return cxd56_get_clock(RCOSC);
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+uint32_t cxd56_get_gps_cpu_baseclock(void)
+{
+ uint32_t gnssdiv;
+
+ gnssdiv = getreg32(CXD56_TOPREG_GNSS_DIV);
+ return cxd56_get_sys_baseclock() / ((gnssdiv & 0x1f) + 1);
+}
+
+uint32_t cxd56_get_gps_ahb_baseclock(void)
+{
+ uint32_t gnssdiv;
+
+ gnssdiv = getreg32(CXD56_TOPREG_GNSS_DIV);
+ return cxd56_get_sys_baseclock() / (((gnssdiv >> 16) & 0x1f) + 1);
+}
+
+uint32_t cxd56_get_usb_baseclock(void)
+{
+ uint32_t val;
+ int n, m;
+
+ val = getreg32(CXD56_CRG_GEAR_PER_USB);
+ n = (val >> 16) & 1;
+ m = val & 0x3;
+
+ if (m != 0)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+uint32_t cxd56_get_img_vsync_baseclock(void)
+{
+ int n, m;
+
+ n = getreg32(CXD56_CRG_GEAR_N_IMG_VENB);
+ m = getreg32(CXD56_CRG_GEAR_M_IMG_VENB);
+
+ if (n != 0)
+ {
+ return cxd56_get_appsmp_baseclock() * n / m;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+int up_pmramctrl(int cmd, uintptr_t addr, size_t size)
+{
+ int startidx, endidx;
+ int i;
+ uint32_t mode, mask, ctrl, stat;
+ uint32_t val;
+ int changed = 0;
+
+ DEBUGASSERT(cmd == PMCMD_RAM_ON || cmd == PMCMD_RAM_OFF ||
+ cmd == PMCMD_RAM_RET);
+
+ /* Get tile index from address and size. */
+
+ startidx = TILEALIGNIDX(addr);
+ endidx = TILEALIGNIDX(TILEALIGN(addr + size));
+
+ DEBUGASSERT(startidx < 12 && endidx <= 12);
+ pmdbg("%x (size: %x) [%d:%d] -> %d\n", addr, size,
+ startidx, endidx, cmd);
+
+ /* Make controls bits for RAM power control */
+
+ mode = 0;
+ mask = 0;
+ ctrl = 0;
+ for (i = startidx; i < endidx; i++)
+ {
+ mode |= cmd << (i * 2);
+ mask |= 3 << (i * 2);
+ ctrl |= 1 << i;
+ }
+
+ /* Determine mode changes on lower half tiles. */
+
+ stat = getreg32(CXD56_TOPREG_APPDSP_RAMMODE_STAT0);
+ if ((stat & (mask & 0xfff)) != (mode & 0xfff))
+ {
+ val = (ctrl & 0x3f) << 24 | (mode & 0xfff);
+ putreg32(val, CXD56_TOPREG_APPDSP_RAMMODE_SEL0);
+ changed = 1;
+ }
+
+ /* Shift all bits for upper tiles. */
+
+ ctrl >>= 6;
+ mode >>= 12;
+ mask >>= 12;
+
+ /* Determine mode changes on upper half tiles. */
+
+ stat = getreg32(CXD56_TOPREG_APPDSP_RAMMODE_STAT1);
+ if ((stat & (mask & 0xfff)) != (mode & 0xfff))
+ {
+ val = (ctrl & 0x3f) << 24 | (mode & 0xfff);
+ putreg32(val, CXD56_TOPREG_APPDSP_RAMMODE_SEL1);
+ changed = 1;
+ }
+
+ /* Apply RAM tile power status changes */
+
+ if (changed)
+ {
+ do_power_control();
+
+ /* Clock gating for inactive tiles. */
+
+ stat = getreg32(CXD56_TOPREG_APPDSP_RAMMODE_STAT1) << 12;
+ stat |= getreg32(CXD56_TOPREG_APPDSP_RAMMODE_STAT0);
+ val = 0;
+ for (i = 0, mask = 3; i < 12; i++, mask <<= 2)
+ {
+ if ((stat & mask) == 0)
+ {
+ val |= 1 << i;
+ }
+ }
+ putreg32(val, CXD56_CRG_APP_TILE_CLK_GATING_ENB);
+ }
+
+ return OK;
+}
+
+#ifdef CONFIG_DEBUG_PM
+/****************************************************************************
+ * Name: up_pmstatdump
+ *
+ * Description:
+ * Print architecture specific power status
+ *
+ ****************************************************************************/
+
+void up_pmstatdump(void)
+{
+ uint32_t stat0, stat1;
+ const char statch[] = " -?+"; /* OFF, retention, invalid, ON */
+ const char gatech[] = "| "; /* clock on, clock off */
+
+ stat0 = getreg32(CXD56_TOPREG_APPDSP_RAMMODE_STAT0);
+ stat1 = getreg32(CXD56_TOPREG_APPDSP_RAMMODE_STAT1);
+
+ pmdbg(" 0 1 2 3 4 5 6 7 8 9 A B\n");
+ pmdbg("DSP RAM stat: %c %c %c %c %c %c %c %c %c %c %c %c\n",
+ statch[(stat0 >> 0) & 3],
+ statch[(stat0 >> 2) & 3],
+ statch[(stat0 >> 4) & 3],
+ statch[(stat0 >> 6) & 3],
+ statch[(stat0 >> 8) & 3],
+ statch[(stat0 >> 10) & 3],
+ statch[(stat1 >> 0) & 3],
+ statch[(stat1 >> 2) & 3],
+ statch[(stat1 >> 4) & 3],
+ statch[(stat1 >> 6) & 3],
+ statch[(stat1 >> 8) & 3],
+ statch[(stat1 >> 10) & 3]);
+
+ stat0 = getreg32(CXD56_CRG_APP_TILE_CLK_GATING_ENB);
+ pmdbg("Clock gating: %c %c %c %c %c %c %c %c %c %c %c %c\n",
+ gatech[(stat0 >> 0) & 1],
+ gatech[(stat0 >> 1) & 1],
+ gatech[(stat0 >> 2) & 1],
+ gatech[(stat0 >> 3) & 1],
+ gatech[(stat0 >> 4) & 1],
+ gatech[(stat0 >> 5) & 1],
+ gatech[(stat0 >> 6) & 1],
+ gatech[(stat0 >> 7) & 1],
+ gatech[(stat0 >> 8) & 1],
+ gatech[(stat0 >> 9) & 1],
+ gatech[(stat0 >> 10) & 1],
+ gatech[(stat0 >> 11) & 1]);
+}
+#endif
diff --git a/arch/arm/src/cxd56xx/cxd56_clock.h b/arch/arm/src/cxd56xx/cxd56_clock.h
new file mode 100644
index 00000000000..406e7c4a339
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_clock.h
@@ -0,0 +1,711 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_clock.h
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_CLOCK_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_CLOCK_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include "hardware/cxd5602_topreg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_spif_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spif_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_spif_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spif_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_get_cpu_baseclk
+ *
+ * Description:
+ * Get CPU clock.
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_cpu_baseclk(void);
+
+/****************************************************************************
+ * Name: cxd56_cpu_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpu_clock_enable(int cpu);
+
+/****************************************************************************
+ * Name: cxd56_cpulist_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpulist_clock_enable(uint32_t cpus);
+
+/****************************************************************************
+ * Name: cxd56_cpu_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpu_clock_disable(int cpu);
+
+/****************************************************************************
+ * Name: cxd56_cpulist_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpulist_clock_disable(uint32_t cpus);
+
+/****************************************************************************
+ * Name: cxd56_cpu_reset
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpu_reset(int cpu);
+
+/****************************************************************************
+ * Name: cxd56_cpulist_reset
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_cpulist_reset(uint32_t cpus);
+
+/****************************************************************************
+ * Name: cxd56_usb_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_usb_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_usb_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_usb_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_emmc_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_emmc_clock_enable(uint32_t div, uint32_t driver, uint32_t sample);
+
+/****************************************************************************
+ * Name: cxd56_emmc_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_emmc_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_sdio_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_sdio_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_sdio_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_sdio_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_audio_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_audio_clock_enable(uint32_t clk, uint32_t div);
+
+/****************************************************************************
+ * Name: cxd56_audio_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_audio_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_audio_clock_is_enabled
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+bool cxd56_audio_clock_is_enabled(void);
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_enable
+ *
+ * Description:
+ * Enable SPI device clock.
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_enable(int port);
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_disable
+ *
+ * Description:
+ * Disable SPI device clock.
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_disable(int port);
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_gate_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_gate_enable(int port);
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_gate_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_gate_disable(int port);
+
+/****************************************************************************
+ * Name: cxd56_spi_clock_gear_adjust
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_spi_clock_gear_adjust(int port, uint32_t maxfreq);
+
+/****************************************************************************
+ * Name: cxd56_i2c0_clock_enable
+ *
+ * Description:
+ * Enable I2C device clock.
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_enable(int port);
+
+/****************************************************************************
+ * Name: cxd56_i2c_clock_dsiable
+ *
+ * Description:
+ * Disable I2C device clock.
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_disable(int port);
+
+/****************************************************************************
+ * Name: cxd56_i2c_clock_gate_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_gate_enable(int port);
+
+/****************************************************************************
+ * Name: cxd56_i2c_clock_gate_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_i2c_clock_gate_disable(int port);
+
+/****************************************************************************
+ * Name: cxd56_scuseq_is_clock_enabled
+ *
+ * Description:
+ * Get whether Sensor Control Unit Sequencer clock is enabled or not
+ *
+ ****************************************************************************/
+
+bool cxd56_scuseq_clock_is_enabled(void);
+
+/****************************************************************************
+ * Name: cxd56_scuseq_clock_enable
+ *
+ * Description:
+ * Enable Sensor Control Unit Sequencer clock.
+ *
+ ****************************************************************************/
+
+int cxd56_scuseq_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_scuseq_release_reset
+ *
+ * Description:
+ * Release sequencer reset. This function must be call after
+ * cxd56_scuseq_clock_enable() and copy sequencer firmware.
+ *
+ ****************************************************************************/
+
+void cxd56_scuseq_release_reset(void);
+
+/****************************************************************************
+ * Name: cxd56_scuseq_clock_dsiable
+ *
+ * Description:
+ * Disable Sensor Control Unit Sequencer clock.
+ *
+ ****************************************************************************/
+
+void cxd56_scuseq_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_img_uart_clock_enable
+ *
+ * Description:
+ * Enable img uart clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_uart_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_img_uart_clock_dsiable
+ *
+ * Description:
+ * Disable img uart clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_uart_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_get_img_uart_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_img_uart_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_img_cisif_clock_enable
+ *
+ * Description:
+ * Enable cisif clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_cisif_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_img_cisif_clock_dsiable
+ *
+ * Description:
+ * Disable cisif clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_cisif_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_img_ge2d_clock_enable
+ *
+ * Description:
+ * Enable ge2d clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_ge2d_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_img_ge2d_clock_dsiable
+ *
+ * Description:
+ * Disable ge2d clock.
+ *
+ ****************************************************************************/
+
+void cxd56_img_ge2d_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_get_com_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_com_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_sdio_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_sdio_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_spi_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_spi_baseclock(int port);
+
+/****************************************************************************
+ * Name: cxd56_get_i2c_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_i2c_baseclock(int port);
+
+/****************************************************************************
+ * Name: cxd56_get_pwm_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_pwm_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_udmac_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_udmac_clock_enable(void);
+
+/****************************************************************************
+ * Name: cxd56_udmac_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_udmac_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_lpadc_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_lpadc_clock_enable(uint32_t div);
+
+/****************************************************************************
+ * Name: cxd56_lpadc_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_lpadc_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_hpadc_clock_enable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_hpadc_clock_enable(uint32_t div);
+
+/****************************************************************************
+ * Name: cxd56_hpadc_clock_disable
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+void cxd56_hpadc_clock_disable(void);
+
+/****************************************************************************
+ * Name: cxd56_get_xosc_clock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_xosc_clock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_rcosc_clock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_rcosc_clock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_rtc_clock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_rtc_clock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_syspll_clock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_syspll_clock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_sys_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_sys_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_sys_ahb_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_sys_ahb_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_sys_apb_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_sys_apb_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_sys_sfc_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_sys_sfc_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_scu_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_scu_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_hpadc_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_hpadc_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_lpadc_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_lpadc_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_pmui2c_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_pmui2c_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_gps_cpu_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_gps_cpu_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_gps_ahb_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_gps_ahb_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_img_spi_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_img_spi_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_img_wspi_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_img_wspi_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_usb_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_usb_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_img_vsync_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_img_vsync_baseclock(void);
+
+/****************************************************************************
+ * Name: cxd56_get_appsmp_baseclock
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+uint32_t cxd56_get_appsmp_baseclock(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_CLOCK_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_config.h b/arch/arm/src/cxd56xx/cxd56_config.h
new file mode 100644
index 00000000000..1a47f401cbb
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_config.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_config.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56XX_CONFIG_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56XX_CONFIG_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Required configuration settings */
+
+/* Are any UARTs enabled? */
+
+#undef HAVE_UART
+#if defined(CONFIG_CXD56_UART0) || defined(CONFIG_CXD56_UART1) || \
+ defined(CONFIG_CXD56_UART2)
+# define HAVE_UART 1
+#endif
+
+/* Make sure all features are disabled for diabled U[S]ARTs. This simplifies
+ * checking later.
+ */
+
+#ifndef CONFIG_CXD56_UART0
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART0_RS485MODE
+# undef CONFIG_UART0_RS485_DTRDIR
+#endif
+
+#ifndef CONFIG_CXD56_UART1
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# undef CONFIG_UART1_RS485MODE
+# undef CONFIG_UART1_RS485_DTRDIR
+#endif
+
+#ifndef CONFIG_CXD56_UART2
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# undef CONFIG_UART2_RS485MODE
+# undef CONFIG_UART2_RS485_DTRDIR
+#endif
+
+/* Is there a serial console? There should be at most one defined. It could
+ * be on any UARTn, n=0,1,2,3 - OR - there might not be any serial console at
+ * all.
+ */
+
+#if defined(CONFIG_UART0_SERIAL_CONSOLE)
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# undef CONFIG_UART3_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#elif defined(CONFIG_UART1_SERIAL_CONSOLE)
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# undef CONFIG_UART3_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#elif defined(CONFIG_UART2_SERIAL_CONSOLE)
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# undef CONFIG_UART3_SERIAL_CONSOLE
+# define HAVE_CONSOLE 1
+#else
+# undef CONFIG_UART0_SERIAL_CONSOLE
+# undef CONFIG_UART1_SERIAL_CONSOLE
+# undef CONFIG_UART2_SERIAL_CONSOLE
+# undef CONFIG_UART3_SERIAL_CONSOLE
+# undef HAVE_CONSOLE
+#endif
+
+/* Check UART flow control (Only supported by UART1) */
+
+# undef CONFIG_UART0_FLOWCONTROL
+# undef CONFIG_UART2_FLOWCONTROL
+# undef CONFIG_UART3_FLOWCONTROL
+#ifndef CONFIG_CXD56_UART1
+# undef CONFIG_UART1_FLOWCONTROL
+#endif
+
+/* Get Firmware version */
+
+#define GET_SBL_VERSION() (BKUP->sbl_version)
+#define GET_SYSFW_VERSION() (BKUP->sysfw_version)
+#define GET_SYSFW_VERSION_MAJOR() ((GET_SYSFW_VERSION() >> 28) & 0xf)
+#define GET_SYSFW_VERSION_MINOR() ((GET_SYSFW_VERSION() >> 20) & 0xff)
+#define GET_SYSFW_VERSION_BUILD() (GET_SYSFW_VERSION() & 0xfffff)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56XX_CONFIG_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_cpufifo.c b/arch/arm/src/cxd56xx/cxd56_cpufifo.c
new file mode 100644
index 00000000000..b5ec0957e34
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_cpufifo.c
@@ -0,0 +1,262 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_cpufifo.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "up_arch.h"
+
+#include "chip.h"
+#include "hardware/cxd56_cpufifo.h"
+#include "cxd56_cpufifo.h"
+
+/****************************************************************************
+ * Private Definitions
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_CPUFIFO_ENTRIES
+#define NR_PUSHBUFENTRIES CONFIG_CXD56_CPUFIFO_ENTRIES
+#else
+#define NR_PUSHBUFENTRIES 8
+#endif
+
+#define MSGFROM(x) (((x)[0] >> 28) & 0xf)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct cfpushdata_s
+{
+ FAR sq_entry_t entry;
+ uint32_t data[2];
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int cpufifo_txhandler(int irq, FAR void *context, FAR void *arg);
+static int cpufifo_rxhandler(int irq, FAR void *context, FAR void *arg);
+static int cpufifo_trypush(uint32_t data[2]);
+static void cpufifo_reserve(uint32_t data[2]);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+/* Only for SYS, GNSS CPUs */
+
+static sq_queue_t g_pushqueue;
+static sq_queue_t g_emptyqueue;
+static struct cfpushdata_s g_pushbuffer[NR_PUSHBUFENTRIES];
+static cpufifo_handler_t g_cfrxhandler;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int cpufifo_txhandler(int irq, FAR void *context, FAR void *arg)
+{
+ FAR struct cfpushdata_s *pd;
+
+ pd = (FAR struct cfpushdata_s *)sq_remfirst(&g_pushqueue);
+ if (pd)
+ {
+ /* Ignore error because always FIFO is not full at here */
+
+ cpufifo_trypush(pd->data);
+ sq_addlast(&pd->entry, &g_emptyqueue);
+ }
+ if (sq_empty(&g_pushqueue))
+ {
+ up_disable_irq(CXD56_IRQ_FIFO_TO);
+ }
+
+ return OK;
+}
+
+static int cpufifo_rxhandler(int irq, FAR void *context, FAR void *arg)
+{
+ uint32_t word[2] = {0};
+ int cpuid;
+
+ /* Drain from PULL FIFO. But not all data because this handler
+ * will be re-entered when data remaining in PULL FIFO.
+ */
+
+ cxd56_cfpull(word);
+ cpuid = MSGFROM(word);
+
+ DEBUGASSERT(cpuid >= 0 && cpuid < 8);
+
+ if (g_cfrxhandler)
+ {
+ g_cfrxhandler(cpuid, word);
+ }
+
+ return OK;
+}
+
+static int cpufifo_trypush(uint32_t data[2])
+{
+ if (getreg32(CXD56_FIF_PUSH_FULL))
+ {
+ return -1;
+ }
+
+ putreg32(data[0], CXD56_FIF_PUSH_WRD0);
+ putreg32(data[1], CXD56_FIF_PUSH_WRD1);
+ putreg32(1, CXD56_FIF_PUSH_CMP);
+
+ return OK;
+}
+
+static void cpufifo_reserve(uint32_t data[2])
+{
+ FAR struct cfpushdata_s *pd;
+
+ pd = (FAR struct cfpushdata_s *)sq_remfirst(&g_emptyqueue);
+
+ /* This assertion indicate that need more sending buffer, it can be
+ * configured by CONFIG_CXD56_CPUFIFO_ENTRIES.
+ */
+
+ ASSERT(pd);
+
+ pd->data[0] = data[0];
+ pd->data[1] = data[1];
+ sq_addlast(&pd->entry, &g_pushqueue);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int cxd56_cfpush(uint32_t data[2])
+{
+ irqstate_t flags;
+ int ret;
+
+ flags = enter_critical_section();
+ if (!sq_empty(&g_pushqueue))
+ {
+ cpufifo_reserve(data);
+ return OK;
+ }
+
+ ret = cpufifo_trypush(data);
+ if (ret < 0)
+ {
+ cpufifo_reserve(data);
+ up_enable_irq(CXD56_IRQ_FIFO_TO);
+ }
+
+ leave_critical_section(flags);
+
+ return OK;
+}
+
+int cxd56_cfpull(uint32_t data[2])
+{
+ if (getreg32(CXD56_FIF_PULL_EMP))
+ {
+ return -1;
+ }
+
+ data[0] = getreg32(CXD56_FIF_PULL_WRD0);
+ data[1] = getreg32(CXD56_FIF_PULL_WRD1);
+ putreg32(1, CXD56_FIF_PULL_CMP);
+
+ return 0;
+}
+
+int cxd56_cfregrxhandler(cpufifo_handler_t handler)
+{
+ irqstate_t flags;
+ int ret = OK;
+
+ flags = enter_critical_section();
+ if (g_cfrxhandler)
+ {
+ ret = -1;
+ }
+ else
+ {
+ g_cfrxhandler = handler;
+ }
+ leave_critical_section(flags);
+ return ret;
+}
+
+void cxd56_cfunregrxhandler(void)
+{
+ irqstate_t flags;
+ flags = enter_critical_section();
+ g_cfrxhandler = NULL;
+ leave_critical_section(flags);
+}
+
+int cxd56_cfinitialize(void)
+{
+ int i;
+
+ /* Setup IRQ handlers. Enable only FROM (RX) interrupt because TO (TX)
+ * interrupt for retry sending when FIFO is full.
+ */
+
+ irq_attach(CXD56_IRQ_FIFO_FROM, cpufifo_rxhandler, NULL);
+ irq_attach(CXD56_IRQ_FIFO_TO, cpufifo_txhandler, NULL);
+ up_enable_irq(CXD56_IRQ_FIFO_FROM);
+
+ /* Initialize push buffer. */
+
+ sq_init(&g_pushqueue);
+ sq_init(&g_emptyqueue);
+
+ for (i = 0; i < NR_PUSHBUFENTRIES; i++)
+ {
+ sq_addlast((FAR sq_entry_t *)&g_pushbuffer[i], &g_emptyqueue);
+ }
+
+ /* Clear user defined receive handler. */
+
+ g_cfrxhandler = NULL;
+
+ return OK;
+}
diff --git a/arch/arm/src/cxd56xx/cxd56_cpufifo.h b/arch/arm/src/cxd56xx/cxd56_cpufifo.h
new file mode 100644
index 00000000000..af96fd28ecf
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_cpufifo.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_cpufifo.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_CPUFIFO_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_CPUFIFO_H
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+typedef int (*cpufifo_handler_t)(int cpuid, uint32_t data[2]);
+
+int cxd56_cfinitialize(void);
+int cxd56_cfpush(uint32_t data[2]);
+int cxd56_cfpull(uint32_t data[2]);
+int cxd56_cfregrxhandler(cpufifo_handler_t handler);
+void cxd56_cfunregrxhandler(void);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_CPUFIFO_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_gpio.c b/arch/arm/src/cxd56xx/cxd56_gpio.c
new file mode 100644
index 00000000000..e4357774ab5
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_gpio.c
@@ -0,0 +1,299 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_gpio.c
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "cxd56_pinconfig.h"
+#include "cxd56_gpio.h"
+#include "hardware/cxd5602_topreg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* GPIO register Definitions */
+
+#define GPIO_OUTPUT_EN_SHIFT (16)
+#define GPIO_OUTPUT_EN_MASK (1u << GPIO_OUTPUT_EN_SHIFT)
+#define GPIO_OUTPUT_ENABLE (0u << GPIO_OUTPUT_EN_SHIFT)
+#define GPIO_OUTPUT_DISABLE (1u << GPIO_OUTPUT_EN_SHIFT)
+#define GPIO_OUTPUT_ENABLED(v) (((v) & GPIO_OUTPUT_EN_MASK) == GPIO_OUTPUT_ENABLE)
+#define GPIO_OUTPUT_SHIFT (8)
+#define GPIO_OUTPUT_MASK (1u << GPIO_OUTPUT_SHIFT)
+#define GPIO_OUTPUT_HIGH (1u << GPIO_OUTPUT_SHIFT)
+#define GPIO_OUTPUT_LOW (0u << GPIO_OUTPUT_SHIFT)
+#define GPIO_INPUT_SHIFT (0)
+#define GPIO_INPUT_MASK (1u << GPIO_INPUT_SHIFT)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static uint32_t get_gpio_regaddr(uint32_t pin)
+{
+ uint32_t base;
+
+ base = (pin < PIN_IS_CLK) ? 1 : 7;
+
+ return CXD56_TOPREG_GP_I2C4_BCK + ((pin - base) * 4);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_gpio_config
+ *
+ * Description:
+ * Configure a GPIO which input is enabled or not.
+ * Output is enabled when cxd56_gpio_write() is called.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_gpio_config(uint32_t pin, bool input_enable)
+{
+ int ret = 0;
+ uint32_t pinconf;
+ uint32_t regaddr;
+ uint32_t ioreg;
+ uint32_t ioval;
+
+ DEBUGASSERT((PIN_I2C4_BCK <= pin) && (pin <= PIN_USB_VBUSINT));
+ DEBUGASSERT((pin <= PIN_GNSS_1PPS_OUT) || (PIN_SPI0_CS_X <= pin));
+ DEBUGASSERT((pin <= PIN_HIF_GPIO0) || (PIN_SEN_IRQ_IN <= pin));
+ DEBUGASSERT((pin <= PIN_PWM3) || (PIN_IS_CLK <= pin));
+
+ ioreg = CXD56_TOPREG_IO_RTC_CLK_IN + (pin * 4);
+ ioval = getreg32(ioreg);
+
+ if (input_enable)
+ {
+ pinconf = PINCONF_SET(pin, PINCONF_MODE0, PINCONF_INPUT_ENABLE,
+ ioval & PINCONF_DRIVE_MASK,
+ ioval & PINCONF_PULL_MASK);
+ }
+ else
+ {
+ pinconf = PINCONF_SET(pin, PINCONF_MODE0, PINCONF_INPUT_DISABLE,
+ ioval & PINCONF_DRIVE_MASK,
+ ioval & PINCONF_PULL_MASK);
+ }
+
+ ret = cxd56_pin_config(pinconf);
+
+ /* output disabled */
+
+ regaddr = get_gpio_regaddr(pin);
+ putreg32(GPIO_OUTPUT_DISABLE, regaddr);
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_gpio_write
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpio_write(uint32_t pin, bool value)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+
+ DEBUGASSERT((PIN_I2C4_BCK <= pin) && (pin <= PIN_USB_VBUSINT));
+ DEBUGASSERT((pin <= PIN_GNSS_1PPS_OUT) || (PIN_SPI0_CS_X <= pin));
+ DEBUGASSERT((pin <= PIN_HIF_GPIO0) || (PIN_SEN_IRQ_IN <= pin));
+ DEBUGASSERT((pin <= PIN_PWM3) || (PIN_IS_CLK <= pin));
+
+ regaddr = get_gpio_regaddr(pin);
+
+ if (value)
+ {
+ regval = GPIO_OUTPUT_ENABLE | GPIO_OUTPUT_HIGH;
+ }
+ else
+ {
+ regval = GPIO_OUTPUT_ENABLE | GPIO_OUTPUT_LOW;
+ }
+
+ putreg32(regval, regaddr);
+}
+
+/****************************************************************************
+ * Name: cxd56_gpio_write_hiz
+ *
+ * Description:
+ * Write HiZ to the selected opendrain GPIO pin
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpio_write_hiz(uint32_t pin)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+
+ DEBUGASSERT((PIN_I2C4_BCK <= pin) && (pin <= PIN_USB_VBUSINT));
+ DEBUGASSERT((pin <= PIN_GNSS_1PPS_OUT) || (PIN_SPI0_CS_X <= pin));
+ DEBUGASSERT((pin <= PIN_HIF_GPIO0) || (PIN_SEN_IRQ_IN <= pin));
+ DEBUGASSERT((pin <= PIN_PWM3) || (PIN_IS_CLK <= pin));
+
+ regaddr = get_gpio_regaddr(pin);
+
+ regval = GPIO_OUTPUT_DISABLE;
+
+ putreg32(regval, regaddr);
+}
+
+/****************************************************************************
+ * Name: cxd56_gpio_read
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ * Returned Value:
+ * The boolean state of the input pin
+ *
+ ****************************************************************************/
+
+bool cxd56_gpio_read(uint32_t pin)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t shift;
+ uint32_t ioreg;
+ uint32_t ioval;
+
+ DEBUGASSERT((PIN_I2C4_BCK <= pin) && (pin <= PIN_USB_VBUSINT));
+ DEBUGASSERT((pin <= PIN_GNSS_1PPS_OUT) || (PIN_SPI0_CS_X <= pin));
+ DEBUGASSERT((pin <= PIN_HIF_GPIO0) || (PIN_SEN_IRQ_IN <= pin));
+ DEBUGASSERT((pin <= PIN_PWM3) || (PIN_IS_CLK <= pin));
+
+ regaddr = get_gpio_regaddr(pin);
+ regval = getreg32(regaddr);
+
+ ioreg = CXD56_TOPREG_IO_RTC_CLK_IN + (pin * 4);
+ ioval = getreg32(ioreg);
+
+ if (PINCONF_INPUT_ENABLED(ioval))
+ {
+ shift = GPIO_INPUT_SHIFT;
+ }
+ else if (GPIO_OUTPUT_ENABLED(regval))
+ {
+ shift = GPIO_OUTPUT_SHIFT;
+ }
+ else
+ {
+ shift = GPIO_INPUT_SHIFT;
+ }
+
+ return ((regval & (1 << shift)) != 0);
+}
+
+/********************************************************************************************
+ * Name: cxd56_gpio_status
+ *
+ * Description:
+ * Get a gpio status which input/output is enabled or not.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_gpio_status(uint32_t pin, cxd56_gpio_status_t *stat)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ uint32_t ioreg;
+ uint32_t ioval;
+
+ if ((pin < PIN_I2C4_BCK) ||
+ ((PIN_GNSS_1PPS_OUT < pin) && (pin < PIN_SPI0_CS_X)) ||
+ ((PIN_HIF_GPIO0 < pin) && (pin < PIN_SEN_IRQ_IN)) ||
+ ((PIN_PWM3 < pin) && (pin < PIN_IS_CLK)) ||
+ (PIN_USB_VBUSINT < pin))
+ {
+ return -EINVAL;
+ }
+
+ ioreg = CXD56_TOPREG_IO_RTC_CLK_IN + (pin * 4);
+ ioval = getreg32(ioreg);
+
+ regaddr = get_gpio_regaddr(pin);
+ regval = getreg32(regaddr);
+
+ stat->input_en = PINCONF_INPUT_ENABLED(ioval);
+ stat->output_en = GPIO_OUTPUT_ENABLED(regval);
+
+ return 0;
+}
diff --git a/arch/arm/src/cxd56xx/cxd56_gpio.h b/arch/arm/src/cxd56xx/cxd56_gpio.h
new file mode 100644
index 00000000000..a94df810e18
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_gpio.h
@@ -0,0 +1,158 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_gpio.h
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_GPIO_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_GPIO_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include
+#include
+
+#include "cxd56_pinconfig.h"
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+struct cxd56_gpio_status_s
+{
+ bool input_en;
+ bool output_en;
+};
+
+typedef struct cxd56_gpio_status_s cxd56_gpio_status_t;
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Name: cxd56_gpio_config
+ *
+ * Description:
+ * Configure a GPIO which input is enabled or not.
+ * Output is enabled when cxd56_gpio_write() is called.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_gpio_config(uint32_t pin, bool input_enable);
+
+/********************************************************************************************
+ * Name: cxd56_gpio_write
+ *
+ * Description:
+ * Write one or zero to the selected GPIO pin
+ *
+ * Returned Value:
+ * None
+ *
+ ********************************************************************************************/
+
+void cxd56_gpio_write(uint32_t pin, bool value);
+
+/********************************************************************************************
+ * Name: cxd56_gpio_write_hiz
+ *
+ * Description:
+ * Output HiZ to the selected opendrain GPIO pin
+ *
+ * Returned Value:
+ * None
+ *
+ ********************************************************************************************/
+
+void cxd56_gpio_write_hiz(uint32_t pin);
+
+/********************************************************************************************
+ * Name: cxd56_gpio_read
+ *
+ * Description:
+ * Read one or zero from the selected GPIO pin
+ *
+ * Returned Value:
+ * The boolean state of the input pin
+ *
+ ********************************************************************************************/
+
+bool cxd56_gpio_read(uint32_t pin);
+
+/********************************************************************************************
+ * Name: cxd56_gpio_status
+ *
+ * Description:
+ * Get a gpio status which input/output is enabled or not.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_gpio_status(uint32_t pin, cxd56_gpio_status_t *stat);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_GPIO_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_gpioint.c b/arch/arm/src/cxd56xx/cxd56_gpioint.c
new file mode 100644
index 00000000000..fed9d517868
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_gpioint.c
@@ -0,0 +1,657 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_gpioint.c
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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
+#include
+
+#include
+
+#include
+#include
+
+#include "up_arch.h"
+#include "chip.h"
+
+#include "cxd56_pinconfig.h"
+#include "cxd56_gpio.h"
+#include "cxd56_gpioint.h"
+#include "hardware/cxd5602_topreg.h"
+
+#ifdef CONFIG_CXD56_GPIO_IRQ
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* GPIO Interrupt Polarity Definitions */
+
+#define GPIOINT_POLARITY_SHIFT (0)
+#define GPIOINT_POLARITY_MASK (7)
+#define GPIOINT_GET_POLARITY(v) (((v) & GPIOINT_POLARITY_MASK) >> GPIOINT_POLARITY_SHIFT)
+#define GPIOINT_SET_POLARITY(v) (((v) << GPIOINT_POLARITY_SHIFT) & GPIOINT_POLARITY_MASK)
+#define GPIOINT_IS_LEVEL(v) (GPIOINT_GET_POLARITY(v) <= GPIOINT_LEVEL_LOW)
+#define GPIOINT_IS_EDGE(v) (GPIOINT_EDGE_RISE <= GPIOINT_GET_POLARITY(v))
+#define GPIOINT_IS_HIGH(v) ((GPIOINT_LEVEL_HIGH == GPIOINT_GET_POLARITY(v)) || \
+ (GPIOINT_EDGE_RISE == GPIOINT_GET_POLARITY(v)))
+#define GPIOINT_IS_LOW(v) ((GPIOINT_LEVEL_LOW == GPIOINT_GET_POLARITY(v)) || \
+ (GPIOINT_EDGE_FALL == GPIOINT_GET_POLARITY(v)))
+
+/* GPIO Interrupt Noise Filter Definitions */
+
+#define GPIOINT_NOISE_FILTER_SHIFT (3)
+#define GPIOINT_NOISE_FILTER_MASK (1u << GPIOINT_NOISE_FILTER_SHIFT)
+#define GPIOINT_NOISE_FILTER_ENABLED(v) (((v) & GPIOINT_NOISE_FILTER_MASK) \
+ == GPIOINT_NOISE_FILTER_ENABLE)
+
+/* Use Pseudo Edge Interrupt */
+
+#define GPIOINT_TOGGLE_MODE_SHIFT (16)
+
+/* GPIO Interrupt Index Number Definitions */
+
+#define MAX_SLOT (12)
+#define MAX_SYS_SLOT (6)
+#define INTSEL_DEFAULT_VAL (63)
+
+#define GET_SLOT2IRQ(slot) (CXD56_IRQ_EXDEVICE_0 + (slot))
+#define GET_IRQ2SLOT(irq) ((irq) - CXD56_IRQ_EXDEVICE_0)
+
+/* PMU_WAKE_TRIG_CPUINTSELx */
+
+#define INT_ROUTE_THROUGH (0)
+#define INT_ROUTE_INVERTER (1)
+#define INT_ROUTE_PMU (2)
+#define INT_ROUTE_PMU_LATCH (3)
+
+#define CXD56_INTC_ENABLE (CXD56_INTC_BASE + 0x10)
+#define CXD56_INTC_INVERT (CXD56_INTC_BASE + 0x20)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static xcpt_t g_isr[MAX_SLOT];
+static uint32_t g_bothedge = 0;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* allocate/deallocate/get slot number (SYS: 0~5, APP: 6~11) */
+
+static int alloc_slot(int pin, bool isalloc)
+{
+ irqstate_t flags;
+ int alloc = -1;
+ int slot;
+ uint8_t val;
+ uint32_t base = (pin < PIN_IS_CLK) ? CXD56_TOPREG_IOCSYS_INTSEL0
+ : CXD56_TOPREG_IOCAPP_INTSEL0;
+ int offset = (pin < PIN_IS_CLK) ? 1 : 56;
+
+ flags = enter_critical_section();
+
+ for (slot = 0; slot < MAX_SYS_SLOT; slot++)
+ {
+ val = getreg8(base + slot);
+ if ((pin - offset) == val)
+ {
+ if (isalloc == false)
+ {
+ putreg8(INTSEL_DEFAULT_VAL, base + slot);
+ }
+ break; /* already used */
+ }
+ if ((-1 == alloc) && (INTSEL_DEFAULT_VAL == val))
+ {
+ alloc = slot;
+ }
+ }
+
+ if (slot == MAX_SYS_SLOT)
+ {
+ if (isalloc && (-1 != alloc))
+ {
+ slot = alloc;
+ putreg8(pin - offset, base + slot);
+ }
+ else
+ {
+ leave_critical_section(flags);
+ return -ENXIO; /* no space */
+ }
+ }
+
+ leave_critical_section(flags);
+
+ if (PIN_IS_CLK <= pin)
+ {
+ slot += MAX_SYS_SLOT;
+ }
+
+ return slot;
+}
+
+/* convert from slot to pin */
+
+static int get_slot2pin(int slot)
+{
+ uint32_t base = (slot < MAX_SYS_SLOT) ? CXD56_TOPREG_IOCSYS_INTSEL0
+ : CXD56_TOPREG_IOCAPP_INTSEL0;
+ int offset = 1;
+
+ if (MAX_SYS_SLOT <= slot)
+ {
+ slot -= MAX_SYS_SLOT;
+ offset = 56;
+ }
+
+ return (int)getreg8(base + slot) + offset;
+}
+
+/* convert from pin to slot number (SYS: 0~5, APP: 6~11) */
+
+static int get_pin2slot(int pin)
+{
+ int slot;
+ uint32_t base = (pin < PIN_IS_CLK) ? CXD56_TOPREG_IOCSYS_INTSEL0
+ : CXD56_TOPREG_IOCAPP_INTSEL0;
+ int offset = (pin < PIN_IS_CLK) ? 1 : 56;
+
+ for (slot = 0; slot < MAX_SYS_SLOT; slot++)
+ {
+ if ((pin - offset) == getreg8(base + slot)) /* byte access */
+ {
+ break;
+ }
+ }
+
+ if (slot == MAX_SYS_SLOT)
+ {
+ return -1;
+ }
+
+ if (PIN_IS_CLK <= pin)
+ {
+ slot += MAX_SYS_SLOT;
+ }
+
+ return slot;
+}
+
+/* convert from pin to irq number */
+
+static int get_pin2irq(int pin)
+{
+ int slot = get_pin2slot(pin);
+
+ if ((0 <= slot) && (slot < MAX_SLOT))
+ {
+ return GET_SLOT2IRQ(slot);
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+/* set GPIO interrupt configuration registers */
+
+static int set_gpioint_config(int slot, uint32_t gpiocfg)
+{
+ uint32_t val;
+ uint32_t shift;
+ uint32_t polreg = CXD56_TOPREG_PMU_WAKE_TRIG_INTDET0;
+ uint32_t selreg = CXD56_TOPREG_PMU_WAKE_TRIG_CPUINTSEL0;
+
+ /* Configure the noise filter */
+
+ val = getreg32(CXD56_TOPREG_PMU_WAKE_TRIG_NOISECUTEN0);
+ if (GPIOINT_NOISE_FILTER_ENABLED(gpiocfg))
+ {
+ val |= (1 << (slot + 16));
+ }
+ else
+ {
+ val &= ~(1 << (slot + 16));
+ }
+ putreg32(val, CXD56_TOPREG_PMU_WAKE_TRIG_NOISECUTEN0);
+
+ /* Configure the polarity */
+
+ shift = 16 + (slot * 4);
+ if (32 <= shift)
+ {
+ polreg = CXD56_TOPREG_PMU_WAKE_TRIG_INTDET1;
+ selreg = CXD56_TOPREG_PMU_WAKE_TRIG_CPUINTSEL1;
+ shift -= 32;
+ }
+
+ val = getreg32(polreg);
+ val &= ~(0x7 << shift);
+ val |= (GPIOINT_GET_POLARITY(gpiocfg) << shift);
+ putreg32(val, polreg);
+
+ /* Configure the interrupt route */
+
+ val = getreg32(selreg);
+ val &= ~(0x7 << shift);
+
+ switch (GPIOINT_GET_POLARITY(gpiocfg))
+ {
+ case GPIOINT_LEVEL_HIGH:
+ if (GPIOINT_NOISE_FILTER_ENABLED(gpiocfg))
+ {
+ val |= (INT_ROUTE_PMU << shift);
+ }
+ else
+ {
+ val |= (INT_ROUTE_THROUGH << shift);
+ }
+ break;
+ case GPIOINT_LEVEL_LOW:
+ if (GPIOINT_NOISE_FILTER_ENABLED(gpiocfg))
+ {
+ val |= (INT_ROUTE_PMU << shift);
+ }
+ else
+ {
+ val |= (INT_ROUTE_INVERTER << shift);
+ }
+ break;
+ case GPIOINT_EDGE_RISE:
+ case GPIOINT_EDGE_FALL:
+ case GPIOINT_EDGE_BOTH:
+ val |= (INT_ROUTE_PMU_LATCH << shift);
+ break;
+ default:
+ DEBUGASSERT(0);
+ break;
+ }
+ putreg32(val, selreg);
+
+ return 0;
+}
+
+/* Invert interrupt polarity in INTC */
+
+static void invert_irq(int irq)
+{
+ irqstate_t flags;
+ uint32_t val;
+
+ flags = enter_critical_section();
+
+ val = getreg32(CXD56_INTC_INVERT);
+ val ^= (1 << (irq - CXD56_IRQ_EXTINT));
+ putreg32(val, CXD56_INTC_INVERT);
+
+ leave_critical_section(flags);
+}
+
+static bool inverted_irq(int irq)
+{
+ uint32_t val;
+
+ val = getreg32(CXD56_INTC_INVERT);
+ return ((val & (1 << (irq - CXD56_IRQ_EXTINT))) != 0);
+}
+
+static bool enabled_irq(int irq)
+{
+ uint32_t val;
+
+ val = getreg32(CXD56_INTC_ENABLE);
+ return ((val & (1 << (irq - CXD56_IRQ_EXTINT))) != 0);
+}
+
+static int gpioint_handler(int irq, FAR void *context, FAR void *arg)
+{
+ uint32_t val;
+ uint32_t shift;
+ uint32_t polreg = CXD56_TOPREG_PMU_WAKE_TRIG_INTDET0;
+ int slot = GET_IRQ2SLOT(irq);
+
+ /* Invert mask of interrupt to be disable temporarily */
+
+ invert_irq(irq);
+
+ if (g_bothedge & (1 << slot))
+ {
+ g_isr[slot](irq, context, arg);
+ return 0;
+ }
+
+ /* Get the polarity */
+
+ shift = 16 + (slot * 4);
+ if (32 <= shift)
+ {
+ polreg = CXD56_TOPREG_PMU_WAKE_TRIG_INTDET1;
+ shift -= 32;
+ }
+
+ val = getreg32(polreg);
+ val = (val >> shift) & 0x7;
+
+ if (inverted_irq(irq))
+ {
+ /* Clear edge interrupt */
+
+ if (GPIOINT_IS_EDGE(val))
+ {
+ /* TBD: ignore access protection */
+
+ putreg32(1 << (slot + 16), CXD56_TOPREG_PMU_WAKE_TRIG0_CLR);
+ }
+
+ g_isr[slot](irq, context, arg);
+ }
+
+ return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_gpioint_config
+ *
+ * Description:
+ * Configure a GPIO pin as an GPIO pin interrupt source
+ *
+ * Input Parameters:
+ * pin - Pin number defined in cxd56_pinconfig.h
+ * gpiocfg - GPIO Interrupt Polarity and Noise Filter Configuration Value
+ * isr - Interrupt handler. If isr is NULL, then free an allocated handler.
+ *
+ * Returned Value:
+ * IRQ number on success; a negated errno value on failure.
+ *
+ * Assumptions:
+ * The interrupt are disabled so that read-modify-write operations are safe.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_config(uint32_t pin, uint32_t gpiocfg, xcpt_t isr)
+{
+ int slot;
+ int irq;
+ irqstate_t flags;
+
+ slot = alloc_slot(pin, (isr != NULL));
+ if (slot < 0)
+ {
+ return -ENXIO;
+ }
+
+ irq = GET_SLOT2IRQ(slot);
+
+ if (isr == NULL)
+ {
+ /* disable GPIO input */
+
+ cxd56_gpio_config(pin, false);
+
+ /* disable interrupt */
+
+ irq_attach(irq, NULL, NULL);
+ g_isr[slot] = NULL;
+
+ flags = enter_critical_section();
+ g_bothedge &= ~(1 << slot);
+ leave_critical_section(flags);
+ return irq;
+ }
+
+ /* enable GPIO input */
+
+ cxd56_gpio_config(pin, true);
+
+ /* set GPIO interrupt configuration */
+
+ if (gpiocfg & GPIOINT_TOGGLE_BOTH_MASK) {
+
+ /* set GPIO pseudo both edge interrupt */
+
+ flags = enter_critical_section();
+ g_bothedge |= (1 << slot);
+ leave_critical_section(flags);
+
+ /* detect the change from the current signal */
+
+ if (true == cxd56_gpio_read(pin)) {
+ gpiocfg |= GPIOINT_SET_POLARITY(GPIOINT_LEVEL_LOW);
+ } else {
+ gpiocfg |= GPIOINT_SET_POLARITY(GPIOINT_LEVEL_HIGH);
+ }
+ }
+
+ set_gpioint_config(slot, gpiocfg);
+
+ if ((gpiocfg & GPIOINT_TOGGLE_MODE_MASK) || GPIOINT_IS_EDGE(gpiocfg))
+ {
+ irq_attach(irq, gpioint_handler, (void *)pin); /* call intermediate handler */
+ g_isr[slot] = isr;
+ }
+ else
+ {
+ irq_attach(irq, isr, (void *)pin); /* call user handler directly */
+ g_isr[slot] = NULL;
+ }
+
+ return irq;
+}
+
+/****************************************************************************
+ * Name: cxd56_gpioint_irq
+ *
+ * Description:
+ * Get a GPIO interrupt number for specified pin number
+ *
+ * Returned Value:
+ * IRQ number on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_irq(uint32_t pin)
+{
+ return get_pin2irq(pin);
+}
+
+/****************************************************************************
+ * Name: cxd56_gpioint_pin
+ *
+ * Description:
+ * Get a pin number for specified IRQ number
+ *
+ * Returned Value:
+ * Pin number on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_pin(int irq)
+{
+ int slot;
+
+ if ((irq < CXD56_IRQ_EXDEVICE_0) || (CXD56_IRQ_EXDEVICE_11 < irq))
+ {
+ return -1;
+ }
+ slot = GET_IRQ2SLOT(irq);
+ return get_slot2pin(slot);
+}
+
+/****************************************************************************
+ * Name: cxd56_gpioint_enable
+ *
+ * Description:
+ * Enable a GPIO interrupt for specified pin number
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpioint_enable(uint32_t pin)
+{
+ int irq = get_pin2irq(pin);
+
+ if (irq > 0)
+ {
+ up_enable_irq(irq);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_gpioint_disable
+ *
+ * Description:
+ * Disable a GPIO interrupt for specified pin number
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpioint_disable(uint32_t pin)
+{
+ int irq = get_pin2irq(pin);
+
+ if (irq > 0)
+ {
+ up_disable_irq(irq);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_gpioint_invert
+ *
+ * Description:
+ * Invert polarity of a GPIO interrupt for specified pin number
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpioint_invert(uint32_t pin)
+{
+ int irq = get_pin2irq(pin);
+
+ if (irq > 0)
+ {
+ invert_irq(irq);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_gpioint_status
+ *
+ * Description:
+ * Get a gpio interrupt status
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_status(uint32_t pin, cxd56_gpioint_status_t *stat)
+{
+ uint32_t val;
+ uint32_t shift;
+ uint32_t polreg = CXD56_TOPREG_PMU_WAKE_TRIG_INTDET0;
+ int slot;
+
+ DEBUGASSERT(stat);
+
+ /* Get IRQ number */
+
+ stat->irq = cxd56_gpioint_irq(pin);
+
+ if (stat->irq < 0)
+ {
+ return -EINVAL;
+ }
+
+ /* Get polarity */
+
+ slot = GET_IRQ2SLOT(stat->irq);
+ shift = 16 + (slot * 4);
+ if (32 <= shift)
+ {
+ polreg = CXD56_TOPREG_PMU_WAKE_TRIG_INTDET1;
+ shift -= 32;
+ }
+
+ val = getreg32(polreg);
+ stat->polarity = GPIOINT_GET_POLARITY(val >> shift);
+
+ /* Replace for pseudo edge */
+
+ if ((g_isr[slot]) && (stat->polarity == GPIOINT_LEVEL_HIGH))
+ {
+ stat->polarity = GPIOINT_EDGE_RISE;
+ }
+ if ((g_isr[slot]) && (stat->polarity == GPIOINT_LEVEL_LOW))
+ {
+ stat->polarity = GPIOINT_EDGE_FALL;
+ }
+ if ((g_isr[slot]) && (g_bothedge & (1 << slot)))
+ {
+ stat->polarity = GPIOINT_EDGE_BOTH;
+ }
+
+ /* Get noise filter enabled or not */
+
+ val = getreg32(CXD56_TOPREG_PMU_WAKE_TRIG_NOISECUTEN0);
+ stat->filter = ((val >> (slot + 16)) & 1) ? true : false;
+
+ /* Get interrupt enabled or not */
+
+ stat->enable = enabled_irq(stat->irq);
+
+ return OK;
+}
+
+#endif /* CONFIG_CXD56_GPIO_IRQ */
diff --git a/arch/arm/src/cxd56xx/cxd56_gpioint.h b/arch/arm/src/cxd56xx/cxd56_gpioint.h
new file mode 100644
index 00000000000..8f198b1fe36
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_gpioint.h
@@ -0,0 +1,233 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_gpioint.h
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_GPIOINT_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_GPIOINT_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include "chip.h"
+
+#ifdef CONFIG_CXD56_GPIO_IRQ
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* 32-bit encoded gpioconf value
+ *
+ * 3322 2222 2222 1111 1111 1100 0000 0000
+ * 1098 7654 3210 9876 5432 1098 7654 3210
+ * ---- ---- ---- ---- ---- ---- ---- ----
+ * .... .... .... ..B. .... .... .... .... Both detect mode
+ * .... .... .... ...T .... .... .... .... Toggle detect mode
+ * .... .... .... .... .... .... .... N... Noise Filter
+ * .... .... .... .... .... .... .... .YYY Polarity
+ */
+
+/* GPIO Interrupt Polarity Definitions */
+
+//#define GPIOINT_INSTANT_HIGH (0) /* Not supported */
+//#define GPIOINT_INSTANT_LOW (1) /* Not supported */
+#define GPIOINT_LEVEL_HIGH (2) /* High Level */
+#define GPIOINT_LEVEL_LOW (3) /* Low Level */
+#define GPIOINT_EDGE_RISE (4) /* Rising Edge */
+#define GPIOINT_EDGE_FALL (5) /* Falling Edge */
+#define GPIOINT_EDGE_BOTH (7) /* Both Edge */
+#define GPIOINT_PSEUDO_EDGE_RISE (GPIOINT_LEVEL_HIGH | \
+ GPIOINT_TOGGLE_MODE_MASK)
+ /* Rising Edge without clear */
+#define GPIOINT_PSEUDO_EDGE_FALL (GPIOINT_LEVEL_LOW | \
+ GPIOINT_TOGGLE_MODE_MASK)
+ /* Falling Edge without clear */
+#define GPIOINT_PSEUDO_EDGE_BOTH (GPIOINT_TOGGLE_MODE_MASK | \
+ GPIOINT_TOGGLE_BOTH_MASK)
+ /* Both Edge without clear */
+
+/* GPIO Interrupt Noise Filter Definitions */
+
+#define GPIOINT_NOISE_FILTER_ENABLE (1u << 3)
+#define GPIOINT_NOISE_FILTER_DISABLE (0u << 3)
+
+/* Use Pseudo Edge Interrupt */
+
+#define GPIOINT_TOGGLE_MODE_MASK (1u << 16)
+#define GPIOINT_TOGGLE_BOTH_MASK (1u << 17)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct cxd56_gpioint_status_s
+{
+ int irq;
+ uint32_t polarity;
+ bool filter;
+ bool enable;
+};
+
+typedef struct cxd56_gpioint_status_s cxd56_gpioint_status_t;
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_gpioint_config
+ *
+ * Description:
+ * Configure a GPIO pin as an GPIO pin interrupt source
+ *
+ * Input Parameters:
+ * pin - Pin number defined in cxd56_pinconfig.h
+ * gpiocfg - GPIO Interrupt Polarity and Noise Filter Configuration Value
+ * isr - Interrupt handler
+ *
+ * Returned Value:
+ * IRQ number on success; a negated errno value on failure.
+ *
+ * Assumptions:
+ * The interrupt are disabled so that read-modify-write operations are safe.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_config(uint32_t pin, uint32_t gpiocfg, xcpt_t isr);
+
+/****************************************************************************
+ * Name: cxd56_gpioint_irq
+ *
+ * Description:
+ * Get a GPIO interrupt number for specified pin number
+ *
+ * Returned Value:
+ * IRQ number on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_irq(uint32_t pin);
+
+/****************************************************************************
+ * Name: cxd56_gpioint_pin
+ *
+ * Description:
+ * Get a pin number for specified IRQ number
+ *
+ * Returned Value:
+ * Pin number on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_gpioint_pin(int irq);
+
+/****************************************************************************
+ * Name: cxd56_gpioint_enable
+ *
+ * Description:
+ * Enable a GPIO interrupt for specified pin number
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpioint_enable(uint32_t pin);
+
+/****************************************************************************
+ * Name: cxd56_gpioint_disable
+ *
+ * Description:
+ * Disable a GPIO interrupt for specified pin number
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpioint_disable(uint32_t pin);
+
+/****************************************************************************
+ * Name: cxd56_gpioint_invert
+ *
+ * Description:
+ * Invert polarity of a GPIO interrupt for specified pin number
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_gpioint_invert(uint32_t pin);
+
+/********************************************************************************************
+ * Name: cxd56_gpioint_status
+ *
+ * Description:
+ * Get a gpio interrupt status
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_gpioint_status(uint32_t pin, cxd56_gpioint_status_t *stat);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_CXD56_GPIO_IRQ */
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_GPIOINT_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_icc.c b/arch/arm/src/cxd56xx/cxd56_icc.c
new file mode 100644
index 00000000000..a7dc5b17df4
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_icc.c
@@ -0,0 +1,653 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_icc.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "up_arch.h"
+#include "chip.h"
+#include "cxd56_cpufifo.h"
+#include "cxd56_icc.h"
+
+#ifdef CONFIG_CXD56_ICC
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifndef CONFIG_CXD56_CPUFIFO_NBUFFERS
+# define NBUFFERS 4
+#else
+# define NBUFFERS CONFIG_CXD56_CPUFIFO_NBUFFERS
+#endif
+
+#define NPROTOCOLS 16
+#define GET_PROTOCOLID(w) (((w)[0] >> 24) & 0xf)
+
+#define NCPUS 8
+
+#define FLAG_TIMEOUT (1 << 0)
+
+#define IS_SIGNAL(w) (((((w)[0]) >> 24) & 0xf) == CXD56_PROTO_SIG)
+
+#ifdef CONFIG_CXD56_ICC_DEBUG
+# define iccerr(fmt, ...) _err(fmt, ##__VA_ARGS__)
+# define iccinfo(fmt, ...) _info(fmt, ##__VA_ARGS__)
+#else
+# define iccerr(fmt, ...)
+# define iccinfo(fmt, ...)
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct iccmsg_msg_s
+{
+ /* Little endian */
+
+ uint16_t pdata;
+ uint8_t msgid;
+ uint8_t proto: 4;
+ uint8_t cpuid: 4;
+
+ uint32_t data;
+};
+
+struct iccreq_s
+{
+ sq_entry_t entry;
+
+ union
+ {
+ uint32_t word[2];
+ struct iccmsg_msg_s msg;
+ };
+};
+
+struct iccdev_s
+{
+ union
+ {
+ cxd56_icchandler_t handler;
+ cxd56_iccsighandler_t sighandler;
+ } u;
+
+ FAR void *userdata;
+ sem_t rxwait;
+ WDOG_ID rxtimeout;
+
+ int flags;
+
+ /* for POSIX signal */
+
+ int signo;
+ int pid;
+ FAR void *sigdata;
+
+ struct sq_queue_s recvq;
+ struct sq_queue_s freelist;
+ struct iccreq_s pool[NBUFFERS];
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int icc_sighandler(int cpuid, int protoid, uint32_t pdata,
+ uint32_t data, FAR void *userdata);
+static int icc_msghandler(int cpuid, int protoid, uint32_t pdata,
+ uint32_t data, FAR void *userdata);
+static int icc_irqhandler(int cpuid, uint32_t word[2]);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct iccdev_s *g_protocol[NPROTOCOLS];
+static struct iccdev_s *g_cpumsg[NCPUS];
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void icc_semtake(sem_t *semid)
+{
+ while (sem_wait(semid) != 0)
+ {
+ ASSERT(errno == EINTR);
+ }
+}
+
+static void icc_semgive(sem_t *semid)
+{
+ sem_post(semid);
+}
+
+static FAR struct iccdev_s *icc_getprotocol(int protoid)
+{
+ if (protoid < 0 || protoid >= NPROTOCOLS)
+ {
+ return NULL;
+ }
+ return g_protocol[protoid];
+}
+
+static FAR struct iccdev_s *icc_getcpu(int cpuid)
+{
+ if (cpuid < 0 || cpuid >= NCPUS)
+ {
+ return NULL;
+ }
+ return g_cpumsg[cpuid];
+}
+
+static int icc_irqhandler(int cpuid, uint32_t word[2])
+{
+ FAR struct iccdev_s *priv;
+ FAR struct iccreq_s *req;
+ int protoid;
+
+ protoid = GET_PROTOCOLID(word);
+ priv = icc_getprotocol(protoid);
+ if (!priv)
+ {
+ /* Nobody waits this message... */
+
+ iccerr("nobody waits %08x %08x\n", word[0], word[1]);
+ return OK;
+ }
+
+ /* If handler has been registered, then call it. */
+
+ if (priv->u.handler)
+ {
+ int ret;
+
+ ret = priv->u.handler(cpuid, protoid, word[0] & 0xffffff, word[1],
+ priv->userdata);
+ if (ret == OK)
+ {
+ return OK;
+ }
+ }
+
+ /* If MSG protocol, then replace priv to cpu ones. */
+
+ if (protoid == CXD56_PROTO_MSG)
+ {
+ priv = icc_getcpu(cpuid);
+ if (!priv)
+ {
+ iccerr("nobody waits from CPU %d\n", cpuid);
+ return OK;
+ }
+ }
+
+ req = (FAR struct iccreq_s *)sq_remfirst(&priv->freelist);
+ if (!req)
+ {
+ iccerr("Receive buffer is full.\n");
+ return -ENOMEM;
+ }
+
+ req->word[0] = word[0];
+ req->word[1] = word[1];
+
+ sq_addlast((FAR sq_entry_t *)req, &priv->recvq);
+
+ icc_semgive(&priv->rxwait);
+
+ /* If signal registered by cxd56_iccnotify(), then send POSIX signal to
+ * process.
+ */
+
+#ifndef CONFIG_DISABLE_SIGNAL
+ if (priv->pid != INVALID_PROCESS_ID)
+ {
+# ifdef CONFIG_CAN_PASS_STRUCTS
+ union sigval value;
+ value.sival_ptr = priv->sigdata;
+ (void)sigqueue(priv->pid, priv->signo, value);
+# else
+ (void)sigqueue(priv->pid, priv->signo, priv->sigdata);
+# endif
+ }
+#endif
+
+ return OK;
+}
+
+static int icc_sighandler(int cpuid, int protoid, uint32_t pdata,
+ uint32_t data, FAR void *userdata)
+{
+ FAR struct iccdev_s *priv = icc_getcpu(cpuid);
+
+ if (!priv)
+ {
+ /* Nobody waits this message... */
+
+ iccerr("nobody waits %08x %08x\n", word[0], word[1]);
+ return OK;
+ }
+
+ iccinfo("Caught signal\n");
+
+ if (priv->u.sighandler)
+ {
+ int8_t signo;
+ uint16_t sigdata;
+
+ signo = (int8_t)((pdata >> 16) & 0xff);
+ sigdata = pdata & 0xffff;
+
+ iccinfo("Call signal handler with No %d.\n", signo);
+ priv->u.sighandler(signo, sigdata, data, priv->userdata);
+ }
+ return OK;
+}
+
+static int icc_msghandler(int cpuid, int protoid, uint32_t pdata,
+ uint32_t data, FAR void *userdata)
+{
+ /* Do nothing. This handler used for reserve MSG protocol handler.
+ * This handler returns -1 to indicate not consumed the passed
+ * message.
+ */
+
+ return -1;
+}
+
+static void icc_rxtimeout(int argc, uint32_t arg, ...)
+{
+ FAR struct iccdev_s *priv = (FAR struct iccdev_s *)arg;
+ icc_semgive(&priv->rxwait);
+}
+
+static int icc_recv(FAR struct iccdev_s *priv, FAR iccmsg_t *msg, int32_t ms)
+{
+ FAR struct iccreq_s *req;
+ irqstate_t flags;
+ int ret = OK;
+
+ if (ms)
+ {
+ int32_t timo;
+ timo = ms * 1000 / CONFIG_USEC_PER_TICK;
+ wd_start(priv->rxtimeout, timo, icc_rxtimeout, 1, (uint32_t)priv);
+ }
+
+ icc_semtake(&priv->rxwait);
+
+ wd_cancel(priv->rxtimeout);
+
+ flags = enter_critical_section();
+ req = (FAR struct iccreq_s *)sq_remfirst(&priv->recvq);
+
+ if (req)
+ {
+ msg->msgid = req->msg.msgid;
+ msg->data = req->msg.data;
+ msg->cpuid = req->msg.cpuid;
+ msg->protodata = req->msg.pdata;
+ sq_addlast((FAR sq_entry_t *)req, &priv->freelist);
+ }
+ else
+ {
+ ret = -ETIMEDOUT;
+ }
+
+ leave_critical_section(flags);
+
+ return ret;
+}
+
+static FAR struct iccdev_s *icc_devnew(void)
+{
+ FAR struct iccdev_s *priv;
+ int i;
+
+ priv = (struct iccdev_s *)kmm_malloc(sizeof(struct iccdev_s));
+ if (!priv)
+ {
+ return NULL;
+ }
+ memset(priv, 0, sizeof(struct iccdev_s));
+
+ priv->rxtimeout = wd_create();
+
+ sem_init(&priv->rxwait, 0, 0);
+
+ /* Initialize receive queue and free list */
+
+ sq_init(&priv->recvq);
+ sq_init(&priv->freelist);
+
+ for (i = 0; i < NBUFFERS; i++)
+ {
+ sq_addlast((FAR sq_entry_t *)&priv->pool[i], &priv->freelist);
+ }
+
+ priv->pid = INVALID_PROCESS_ID;
+
+ return priv;
+}
+
+static void icc_devfree(FAR struct iccdev_s *priv)
+{
+ wd_delete(priv->rxtimeout);
+ kmm_free(priv);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int cxd56_iccregisterhandler(int protoid, cxd56_icchandler_t handler,
+ FAR void *data)
+{
+ FAR struct iccdev_s *priv;
+ irqstate_t flags;
+ int ret = OK;
+
+ flags = enter_critical_section();
+ priv = icc_getprotocol(protoid);
+ if (priv)
+ {
+ priv->u.handler = handler;
+ priv->userdata = data;
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+ leave_critical_section(flags);
+
+ return ret;
+}
+
+int cxd56_iccregistersighandler(int cpuid, cxd56_iccsighandler_t handler,
+ FAR void *data)
+{
+ FAR struct iccdev_s *priv;
+ irqstate_t flags;
+ int ret = OK;
+
+ flags = enter_critical_section();
+ priv = icc_getcpu(cpuid);
+ if (priv)
+ {
+ priv->u.sighandler = handler;
+ priv->userdata = data;
+ }
+ else
+ {
+ ret = -EINVAL;
+ }
+ leave_critical_section(flags);
+
+ return ret;
+}
+
+int cxd56_iccsend(int protoid, FAR iccmsg_t *msg, int32_t ms)
+{
+ FAR struct iccdev_s *priv;
+ struct iccreq_s req;
+
+ if (!msg)
+ {
+ return -EINVAL;
+ }
+
+ priv = icc_getprotocol(protoid);
+ if (!priv)
+ {
+ return -EINVAL;
+ }
+
+ req.msg.cpuid = msg->cpuid;
+ req.msg.msgid = msg->msgid;
+ req.msg.data = msg->data;
+ req.msg.pdata = msg->protodata;
+ req.msg.proto = protoid;
+
+ priv->flags = 0;
+
+ return cxd56_cfpush(req.word);
+}
+
+int cxd56_iccsendmsg(FAR iccmsg_t *msg, int32_t ms)
+{
+ return cxd56_iccsend(CXD56_PROTO_MSG, msg, ms);
+}
+
+int cxd56_iccrecv(int protoid, FAR iccmsg_t *msg, int32_t ms)
+{
+ FAR struct iccdev_s *priv;
+
+ if (!msg)
+ {
+ return -EINVAL;
+ }
+
+ priv = icc_getprotocol(protoid);
+ if (!priv)
+ {
+ return -EINVAL;
+ }
+
+ return icc_recv(priv, msg, ms);
+}
+
+int cxd56_iccrecvmsg(FAR iccmsg_t *msg, int32_t ms)
+{
+ FAR struct iccdev_s *priv;
+
+ if (!msg)
+ {
+ return -EINVAL;
+ }
+
+ priv = icc_getcpu(msg->cpuid);
+ if (!priv)
+ {
+ return -EINVAL;
+ }
+
+ return icc_recv(priv, msg, ms);
+}
+
+int cxd56_iccsignal(int8_t cpuid, int8_t signo, int16_t sigdata, uint32_t data)
+{
+ struct iccreq_s req;
+
+ if (cpuid <= 2 && cpuid >= 7)
+ {
+ return -EINVAL;
+ }
+
+ req.msg.cpuid = cpuid;
+ req.msg.proto = CXD56_PROTO_SIG;
+ req.msg.msgid = signo;
+ req.msg.pdata = sigdata;
+ req.msg.data = data;
+
+ return cxd56_cfpush(req.word);
+}
+
+int cxd56_iccnotify(int cpuid, int signo, FAR void *sigdata)
+{
+ FAR struct iccdev_s *priv;
+
+ priv = icc_getcpu(cpuid);
+ if (!priv)
+ {
+ return -ESRCH;
+ }
+
+ priv->pid = getpid();
+ priv->signo = signo;
+ priv->sigdata = sigdata;
+
+ return OK;
+}
+
+int cxd56_iccinit(int protoid)
+{
+ FAR struct iccdev_s *priv;
+
+ if (protoid < 0 || protoid >= NPROTOCOLS)
+ {
+ return -EINVAL;
+ }
+
+ if (g_protocol[protoid])
+ {
+ return OK;
+ }
+
+ priv = icc_devnew();
+ if (!priv)
+ {
+ return -ENOMEM;
+ }
+ g_protocol[protoid] = priv;
+
+ return OK;
+}
+
+int cxd56_iccinitmsg(int cpuid)
+{
+ FAR struct iccdev_s *priv;
+
+ if (cpuid < 0 || cpuid >= NCPUS)
+ {
+ return -EINVAL;
+ }
+
+ if (g_cpumsg[cpuid])
+ {
+ return OK;
+ }
+
+ priv = icc_devnew();
+ if (!priv)
+ {
+ return -ENOMEM;
+ }
+ g_cpumsg[cpuid] = priv;
+
+ return OK;
+}
+
+void cxd56_iccuninit(int protoid)
+{
+ FAR struct iccdev_s *priv;
+ irqstate_t flags;
+
+ if (protoid < 0 || protoid >= NPROTOCOLS)
+ {
+ return;
+ }
+
+ flags = enter_critical_section();
+ priv = g_protocol[protoid];
+ if (priv)
+ {
+ icc_devfree(priv);
+ g_protocol[protoid] = NULL;
+ }
+ leave_critical_section(flags);
+}
+
+void cxd56_iccuninitmsg(int cpuid)
+{
+ FAR struct iccdev_s *priv;
+ irqstate_t flags;
+
+ if (cpuid < 0 || cpuid >= NCPUS)
+ {
+ return;
+ }
+
+ flags = enter_critical_section();
+ priv = g_cpumsg[cpuid];
+ if (priv)
+ {
+ icc_devfree(priv);
+ g_cpumsg[cpuid] = NULL;
+ }
+ leave_critical_section(flags);
+}
+
+void cxd56_iccinitialize(void)
+{
+ int i;
+
+ for (i = 0; i < NPROTOCOLS; i++)
+ {
+ g_protocol[i] = NULL;
+ }
+
+ for (i = 0; i < NCPUS; i++)
+ {
+ g_cpumsg[i] = NULL;
+ }
+
+ /* Protocol MSG and SIG is special, reserved by ICC driver. */
+
+ cxd56_iccinit(CXD56_PROTO_MSG);
+ cxd56_iccregisterhandler(CXD56_PROTO_MSG, icc_msghandler, NULL);
+ cxd56_iccinit(CXD56_PROTO_SIG);
+ cxd56_iccregisterhandler(CXD56_PROTO_SIG, icc_sighandler, NULL);
+
+ cxd56_cfregrxhandler(icc_irqhandler);
+}
+
+#endif
diff --git a/arch/arm/src/cxd56xx/cxd56_icc.h b/arch/arm/src/cxd56xx/cxd56_icc.h
new file mode 100644
index 00000000000..a5d9f667f9d
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_icc.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_icc.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_ICC_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_ICC_H
+
+#define CXD56_PROTO_MSG 0 /* Generic message */
+#define CXD56_PROTO_MBX 1
+#define CXD56_PROTO_SEM 2
+#define CXD56_PROTO_FLG 3
+#define CXD56_PROTO_MPF 4
+#define CXD56_PROTO_DBG 5
+#define CXD56_PROTO_AUDIO 6
+#define CXD56_PROTO_CALLBACK 7
+#define CXD56_PROTO_HOTSLEEP 8
+#define CXD56_PROTO_IMAGE 9
+#define CXD56_PROTO_PM 10 /* Power manager */
+#define CXD56_PROTO_SYSCTL 12
+#define CXD56_PROTO_GNSS 13
+#define CXD56_PROTO_SIG 15 /* Inter-CPU Comm signal */
+
+typedef int (*cxd56_icchandler_t)(int cpuid, int protoid, uint32_t pdata,
+ uint32_t data, FAR void *userdata);
+typedef int (*cxd56_iccsighandler_t)(int8_t signo, uint16_t sigdata,
+ uint32_t data, FAR void *userdata);
+
+struct cxd56_iccmsg_s
+{
+ int8_t cpuid;
+ int8_t msgid;
+ uint16_t protodata;
+ uint32_t data;
+};
+typedef struct cxd56_iccmsg_s iccmsg_t;
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+int cxd56_iccinit(int protoid);
+int cxd56_iccinitmsg(int cpuid);
+void cxd56_iccuninit(int protoid);
+void cxd56_iccuninitmsg(int cpuid);
+int cxd56_iccregisterhandler(int protoid, cxd56_icchandler_t handler,
+ FAR void *data);
+int cxd56_iccregistersighandler(int cpuid, cxd56_iccsighandler_t handler,
+ FAR void *data);
+int cxd56_iccsend(int protoid, FAR iccmsg_t *msg, int32_t ms);
+int cxd56_iccrecv(int protoid, FAR iccmsg_t *msg, int32_t ms);
+int cxd56_iccsendmsg(FAR iccmsg_t *msg, int32_t ms);
+int cxd56_iccrecvmsg(FAR iccmsg_t *msg, int32_t ms);
+int cxd56_iccsignal(int8_t cpuid, int8_t signo, int16_t sigdata,
+ uint32_t data);
+int cxd56_iccnotify(int cpuid, int signo, FAR void *sigdata);
+
+void cxd56_iccinitialize(void);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_ICC_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_idle.c b/arch/arm/src/cxd56xx/cxd56_idle.c
new file mode 100644
index 00000000000..b0655d025a2
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_idle.c
@@ -0,0 +1,189 @@
+/****************************************************************************
+ * arch/arm/src/cxd56/cxd56_idle.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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
+#include
+
+#include
+#include
+#include
+
+#include
+
+#include "up_internal.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Does the board support an IDLE LED to indicate that the board is in the
+ * IDLE state?
+ */
+
+#if defined(CONFIG_ARCH_LEDS) && defined(LED_IDLE)
+# define BEGIN_IDLE() board_autoled_on(LED_IDLE)
+# define END_IDLE() board_autoled_off(LED_IDLE)
+#else
+# define BEGIN_IDLE()
+# define END_IDLE()
+#endif
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_idlepm
+ *
+ * Description:
+ * Perform IDLE state power management.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_PM
+static void up_idlepm(void)
+{
+ static enum pm_state_e oldstate = PM_NORMAL;
+ enum pm_state_e newstate;
+ irqstate_t flags;
+ int ret;
+
+ /* Decide, which power saving level can be obtained */
+
+ newstate = pm_checkstate(PM_IDLE_DOMAIN);
+
+ /* Check for state changes */
+
+ if (newstate != oldstate)
+ {
+ flags = enter_critical_section();
+
+ /* Perform board-specific, state-dependent logic here */
+
+ _info("newstate= %d oldstate=%d\n", newstate, oldstate);
+
+ /* Then force the global state change */
+
+ ret = pm_changestate(PM_IDLE_DOMAIN, newstate);
+ if (ret < 0)
+ {
+ /* The new state change failed, revert to the preceding state */
+
+ (void)pm_changestate(PM_IDLE_DOMAIN, oldstate);
+ }
+ else
+ {
+ /* Save the new state */
+
+ oldstate = newstate;
+ }
+
+ /* MCU-specific power management logic */
+
+ switch (newstate)
+ {
+ case PM_NORMAL:
+ break;
+
+ case PM_IDLE:
+ break;
+
+ case PM_STANDBY:
+ cxd56_pmstandby(true);
+ break;
+
+ case PM_SLEEP:
+ (void)cxd56_pmsleep();
+ break;
+
+ default:
+ break;
+ }
+
+ leave_critical_section(flags);
+ }
+}
+#else
+# define up_idlepm()
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_idle
+ *
+ * Description:
+ * up_idle() is the logic that will be executed when their is no other
+ * ready-to-run task. This is processor idle time and will continue until
+ * some interrupt occurs to cause a context switch from the idle task.
+ *
+ * Processing in this state may be processor-specific. e.g., this is where
+ * power management operations might be performed.
+ *
+ ****************************************************************************/
+
+void up_idle(void)
+{
+#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
+ /* If the system is idle and there are no timer interrupts, then process
+ * "fake" timer interrupts. Hopefully, something will wake up.
+ */
+
+ nxsched_process_timer();
+#else
+
+ /* Perform IDLE mode power management */
+
+ up_idlepm();
+
+ /* Sleep until an interrupt occurs to save power */
+
+ BEGIN_IDLE();
+ asm("WFI");
+ END_IDLE();
+#endif
+}
diff --git a/arch/arm/src/cxd56xx/cxd56_irq.c b/arch/arm/src/cxd56xx/cxd56_irq.c
new file mode 100644
index 00000000000..1734e25493c
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_irq.c
@@ -0,0 +1,558 @@
+/****************************************************************************
+ * arch/arm/src/cxd56/cxd56_irq.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012-2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include "chip.h"
+#include "nvic.h"
+#include "ram_vectors.h"
+#include "up_arch.h"
+#include "up_internal.h"
+
+#include "cxd56_irq.h"
+
+#ifdef CONFIG_SMP
+# include "init/init.h"
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Get a 32-bit version of the default priority */
+
+#define DEFPRIORITY32 \
+ (CXD56M4_SYSH_PRIORITY_DEFAULT << 24 | CXD56M4_SYSH_PRIORITY_DEFAULT << 16 | \
+ CXD56M4_SYSH_PRIORITY_DEFAULT << 8 | CXD56M4_SYSH_PRIORITY_DEFAULT)
+
+#define INTC_EN(n) (CXD56_INTC_BASE + 0x10 + (((n) >> 5) << 2))
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* g_current_regs[] holds a references to the current interrupt level
+ * register storage structure. If is non-NULL only during interrupt
+ * processing. Access to g_current_regs[] must be through the macro
+ * CURRENT_REGS for portability.
+ */
+
+#ifdef CONFIG_SMP
+/* For the case of configurations with multiple CPUs, then there must be one
+ * such value for each processor that can receive an interrupt.
+ */
+
+volatile uint32_t *g_current_regs[CONFIG_SMP_NCPUS];
+#else
+volatile uint32_t *g_current_regs[1];
+#endif
+
+/* This is the address of the exception vector table (determined by the
+ * linker script).
+ */
+
+extern uint32_t _vectors[];
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_dumpnvic
+ *
+ * Description:
+ * Dump some interesting NVIC registers
+ *
+ ****************************************************************************/
+
+#if defined(CONFIG_DEBUG_IRQ_INFO)
+static void cxd56_dumpnvic(const char *msg, int irq)
+{
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+ irqinfo("NVIC (%s, irq=%d):\n", msg, irq);
+ irqinfo(" INTCTRL: %08x VECTAB: %08x\n", getreg32(NVIC_INTCTRL),
+ getreg32(NVIC_VECTAB));
+# if 0
+ irqinfo(" SYSH ENABLE MEMFAULT: %08x BUSFAULT: %08x USGFAULT: %08x SYSTICK: %08x\n",
+ getreg32(NVIC_SYSHCON_MEMFAULTENA),
+ getreg32(NVIC_SYSHCON_BUSFAULTENA),
+ getreg32(NVIC_SYSHCON_USGFAULTENA),
+ getreg32(NVIC_SYSTICK_CTRL_ENABLE));
+# endif
+ irqinfo(" IRQ ENABLE: %08x %08x\n", getreg32(NVIC_IRQ0_31_ENABLE),
+ getreg32(NVIC_IRQ32_63_ENABLE));
+ irqinfo(" SYSH_PRIO: %08x %08x %08x\n",
+ getreg32(NVIC_SYSH4_7_PRIORITY),
+ getreg32(NVIC_SYSH8_11_PRIORITY),
+ getreg32(NVIC_SYSH12_15_PRIORITY));
+ irqinfo(" IRQ PRIO: %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ0_3_PRIORITY),
+ getreg32(NVIC_IRQ4_7_PRIORITY),
+ getreg32(NVIC_IRQ8_11_PRIORITY),
+ getreg32(NVIC_IRQ12_15_PRIORITY));
+ irqinfo(" %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ16_19_PRIORITY),
+ getreg32(NVIC_IRQ20_23_PRIORITY),
+ getreg32(NVIC_IRQ24_27_PRIORITY),
+ getreg32(NVIC_IRQ28_31_PRIORITY));
+ irqinfo(" %08x %08x %08x %08x\n",
+ getreg32(NVIC_IRQ32_35_PRIORITY),
+ getreg32(NVIC_IRQ36_39_PRIORITY),
+ getreg32(NVIC_IRQ40_43_PRIORITY),
+ getreg32(NVIC_IRQ44_47_PRIORITY));
+ irqinfo(" %08x %08x %08x\n",
+ getreg32(NVIC_IRQ48_51_PRIORITY),
+ getreg32(NVIC_IRQ52_55_PRIORITY),
+ getreg32(NVIC_IRQ56_59_PRIORITY));
+ leave_critical_section(flags);
+}
+#else
+# define cxd56_dumpnvic(msg, irq)
+#endif
+
+/****************************************************************************
+ * Name: cxd56_nmi, cxd56_busfault, cxd56_usagefault, cxd56_pendsv,
+ * cxd56_dbgmonitor, cxd56_pendsv, cxd56_reserved
+ *
+ * Description:
+ * Handlers for various exceptions. None are handled and all are fatal
+ * error conditions. The only advantage these provided over the default
+ * unexpected interrupt handler is that they provide a diagnostic output.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEBUG_FEATURES
+static int cxd56_nmi(int irq, FAR void *context, FAR void *arg)
+{
+ (void)up_irq_save();
+ _err("PANIC!!! NMI received\n");
+ PANIC();
+ return 0;
+}
+
+static int cxd56_busfault(int irq, FAR void *context, FAR void *arg)
+{
+ (void)up_irq_save();
+ _err("PANIC!!! Bus fault recived\n");
+ PANIC();
+ return 0;
+}
+
+static int cxd56_usagefault(int irq, FAR void *context, FAR void *arg)
+{
+ (void)up_irq_save();
+ _err("PANIC!!! Usage fault received\n");
+ PANIC();
+ return 0;
+}
+
+static int cxd56_pendsv(int irq, FAR void *context, FAR void *arg)
+{
+ (void)up_irq_save();
+ _err("PANIC!!! PendSV received\n");
+ PANIC();
+ return 0;
+}
+
+static int cxd56_dbgmonitor(int irq, FAR void *context, FAR void *arg)
+{
+ (void)up_irq_save();
+ _err("PANIC!!! Debug Monitor received\n");
+ PANIC();
+ return 0;
+}
+
+static int cxd56_reserved(int irq, FAR void *context, FAR void *arg)
+{
+ (void)up_irq_save();
+ _err("PANIC!!! Reserved interrupt\n");
+ PANIC();
+ return 0;
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_prioritize_syscall
+ *
+ * Description:
+ * Set the priority of an exception. This function may be needed
+ * internally even if support for prioritized interrupts is not enabled.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARMV7M_USEBASEPRI
+static inline void cxd56_prioritize_syscall(int priority)
+{
+ uint32_t regval;
+
+ /* SVCALL is system handler 11 */
+
+ regval = getreg32(NVIC_SYSH8_11_PRIORITY);
+ regval &= ~NVIC_SYSH_PRIORITY_PR11_MASK;
+ regval |= (priority << NVIC_SYSH_PRIORITY_PR11_SHIFT);
+ putreg32(regval, NVIC_SYSH8_11_PRIORITY);
+}
+#endif
+
+static int excinfo(int irq, uint32_t *regaddr, uint32_t *bit)
+{
+ *regaddr = NVIC_SYSHCON;
+ switch (irq)
+ {
+ case CXD56_IRQ_MEMFAULT:
+ *bit = NVIC_SYSHCON_MEMFAULTENA;
+ break;
+
+ case CXD56_IRQ_BUSFAULT:
+ *bit = NVIC_SYSHCON_BUSFAULTENA;
+ break;
+
+ case CXD56_IRQ_USAGEFAULT:
+ *bit = NVIC_SYSHCON_USGFAULTENA;
+ break;
+
+ case CXD56_IRQ_SYSTICK:
+ *regaddr = NVIC_SYSTICK_CTRL;
+ *bit = NVIC_SYSTICK_CTRL_ENABLE;
+ break;
+
+ default:
+ return ERROR; /* Invalid or unsupported exception */
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_irqinitialize
+ *
+ * Description:
+ * Complete initialization of the interrupt system and enable normal,
+ * interrupt processing.
+ *
+ ****************************************************************************/
+
+void up_irqinitialize(void)
+{
+ uint32_t regaddr;
+ int num_priority_registers;
+
+ /* Disable all interrupts */
+
+ putreg32(0, NVIC_IRQ0_31_ENABLE);
+ putreg32(0, NVIC_IRQ32_63_ENABLE);
+ putreg32(0, NVIC_IRQ64_95_ENABLE);
+ putreg32(0, NVIC_IRQ96_127_ENABLE);
+
+ /* Make sure that we are using the correct vector table. The default
+ * vector address is 0x0000:0000 but if we are executing code that is
+ * positioned in SRAM or in external FLASH, then we may need to reset
+ * the interrupt vector so that it refers to the table in SRAM or in
+ * external FLASH.
+ */
+
+ putreg32((uint32_t)_vectors, NVIC_VECTAB);
+
+#ifdef CONFIG_ARCH_RAMVECTORS
+ /* If CONFIG_ARCH_RAMVECTORS is defined, then we are using a RAM-based
+ * vector table that requires special initialization.
+ */
+
+ up_ramvec_initialize();
+#endif
+
+ /* Set all interrupts (and exceptions) to the default priority */
+
+ putreg32(DEFPRIORITY32, NVIC_SYSH4_7_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH8_11_PRIORITY);
+ putreg32(DEFPRIORITY32, NVIC_SYSH12_15_PRIORITY);
+
+ /* The NVIC ICTR register (bits 0-4) holds the number of of interrupt
+ * lines that the NVIC supports:
+ *
+ * 0 -> 32 interrupt lines, 8 priority registers
+ * 1 -> 64 " " " ", 16 priority registers
+ * 2 -> 96 " " " ", 32 priority registers
+ * ...
+ */
+
+ num_priority_registers = (getreg32(NVIC_ICTR) + 1) * 8;
+
+ /* Now set all of the interrupt lines to the default priority */
+
+ regaddr = NVIC_IRQ0_3_PRIORITY;
+ while (num_priority_registers--)
+ {
+ putreg32(DEFPRIORITY32, regaddr);
+ regaddr += 4;
+ }
+
+ /* currents_regs is non-NULL only while processing an interrupt */
+
+ CURRENT_REGS = NULL;
+
+ /* Attach the SVCall and Hard Fault exception handlers. The SVCall
+ * exception is used for performing context switches; The Hard Fault
+ * must also be caught because a SVCall may show up as a Hard Fault
+ * under certain conditions.
+ */
+
+ irq_attach(CXD56_IRQ_SVCALL, up_svcall, NULL);
+ irq_attach(CXD56_IRQ_HARDFAULT, up_hardfault, NULL);
+
+ /* Set the priority of the SVCall interrupt */
+
+#ifdef CONFIG_ARCH_IRQPRIO
+ /* up_prioritize_irq(CXD56_IRQ_PENDSV, NVIC_SYSH_PRIORITY_MIN); */
+#endif
+#ifdef CONFIG_ARMV7M_USEBASEPRI
+ cxd56_prioritize_syscall(NVIC_SYSH_SVCALL_PRIORITY);
+#endif
+
+ /* If the MPU is enabled, then attach and enable the Memory Management
+ * Fault handler.
+ */
+
+#ifdef CONFIG_ARM_MPU
+ irq_attach(CXD56_IRQ_MEMFAULT, up_memfault, NULL);
+ up_enable_irq(CXD56_IRQ_MEMFAULT);
+#endif
+
+ /* Attach all other processor exceptions (except reset and sys tick) */
+
+#ifdef CONFIG_DEBUG_FEATURES
+ irq_attach(CXD56_IRQ_NMI, cxd56_nmi, NULL);
+# ifndef CONFIG_ARM_MPU
+ irq_attach(CXD56_IRQ_MEMFAULT, up_memfault, NULL);
+# endif
+ irq_attach(CXD56_IRQ_BUSFAULT, cxd56_busfault, NULL);
+ irq_attach(CXD56_IRQ_USAGEFAULT, cxd56_usagefault, NULL);
+ irq_attach(CXD56_IRQ_PENDSV, cxd56_pendsv, NULL);
+ irq_attach(CXD56_IRQ_DBGMONITOR, cxd56_dbgmonitor, NULL);
+ irq_attach(CXD56_IRQ_RESERVED, cxd56_reserved, NULL);
+#endif
+
+ cxd56_dumpnvic("initial", CXD56_IRQ_NIRQS);
+
+ /* If a debugger is connected, try to prevent it from catching hardfaults.
+ * If CONFIG_ARMV7M_USEBASEPRI, no hardfaults are expected in normal
+ * operation.
+ */
+
+#if defined(CONFIG_DEBUG_FEATURES) && !defined(CONFIG_ARMV7M_USEBASEPRI)
+ {
+ uint32_t regval;
+
+ regval = getreg32(NVIC_DEMCR);
+ regval &= ~NVIC_DEMCR_VCHARDERR;
+ putreg32(regval, NVIC_DEMCR);
+ }
+#endif
+
+ /* And finally, enable interrupts */
+
+#ifndef CONFIG_SUPPRESS_INTERRUPTS
+ up_irq_enable();
+#endif
+}
+
+/****************************************************************************
+ * Name: up_disable_irq
+ *
+ * Description:
+ * Disable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_disable_irq(int irq)
+{
+ uintptr_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (irq >= CXD56_IRQ_EXTINT)
+ {
+ irqstate_t flags = enter_critical_section();
+ irq -= CXD56_IRQ_EXTINT;
+ bit = 1 << (irq & 0x1f);
+
+ regval = getreg32(INTC_EN(irq));
+ regval &= ~bit;
+ putreg32(regval, INTC_EN(irq));
+ leave_critical_section(flags);
+ putreg32(bit, NVIC_IRQ_CLEAR(irq));
+ }
+ else
+ {
+ if (excinfo(irq, ®addr, &bit) == OK)
+ {
+ regval = getreg32(regaddr);
+ regval &= ~bit;
+ putreg32(regval, regaddr);
+ }
+ }
+
+ cxd56_dumpnvic("disable", irq);
+}
+
+/****************************************************************************
+ * Name: up_enable_irq
+ *
+ * Description:
+ * Enable the IRQ specified by 'irq'
+ *
+ ****************************************************************************/
+
+void up_enable_irq(int irq)
+{
+ uintptr_t regaddr;
+ uint32_t regval;
+ uint32_t bit;
+
+ if (irq >= CXD56_IRQ_EXTINT)
+ {
+ irqstate_t flags = enter_critical_section();
+ irq -= CXD56_IRQ_EXTINT;
+ bit = 1 << (irq & 0x1f);
+
+ regval = getreg32(INTC_EN(irq));
+ regval |= bit;
+ putreg32(regval, INTC_EN(irq));
+ leave_critical_section(flags);
+ putreg32(bit, NVIC_IRQ_ENABLE(irq));
+ }
+ else
+ {
+ if (excinfo(irq, ®addr, &bit) == OK)
+ {
+ regval = getreg32(regaddr);
+ regval |= bit;
+ putreg32(regval, regaddr);
+ }
+ }
+
+ cxd56_dumpnvic("enable", irq);
+}
+
+/****************************************************************************
+ * Name: up_ack_irq
+ *
+ * Description:
+ * Acknowledge the IRQ
+ *
+ ****************************************************************************/
+
+void up_ack_irq(int irq)
+{
+ /* Check for external interrupt */
+
+ if (irq >= CXD56_IRQ_EXTINT)
+ {
+ irq -= CXD56_IRQ_EXTINT;
+ putreg32(1 << (irq & 0x1f), NVIC_IRQ_CLRPEND(irq));
+ }
+}
+
+/****************************************************************************
+ * Name: up_prioritize_irq
+ *
+ * Description:
+ * Set the priority of an IRQ.
+ *
+ * Since this API is not supported on all architectures, it should be
+ * avoided in common implementations where possible.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_ARCH_IRQPRIO
+int up_prioritize_irq(int irq, int priority)
+{
+ uint32_t regaddr;
+ uint32_t regval;
+ int shift;
+
+ DEBUGASSERT(irq >= CXD56_IRQ_MEMFAULT && irq < NR_IRQS &&
+ (unsigned)priority <= NVIC_SYSH_PRIORITY_MIN);
+
+ if (irq < CXD56_IRQ_EXTINT)
+ {
+ /* NVIC_SYSH_PRIORITY() maps {0..15} to one of three priority
+ * registers (0-3 are invalid)
+ */
+
+ regaddr = NVIC_SYSH_PRIORITY(irq);
+ irq -= 4;
+ }
+ else
+ {
+ /* NVIC_IRQ_PRIORITY() maps {0..} to one of many priority registers */
+
+ irq -= CXD56_IRQ_EXTINT;
+ regaddr = NVIC_IRQ_PRIORITY(irq);
+ }
+
+ regval = getreg32(regaddr);
+ shift = ((irq & 3) << 3);
+ regval &= ~(0xff << shift);
+ regval |= (priority << shift);
+ putreg32(regval, regaddr);
+
+ cxd56_dumpnvic("prioritize", irq);
+ return OK;
+}
+#endif
diff --git a/arch/arm/src/cxd56xx/cxd56_irq.h b/arch/arm/src/cxd56xx/cxd56_irq.h
new file mode 100644
index 00000000000..568e5d1963e
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_irq.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_irq.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012, 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_IRQ_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_IRQ_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_IRQ_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_pinconfig.c b/arch/arm/src/cxd56xx/cxd56_pinconfig.c
new file mode 100644
index 00000000000..5b9d4de9c68
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_pinconfig.c
@@ -0,0 +1,462 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_pinconfig.c
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "chip.h"
+#include "up_arch.h"
+
+#include "cxd56_pinconfig.h"
+#include "hardware/cxd5602_topreg.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GET_IOVAL_MASK(p) \
+ ((p) & (PINCONF_DRIVE_MASK | PINCONF_PULL_MASK | PINCONF_IN_EN_MASK))
+
+/* IOCSYS_IOMD0 */
+
+#define GROUP_I2C4 (0)
+#define GROUP_PMIC_INT (2)
+#define GROUP_RTC_IRQ_OUT (4)
+#define GROUP_AP_CLK (6)
+#define GROUP_GNSS_1PPS_OUT (8)
+#define GROUP_SPI0A (12)
+#define GROUP_SPI0B (14)
+#define GROUP_SPI1A (16)
+#define GROUP_SPI1B (18)
+#define GROUP_SPI2A (20)
+#define GROUP_SPI2B (22)
+#define GROUP_HIFIRQ (24)
+#define GROUP_HIFEXT (26)
+
+/* IOCSYS_IOMD1 */
+
+#define GROUP_SEN_IRQ_IN (8)
+#define GROUP_SPI3_CS0_X (10)
+#define GROUP_SPI3_CS1_X (12)
+#define GROUP_SPI3_CS2_X (14)
+#define GROUP_SPI3 (16)
+#define GROUP_I2C0 (18)
+#define GROUP_PWMA (20)
+#define GROUP_PWMB (22)
+
+/* IOCAPP_IOMD */
+
+#define GROUP_IS (0)
+#define GROUP_UART2 (2)
+#define GROUP_SPI4 (4)
+#define GROUP_EMMCA (6)
+#define GROUP_EMMCB (8)
+#define GROUP_SDIOA (10)
+#define GROUP_SDIOB (12)
+#define GROUP_SDIOC (14)
+#define GROUP_SDIOD (16)
+#define GROUP_I2S0 (18)
+#define GROUP_I2S1 (20)
+#define GROUP_MCLK (22)
+#define GROUP_PDM (24)
+#define GROUP_USBVBUS (26)
+
+/* DBG_HOSTIF_SEL */
+
+#define LATCH_OFF (1ul << 0)
+#define LATCH_OFF_MASK (1ul << 0)
+
+/* SYSTEM_CONFIG */
+
+#define SYSTEM_CONFIG_I2C (0)
+#define SYSTEM_CONFIG_UART (1)
+#define SYSTEM_CONFIG_SPI (2)
+#define SYSTEM_CONFIG_MON (3)
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int get_mode_regaddr(uint32_t pin, uint32_t *addr, uint32_t *shift)
+{
+ DEBUGASSERT(addr && shift);
+
+ if ((pin < PIN_I2C4_BCK) || (PIN_USB_VBUSINT < pin))
+ return -EINVAL;
+
+ if (pin <= PIN_HIF_GPIO0)
+ {
+ if (pin <= PIN_I2C4_BDT)
+ {
+ *shift = GROUP_I2C4;
+ }
+ else if (pin <= PIN_PMIC_INT)
+ {
+ *shift = GROUP_PMIC_INT;
+ }
+ else if (pin <= PIN_RTC_IRQ_OUT)
+ {
+ *shift = GROUP_RTC_IRQ_OUT;
+ }
+ else if (pin <= PIN_AP_CLK)
+ {
+ *shift = GROUP_AP_CLK;
+ }
+ else if (pin <= PIN_GNSS_1PPS_OUT)
+ {
+ *shift = GROUP_GNSS_1PPS_OUT;
+ }
+ else if (pin <= PIN_SPI0_SCK)
+ {
+ *shift = GROUP_SPI0A;
+ }
+ else if (pin <= PIN_SPI0_MISO)
+ {
+ *shift = GROUP_SPI0B;
+ }
+ else if (pin <= PIN_SPI1_IO1)
+ {
+ *shift = GROUP_SPI1A;
+ }
+ else if (pin <= PIN_SPI1_IO3)
+ {
+ *shift = GROUP_SPI1B;
+ }
+ else if (pin <= PIN_SPI2_SCK)
+ {
+ *shift = GROUP_SPI2A;
+ }
+ else if (pin <= PIN_SPI2_MISO)
+ {
+ *shift = GROUP_SPI2B;
+ }
+ else if (pin <= PIN_HIF_IRQ_OUT)
+ {
+ *shift = GROUP_HIFIRQ;
+ }
+ else
+ {
+ *shift = GROUP_HIFEXT;
+ }
+ *addr = CXD56_TOPREG_IOCSYS_IOMD0;
+ }
+ else if (pin <= PIN_PWM3)
+ {
+ if (pin <= PIN_SEN_IRQ_IN)
+ {
+ *shift = GROUP_SEN_IRQ_IN;
+ }
+ else if (pin <= PIN_SPI3_CS0_X)
+ {
+ *shift = GROUP_SPI3_CS0_X;
+ }
+ else if (pin <= PIN_SPI3_CS1_X)
+ {
+ *shift = GROUP_SPI3_CS1_X;
+ }
+ else if (pin <= PIN_SPI3_CS2_X)
+ {
+ *shift = GROUP_SPI3_CS2_X;
+ }
+ else if (pin <= PIN_SPI3_MISO)
+ {
+ *shift = GROUP_SPI3;
+ }
+ else if (pin <= PIN_I2C0_BDT)
+ {
+ *shift = GROUP_I2C0;
+ }
+ else if (pin <= PIN_PWM1)
+ {
+ *shift = GROUP_PWMA;
+ }
+ else
+ {
+ *shift = GROUP_PWMB;
+ }
+ *addr = CXD56_TOPREG_IOCSYS_IOMD1;
+ }
+ else
+ {
+ if (pin <= PIN_IS_DATA7)
+ {
+ *shift = GROUP_IS;
+ }
+ else if (pin <= PIN_UART2_RTS)
+ {
+ *shift = GROUP_UART2;
+ }
+ else if (pin <= PIN_SPI4_MISO)
+ {
+ *shift = GROUP_SPI4;
+ }
+ else if (pin <= PIN_EMMC_DATA1)
+ {
+ *shift = GROUP_EMMCA;
+ }
+ else if (pin <= PIN_EMMC_DATA3)
+ {
+ *shift = GROUP_EMMCB;
+ }
+ else if (pin <= PIN_SDIO_DATA3)
+ {
+ *shift = GROUP_SDIOA;
+ }
+ else if (pin <= PIN_SDIO_WP)
+ {
+ *shift = GROUP_SDIOB;
+ }
+ else if (pin <= PIN_SDIO_DIR1_3)
+ {
+ *shift = GROUP_SDIOC;
+ }
+ else if (pin <= PIN_SDIO_CLKI)
+ {
+ *shift = GROUP_SDIOD;
+ }
+ else if (pin <= PIN_I2S0_DATA_OUT)
+ {
+ *shift = GROUP_I2S0;
+ }
+ else if (pin <= PIN_I2S1_DATA_OUT)
+ {
+ *shift = GROUP_I2S1;
+ }
+ else if (pin <= PIN_MCLK)
+ {
+ *shift = GROUP_MCLK;
+ }
+ else if (pin <= PIN_PDM_OUT)
+ {
+ *shift = GROUP_PDM;
+ }
+ else
+ {
+ *shift = GROUP_USBVBUS;
+ }
+ *addr = CXD56_TOPREG_IOCAPP_IOMD;
+ }
+
+ return 0;
+}
+
+static void set_i2s_output_config(uint32_t pin, uint32_t mode, bool is_slave)
+{
+ uint32_t mask =
+ (PIN_I2S0_BCK == pin) ? (I2S0_BCK | I2S0_LRCK) : (I2S1_BCK | I2S1_LRCK);
+
+ if (is_slave)
+ {
+ modifyreg32(CXD56_TOPREG_IOOEN_APP, 0, mask);
+ }
+ else
+ {
+ modifyreg32(CXD56_TOPREG_IOOEN_APP, mask, 0);
+ }
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_pin_config
+ *
+ * Description:
+ * Configure a pin based on bit-encoded description of the pin.
+ *
+ * Input Value:
+ * 32-bit encoded value describing the pin.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_pin_config(uint32_t pinconf)
+{
+ return cxd56_pin_configs(&pinconf, 1);
+}
+
+/****************************************************************************
+ * Name: cxd56_pin_configs
+ *
+ * Description:
+ * Configure multiple pins based on bit-encoded description of the pin.
+ *
+ * Input Value:
+ * pinconfs[] - Array of 32-bit encoded value describing the pin.
+ * n - The number of elements in the array.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int cxd56_pin_configs(uint32_t pinconfs[], size_t n)
+{
+ int ret = 0;
+ int i;
+ uint32_t pin;
+ uint32_t mode;
+ uint32_t ioreg;
+ uint32_t ioval;
+ uint32_t modereg;
+ uint32_t shift;
+ uint32_t oldreg = 0;
+ uint32_t oldshift = 0;
+ uint32_t latch_endpin = PIN_SPI2_SCK;
+
+ if (SYSTEM_CONFIG_SPI == getreg8(CXD56_TOPREG_SYSTEM_CONFIG))
+ {
+ latch_endpin = PIN_SPI2_MISO;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ pin = PINCONF_GET_PIN(pinconfs[i]);
+ mode = PINCONF_GET_MODE(pinconfs[i]);
+ ioval = GET_IOVAL_MASK(pinconfs[i]);
+
+ DEBUGASSERT((PIN_RTC_CLK_IN <= pin) && (pin <= PIN_USB_VBUSINT));
+ DEBUGASSERT((pin <= PIN_GNSS_1PPS_OUT) || (PIN_SPI0_CS_X <= pin));
+ DEBUGASSERT((pin <= PIN_HIF_GPIO0) || (PIN_SEN_IRQ_IN <= pin));
+ DEBUGASSERT((pin <= PIN_PWM3) || (PIN_IS_CLK <= pin));
+
+ /* Set HostIF latch off */
+
+ if (((PIN_SPI2_CS_X <= pin) && (pin <= latch_endpin)) &&
+ (PINCONF_MODE0 == mode))
+ {
+ modifyreg32(CXD56_TOPREG_DBG_HOSTIF_SEL, LATCH_OFF_MASK, LATCH_OFF);
+ }
+
+ /* Set IO cell register */
+
+ ioreg = CXD56_TOPREG_IO_RTC_CLK_IN + (pin * 4);
+ putreg32(ioval, ioreg);
+
+ /* Set i2s output register */
+
+ if (((PIN_I2S0_BCK == pin) || (PIN_I2S1_BCK == pin)) &&
+ (PINCONF_MODE1 == mode))
+ {
+ set_i2s_output_config(pin, mode, PINCONF_INPUT_ENABLED(pinconfs[i]));
+ }
+
+ ret = get_mode_regaddr(pin, &modereg, &shift);
+
+ if ((!ret) && ((oldreg != modereg) || (oldshift != shift)))
+ {
+ oldreg = modereg;
+ oldshift = shift;
+
+ /* Set alternative mode register */
+
+ modifyreg32(modereg, (0x3 << shift), (mode << shift));
+ }
+ }
+ return 0;
+}
+
+/********************************************************************************************
+ * Name: cxd56_pin_status
+ *
+ * Description:
+ * Get a pin status.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_pin_status(uint32_t pin, cxd56_pin_status_t *stat)
+{
+ int ret = 0;
+ uint32_t ioreg;
+ uint32_t ioval;
+ uint32_t modereg;
+ uint32_t modeval;
+ uint32_t shift;
+
+ DEBUGASSERT(stat);
+
+ stat->mode = -1;
+ stat->input_en = -1;
+ stat->drive = -1;
+ stat->pull = -1;
+
+ if (((PIN_GNSS_1PPS_OUT < pin) && (pin < PIN_SPI0_CS_X)) ||
+ ((PIN_HIF_GPIO0 < pin) && (pin < PIN_SEN_IRQ_IN)) ||
+ ((PIN_PWM3 < pin) && (pin < PIN_IS_CLK)) || (PIN_USB_VBUSINT < pin))
+ {
+ return -EINVAL;
+ }
+
+ ioreg = CXD56_TOPREG_IO_RTC_CLK_IN + (pin * 4);
+ ioval = getreg32(ioreg);
+
+ ret = get_mode_regaddr(pin, &modereg, &shift);
+
+ if (!ret)
+ {
+ modeval = getreg32(modereg);
+ modeval = (modeval >> shift) & 0x3;
+
+ stat->mode = modeval;
+ stat->input_en = (ioval & PINCONF_IN_EN_MASK);
+ stat->drive = (ioval & PINCONF_DRIVE_MASK);
+ stat->pull = (ioval & PINCONF_PULL_MASK);
+ }
+
+ return ret;
+}
diff --git a/arch/arm/src/cxd56xx/cxd56_pinconfig.h b/arch/arm/src/cxd56xx/cxd56_pinconfig.h
new file mode 100644
index 00000000000..27c6c972408
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_pinconfig.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_pinconfig.h
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_PINCONFIG_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_PINCONFIG_H
+
+/********************************************************************************************
+ * Included Files
+ ********************************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include "hardware/cxd5602_pinconfig.h"
+
+/********************************************************************************************
+ * Pre-processor Definitions
+ ********************************************************************************************/
+
+/* 32-bit encoded pinconf value
+ *
+ * 3322 2222 2222 1111 1111 1100 0000 0000
+ * 1098 7654 3210 9876 5432 1098 7654 3210
+ * ---- ---- ---- ---- ---- ---- ---- ----
+ * PPPP PPP. .... .... .... .... .... .... Pin number
+ * .... ...D .... .... .... .... .... .... Drive strength
+ * .... .... .... ...U .... ...U .... .... Pull-up/down/off
+ * .... .... .... .... .... .... .... ...I Input enable
+ * .... .... .... .... .... .... .... .MM. Alternate mode number
+ */
+
+/* Pin number Definitions */
+
+#define PINCONF_PIN_SHIFT (25)
+#define PINCONF_PIN_MASK (0x7Fu << PINCONF_PIN_SHIFT)
+#define PINCONF_GET_PIN(p) (((p) & PINCONF_PIN_MASK) >> PINCONF_PIN_SHIFT)
+#define PINCONF_SET_PIN(p) (((p) << PINCONF_PIN_SHIFT) & PINCONF_PIN_MASK)
+
+/* Drive strength Definitions */
+
+#define PINCONF_DRIVE_SHIFT (24)
+#define PINCONF_DRIVE_MASK (1u << PINCONF_DRIVE_SHIFT)
+
+#define PINCONF_DRIVE_NORMAL (1u << PINCONF_DRIVE_SHIFT) /* 2mA */
+#define PINCONF_DRIVE_HIGH (0u << PINCONF_DRIVE_SHIFT) /* 4mA */
+
+#define PINCONF_IS_DRIVE_NORM(p) (((p) & PINCONF_DRIVE_MASK) == PINCONF_DRIVE_NORMAL)
+#define PINCONF_IS_DRIVE_HIGH(p) (((p) & PINCONF_DRIVE_MASK) == PINCONF_DRIVE_HIGH)
+
+/* Pull-up/down/off Definitions */
+
+#define PINCONF_PULL_MASK ((1u << 16) | (1u << 8))
+
+#define PINCONF_FLOAT ((1u << 16) | (1u << 8))
+#define PINCONF_PULLUP ((1u << 16) | (0u << 8))
+#define PINCONF_PULLDOWN ((0u << 16) | (1u << 8))
+#define PINCONF_BUSKEEPER ((0u << 16) | (0u << 8))
+
+#define PINCONF_IS_FLOAT(p) (((p) & PINCONF_PULL_MASK) == PINCONF_FLOAT)
+#define PINCONF_IS_PULLUP(p) (((p) & PINCONF_PULL_MASK) == PINCONF_PULLUP)
+#define PINCONF_IS_PULLDOWN(p) (((p) & PINCONF_PULL_MASK) == PINCONF_PULLDOWN)
+#define PINCONF_IS_BUSKEEPER(p) (((p) & PINCONF_PULL_MASK) == PINCONF_BUSKEEPER)
+
+/* Input enable Definitions */
+
+#define PINCONF_IN_EN_SHIFT (0)
+#define PINCONF_IN_EN_MASK (1u << PINCONF_IN_EN_SHIFT)
+
+#define PINCONF_INPUT_ENABLE (1u << PINCONF_IN_EN_SHIFT)
+#define PINCONF_INPUT_DISABLE (0u << PINCONF_IN_EN_SHIFT)
+
+#define PINCONF_INPUT_ENABLED(p) (((p) & PINCONF_IN_EN_MASK) == PINCONF_INPUT_ENABLE)
+
+/* Alternate mode number Definitions */
+
+#define PINCONF_MODE_SHIFT (1)
+#define PINCONF_MODE_MASK (3u << PINCONF_MODE_SHIFT)
+
+#define PINCONF_GET_MODE(p) (((p) & PINCONF_MODE_MASK) >> PINCONF_MODE_SHIFT)
+#define PINCONF_SET_MODE(p) (((p) << PINCONF_MODE_SHIFT) & PINCONF_MODE_MASK)
+
+#define PINCONF_MODE0 (0) /* GPIO */
+#define PINCONF_MODE1 (1) /* Function */
+#define PINCONF_MODE2 (2) /* Function */
+#define PINCONF_MODE3 (3) /* Function */
+
+/* Set pinconf macro Definitions */
+
+#define PINCONF_SET(pin, mode, input, drive, pull) \
+ ( \
+ (PINCONF_SET_PIN(pin)) | \
+ (PINCONF_SET_MODE(mode)) | \
+ (input) | (drive) | (pull) \
+ )
+
+#define PINCONF_SET_GPIO(pin, input) \
+ PINCONF_SET((pin), PINCONF_MODE0, (input), PINCONF_DRIVE_NORMAL, PINCONF_FLOAT)
+
+#define CXD56_PIN_CONFIGS(pin) do { \
+ uint32_t p[] = pin; \
+ cxd56_pin_configs((p), sizeof(p) / sizeof((p)[0])); \
+} while (0)
+
+/********************************************************************************************
+ * Public Types
+ ********************************************************************************************/
+
+struct cxd56_pin_status_s
+{
+ uint32_t mode; /* alternate pin function mode */
+ uint32_t input_en; /* input enable or disable */
+ uint32_t drive; /* strength of drive current */
+ uint32_t pull; /* internal pull-up, pull-down, floating or buskeeper */
+};
+
+typedef struct cxd56_pin_status_s cxd56_pin_status_t;
+
+/********************************************************************************************
+ * Public Data
+ ********************************************************************************************/
+
+#ifndef __ASSEMBLY__
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/********************************************************************************************
+ * Public Functions
+ ********************************************************************************************/
+
+/********************************************************************************************
+ * Name: cxd56_pin_config
+ *
+ * Description:
+ * Configure a pin based on bit-encoded description of the pin.
+ *
+ * Input Value:
+ * 32-bit encoded value describing the pin.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_pin_config(uint32_t pinconf);
+
+/********************************************************************************************
+ * Name: cxd56_pin_configs
+ *
+ * Description:
+ * Configure multiple pins based on bit-encoded description of the pin.
+ *
+ * Input Value:
+ * Array of 32-bit encoded value describing the pin.
+ * Number of elements in the array.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_pin_configs(uint32_t pinconfs[], size_t n);
+
+/********************************************************************************************
+ * Name: cxd56_pin_status
+ *
+ * Description:
+ * Get a pin status.
+ *
+ * Returned Value:
+ * OK on success; A negated errno value on failure.
+ *
+ ********************************************************************************************/
+
+int cxd56_pin_status(uint32_t pin, cxd56_pin_status_t *stat);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_PINCONFIG_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_pmic.c b/arch/arm/src/cxd56xx/cxd56_pmic.c
new file mode 100644
index 00000000000..67690811596
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_pmic.c
@@ -0,0 +1,1467 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_pmic.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#include
+#include "cxd56_pmic.h"
+
+#ifdef CONFIG_CXD56_PMIC
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+enum pmic_cmd_type_e
+{
+ /* basic */
+ PMIC_CMD_READ = 0x00,
+ PMIC_CMD_WRITE,
+ PMIC_CMD_GPO,
+ PMIC_CMD_LOADSW,
+ PMIC_CMD_DDCLDO,
+ PMIC_CMD_INTSTATUS,
+ PMIC_CMD_SETPREVSYS,
+ PMIC_CMD_GETPREVSYS,
+ PMIC_CMD_SETVSYS,
+ PMIC_CMD_GETVSYS,
+ /* charger */
+ PMIC_CMD_GAUGE = 0x10,
+ PMIC_CMD_GET_USB_PORT_TYPE,
+ PMIC_CMD_GET_CHG_STATE,
+ PMIC_CMD_SET_CHG_VOLTAGE,
+ PMIC_CMD_GET_CHG_VOLTAGE,
+ PMIC_CMD_SET_CHG_CURRENT,
+ PMIC_CMD_GET_CHG_CURRENT,
+ PMIC_CMD_SET_CHG_TEMPERATURE_MODE,
+ PMIC_CMD_GET_CHG_TEMPERATURE_MODE,
+ PMIC_CMD_SET_RECHG_VOLTAGE,
+ PMIC_CMD_GET_RECHG_VOLTAGE,
+ PMIC_CMD_PRESET_CHG_CURRENT,
+ PMIC_CMD_CHG_START,
+ PMIC_CMD_CHG_STOP,
+ PMIC_CMD_CHG_PAUSE,
+ PMIC_CMD_CHG_ENABLE,
+ PMIC_CMD_CHG_DISABLE,
+ /* power monitor */
+ PMIC_CMD_POWER_MONITOR_ENABLE = 0x30,
+ PMIC_CMD_POWER_MONITOR_STATUS,
+ PMIC_CMD_POWER_MONITOR_SET,
+ PMIC_CMD_POWER_MONITOR_GET,
+ PMIC_CMD_AFE,
+ PMIC_CMD_SET_CHG_IFIN,
+ PMIC_CMD_GET_CHG_IFIN,
+ PMIC_CMD_SET_CHG_TEMPERATURE_TABLE,
+ PMIC_CMD_GET_CHG_TEMPERATURE_TABLE,
+};
+
+/* Register CNT_USB2 [1:0] USB_CUR_LIM constants */
+
+#define PMIC_CUR_LIM_2_5mA 0
+#define PMIC_CUR_LIM_100mA 1
+#define PMIC_CUR_LIM_500mA 2
+
+/* Register CNT_CHG1 [6:5] VO_CHG_DET4 constants */
+
+#define PMIC_CHG_DET_MINUS400 0
+#define PMIC_CHG_DET_MINUS350 1
+#define PMIC_CHG_DET_MINUS300 2
+#define PMIC_CHG_DET_MINUS250 3
+
+/* Register CNT_CHG2 [7:5] SET_CHG_IFIN constants */
+
+#define PMIC_CHG_IFIN_50 0
+#define PMIC_CHG_IFIN_40 1
+#define PMIC_CHG_IFIN_30 2
+#define PMIC_CHG_IFIN_20 3
+#define PMIC_CHG_IFIN_10 4
+
+/* RTC Register */
+
+#define PMIC_REG_RTC (0x40)
+#define PMIC_REG_RRQ_TIME (0x46)
+#define PMIC_REG_RTC_ALM (0x58)
+#define PMIC_REG_LRQ_ALM (0x5E)
+#define PMIC_REG_RRQ_LRQ_STATUS (0x60)
+
+/* Register RRQ_LRQ_STATUS */
+
+#define RRQ_TIME_STATE (1 << 4)
+#define LRQ_TIME_STATE (1 << 3)
+#define LRQ_OFST_STATE (1 << 2)
+#define LRQ_WU_STATE (1 << 1)
+#define LRQ_ALM_STATE (1 << 0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+/* FarAPI interface structures */
+
+struct pmic_afe_s
+{
+ int voltage;
+ int current;
+ int temperature;
+};
+
+struct pmic_temp_mode_s
+{
+ int low;
+ int high;
+};
+
+extern int PM_PmicControl(int cmd, void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_PMIC_INT
+static pmic_notify_t g_pmic_notify[PMIC_NOTIFY_MAX];
+static struct work_s g_irqwork;
+#endif /* CONFIG_CXD56_PMIC_INT */
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_PMIC_INT
+/************************************************************************************
+ * Name: is_notify_registerd
+ *
+ * Description:
+ * Return whether any notification is registered or not
+ *
+ ************************************************************************************/
+
+static bool is_notify_registerd(void)
+{
+ int i;
+
+ for (i = PMIC_NOTIFY_ALARM; i < PMIC_NOTIFY_MAX; i++)
+ {
+ if (g_pmic_notify[i])
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+/************************************************************************************
+ * Name: pmic_int_worker
+ *
+ * Description:
+ * Work queue for pmic interrupt
+ *
+ ************************************************************************************/
+
+static void pmic_int_worker(void *arg)
+{
+ int i;
+ uint8_t stat;
+ irqstate_t flags;
+ int irq = CXD56_IRQ_PMIC;
+
+ /* Get interrupt cause with clear and call the registered callback */
+
+ cxd56_pmic_get_interrupt_status(&stat);
+
+ for (i = PMIC_NOTIFY_ALARM; i < PMIC_NOTIFY_MAX; i++)
+ {
+ if ((stat & (1 << i)) && g_pmic_notify[i])
+ {
+ g_pmic_notify[i](arg);
+ }
+ }
+
+ /* Prevent from the race condition with up_pmic_set_notify() */
+
+ flags = enter_critical_section();
+
+ /* After processing of each notification, enable the pmic interrupt again */
+
+ if (is_notify_registerd())
+ {
+ up_enable_irq(irq);
+ }
+
+ leave_critical_section(flags);
+}
+
+/************************************************************************************
+ * Name: pmic_int_handler
+ *
+ * Description:
+ * Interrupt handler for pmic interrupt
+ *
+ ************************************************************************************/
+
+static int pmic_int_handler(int irq, void *context, void *arg)
+{
+ int ret;
+
+ /* Schedule the callback to occur on the low-priority worker thread */
+
+ DEBUGASSERT(work_available(&g_irqwork));
+ ret = work_queue(LPWORK, &g_irqwork, pmic_int_worker, NULL, 0);
+ if (ret < 0)
+ {
+ logerr("ERROR: work_queue failed: %d\n", ret);
+ }
+
+ /* Disable any further pmic interrupts */
+
+ up_disable_irq(irq);
+
+ return OK;
+}
+#endif /* CONFIG_CXD56_PMIC_INT */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_interrupt_status
+ *
+ * Description:
+ * Get Raw Interrupt Status register. And furthermore, if status is set,
+ * then clear the interrupt. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---------------+-----+-----+-----+-----+
+ * | x x x x |VSYS |WKUPL|WKUPS|ALARM| target of status
+ * +---------------+-----+-----+-----+-----+
+ *
+ * Input Parameter:
+ * status - a pointer to the polled value of interrupt status
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * status - return the value of interrupt status register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_get_interrupt_status(uint8_t *status)
+{
+ return PM_PmicControl(PMIC_CMD_INTSTATUS, status);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_gpo_reg
+ *
+ * Description:
+ * Set GPO register. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---+---+---+---+---+---+---+---+
+ * |CH3|CH2|CH1|CH0|CH3|CH2|CH1|CH0| target of setbit0/clrbit0
+ * +---+---+---+---+---+---+---+---+
+ * +---+---+---+---+---+---+---+---+
+ * |CH7|CH6|CH5|CH4|CH7|CH6|CH5|CH4| target of setbit1/clrbit1
+ * +---+---+---+---+---+---+---+---+
+ * |<- 0: Hi-Z ->|<- 0: Low ->|
+ * |<- 1: Output ->|<- 1: High ->|
+ *
+ * Input Parameter:
+ * setbitX - set bit that 1 is set
+ * clrbitX - clear bit that 1 is set
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * setbitX - return the current value of register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_gpo_reg(uint8_t *setbit0, uint8_t *clrbit0,
+ uint8_t *setbit1, uint8_t *clrbit1)
+{
+ struct pmic_gpo_arg_s
+ {
+ uint8_t *setbit0;
+ uint8_t *clrbit0;
+ uint8_t *setbit1;
+ uint8_t *clrbit1;
+ }
+ arg =
+ {
+ .setbit0 = setbit0,
+ .clrbit0 = clrbit0,
+ .setbit1 = setbit1,
+ .clrbit1 = clrbit1,
+ };
+
+ return PM_PmicControl(PMIC_CMD_GPO, &arg);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_gpo
+ *
+ * Description:
+ * Set High/Low to the specified GPO channel(s)
+ *
+ * Input Parameter:
+ * chset - GPO Channel number(s)
+ * value - true if output high, false if output low.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_gpo(uint8_t chset, bool value)
+{
+ uint8_t setbit0 = 0;
+ uint8_t clrbit0 = 0;
+ uint8_t setbit1 = 0;
+ uint8_t clrbit1 = 0;
+ uint8_t set;
+
+ /* Set GPO0~3 */
+
+ set = chset & 0xf;
+ if (set)
+ {
+ if (value)
+ {
+ setbit0 = (set << 4) | set;
+ }
+ else
+ {
+ setbit0 = (set << 4);
+ clrbit0 = set;
+ }
+ }
+
+ /* Set GPO4~7 */
+
+ set = (chset >> 4) & 0xf;
+ if (set)
+ {
+ if (value)
+ {
+ setbit1 = (set << 4) | set;
+ }
+ else
+ {
+ setbit1 = (set << 4);
+ clrbit1 = set;
+ }
+ }
+
+ return cxd56_pmic_set_gpo_reg(&setbit0, &clrbit0, &setbit1, &clrbit1);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_gpo_hiz
+ *
+ * Description:
+ * Set Hi-Z to the specified GPO channel(s)
+ *
+ * Input Parameter:
+ * chset - GPO Channel number(s)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_gpo_hiz(uint8_t chset)
+{
+ uint8_t setbit0 = 0;
+ uint8_t clrbit0 = 0;
+ uint8_t setbit1 = 0;
+ uint8_t clrbit1 = 0;
+ uint8_t set;
+
+ /* Set GPO0~3 */
+
+ set = chset & 0xf;
+ if (set)
+ {
+ clrbit0 = (set << 4) | set;
+ }
+
+ /* Set GPO4~7 */
+
+ set = (chset >> 4) & 0xf;
+ if (set)
+ {
+ clrbit1 = (set << 4) | set;
+ }
+
+ return cxd56_pmic_set_gpo_reg(&setbit0, &clrbit0, &setbit1, &clrbit1);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_gpo
+ *
+ * Description:
+ * Get the value from the specified GPO channel(s)
+ *
+ * Input Parameter:
+ * chset : GPO Channel number(s)
+ *
+ * Returned Value:
+ * Return true if all of the specified chset are high. Otherwise, return false
+ *
+ ****************************************************************************/
+
+bool cxd56_pmic_get_gpo(uint8_t chset)
+{
+ uint8_t setbit0 = 0;
+ uint8_t clrbit0 = 0;
+ uint8_t setbit1 = 0;
+ uint8_t clrbit1 = 0;
+ uint8_t set;
+
+ cxd56_pmic_set_gpo_reg(&setbit0, &clrbit0, &setbit1, &clrbit1);
+
+ set = ((setbit1 & 0xf) << 4) | (setbit0 & 0xf);
+
+ /* If all of the specified chset is high, return true */
+
+ if ((set & chset) == chset)
+ {
+ return true;
+ }
+ return false;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_loadswitch_reg
+ *
+ * Description:
+ * Set LoadSwitch register. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---+---+---+---+---+---+---+---+
+ * | - | - | - |CH4|CH3|CH2| 1 | 1 | target of setbit/clrbit
+ * +---+---+---+---+---+---+---+---+
+ * |<- 0: Off->|
+ * |<- 1: On ->|
+ *
+ * Input Parameter:
+ * setbit - set bit that 1 is set
+ * clrbit - clear bit that 1 is set
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * setbit - return the current value of register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_loadswitch_reg(uint8_t *setbit, uint8_t *clrbit)
+{
+ struct pmic_loadswitch_arg_s
+ {
+ uint8_t *setbit;
+ uint8_t *clrbit;
+ }
+ arg =
+ {
+ .setbit = setbit,
+ .clrbit = clrbit,
+ };
+
+ return PM_PmicControl(PMIC_CMD_LOADSW, &arg);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_loadswitch
+ *
+ * Description:
+ * Set On/Off to the specified LoadSwitch channel(s)
+ *
+ * Input Parameter:
+ * chset - LoadSwitch Channel number(s)
+ * value - true if set on, false if set off.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_loadswitch(uint8_t chset, bool value)
+{
+ uint8_t setbit = 0;
+ uint8_t clrbit = 0;
+
+ if (value)
+ {
+ setbit = chset;
+ }
+ else
+ {
+ clrbit = chset;
+ }
+ return cxd56_pmic_set_loadswitch_reg(&setbit, &clrbit);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_loadswitch
+ *
+ * Description:
+ * Get the value from the specified LoadSwitch channel(s)
+ *
+ * Input Parameter:
+ * chset - LoadSwitch Channel number(s)
+ *
+ * Returned Value:
+ * Return true if all of the specified chset are on. Otherwise, return false
+ *
+ ****************************************************************************/
+
+bool cxd56_pmic_get_loadswitch(uint8_t chset)
+{
+ uint8_t setbit = 0;
+ uint8_t clrbit = 0;
+
+ cxd56_pmic_set_loadswitch_reg(&setbit, &clrbit);
+
+ return ((setbit & chset) == chset);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_ddc_ldo_reg
+ *
+ * Description:
+ * Set DDC/LDO register. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +----+----+----+----+----+----+----+----+
+ * | | |LDO |DDC |LDO |DDC |LDO |DDC | target of setbit/clrbit
+ * | - | - |PERI|CORE|ANA |ANA |EMMC|IO |
+ * +----+----+----+----+----+----+----+----+
+ * |<- 0: Off ->|
+ * |<- 1: On ->|
+ *
+ * Input Parameter:
+ * setbit - set bit that 1 is set
+ * clrbit - clear bit that 1 is set
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * setbit - return the current value of register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_ddc_ldo_reg(uint8_t *setbit, uint8_t *clrbit)
+{
+ struct pmic_ddc_ldo_arg_s
+ {
+ uint8_t *setbit;
+ uint8_t *clrbit;
+ }
+ arg =
+ {
+ .setbit = setbit,
+ .clrbit = clrbit,
+ };
+
+ return PM_PmicControl(PMIC_CMD_DDCLDO, &arg);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_ddc_ldo
+ *
+ * Description:
+ * Set On/Off to the specified DDC/LDO channel(s)
+ *
+ * Input Parameter:
+ * chset - DDC/LO Channel number(s)
+ * value - true if set on, false if set off.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_ddc_ldo(uint8_t chset, bool value)
+{
+ uint8_t setbit = 0;
+ uint8_t clrbit = 0;
+
+ if (value)
+ {
+ setbit = chset;
+ }
+ else
+ {
+ clrbit = chset;
+ }
+ return cxd56_pmic_set_ddc_ldo_reg(&setbit, &clrbit);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_ddc_ldo
+ *
+ * Description:
+ * Get the value from the specified DDC/LDO channel(s)
+ *
+ * Input Parameter:
+ * chset - DDC/LDO Channel number(s)
+ *
+ * Returned Value:
+ * Return true if all of the specified chset are on. Otherwise, return false
+ *
+ ****************************************************************************/
+
+bool cxd56_pmic_get_ddc_ldo(uint8_t chset)
+{
+ uint8_t setbit = 0;
+ uint8_t clrbit = 0;
+
+ cxd56_pmic_set_ddc_ldo_reg(&setbit, &clrbit);
+
+ return ((setbit & chset) == chset);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_rtc
+ *
+ * Description:
+ * Get the RTC value from PMIC
+ *
+ * Input Parameter:
+ * count - the pointer to the returned RTC counter value
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_get_rtc(uint64_t *count)
+{
+ int ret = 0;
+ uint8_t data;
+ uint8_t rtc[6];
+
+ if (!count) return -EINVAL;
+
+ data = 0x1;
+ ret = cxd56_pmic_write(PMIC_REG_RRQ_TIME, &data, sizeof(data));
+ if (ret) goto error;
+
+ do {
+ ret = cxd56_pmic_read(PMIC_REG_RRQ_LRQ_STATUS, &data, sizeof(data));
+ if (ret) goto error;
+ } while (!(RRQ_TIME_STATE & data));
+
+ ret = cxd56_pmic_read(PMIC_REG_RTC, rtc, sizeof(rtc));
+ if (ret) goto error;
+
+ *count =
+ (((uint64_t)((rtc[5] << 24) | (rtc[4] << 16) | (rtc[3] << 8) | rtc[2]) << 15) |
+ ((rtc[1] << 8) | rtc[0]));
+
+error:
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_gauge
+ *
+ * Description:
+ * Get the set of values (voltage, current and temperature) from PMIC.
+ *
+ * Input Parameter:
+ * gauge - Set of gauge related values
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_get_gauge(FAR struct pmic_gauge_s *gauge)
+{
+ return PM_PmicControl(PMIC_CMD_AFE, gauge);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getlowervol
+ *
+ * Description:
+ * Get lower limit of voltage for system to be running.
+ *
+ * Input Parameter:
+ * voltage - Lower limit voltage (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getlowervol(FAR int *vol)
+{
+ return PM_PmicControl(PMIC_CMD_GETVSYS, vol);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargevol
+ *
+ * Description:
+ * Get charge voltage
+ *
+ * Input Parameter:
+ * voltage - Possible values are every 50 between 4000 to 4400 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargevol(FAR int *voltage)
+{
+ int val;
+ int ret;
+
+ ret = PM_PmicControl(PMIC_CMD_GET_CHG_VOLTAGE, &val);
+ if (ret)
+ {
+ return -EIO;
+ }
+
+ val &= 0xf;
+
+ /* Convert register value to actual voltage (mV) */
+
+ if (val <= 8)
+ {
+ *voltage = 4000 + (val * 50);
+ }
+ else
+ {
+ *voltage = 4200;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargevol
+ *
+ * Description:
+ * Set charge voltage
+ *
+ * Input Parameter:
+ * voltage - Avalable values are every 50 between 4000 to 4400 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargevol(int voltage)
+{
+ int val;
+
+ /* Sanity check */
+
+ if (voltage < 4000 || voltage > 4400)
+ {
+ return -EINVAL;
+ }
+ if (voltage % 50)
+ {
+ return -EINVAL;
+ }
+
+ /* Register setting values are every 50mV between 4.0V to 4.4V */
+
+ val = (voltage - 4000) / 50;
+
+ return PM_PmicControl(PMIC_CMD_SET_CHG_VOLTAGE, (void *)val);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargecurrent
+ *
+ * Description:
+ * Get charge current value
+ *
+ * Input Parameter:
+ * current - Possible values are 2, 100 and 500 (mA). However,
+ * 2 means 2.5 mA actually.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargecurrent(FAR int *current)
+{
+ int val;
+ int ret;
+
+ ret = PM_PmicControl(PMIC_CMD_GET_CHG_CURRENT, &val);
+ if (ret)
+ {
+ return ret;
+ }
+
+ /* Convert register value to current */
+
+ switch (val & 0x3)
+ {
+ case PMIC_CUR_LIM_2_5mA:
+ *current = 2;
+ break;
+
+ case PMIC_CUR_LIM_100mA:
+ *current = 100;
+ break;
+
+ case PMIC_CUR_LIM_500mA:
+ *current = 500;
+ break;
+
+ default:
+ return -EFAULT;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargecurrent
+ *
+ * Description:
+ * Set charge current value
+ *
+ * Input Parameter:
+ * current - Available values are 2, 100 and 500 (mA). However, 2 means
+ * 2.5 mA actually.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargecurrent(int current)
+{
+ int val;
+
+ /* Replace current values for CNT_USB2 [1:0] USB_CUR_LIM */
+
+ switch (current)
+ {
+ case 2:
+ val = PMIC_CUR_LIM_2_5mA;
+ break;
+
+ case 100:
+ val = PMIC_CUR_LIM_100mA;
+ break;
+
+ case 500:
+ val = PMIC_CUR_LIM_500mA;
+ break;
+
+ default:
+ return -EFAULT;
+ }
+
+ return PM_PmicControl(PMIC_CMD_SET_CHG_CURRENT, (void *)val);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getporttype
+ *
+ * Description:
+ * Get USB port type
+ *
+ * Input Parameter:
+ * porttype - PMIC_PORTTYPE_SDP or PMIC_PORTTYPE_DCPCDP
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getporttype(FAR int *porttype)
+{
+ return PM_PmicControl(PMIC_CMD_GET_USB_PORT_TYPE, porttype);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargestate
+ *
+ * Description:
+ * Read charging status
+ *
+ * Input Parameter:
+ * state - Charging status (see PMIC_STAT_* definitions)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargestate(uint8_t *state)
+{
+ struct pmic_afe_s arg;
+ int val;
+ int ret;
+
+ /* Update charge state */
+
+ ret = PM_PmicControl(PMIC_CMD_AFE, &arg);
+ if (ret)
+ {
+ return ret;
+ }
+
+ /* Get actual charging state (CNT_USB1) */
+
+ ret = PM_PmicControl(PMIC_CMD_GET_CHG_STATE, &val);
+ *state = val & 0xff;
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_setrechargevol
+ *
+ * Description:
+ * Set threshold voltage against full charge for automatic restart charging.
+ *
+ * Input Parameter:
+ * mV - Available values are -400, -350, -300 and -250 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setrechargevol(int mV)
+{
+ int val;
+
+ /* Convert voltage to register value */
+
+ switch (mV)
+ {
+ case -400:
+ val = PMIC_CHG_DET_MINUS400;
+ break;
+
+ case -350:
+ val = PMIC_CHG_DET_MINUS350;
+ break;
+
+ case -300:
+ val = PMIC_CHG_DET_MINUS300;
+ break;
+
+ case -250:
+ val = PMIC_CHG_DET_MINUS250;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return PM_PmicControl(PMIC_CMD_SET_RECHG_VOLTAGE, (void *)val);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getrechargevol
+ *
+ * Description:
+ * Get threshold voltage against full charge for automatic restart charging.
+ *
+ * Input Parameter:
+ * mV - Possible values are -400, -350, -300 and -250 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getrechargevol(FAR int *mV)
+{
+ int val;
+ int ret;
+
+ ret = PM_PmicControl(PMIC_CMD_GET_RECHG_VOLTAGE, &val);
+ if (ret)
+ {
+ return ret;
+ }
+
+ /* Convert regsiter value to voltage */
+
+ switch (val)
+ {
+ case PMIC_CHG_DET_MINUS400:
+ *mV = -400;
+ break;
+
+ case PMIC_CHG_DET_MINUS350:
+ *mV = -350;
+ break;
+
+ case PMIC_CHG_DET_MINUS300:
+ *mV = -300;
+ break;
+
+ case PMIC_CHG_DET_MINUS250:
+ *mV = -250;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargecompcurrent
+ *
+ * Description:
+ * Set current value setting for determine fully charged.
+ *
+ * Input Parameter:
+ * current - Possible values are 50, 40, 30, 20 and 10 (mA)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargecompcurrent(int current)
+{
+ int val;
+
+ /* Convert current (mA) to register value */
+
+ switch (current)
+ {
+ case 50:
+ val = PMIC_CHG_IFIN_50;
+ break;
+
+ case 40:
+ val = PMIC_CHG_IFIN_40;
+ break;
+
+ case 30:
+ val = PMIC_CHG_IFIN_30;
+ break;
+
+ case 20:
+ val = PMIC_CHG_IFIN_20;
+ break;
+
+ case 10:
+ val = PMIC_CHG_IFIN_10;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return PM_PmicControl(PMIC_CMD_SET_CHG_IFIN, (void*)val);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargecompcurrent
+ *
+ * Description:
+ * Get current value setting for determine fully charged.
+ *
+ * Input Parameter:
+ * current - Available values are 50, 40, 30, 20 and 10 (mA)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargecompcurrent(FAR int *current)
+{
+ int val;
+ int ret;
+
+ ret = PM_PmicControl(PMIC_CMD_GET_CHG_IFIN, &val);
+ if (ret)
+ {
+ return ret;
+ }
+
+ /* Convert register value to current (mA) */
+
+ switch (val)
+ {
+ case PMIC_CHG_IFIN_50:
+ *current = 50;
+ break;
+
+ case PMIC_CHG_IFIN_40:
+ *current = 40;
+ break;
+
+ case PMIC_CHG_IFIN_30:
+ *current = 30;
+ break;
+
+ case PMIC_CHG_IFIN_20:
+ *current = 20;
+ break;
+
+ case PMIC_CHG_IFIN_10:
+ *current = 10;
+ break;
+
+ default:
+ *current = 0;
+ ret = -EFAULT;
+ break;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_gettemptable
+ *
+ * Description:
+ * Get temperature detect resistance table
+ *
+ * Input Parameter:
+ * table - Settings values for temperature detecting (see CXD5247GF
+ * specification for more detail)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_gettemptable(FAR struct pmic_temp_table_s *table)
+{
+ /* SET_T60 (70h) - SET_T0_2 (78h) */
+
+ return PM_PmicControl(PMIC_CMD_GET_CHG_TEMPERATURE_TABLE, table);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_settemptable
+ *
+ * Description:
+ * Set temperature detect resistance table
+ *
+ * Input Parameter:
+ * table - Settings values for temperature detecting (see CXD5247GF
+ * specification for more detail)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_settemptable(FAR struct pmic_temp_table_s *table)
+{
+ return PM_PmicControl(PMIC_CMD_SET_CHG_TEMPERATURE_TABLE, table);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargemode
+ *
+ * Description:
+ * Set charging mode in each low/high temperatures.
+ * In lower than 10 degrees Celsius, charging mode will be changed on/off
+ * and weak (half of charge current) according to setting.
+ * In higher than 45 degrees Celsius, charging mode will be charged on/off
+ * and weak (-0.15V from charge voltage) according to setting.
+ *
+ * Input Parameter:
+ * low - Charging mode in low temperature (see PMIC_CHGMODE_*)
+ * high - Charging mode in high temperature (see PMIC_CHGMODE_*)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargemode(int low, int high)
+{
+ struct pmic_temp_mode_s arg;
+
+ /* CNT_CHG3
+ * [3:2] SEL_CHG_THL: <-> low
+ * [1:0] SEL_CHG_THH: <-> high
+ */
+
+ /* Sanity check */
+
+ if (low == PMIC_CHGMODE_ON || low == PMIC_CHGMODE_OFF ||
+ low == PMIC_CHGMODE_WEAK)
+ {
+ arg.low = low;
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ if (high == PMIC_CHGMODE_ON || high == PMIC_CHGMODE_OFF ||
+ high == PMIC_CHGMODE_WEAK)
+ {
+ arg.high = high;
+ }
+ else
+ {
+ return -EINVAL;
+ }
+
+ return PM_PmicControl(PMIC_CMD_SET_CHG_TEMPERATURE_MODE, &arg);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargemode
+ *
+ * Description:
+ * Get charging mode in each low/high temperatures.
+ * In lower than 10 degrees Celsius, charging mode will be changed on/off
+ * and weak (half of charge current) according to setting.
+ * In higher than 45 degrees Celsius, charging mode will be charged on/off
+ * and weak (-0.15V from charge voltage) according to setting.
+ *
+ * Input Parameter:
+ * low - Charging mode in low temperature (see PMIC_CHG_*)
+ * high - Charging mode in high temperature (see PMIC_CHG_*)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargemode(FAR int *low, FAR int *high)
+{
+ struct pmic_temp_mode_s arg;
+ int ret;
+
+ ret = PM_PmicControl(PMIC_CMD_GET_CHG_TEMPERATURE_MODE, &arg);
+ if (ret)
+ {
+ return ret;
+ }
+
+ *low = arg.low;
+ *high = arg.high;
+
+ return OK;
+}
+
+#ifdef CONFIG_CXD56_PMIC_BATMONITOR
+/****************************************************************************
+ * Battery monitor for debug
+ ****************************************************************************/
+
+int cxd56_pmic_monitor_enable(FAR struct pmic_mon_s *ptr)
+{
+ return PM_PmicControl(PMIC_CMD_POWER_MONITOR_ENABLE, ptr);
+}
+
+int cxd56_pmic_monitor_status(FAR struct pmic_mon_status_s *ptr)
+{
+ return PM_PmicControl(PMIC_CMD_POWER_MONITOR_STATUS, ptr);
+}
+
+int cxd56_pmic_monitor_set(FAR struct pmic_mon_set_s *ptr)
+{
+ return PM_PmicControl(PMIC_CMD_POWER_MONITOR_SET, ptr);
+}
+
+int cxd56_pmic_monitor_get(FAR struct pmic_mon_log_s *ptr)
+{
+ return PM_PmicControl(PMIC_CMD_POWER_MONITOR_GET, ptr);
+}
+#endif
+
+#ifdef CONFIG_CXD56_PMIC_INT
+/****************************************************************************
+ * Name: up_pmic_set_notify
+ *
+ * Description:
+ * Register a callback for pmic interrupt
+ *
+ * Input Parameter:
+ * kind - A kind of pmic interrupt defined as pmic_notify_e
+ * cb - A callback function for a kind of pmic interrupt
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int up_pmic_set_notify(int kind, pmic_notify_t cb)
+{
+ static int is_first = 1;
+ irqstate_t flags;
+ int irq = CXD56_IRQ_PMIC;
+ int delayed_work = 0;
+
+ if ((kind < PMIC_NOTIFY_ALARM) || (PMIC_NOTIFY_MAX <= kind))
+ {
+ return -EINVAL;
+ }
+
+ /* attach interrupt handler only for the first time */
+
+ if (is_first)
+ {
+ irq_attach(irq, pmic_int_handler, NULL);
+ is_first = 0;
+ }
+
+ flags = enter_critical_section();
+
+ g_pmic_notify[kind] = cb;
+
+ if (is_notify_registerd())
+ {
+ /* If up_enable_irq() is called when interrupt is pending,
+ * an assertion may occur because workqueue is not prepared yet.
+ * As the workaround, call worker directly and in the worker
+ * both interrupt clear and enable processing are performed.
+ */
+
+ delayed_work = 1;
+ }
+ else
+ {
+ up_disable_irq(irq);
+ }
+
+ leave_critical_section(flags);
+
+ if (delayed_work)
+ {
+ pmic_int_worker(NULL);
+ }
+
+ return 0;
+}
+#endif /* CONFIG_CXD56_PMIC_INT */
+
+/****************************************************************************
+ * Name: cxd56_pmic_read
+ *
+ * Description:
+ * Read the value from the specified sub address
+ *
+ * Input Parameter:
+ * addr - sub address
+ * buf - pointer to read buffer
+ * size - byte count of read
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_read(uint8_t addr, void *buf, uint32_t size)
+{
+ struct pmic_trans_arg_s
+ {
+ uint8_t addr;
+ void *buf;
+ uint32_t size;
+ }
+ arg =
+ {
+ .addr = addr,
+ .buf = buf,
+ .size = size,
+ };
+
+ return PM_PmicControl(PMIC_CMD_READ, &arg);
+}
+
+/****************************************************************************
+ * Name: cxd56_pmic_write
+ *
+ * Description:
+ * Write the value to the specified sub address
+ *
+ * Input Parameter:
+ * addr - sub address
+ * buf - pointer to write buffer
+ * size - byte count of write
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_write(uint8_t addr, void *buf, uint32_t size)
+{
+ struct pmic_trans_arg_s
+ {
+ uint8_t addr;
+ void *buf;
+ uint32_t size;
+ }
+ arg =
+ {
+ .addr = addr,
+ .buf = buf,
+ .size = size,
+ };
+
+ return PM_PmicControl(PMIC_CMD_WRITE, &arg);
+}
+
+#endif /* CONFIG_CXD56_PMIC */
diff --git a/arch/arm/src/cxd56xx/cxd56_pmic.h b/arch/arm/src/cxd56xx/cxd56_pmic.h
new file mode 100644
index 00000000000..7712c0a9a35
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_pmic.h
@@ -0,0 +1,761 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_pmic.h
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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 of Sony Semiconductor Solutions Corporation 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_PMIC_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_PMIC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+
+#include
+#include
+#include
+
+#ifdef CONFIG_CXD56_PMIC
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* PMIC Register Definitions */
+
+#define PMIC_REG_DDC_ANA1 (0x26)
+#define PMIC_REG_CNT_USB2 (0x81)
+
+/* PMIC DDC_ANA1 Definitions */
+
+#define PMIC_PM_HIZ (2u << 4)
+#define PMIC_PM_DEF (0u << 4)
+#define PMIC_IOST_DEF (2u << 2)
+#define PMIC_IOMAX_DEF (2u << 0)
+
+/* PMIC CNT_USB2 Definitions */
+
+#define PMIC_SET_CHGOFF (1u << 2)
+
+/* PMIC Interrupt Status Definitions */
+
+#define PMIC_INT_ALARM (1u << 0)
+#define PMIC_INT_WKUPS (1u << 1)
+#define PMIC_INT_WKUPL (1u << 2)
+#define PMIC_INT_VSYS (1u << 3)
+
+/* PMIC GPO Channel Definitions */
+
+#define PMIC_GPO0 (1u << 0)
+#define PMIC_GPO1 (1u << 1)
+#define PMIC_GPO2 (1u << 2)
+#define PMIC_GPO3 (1u << 3)
+#define PMIC_GPO4 (1u << 4)
+#define PMIC_GPO5 (1u << 5)
+#define PMIC_GPO6 (1u << 6)
+#define PMIC_GPO7 (1u << 7)
+
+/* PMIC LoadSwitch Channel Definitions */
+
+#define PMIC_LOADSW2 (1u << 2)
+#define PMIC_LOADSW3 (1u << 3)
+#define PMIC_LOADSW4 (1u << 4)
+
+/* PMIC DDC/LDO Channel Definitions */
+
+#define PMIC_DDC_IO (1u << 0)
+#define PMIC_LDO_EMMC (1u << 1)
+#define PMIC_DDC_ANA (1u << 2)
+#define PMIC_LDO_ANA (1u << 3)
+#define PMIC_DDC_CORE (1u << 4)
+#define PMIC_LDO_PERI (1u << 5)
+
+/* Charge mode for both of low/high temperature */
+
+#define PMIC_CHGMODE_ON 0x00
+#define PMIC_CHGMODE_OFF 0x01
+#define PMIC_CHGMODE_WEAK 0x02
+
+/* Charge status */
+
+#define PMIC_STAT_INIT_RST 0
+#define PMIC_STAT_INIT_WAIT 1
+#define PMIC_STAT_INIT_CHK 2
+#define PMIC_STAT_DBP_START 3
+#define PMIC_STAT_DB_INICHARGE 4
+#define PMIC_STAT_DB_PRECHARGE 5
+#define PMIC_STAT_DCON_WAIT 6
+#define PMIC_STAT_PD_START 7
+#define PMIC_STAT_DM_COMPARE 8
+#define PMIC_STAT_PD_END 9
+#define PMIC_STAT_BAT_WAIT 10
+#define PMIC_STAT_CHG_STOP 11
+#define PMIC_STAT_GB_PRECHARGE 12
+#define PMIC_STAT_GB_QCKCHARGE 13
+#define PMIC_STAT_GB_LOWCHARGE 14
+#define PMIC_STAT_GB_HIGHCHARGE 15
+#define PMIC_STAT_CHG_JUDGE 16
+#define PMIC_STAT_CHG_COMPLETE 17
+#define PMIC_STAT_GB_CONWAIT 18
+#define PMIC_STAT_GB_CPTEMPWAIT1 19
+#define PMIC_STAT_GB_CPTEMPWAIT2 20
+#define PMIC_STAT_GB_TEMPWAIT 21
+#define PMIC_STAT_DB_TEMPWAIT 22
+#define PMIC_STAT_DB_CONWAIT 23
+#define PMIC_STAT_BAT_UNUSUAL 24
+#define PMIC_STAT_BAT_DISCON 25
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct pmic_gauge_s
+{
+ int voltage;
+ int current;
+ int temp;
+};
+
+struct pmic_temp_table_s
+{
+ int T60;
+ int T45;
+ int T10;
+ int T00;
+};
+
+struct pmic_mon_s
+{
+ int on;
+ int interval;
+ int threshold_volt;
+ int threshold_current;
+};
+
+struct pmic_mon_status_s
+{
+ int bRun;
+ int index;
+ int latest;
+ int total_watt;
+ int total_time;
+};
+
+struct pmic_mon_set_s
+{
+ int clearBuf;
+ int clearSum;
+};
+
+struct pmic_mon_rec_s
+{
+ uint16_t index;
+ uint16_t timestamp;
+ uint16_t voltage;
+ int16_t current;
+};
+
+struct pmic_mon_log_s
+{
+ FAR struct pmic_monitor_rec_s *rec;
+ int index;
+ int size;
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifndef __ASSEMBLY__
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_interrupt_status
+ *
+ * Description:
+ * Get Raw Interrupt Status register. And furthermore, if status is set,
+ * then clear the interrupt. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---------------+-----+-----+-----+-----+
+ * | x x x x |VSYS |WKUPL|WKUPS|ALARM| target of status
+ * +---------------+-----+-----+-----+-----+
+ *
+ * Input Parameter:
+ * status - a pointer to the polled value of interrupt status
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * status - return the value of interrupt status register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_get_interrupt_status(FAR uint8_t *status);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_gpo_reg
+ *
+ * Description:
+ * Set GPO register. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---+---+---+---+---+---+---+---+
+ * |CH3|CH2|CH1|CH0|CH3|CH2|CH1|CH0| target of setbit0/clrbit0
+ * +---+---+---+---+---+---+---+---+
+ * +---+---+---+---+---+---+---+---+
+ * |CH7|CH6|CH5|CH4|CH7|CH6|CH5|CH4| target of setbit1/clrbit1
+ * +---+---+---+---+---+---+---+---+
+ * |<- 0: Hi-Z ->|<- 0: Low ->|
+ * |<- 1: Output ->|<- 1: High ->|
+ *
+ * Input Parameter:
+ * setbitX - set bit that 1 is set
+ * clrbitX - clear bit that 1 is set
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * setbitX - return the current value of register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_gpo_reg(FAR uint8_t *setbit0, FAR uint8_t *clrbit0,
+ FAR uint8_t *setbit1, FAR uint8_t *clrbit1);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_gpo
+ *
+ * Description:
+ * Set High/Low to the specified GPO channel(s)
+ *
+ * Input Parameter:
+ * chset - GPO Channel number(s)
+ * value - true if output high, false if output low.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_gpo(uint8_t chset, bool value);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_gpo_hiz
+ *
+ * Description:
+ * Set Hi-Z to the specified GPO channel(s)
+ *
+ * Input Parameter:
+ * chset - GPO Channel number(s)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_gpo_hiz(uint8_t chset);
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_gpo
+ *
+ * Description:
+ * Get the value from the specified GPO channel(s)
+ *
+ * Input Parameter:
+ * chset : GPO Channel number(s)
+ *
+ * Returned Value:
+ * Return true if all of the specified chset are high. Otherwise, return false
+ *
+ ****************************************************************************/
+
+bool cxd56_pmic_get_gpo(uint8_t chset);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_loadswitch_reg
+ *
+ * Description:
+ * Set LoadSwitch register. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +---+---+---+---+---+---+---+---+
+ * | - | - | - |CH4|CH3|CH2| 1 | 1 | target of setbit/clrbit
+ * +---+---+---+---+---+---+---+---+
+ * |<- 0: Off->|
+ * |<- 1: On ->|
+ *
+ * Input Parameter:
+ * setbit - set bit that 1 is set
+ * clrbit - clear bit that 1 is set
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * setbit - return the current value of register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_loadswitch_reg(FAR uint8_t *setbit, FAR uint8_t *clrbit);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_loadswitch
+ *
+ * Description:
+ * Set On/Off to the specified LoadSwitch channel(s)
+ *
+ * Input Parameter:
+ * chset - LoadSwitch Channel number(s)
+ * value - true if set on, false if set off.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_loadswitch(uint8_t chset, bool value);
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_loadswitch
+ *
+ * Description:
+ * Get the value from the specified LoadSwitch channel(s)
+ *
+ * Input Parameter:
+ * chset - LoadSwitch Channel number(s)
+ *
+ * Returned Value:
+ * Return true if all of the specified chset are on. Otherwise, return false
+ *
+ ****************************************************************************/
+
+bool cxd56_pmic_get_loadswitch(uint8_t chset);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_ddc_ldo_reg
+ *
+ * Description:
+ * Set DDC/LDO register. Register's decription is below:
+ *
+ * 7 6 5 4 3 2 1 0
+ * +----+----+----+----+----+----+----+----+
+ * | | |LDO |DDC |LDO |DDC |LDO |DDC | target of setbit/clrbit
+ * | - | - |PERI|CORE|ANA |ANA |EMMC|IO |
+ * +----+----+----+----+----+----+----+----+
+ * |<- 0: Off ->|
+ * |<- 1: On ->|
+ *
+ * Input Parameter:
+ * setbit - set bit that 1 is set
+ * clrbit - clear bit that 1 is set
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ * setbit - return the current value of register
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_ddc_ldo_reg(FAR uint8_t *setbit, FAR uint8_t *clrbit);
+
+/****************************************************************************
+ * Name: cxd56_pmic_set_ddc_ldo
+ *
+ * Description:
+ * Set On/Off to the specified DDC/LDO channel(s)
+ *
+ * Input Parameter:
+ * chset - DDC/LO Channel number(s)
+ * value - true if set on, false if set off.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_set_ddc_ldo(uint8_t chset, bool value);
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_ddc_ldo
+ *
+ * Description:
+ * Get the value from the specified DDC/LDO channel(s)
+ *
+ * Input Parameter:
+ * chset - DDC/LDO Channel number(s)
+ *
+ * Returned Value:
+ * Return true if all of the specified chset are on. Otherwise, return false
+ *
+ ****************************************************************************/
+
+bool cxd56_pmic_get_ddc_ldo(uint8_t chset);
+
+/****************************************************************************
+ * Name: cxd56_pmic_get_gauge
+ *
+ * Description:
+ * Get the set of values (gauge, voltage, current and temperature) from
+ * PMIC.
+ *
+ * Input Parameter:
+ * gauge - Set of gauge values
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_get_gauge(FAR struct pmic_gauge_s *gauge);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getlowervol
+ *
+ * Description:
+ * Get lower limit of voltage for system to be running.
+ *
+ * Input Parameter:
+ * voltage - Lower limit voltage (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getlowervol(FAR int *vol);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargevol
+ *
+ * Description:
+ * Get charge voltage
+ *
+ * Input Parameter:
+ * voltage - Possible values are every 50 between 4000 to 4400 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargevol(FAR int *voltage);
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargevol
+ *
+ * Description:
+ * Set charge voltage
+ *
+ * Input Parameter:
+ * voltage - Avalable values are every 50 between 4000 to 4400 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargevol(int voltage);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargecurrent
+ *
+ * Description:
+ * Get charge current value
+ *
+ * Input Parameter:
+ * current - Possible values are 2, 100 and 500 (mA). However,
+ * 2 means 2.5 mA actually.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargecurrent(FAR int *current);
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargecurrent
+ *
+ * Description:
+ * Set charge current value
+ *
+ * Input Parameter:
+ * current - Available values are 2, 100 and 500 (mA). However, 2 means
+ * 2.5 mA actually.
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargecurrent(int current);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getporttype
+ *
+ * Description:
+ * Get USB port type
+ *
+ * Input Parameter:
+ * porttype - PMIC_PORTTYPE_SDP or PMIC_PORTTYPE_DCPCDP
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getporttype(FAR int *porttype);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargestate
+ *
+ * Description:
+ * Read charging status
+ *
+ * Input Parameter:
+ * state - Charging status (see PMIC_STAT_* definitions)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargestate(FAR uint8_t *state);
+
+/****************************************************************************
+ * Name: cxd56_pmic_setrechargevol
+ *
+ * Description:
+ * Set threshold voltage against full charge for automatic restart charging.
+ *
+ * Input Parameter:
+ * mV - Available values are -400, -350, -300 and -250 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setrechargevol(int mV);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getrechargevol
+ *
+ * Description:
+ * Get threshold voltage against full charge for automatic restart charging.
+ *
+ * Input Parameter:
+ * mV - Possible values are -400, -350, -300 and -250 (mV)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getrechargevol(FAR int *mV);
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargecompcurrent
+ *
+ * Description:
+ * Set current value setting for determine fully charged.
+ *
+ * Input Parameter:
+ * current - Possible values are 50, 40, 30, 20 and 10 (mA)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargecompcurrent(int current);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargecompcurrent
+ *
+ * Description:
+ * Get current value setting for determine fully charged.
+ *
+ * Input Parameter:
+ * current - Available values are 50, 40, 30, 20 and 10 (mA)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargecompcurrent(FAR int *current);
+
+/****************************************************************************
+ * Name: cxd56_pmic_gettemptable
+ *
+ * Description:
+ * Get temperature detect resistance table
+ *
+ * Input Parameter:
+ * table - Settings values for temperature detecting (see CXD5247GF
+ * specification for more detail)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_gettemptable(FAR struct pmic_temp_table_s *table);
+
+/****************************************************************************
+ * Name: cxd56_pmic_settemptable
+ *
+ * Description:
+ * Set temperature detect resistance table
+ *
+ * Input Parameter:
+ * table - Settings values for temperature detecting (see CXD5247GF
+ * specification for more detail)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_settemptable(FAR struct pmic_temp_table_s *table);
+
+/****************************************************************************
+ * Name: cxd56_pmic_setchargemode
+ *
+ * Description:
+ * Set charging mode in each low/high temperatures.
+ * In lower than 10 degrees Celsius, charging mode will be changed on/off
+ * and weak (half of charge current) according to setting.
+ * In higher than 45 degrees Celsius, charging mode will be charged on/off
+ * and weak (-0.15V from charge voltage) according to setting.
+ *
+ * Input Parameter:
+ * low - Charging mode in low temperature (see PMIC_CHGMODE_*)
+ * high - Charging mode in high temperature (see PMIC_CHGMODE_*)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_setchargemode(int low, int high);
+
+/****************************************************************************
+ * Name: cxd56_pmic_getchargemode
+ *
+ * Description:
+ * Get charging mode in each low/high temperatures.
+ * In lower than 10 degrees Celsius, charging mode will be changed on/off
+ * and weak (half of charge current) according to setting.
+ * In higher than 45 degrees Celsius, charging mode will be charged on/off
+ * and weak (-0.15V from charge voltage) according to setting.
+ *
+ * Input Parameter:
+ * low - Charging mode in low temperature (see PMIC_CHG_*)
+ * high - Charging mode in high temperature (see PMIC_CHG_*)
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_getchargemode(FAR int *low, FAR int *high);
+
+/****************************************************************************
+ * Name: cxd56_pmic_read
+ *
+ * Description:
+ * Read the value from the specified sub address
+ *
+ * Input Parameter:
+ * addr - sub address
+ * buf - pointer to read buffer
+ * size - byte count of read
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_read(uint8_t addr, FAR void *buf, uint32_t size);
+
+/****************************************************************************
+ * Name: cxd56_pmic_write
+ *
+ * Description:
+ * Write the value to the specified sub address
+ *
+ * Input Parameter:
+ * addr - sub address
+ * buf - pointer to write buffer
+ * size - byte count of write
+ *
+ * Returned Value:
+ * Return 0 on success. Otherwise, return a negated errno.
+ *
+ ****************************************************************************/
+
+int cxd56_pmic_write(uint8_t addr, FAR void *buf, uint32_t size);
+
+/****************************************************************************
+ * Battery monitor for debug
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_PMIC_BATMONITOR
+int cxd56_pmic_monitor_enable(FAR struct pmic_mon_s *ptr);
+int cxd56_pmic_monitor_status(FAR struct pmic_mon_status_s *ptr);
+int cxd56_pmic_monitor_set(FAR struct pmic_mon_set_s *ptr);
+int cxd56_pmic_monitor_get(FAR struct pmic_mon_log_s *ptr);
+#else
+#define cxd56_pmic_monitor_enable(ptr)
+#define cxd56_pmic_monitor_status(ptr)
+#define cxd56_pmic_monitor_set(ptr)
+#define cxd56_pmic_monitor_get(ptr)
+#endif
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_CXD56_PMIC */
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_PMIC_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_sdhci.c b/arch/arm/src/cxd56xx/cxd56_sdhci.c
new file mode 100644
index 00000000000..a8129144be2
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_sdhci.c
@@ -0,0 +1,4583 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_sdhci.c
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include "chip.h"
+#include "up_arch.h"
+#include "cxd56_sdhci.h"
+#include "cxd56_clock.h"
+#include "cxd56_pinconfig.h"
+
+#ifdef CONFIG_CXD56_SDIO
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_CXD56_SDIO_DMA
+# warning "Large Non-DMA transfer may result in RX overrun failures"
+#endif
+
+#if !defined(CONFIG_SCHED_WORKQUEUE) || !defined(CONFIG_SCHED_HPWORK)
+# error "Callback support requires CONFIG_SCHED_WORKQUEUE and CONFIG_SCHED_HPWORK"
+#endif
+
+#if !defined(CONFIG_MMCSD_MULTIBLOCK_DISABLE) && !defined(CONFIG_SDIO_BLOCKSETUP)
+# error "This driver requires CONFIG_SDIO_BLOCKSETUP"
+#endif
+
+#ifndef CONFIG_CXD56_SDHCI_PRIO
+# define CONFIG_CXD56_SDHCI_PRIO NVIC_SYSH_PRIORITY_DEFAULT
+#endif
+
+#ifndef CONFIG_CXD56_SDHCI_DMAPRIO
+# define CONFIG_CXD56_SDHCI_DMAPRIO DMA_CCR_PRIMED
+#endif
+
+#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_VERBOSE)
+# undef CONFIG_SDIO_XFRDEBUG
+#endif
+
+/* SDCLK frequencies corresponding to various modes of operation. These
+ * values may be provided in either the NuttX configuration file or in
+ * the board.h file
+ *
+ * NOTE: These settings are not currently used. Since there are only four
+ * frequencies, it makes more sense to just "can" the fixed frequency prescaler
+ * and divider values.
+ */
+
+#ifndef CONFIG_CXD56_IDMODE_FREQ
+# define CONFIG_CXD56_IDMODE_FREQ 400000 /* 400 KHz, ID mode */
+#endif
+#ifndef CONFIG_CXD56_MMCXFR_FREQ
+# define CONFIG_CXD56_MMCXFR_FREQ 20000000 /* 20MHz MMC, normal clocking */
+#endif
+#ifndef CONFIG_CXD56_SD1BIT_FREQ
+# define CONFIG_CXD56_SD1BIT_FREQ 20000000 /* 20MHz SD 1-bit, normal clocking */
+#endif
+#ifndef CONFIG_CXD56_SD4BIT_FREQ
+# define CONFIG_CXD56_SD4BIT_FREQ 25000000 /* 25MHz SD 4-bit, normal clocking */
+#endif
+#ifndef CONFIG_CXD56_HSSD4BIT_FREQ
+# define CONFIG_CXD56_HSSD4BIT_FREQ 50000000 /* 50MHz SD 4-bit, highspeed clocking */
+#endif
+
+#define CXD56_SDIO_BASECLK_FREQ (cxd56_get_sdio_baseclock()*2)
+
+/* Timing */
+
+#define SDHCI_CARDSTATETIMEOUT (2000000)
+#define SDHCI_CMDTIMEOUT (100000)
+#define SDHCI_LONGTIMEOUT (1000000)
+
+#define SDHCI_WAIT_POWERON MSEC2TICK(252)
+#define SDHCI_WAIT_POWEROFF MSEC2TICK(300)
+
+/* Big DVS setting. Range is 0=SDCLK*213 through 14=SDCLK*227 */
+
+#define SDHCI_DTOCV_MAXTIMEOUT (0xF-0x1)
+#define SDHCI_DTOCV_DATATIMEOUT (0XF-0x1)
+
+/* Data transfer / Event waiting interrupt mask bits */
+
+#define SDHCI_RESPERR_INTS (SDHCI_INT_CCE|SDHCI_INT_CTOE|SDHCI_INT_CEBE|SDHCI_INT_CIE)
+#define SDHCI_RESPDONE_INTS (SDHCI_RESPERR_INTS|SDHCI_INT_CC)
+
+#define SDHCI_XFRERR_INTS (SDHCI_INT_DCE|SDHCI_INT_DTOE|SDHCI_INT_DEBE)
+#define SDHCI_RCVDONE_INTS (SDHCI_XFRERR_INTS|SDHCI_INT_BRR|SDHCI_INT_TC)
+#define SDHCI_SNDDONE_INTS (SDHCI_XFRERR_INTS|SDHCI_INT_BWR|SDHCI_INT_TC)
+#define SDHCI_XFRDONE_INTS (SDHCI_XFRERR_INTS|SDHCI_INT_BRR|SDHCI_INT_BWR|SDHCI_INT_TC)
+
+#define SDHCI_DMAERR_INTS (SDHCI_INT_DCE|SDHCI_INT_DTOE|SDHCI_INT_DEBE|SDHCI_INT_DMAE)
+#define SDHCI_DMADONE_INTS (SDHCI_DMAERR_INTS|SDHCI_INT_DINT|SDHCI_INT_TC)
+
+#define SDHCI_WAITALL_INTS (SDHCI_RESPDONE_INTS|SDHCI_XFRDONE_INTS|SDHCI_DMADONE_INTS)
+
+/* Register logging support */
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+# define SAMPLENDX_BEFORE_SETUP 0
+# define SAMPLENDX_AFTER_SETUP 1
+# define SAMPLENDX_END_TRANSFER 2
+# define DEBUG_NSAMPLES 3
+#endif
+
+/* DMA */
+
+#define CXD56_SDHCI_BUF_SIZE (2048)
+#define SDHCI_MAX_BLOCK_COUNT (0xffffffff)
+#define SDHCI_MAX_ADMA_TRANS_SIZE (0xffff+1)
+#ifndef CONFIG_CXD56_SDIO_MAX_LEN_ADMA_DSCR
+# define CXD56_SDIO_MAX_LEN_ADMA_DSCR (16)
+#else
+# define CXD56_SDIO_MAX_LEN_ADMA_DSCR (CONFIG_CXD56_SDIO_MAX_LEN_ADMA_DSCR)
+#endif
+
+#define SDHCI_ADMA_DSCR_L_LEN_MASK (0xffff0000)
+#define SDHCI_ADMA_DSCR_L_LEN_SHIFT (16)
+#define SDHCI_ADMA_DSCR_L_ACT_SHIFT (4)
+#define SDHCI_ADMA_DSCR_L_ACT_NOP (0<<4)
+#define SDHCI_ADMA_DSCR_L_ACT_RSV (1<<4)
+#define SDHCI_ADMA_DSCR_L_ACT_TRAN (2<<4)
+#define SDHCI_ADMA_DSCR_L_ACT_LNK (3<<4)
+#define SDHCI_ADMA_DSCR_L_INT (0x00000004)
+#define SDHCI_ADMA_DSCR_L_END (0x00000002)
+#define SDHCI_ADMA_DSCR_L_VALID (0x00000001)
+#define SDHCI_ADMA_DSCR_H_ADDR_MASK (0xffffffff)
+
+#define CXD56_SDHCI_ADSADDR_H (CXD56_SDHCI_ADSADDR+0x4)
+
+/* Card Common Control Registers (CCCR) */
+
+#define SDIO_CCCR_SIZE 0x100
+
+#define SDIO_CMD5253_READ (0<<31)
+#define SDIO_CMD5253_WRITE (1<<31)
+#define SDIO_CMD5253_FUNC_SHIFT (28)
+
+#define SDIO_CMD52_EXCHANGE (1<<27)
+#define SDIO_CMD52_REG_SHIFT (9)
+#define SDIO_CMD52_DATA_MASK 0xff
+
+#define CMD52_RESP_OK(resp) (0 == (resp&0xCB00))
+
+/* For Function Basic Registers */
+
+#define SDIO_FBR_START 0x100
+
+/* Card Information Structure (CIS) */
+
+#define SDIO_CIS_START 0x1000
+#define SDIO_CIS_END (SDIO_CIS_START+0x17000-0x10)
+
+/* CIS tuple codes (based on PC Card 16) */
+
+#define SDIO_CISTPL_NULL 0x00
+#define SDIO_CISTPL_VERS_1 0x15
+#define SDIO_CISTPL_MANFID 0x20
+#define SDIO_CISTPL_FUNCID 0x21
+#define SDIO_CISTPL_FUNCE 0x22
+#define SDIO_CISTPL_END 0xff
+
+/* CISTPL_FUNCID codes */
+
+#define TPLFID_FUNC_SDIO 0x0c
+
+#define SDIO_THREAD_DEFPRIO 50
+#define SDIO_THREAD_STACKSIZE 1024
+
+#define SDIO_OCR_NUM_FUNCTIONS(ocr) (((ocr) >> 28) & 0x7)
+#define SDIO_FUNC_NUM_MAX (7)
+
+#ifndef MIN
+# define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define SDIO_BLOCK_TIMEOUT 200
+#define SDIO_BLOCK_SIZE 512
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+/* Structure describing a single SDIO card slot. */
+
+struct sdio_softc_s
+{
+ int func_num; /* number of I/O functions (SDIO) */
+ FAR struct sdio_function_s *fn[SDIO_FUNC_NUM_MAX + 1]; /* selected card */
+ bool full_speed; /* high speed mode */
+ uint8_t dma; /* true: hardware supports DMA */
+ sem_t sem; /* Assures mutually exclusive access to the sdio */
+};
+
+/* Structure describing either an SDIO device I/O function. */
+
+struct sdio_function_s
+{
+ /* common members */
+ FAR struct sdio_softc_s *sc; /* card slot softc */
+ sdio_irqhandler_t *irq_callback; /* function callback */
+ int number; /* I/O function number or -1, 0 for func0,1 for func1... */
+ struct sdio_cis_s cis; /* decoded CIS */
+};
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+
+/* This structure defines the state of the CXD56xx SDIO interface */
+
+struct cxd56_sdiodev_s
+{
+ struct sdio_dev_s dev; /* Standard, base SDIO interface */
+
+ /* CXD56xx-specific extensions */
+ /* Event support */
+
+ sem_t waitsem; /* Implements event waiting */
+ sdio_eventset_t waitevents; /* Set of events to be waited for */
+ uint32_t waitints; /* Interrupt enables for event waiting */
+ volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */
+ WDOG_ID waitwdog; /* Watchdog that handles event timeouts */
+
+ /* Callback support */
+
+ sdio_statset_t cdstatus; /* Card status */
+ sdio_eventset_t cbevents; /* Set of events to be cause callbacks */
+ worker_t callback; /* Registered callback function */
+ void *cbarg; /* Registered callback argument */
+ struct work_s cbwork; /* Callback work queue structure */
+
+ /* Interrupt mode data transfer support */
+
+ uint32_t *buffer; /* Address of current R/W buffer */
+ size_t remaining; /* Number of bytes remaining in the transfer */
+ uint32_t xfrints; /* Interrupt enables for data transfer */
+
+ /* DMA data transfer support */
+
+#ifdef CONFIG_SDIO_DMA
+ volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */
+ bool usedma;
+ bool dmasend_prepare;
+ size_t receive_size;
+ uint8_t *aligned_buffer; /* Used to buffer alignment */
+ uint8_t *receive_buffer; /* Used to keep receive buffer address */
+ uint32_t dma_cmd;
+ uint32_t dmasend_cmd;
+ uint32_t dmasend_regcmd;
+#endif
+
+ /* Parameters */
+
+ uint16_t blocksize;
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+ struct sdio_softc_s sc; /* Structure describing a single SDIO card slot. */
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+};
+
+/* Register logging support */
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+struct cxd56_sdhcregs_s
+{
+ /* All read-able SDHC registers */
+
+ uint32_t dsaddr; /* DMA System Address Register */
+ uint32_t blkattr; /* Block Attributes Register */
+ uint32_t cmdarg; /* Command Argument Register */
+ uint32_t xferty; /* Transfer Type Register */
+ uint32_t cmdrsp0; /* Command Response 0 */
+ uint32_t cmdrsp1; /* Command Response 1 */
+ uint32_t cmdrsp2; /* Command Response 2 */
+ uint32_t cmdrsp3; /* Command Response 3 */
+ uint32_t prsstat; /* Present State Register */
+ uint32_t proctl; /* Protocol Control Register */
+ uint32_t sysctl; /* System Control Register */
+ uint32_t irqstat; /* Interrupt Status Register */
+ uint32_t irqstaten; /* Interrupt Status Enable Register */
+ uint32_t irqsigen; /* Interrupt Signal Enable Register */
+ uint32_t ac12err; /* Auto CMD12 Error Status Register */
+ uint32_t htcapblt; /* Host Controller Capabilities */
+ uint32_t admaes; /* ADMA Error Status Register */
+ uint32_t adsaddr; /* ADMA System Address Register */
+ uint32_t vendor; /* Vendor Specific Register */
+ uint32_t hostver; /* Host Controller Version */
+};
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Low-level helpers ********************************************************/
+
+static void cxd56_takesem(struct cxd56_sdiodev_s *priv);
+#define cxd56_givesem(priv) (sem_post(&(priv)->waitsem))
+static void cxd56_configwaitints(struct cxd56_sdiodev_s *priv, uint32_t waitints,
+ sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
+static void cxd56_configxfrints(struct cxd56_sdiodev_s *priv, uint32_t xfrints);
+
+/* DMA Helpers **************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_sampleinit(void);
+static void cxd56_sdhcsample(struct cxd56_sdhcregs_s *regs);
+static void cxd56_sample(struct cxd56_sdiodev_s *priv, int index);
+static void cxd56_dumpsample(struct cxd56_sdiodev_s *priv,
+ struct cxd56_sdhcregs_s *regs, const char *msg);
+static void cxd56_dumpsamples(struct cxd56_sdiodev_s *priv);
+static void cxd56_showregs(struct cxd56_sdiodev_s *priv, const char *msg);
+#else
+# define cxd56_sampleinit()
+# define cxd56_sample(priv,index)
+# define cxd56_dumpsamples(priv)
+# define cxd56_showregs(priv,msg)
+#endif
+
+/* Data Transfer Helpers ****************************************************/
+
+static void cxd56_dataconfig(struct cxd56_sdiodev_s *priv, bool bwrite,
+ unsigned int blocksize, unsigned int nblocks,
+ unsigned int timeout);
+static void cxd56_datadisable(void);
+static void cxd56_transmit(struct cxd56_sdiodev_s *priv);
+static void cxd56_receive(struct cxd56_sdiodev_s *priv);
+static void cxd56_eventtimeout(int argc, uint32_t arg);
+static void cxd56_endwait(struct cxd56_sdiodev_s *priv, sdio_eventset_t wkupevent);
+static void cxd56_endtransfer(struct cxd56_sdiodev_s *priv, sdio_eventset_t wkupevent);
+
+/* Interrupt Handling *******************************************************/
+
+static int cxd56_interrupt(int irq, FAR void *context, FAR void *arg);
+
+/* SDIO interface methods ***************************************************/
+
+/* Mutual exclusion */
+
+#ifdef CONFIG_SDIO_MUXBUS
+static int cxd56_sdio_lock(FAR struct sdio_dev_s *dev, bool lock);
+#endif
+
+/* Initialization/setup */
+
+static void cxd56_sdio_sdhci_reset(FAR struct sdio_dev_s *dev);
+static sdio_capset_t cxd56_sdio_capabilities(FAR struct sdio_dev_s *dev);
+static sdio_statset_t cxd56_sdio_status(FAR struct sdio_dev_s *dev);
+static void cxd56_sdio_widebus(FAR struct sdio_dev_s *dev, bool enable);
+static void cxd56_sdio_frequency(uint32_t frequency);
+static void cxd56_sdio_clock(FAR struct sdio_dev_s *dev,
+ enum sdio_clock_e rate);
+static int cxd56_sdio_attach(FAR struct sdio_dev_s *dev);
+
+/* Command/Status/Data Transfer */
+
+static int cxd56_sdio_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t arg);
+static void cxd56_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen,
+ unsigned int nblocks);
+static int cxd56_sdio_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
+ size_t nbytes);
+static int cxd56_sdio_sendsetup(FAR struct sdio_dev_s *dev,
+ FAR const uint8_t *buffer, uint32_t nbytes);
+static int cxd56_sdio_cancel(FAR struct sdio_dev_s *dev);
+
+static int cxd56_sdio_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd);
+static int cxd56_sdio_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t *rshort);
+static int cxd56_sdio_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t rlong[4]);
+static int cxd56_sdio_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t *rshort);
+
+/* EVENT handler */
+
+static void cxd56_sdio_waitenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset);
+static sdio_eventset_t
+ cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout);
+static void cxd56_sdio_callbackenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset);
+static int cxd56_sdio_registercallback(FAR struct sdio_dev_s *dev,
+ worker_t callback, void *arg);
+
+/* DMA */
+
+#ifdef CONFIG_SDIO_DMA
+static int cxd56_sdio_admasetup(FAR const uint8_t *buffer, size_t buflen);
+static int cxd56_sdio_dmarecvsetup(FAR struct sdio_dev_s *dev,
+ FAR uint8_t *buffer, size_t buflen);
+static int cxd56_sdio_dmasendsetup(FAR struct sdio_dev_s *dev,
+ FAR const uint8_t *buffer, size_t buflen);
+#endif
+
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+static int cxd56_sdio_enable_cardint(void);
+static int cxd56_sdio_register_irq(FAR struct sdio_dev_s *dev, int func_num,
+ FAR sdio_irqhandler_t * handler);
+static int cxd56_sdio_function_disable(FAR struct sdio_dev_s *dev, int func_num);
+static int cxd56_sdio_function_enable(FAR struct sdio_dev_s *dev, int func_num);
+static int cxd56_sdio_readb(FAR struct sdio_dev_s *dev, int func_num,
+ uint32_t addr, FAR uint8_t * rdata);
+static int cxd56_sdio_writeb(FAR struct sdio_dev_s *dev, int func_num,
+ uint32_t addr, uint8_t data, FAR uint8_t * rdata);
+static int cxd56_sdio_read(FAR struct sdio_dev_s *dev, int func_num, uint32_t addr,
+ FAR uint8_t * data, uint32_t size);
+static int cxd56_sdio_write(FAR struct sdio_dev_s *dev, int func_num, uint32_t addr,
+ FAR uint8_t * data, uint32_t size);
+static int cxd56_sdhci_irq_handler(FAR struct sdio_dev_s *dev);
+static int cxd56_sdio_get_cis(FAR struct sdio_dev_s *dev, int func_num,
+ FAR struct sdio_cis_s * cis);
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+
+/* Initialization/uninitialization/reset ************************************/
+
+static void cxd56_sdio_callback(void *arg);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+struct cxd56_sdiodev_s g_sdhcdev =
+{
+ .dev =
+ {
+#ifdef CONFIG_SDIO_MUXBUS
+ .lock = cxd56_sdio_lock,
+#endif
+ .reset = cxd56_sdio_sdhci_reset,
+ .capabilities = cxd56_sdio_capabilities,
+ .status = cxd56_sdio_status,
+ .widebus = cxd56_sdio_widebus,
+ .clock = cxd56_sdio_clock,
+ .attach = cxd56_sdio_attach,
+ .sendcmd = cxd56_sdio_sendcmd,
+ .blocksetup = cxd56_blocksetup,
+ .recvsetup = cxd56_sdio_recvsetup,
+ .sendsetup = cxd56_sdio_sendsetup,
+ .cancel = cxd56_sdio_cancel,
+ .waitresponse = cxd56_sdio_waitresponse,
+ .recvR1 = cxd56_sdio_recvshortcrc,
+ .recvR2 = cxd56_sdio_recvlong,
+ .recvR3 = cxd56_sdio_recvshort,
+ .recvR4 = cxd56_sdio_recvshort,
+ .recvR5 = cxd56_sdio_recvshort,
+ .recvR6 = cxd56_sdio_recvshortcrc,
+ .recvR7 = cxd56_sdio_recvshort,
+ .waitenable = cxd56_sdio_waitenable,
+ .eventwait = cxd56_sdio_eventwait,
+ .callbackenable = cxd56_sdio_callbackenable,
+ .registercallback = cxd56_sdio_registercallback,
+#ifdef CONFIG_SDIO_DMA
+ .dmarecvsetup = cxd56_sdio_dmarecvsetup,
+ .dmasendsetup = cxd56_sdio_dmasendsetup,
+#endif
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+ .register_irq = cxd56_sdio_register_irq,
+ .function_disable = cxd56_sdio_function_disable,
+ .function_enable = cxd56_sdio_function_enable,
+ .readb = cxd56_sdio_readb,
+ .writeb = cxd56_sdio_writeb,
+ .read = cxd56_sdio_read,
+ .write = cxd56_sdio_write,
+ .get_cis = cxd56_sdio_get_cis,
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+ },
+};
+
+/* Register logging support */
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static struct cxd56_sdhcregs_s g_sampleregs[DEBUG_NSAMPLES];
+#endif
+
+/* DMA */
+
+#ifdef CONFIG_SDIO_DMA
+static FAR uint32_t cxd56_sdhci_adma_dscr[CXD56_SDIO_MAX_LEN_ADMA_DSCR*2];
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Low-level Helpers
+ ****************************************************************************/
+/****************************************************************************
+ * Name: cxd56_takesem
+ *
+ * Description:
+ * Take the wait semaphore (handling false alarm wakeups due to the receipt
+ * of signals).
+ *
+ * Input Parameters:
+ * dev - Instance of the SDIO device driver state structure.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_takesem(struct cxd56_sdiodev_s *priv)
+{
+ /* Take the semaphore (perhaps waiting) */
+
+ while (sem_wait(&priv->waitsem) != 0)
+ {
+ /* The only case that an error should occr here is if the wait was
+ * awakened by a signal.
+ */
+
+ ASSERT(errno == EINTR);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_configwaitints
+ *
+ * Description:
+ * Enable/disable SDIO interrupts needed to suport the wait function
+ *
+ * Input Parameters:
+ * priv - A reference to the SDIO device state structure
+ * waitints - The set of bits in the SDIO MASK register to set
+ * waitevents - Waited for events
+ * wkupevent - Wake-up events
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_configwaitints(struct cxd56_sdiodev_s *priv, uint32_t waitints,
+ sdio_eventset_t waitevents,
+ sdio_eventset_t wkupevent)
+{
+ irqstate_t flags;
+
+ /* Save all of the data and set the new interrupt mask in one, atomic
+ * operation.
+ */
+
+ flags = enter_critical_section();
+ priv->waitevents = waitevents;
+ priv->wkupevent = wkupevent;
+ priv->waitints = waitints;
+#ifdef CONFIG_SDIO_DMA
+ priv->xfrflags = 0;
+#endif
+ putreg32(priv->xfrints | priv->waitints | SDHCI_INT_CINT,
+ CXD56_SDHCI_IRQSIGEN);
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * Name: cxd56_configxfrints
+ *
+ * Description:
+ * Enable SDIO interrupts needed to support the data transfer event
+ *
+ * Input Parameters:
+ * priv - A reference to the SDIO device state structure
+ * xfrints - The set of bits in the SDIO MASK register to set
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_configxfrints(struct cxd56_sdiodev_s *priv, uint32_t xfrints)
+{
+ irqstate_t flags;
+ flags = enter_critical_section();
+ priv->xfrints = xfrints;
+ putreg32(priv->xfrints | priv->waitints | SDHCI_INT_CINT,CXD56_SDHCI_IRQSIGEN);
+ leave_critical_section(flags);
+}
+
+/****************************************************************************
+ * DMA Helpers
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_sampleinit
+ *
+ * Description:
+ * Setup prior to collecting DMA samples
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_sampleinit(void)
+{
+ memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct cxd56_sdhcregs_s));
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_sdhcsample
+ *
+ * Description:
+ * Sample SDIO registers
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_sdhcsample(struct cxd56_sdhcregs_s *regs)
+{
+ regs->dsaddr = getreg32(CXD56_SDHCI_DSADDR); /* DMA System Address Register */
+ regs->blkattr = getreg32(CXD56_SDHCI_BLKATTR); /* Block Attributes Register */
+ regs->cmdarg = getreg32(CXD56_SDHCI_CMDARG); /* Command Argument Register */
+ regs->xferty = getreg32(CXD56_SDHCI_XFERTYP); /* Transfer Type Register */
+ regs->cmdrsp0 = getreg32(CXD56_SDHCI_CMDRSP0); /* Command Response 0 */
+ regs->cmdrsp1 = getreg32(CXD56_SDHCI_CMDRSP1); /* Command Response 1 */
+ regs->cmdrsp2 = getreg32(CXD56_SDHCI_CMDRSP2); /* Command Response 2 */
+ regs->cmdrsp3 = getreg32(CXD56_SDHCI_CMDRSP3); /* Command Response 3 */
+ regs->prsstat = getreg32(CXD56_SDHCI_PRSSTAT); /* Present State Register */
+ regs->proctl = getreg32(CXD56_SDHCI_PROCTL); /* Protocol Control Register */
+ regs->sysctl = getreg32(CXD56_SDHCI_SYSCTL); /* System Control Register */
+ regs->irqstat = getreg32(CXD56_SDHCI_IRQSTAT); /* Interrupt Status Register */
+ regs->irqstaten = getreg32(CXD56_SDHCI_IRQSTATEN); /* Interrupt Status Enable Register */
+ regs->irqsigen = getreg32(CXD56_SDHCI_IRQSIGEN); /* Interrupt Signal Enable Register */
+ regs->ac12err = getreg32(CXD56_SDHCI_AC12ERR); /* Auto CMD12 Error Status Register */
+ regs->htcapblt = getreg32(CXD56_SDHCI_HTCAPBLT); /* Host Controller Capabilities */
+ regs->admaes = getreg32(CXD56_SDHCI_ADMAES); /* ADMA Error Status Register */
+ regs->adsaddr = getreg32(CXD56_SDHCI_ADSADDR); /* ADMA System Address Register */
+ regs->vendor = getreg32(CXD56_SDHCI_VENDOR); /* Vendor Specific Register */
+ regs->hostver = getreg32(CXD56_SDHCI_HOSTVER); /* Host Controller Version */
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_sample
+ *
+ * Description:
+ * Sample SDIO/DMA registers
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_sample(struct cxd56_sdiodev_s *priv, int index)
+{
+ cxd56_sdhcsample(&g_sampleregs[index]);
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_dumpsample
+ *
+ * Description:
+ * Dump one register sample
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_dumpsample(struct cxd56_sdiodev_s *priv,
+ struct cxd56_sdhcregs_s *regs, const char *msg)
+{
+ mcinfo("SDHC Registers: %s\n", msg);
+ mcinfo(" DSADDR[%08x]: %08x\n", CXD56_SDHCI_DSADDR, regs->dsaddr);
+ mcinfo(" BLKATTR[%08x]: %08x\n", CXD56_SDHCI_BLKATTR, regs->blkattr);
+ mcinfo(" CMDARG[%08x]: %08x\n", CXD56_SDHCI_CMDARG, regs->cmdarg);
+ mcinfo(" COMMAND[%08x]: %08x\n", CXD56_SDHCI_XFERTYP, regs->xferty);
+ mcinfo(" CMDRSP0[%08x]: %08x\n", CXD56_SDHCI_CMDRSP0, regs->cmdrsp0);
+ mcinfo(" CMDRSP1[%08x]: %08x\n", CXD56_SDHCI_CMDRSP1, regs->cmdrsp1);
+ mcinfo(" CMDRSP2[%08x]: %08x\n", CXD56_SDHCI_CMDRSP2, regs->cmdrsp2);
+ mcinfo(" CMDRSP3[%08x]: %08x\n", CXD56_SDHCI_CMDRSP3, regs->cmdrsp3);
+ mcinfo(" PRSSTAT[%08x]: %08x\n", CXD56_SDHCI_PRSSTAT, regs->prsstat);
+ mcinfo(" PROCTL[%08x]: %08x\n", CXD56_SDHCI_PROCTL, regs->proctl);
+ mcinfo(" HOSTCTL[%08x]: %08x\n", CXD56_SDHCI_SYSCTL, regs->sysctl);
+ mcinfo(" IRQSTAT[%08x]: %08x\n", CXD56_SDHCI_IRQSTAT, regs->irqstat);
+ mcinfo("IRQSTATEN[%08x]: %08x\n", CXD56_SDHCI_IRQSTATEN, regs->irqstaten);
+ mcinfo(" IRQSIGEN[%08x]: %08x\n", CXD56_SDHCI_IRQSIGEN, regs->irqsigen);
+ mcinfo(" AC12ERR[%08x]: %08x\n", CXD56_SDHCI_AC12ERR, regs->ac12err);
+ mcinfo(" HTCAPBLT[%08x]: %08x\n", CXD56_SDHCI_HTCAPBLT, regs->htcapblt);
+ mcinfo(" ADMAES[%08x]: %08x\n", CXD56_SDHCI_ADMAES, regs->admaes);
+ mcinfo(" ADSADDR[%08x]: %08x\n", CXD56_SDHCI_ADSADDR, regs->adsaddr);
+ mcinfo(" HOSTVER[%08x]: %08x\n", CXD56_SDHCI_HOSTVER, regs->hostver);
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_dumpsamples
+ *
+ * Description:
+ * Dump all sampled register data
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_dumpsamples(struct cxd56_sdiodev_s *priv)
+{
+ cxd56_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup");
+ cxd56_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup");
+ cxd56_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER], "End of transfer");
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_showregs
+ *
+ * Description:
+ * Dump the current state of all registers
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_XFRDEBUG
+static void cxd56_showregs(struct cxd56_sdiodev_s *priv, const char *msg)
+{
+ struct cxd56_sdhcregs_s regs;
+
+ cxd56_sdhcsample(®s);
+ cxd56_dumpsample(priv, ®s, msg);
+}
+#endif
+
+/****************************************************************************
+ * Data Transfer Helpers
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_dataconfig
+ *
+ * Description:
+ * Configure the SDIO data path for the next data transfer
+ *
+ ****************************************************************************/
+
+static void cxd56_dataconfig(struct cxd56_sdiodev_s *priv, bool bwrite,
+ unsigned int blocksize, unsigned int nblocks,
+ unsigned int timeout)
+{
+ //unsigned int watermark;
+ uint32_t regval = 0;
+
+ /* Set the data timeout value in the SDHCI_SYSCTL field to the selected value */
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval &= ~SDHCI_SYSCTL_DTOCV_MASK;
+ regval |= timeout << SDHCI_SYSCTL_DTOCV_SHIFT;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+
+ /* Set the block size and count in the SDHCI_BLKATTR register. The block
+ * size is only valid for multiple block transfers.
+ */
+
+ priv->blocksize = blocksize;
+
+ regval = blocksize << SDHCI_BLKATTR_SIZE_SHIFT |
+ nblocks << SDHCI_BLKATTR_CNT_SHIFT;
+ putreg32(regval, CXD56_SDHCI_BLKATTR);
+}
+
+/****************************************************************************
+ * Name: cxd56_datadisable
+ *
+ * Description:
+ * Disable the SDIO data path setup by cxd56_dataconfig() and
+ * disable DMA.
+ *
+ ****************************************************************************/
+
+static void cxd56_datadisable(void)
+{
+ uint32_t regval;
+
+ /* Set the data timeout value in the SDHCI_SYSCTL field to the maximum value */
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval &= ~SDHCI_SYSCTL_DTOCV_MASK;
+ regval |= SDHCI_DTOCV_MAXTIMEOUT << SDHCI_SYSCTL_DTOCV_SHIFT;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+
+ /* Set the block size to zero (no transfer) */
+
+ putreg32(0, CXD56_SDHCI_BLKATTR);
+}
+
+/****************************************************************************
+ * Name: cxd56_transmit
+ *
+ * Description:
+ * Send SDIO data in interrupt mode
+ *
+ * Input Parameters:
+ * priv - An instance of the SDIO device interface
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_transmit(struct cxd56_sdiodev_s *priv)
+{
+ union
+ {
+ uint32_t w;
+ uint8_t b[4];
+ } data;
+
+ /* Loop while there is more data to be sent, waiting for buffer write
+ * ready (BWR)
+ */
+
+ if (priv->buffer == 0)
+ {
+ return;
+ }
+
+ mcinfo("Entry: remaining: %d IRQSTAT: %08x\n",
+ priv->remaining, getreg32(CXD56_SDHCI_IRQSTAT));
+
+ while (priv->remaining > 0 &&
+ (getreg32(CXD56_SDHCI_IRQSTAT) & SDHCI_INT_BWR) != 0)
+ {
+ /* Clear BWR. If there is more data in the buffer, writing to the
+ * buffer should reset BRR.
+ */
+
+ putreg32(SDHCI_INT_BWR, CXD56_SDHCI_IRQSTAT);
+
+ while (priv->remaining > 0 && (getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_BWEN) != 0)
+ {
+ /* Is there a full word remaining in the user buffer? */
+
+ if (priv->remaining >= sizeof(uint32_t))
+ {
+ /* Yes, transfer the word to the TX FIFO */
+
+ data.w = *priv->buffer++;
+ priv->remaining -= sizeof(uint32_t);
+ }
+ else
+ {
+ /* No.. transfer just the bytes remaining in the user buffer,
+ * padding with zero as necessary to extend to a full word.
+ */
+
+ uint8_t *ptr = (uint8_t *)priv->buffer;
+ int i;
+
+ data.w = 0;
+ for (i = 0; i < priv->remaining; i++)
+ {
+ data.b[i] = *ptr++;
+ }
+
+ /* Now the transfer is finished */
+
+ priv->remaining = 0;
+ }
+
+ /* Put the word in the FIFO */
+
+ putreg32(data.w, CXD56_SDHCI_DATPORT);
+ }
+ }
+
+ mcinfo("Exit: remaining: %d IRQSTAT: %08x\n",
+ priv->remaining, getreg32(CXD56_SDHCI_IRQSTAT));
+}
+
+/****************************************************************************
+ * Name: cxd56_receive
+ *
+ * Description:
+ * Receive SDIO data in interrupt mode
+ *
+ * Input Parameters:
+ * priv - An instance of the SDIO device interface
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_receive(struct cxd56_sdiodev_s *priv)
+{
+ union
+ {
+ uint32_t w;
+ uint8_t b[4];
+ } data;
+
+ /* Loop while there is space to store the data, waiting for buffer read
+ * ready (BRR)
+ */
+
+ if (priv->buffer == 0)
+ {
+ return;
+ }
+
+ mcinfo("Entry: remaining: %d IRQSTAT: %08x\n",
+ priv->remaining, getreg32(CXD56_SDHCI_IRQSTAT));
+
+ while (priv->remaining > 0 &&
+ (getreg32(CXD56_SDHCI_IRQSTAT) & SDHCI_INT_BRR) != 0)
+ {
+ /* Clear BRR. If there is more data in the buffer, reading from the
+ * buffer should reset BRR.
+ */
+
+ putreg32(SDHCI_INT_BRR, CXD56_SDHCI_IRQSTAT);
+
+ while (priv->remaining > 0 && (getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_BREN) != 0)
+ {
+ /* Read the next word from the RX buffer */
+
+ data.w = getreg32(CXD56_SDHCI_DATPORT);
+ if (priv->remaining >= sizeof(uint32_t))
+ {
+ /* Transfer the whole word to the user buffer */
+
+ *priv->buffer++ = data.w;
+ priv->remaining -= sizeof(uint32_t);
+ }
+ else
+ {
+ /* Transfer any trailing fractional word */
+
+ uint8_t *ptr = (uint8_t *)priv->buffer;
+ int i;
+
+ for (i = 0; i < priv->remaining; i++)
+ {
+ *ptr++ = data.b[i];
+ }
+
+ /* Now the transfer is finished */
+
+ priv->remaining = 0;
+ }
+ }
+ }
+
+}
+
+/****************************************************************************
+ * Name: cxd56_eventtimeout
+ *
+ * Description:
+ * The watchdog timeout setup when the event wait start has expired without
+ * any other waited-for event occurring.
+ *
+ * Input Parameters:
+ * argc - The number of arguments (should be 1)
+ * arg - The argument (state structure reference cast to uint32_t)
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Always called from the interrupt level with interrupts disabled.
+ *
+ ****************************************************************************/
+
+static void cxd56_eventtimeout(int argc, uint32_t arg)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)arg;
+
+ DEBUGASSERT(argc == 1 && priv != NULL);
+ DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0);
+
+ /* Is a data transfer complete event expected? */
+
+ if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0)
+ {
+ /* Yes.. Sample registers at the time of the timeout */
+
+ cxd56_sample(priv, SAMPLENDX_END_TRANSFER);
+
+ /* Wake up any waiting threads */
+
+ cxd56_endwait(priv, SDIOWAIT_TIMEOUT);
+ mcwarn("Timeout: remaining: %d\n", priv->remaining);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_endwait
+ *
+ * Description:
+ * Wake up a waiting thread if the waited-for event has occurred.
+ *
+ * Input Parameters:
+ * priv - An instance of the SDIO device interface
+ * wkupevent - The event that caused the wait to end
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Always called from the interrupt level with interrupts disabled.
+ *
+ ****************************************************************************/
+
+static void cxd56_endwait(struct cxd56_sdiodev_s *priv, sdio_eventset_t wkupevent)
+{
+ /* Cancel the watchdog timeout */
+
+ (void)wd_cancel(priv->waitwdog);
+
+ /* Disable event-related interrupts */
+
+ cxd56_configwaitints(priv, 0, 0, wkupevent);
+
+ /* Wake up the waiting thread */
+
+ cxd56_givesem(priv);
+}
+
+/****************************************************************************
+ * Name: cxd56_endtransfer
+ *
+ * Description:
+ * Terminate a transfer with the provided status. This function is called
+ * only from the SDIO interrupt handler when end-of-transfer conditions
+ * are detected.
+ *
+ * Input Parameters:
+ * priv - An instance of the SDIO device interface
+ * wkupevent - The event that caused the transfer to end
+ *
+ * Returned Value:
+ * None
+ *
+ * Assumptions:
+ * Always called from the interrupt level with interrupts disabled.
+ *
+ ****************************************************************************/
+
+static void cxd56_endtransfer(struct cxd56_sdiodev_s *priv, sdio_eventset_t wkupevent)
+{
+#ifdef CONFIG_SDIO_DMA
+ uint32_t regval;
+#endif
+
+ if (priv->buffer == 0)
+ {
+ return;
+ }
+
+ /* Disable all transfer related interrupts */
+
+ cxd56_configxfrints(priv, 0);
+
+ /* Clearing pending interrupt status on all transfer related interrupts */
+
+ putreg32(SDHCI_XFRDONE_INTS, CXD56_SDHCI_IRQSTAT);
+
+ /* If this was a DMA transfer, make sure that DMA is stopped */
+
+#ifdef CONFIG_SDIO_DMA
+ /* Stop the DMA by resetting the data path */
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval |= SDHCI_SYSCTL_RSTD;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+ cxd56_sdhci_adma_dscr[0] = 0;
+ cxd56_sdhci_adma_dscr[1] = 0;
+ putreg32((uint32_t)cxd56_sdhci_adma_dscr, CXD56_SDHCI_ADSADDR);
+ putreg32(0, CXD56_SDHCI_ADSADDR_H);
+ priv->usedma = false;
+ priv->dmasend_prepare = false;
+ priv->dmasend_cmd = 0;
+ priv->dmasend_regcmd = 0;
+#endif
+
+ /* Mark the transfer finished */
+
+ if ((priv->waitevents & wkupevent & (SDIOWAIT_TRANSFERDONE | SDIOWAIT_RESPONSEDONE)) == 0)
+ {
+ priv->remaining = 0;
+ }
+ priv->buffer = 0;
+
+ /* Debug instrumentation */
+
+ cxd56_sample(priv, SAMPLENDX_END_TRANSFER);
+
+ /* Is a thread wait for these data transfer complete events? */
+
+ if ((priv->waitevents & wkupevent) != 0)
+ {
+ /* Yes.. wake up any waiting threads */
+
+ cxd56_endwait(priv, wkupevent);
+ }
+}
+
+/****************************************************************************
+ * Interrupt Handling
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_interrupt
+ *
+ * Description:
+ * SDIO interrupt handler
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int cxd56_interrupt(int irq, FAR void *context, FAR void *arg)
+{
+ struct cxd56_sdiodev_s *priv = &g_sdhcdev;
+ uint32_t enabled;
+ uint32_t pending;
+ uint32_t regval;
+
+ /* Check the SDHC IRQSTAT register. Mask out all bits that don't
+ * correspond to enabled interrupts. (This depends on the fact that bits
+ * are ordered the same in both the IRQSTAT and IRQSIGEN registers). If
+ * there are non-zero bits remaining, then we have work to do here.
+ */
+
+ regval = getreg32(CXD56_SDHCI_IRQSIGEN);
+ enabled = getreg32(CXD56_SDHCI_IRQSTAT) & regval;
+ mcinfo("IRQSTAT: %08x IRQSIGEN %08x enabled: %08x\n",
+ getreg32(CXD56_SDHCI_IRQSTAT), regval, enabled);
+
+ /* Disable card interrupts to clear the card interrupt to the host system. */
+
+ regval &= ~(SDHCI_INT_CINT | enabled);
+ putreg32(regval, CXD56_SDHCI_IRQSIGEN);
+
+ /* Clear all pending interrupts */
+
+ //putreg32(enabled, CXD56_SDHCI_IRQSTAT);
+
+ /* Handle in progress, interrupt driven data transfers ********************/
+
+ pending = enabled & priv->xfrints;
+ if (pending != 0)
+ {
+ /* Is the RX buffer read ready? Is so then we must be processing a
+ * non-DMA receive transaction.
+ */
+
+ if ((pending & SDHCI_INT_BRR) != 0)
+ {
+ /* Receive data from the RX buffer */
+
+ cxd56_receive(priv);
+ }
+
+ /* Otherwise, Is the TX buffer write ready? If so we must
+ * be processing a non-DMA send transaction. NOTE: We can't be
+ * processing both!
+ */
+
+ else if ((pending & SDHCI_INT_BWR) != 0)
+ {
+ /* Send data via the TX FIFO */
+
+ cxd56_transmit(priv);
+ }
+
+ /* Handle transfer complete events */
+
+ if ((pending & SDHCI_INT_TC) != 0)
+ {
+ /* Terminate the transfer */
+
+ cxd56_endtransfer(priv, SDIOWAIT_TRANSFERDONE);
+ }
+
+ /* Handle data block send/receive CRC failure */
+
+ else if ((pending & SDHCI_INT_DCE) != 0)
+ {
+ /* Terminate the transfer with an error */
+
+ mcerr("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining);
+ cxd56_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR);
+ }
+
+ /* Handle data timeout error */
+
+ else if ((pending & SDHCI_INT_DTOE) != 0)
+ {
+ /* Terminate the transfer with an error */
+
+ mcerr("ERROR: Data timeout, remaining: %d\n", priv->remaining);
+ cxd56_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT);
+ }
+ }
+
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+ if (enabled & SDHCI_INT_CINT)
+ {
+ /* Handle card interrupt events */
+
+ putreg32(getreg32(CXD56_SDHCI_IRQSIGEN) & (~SDHCI_INT_CINT), CXD56_SDHCI_IRQSIGEN);
+ putreg32(getreg32(CXD56_SDHCI_IRQSTATEN) & (~SDHCI_INT_CINT), CXD56_SDHCI_IRQSTATEN);
+ work_cancel(HPWORK, &priv->cbwork);
+ (void)work_queue(HPWORK, &priv->cbwork, (worker_t)cxd56_sdhci_irq_handler, &priv->dev, 0);
+ }
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+
+ /* Handle wait events *****************************************************/
+
+ pending = enabled & priv->waitints;
+ if (pending != 0)
+ {
+ /* Is this a response completion event? */
+
+ if ((pending & SDHCI_RESPDONE_INTS) != 0)
+ {
+ /* Yes.. Is their a thread waiting for response done? */
+
+ if ((priv->waitevents & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0)
+ {
+ /* Yes.. mask further interrupts and wake the thread up */
+
+ regval = getreg32(CXD56_SDHCI_IRQSIGEN);
+ regval &= ~SDHCI_RESPDONE_INTS;
+ putreg32(regval, CXD56_SDHCI_IRQSIGEN);
+
+ cxd56_endwait(priv, SDIOWAIT_RESPONSEDONE);
+ }
+ }
+ }
+
+ /* Re-enable card interrupts */
+
+ regval = getreg32(CXD56_SDHCI_IRQSIGEN);
+ regval |= SDHCI_INT_CINT | enabled;
+ putreg32(regval, CXD56_SDHCI_IRQSIGEN);
+
+ return OK;
+}
+
+/****************************************************************************
+ * SDIO Interface Methods
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_sdio_lock
+ *
+ * Description:
+ * Locks the bus. Function calls low-level multiplexed bus routines to
+ * resolve bus requests and acknowledgement issues.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * lock - TRUE to lock, FALSE to unlock.
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_MUXBUS
+static int cxd56_sdio_lock(FAR struct sdio_dev_s *dev, bool lock)
+{
+ /* Single SDIO instance so there is only one possibility. The multiplex
+ * bus is part of board support package.
+ */
+
+ cxd56_muxbus_sdio_lock(lock);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_sdio_sdhci_reset
+ *
+ * Description:
+ * Reset the SDIO controller. Undo all setup and initialization.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_sdio_sdhci_reset(FAR struct sdio_dev_s *dev)
+{
+ FAR struct cxd56_sdiodev_s *priv = (FAR struct cxd56_sdiodev_s *)dev;
+ uint32_t regval;
+ int32_t timeout = 100;
+
+ /* Disable all interrupts so that nothing interferes with the following. */
+
+ putreg32(0, CXD56_SDHCI_IRQSIGEN);
+
+ /* Reset the SDHC block, putting registers in their default, reset state.
+ * Initiate the reset by setting the RSTA bit in the SYSCTL register.
+ */
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval |= SDHCI_SYSCTL_RSTA;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+
+ /* The SDHC will reset the RSTA bit to 0 when the capabilities
+ * registers are valid and the host driver can read them.
+ */
+
+ while ((getreg32(CXD56_SDHCI_SYSCTL) & SDHCI_SYSCTL_RSTA) != 0)
+ {
+ timeout--;
+ if (timeout < 1)
+ {
+ break;
+ }
+ up_mdelay(30);
+ }
+
+ /* Make sure that all clocking is disabled */
+
+ cxd56_sdio_clock(dev, CLOCK_SDIO_DISABLED);
+
+ /* Enable all status bits (these could not all be potential sources of
+ * interrupts.
+ */
+
+ putreg32(SDHCI_INT_ALL & (~SDHCI_INT_CINT), CXD56_SDHCI_IRQSTATEN);
+
+ mcinfo("SYSCTL: %08x PRSSTAT: %08x IRQSTATEN: %08x\n",
+ getreg32(CXD56_SDHCI_SYSCTL), getreg32(CXD56_SDHCI_PRSSTAT),
+ getreg32(CXD56_SDHCI_IRQSTATEN));
+
+ /* The next phase of the hardware reset would be to set the SYSCTRL INITA
+ * bit to send 80 clock ticks for card to power up and then reset the card
+ * with CMD0. This is done elsewhere.
+ */
+
+ /* Reset state data */
+ sem_init(&priv->waitsem, 0, 1);
+ priv->waitwdog = wd_create();
+ DEBUGASSERT(priv->waitwdog);
+ sem_init(&priv->waitsem, 0, 1);
+ priv->waitevents = 0; /* Set of events to be waited for */
+ priv->waitints = 0; /* Interrupt enables for event waiting */
+ priv->wkupevent = 0; /* The event that caused the wakeup */
+#ifdef CONFIG_SDIO_DMA
+ priv->xfrflags = 0; /* Used to synchronize SDIO and DMA completion events */
+#endif
+
+ wd_cancel(priv->waitwdog); /* Cancel any timeouts */
+
+ /* Interrupt mode data transfer support */
+
+ priv->buffer = 0; /* Address of current R/W buffer */
+ priv->remaining = 0; /* Number of bytes remaining in the transfer */
+ priv->xfrints = 0; /* Interrupt enables for data transfer */
+
+ priv->blocksize = CXD56_SDHCI_BUF_SIZE;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_capabilities
+ *
+ * Description:
+ * Get capabilities (and limitations) of the SDIO driver (optional)
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Returns a bitset of status values (see SDIO_CAPS_* defines)
+ *
+ ****************************************************************************/
+
+static sdio_capset_t cxd56_sdio_capabilities(FAR struct sdio_dev_s *dev)
+{
+ sdio_capset_t caps = 0;
+
+#ifdef CONFIG_CXD56_SDIO_WIDTH_D1_ONLY
+ caps |= SDIO_CAPS_1BIT_ONLY;
+#endif
+#ifdef CONFIG_CXD56_SDIO_DMA
+ caps |= SDIO_CAPS_DMASUPPORTED;
+#endif
+#ifndef CONFIG_CXD56_SDIO_DMA
+ /* In case of non-DMA, add below capability to change the write single
+ * sequence with sending CMD24. If not, write is not completed.
+ */
+
+ caps |= SDIO_CAPS_DMABEFOREWRITE;
+#endif
+
+ return caps;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_status
+ *
+ * Description:
+ * Get SDIO status.
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ *
+ * Returned Value:
+ * Returns a bitset of status values (see cxd56_status_* defines)
+ *
+ ****************************************************************************/
+
+static sdio_statset_t cxd56_sdio_status(FAR struct sdio_dev_s *dev)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ return priv->cdstatus;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_widebus
+ *
+ * Description:
+ * Called after change in Bus width has been selected (via ACMD6). Most
+ * controllers will need to perform some special operations to work
+ * correctly in the new bus mode.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * wide - true: wide bus (4-bit) bus mode enabled
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_sdio_widebus(FAR struct sdio_dev_s *dev, bool wide)
+{
+ uint32_t regval;
+
+ /* Set the Data Transfer Width (DTW) field in the PROCTL register */
+
+ regval = getreg32(CXD56_SDHCI_PROCTL);
+ regval &= ~SDHCI_PROCTL_DTW_MASK;
+ if (wide)
+ {
+ regval |= SDHCI_PROCTL_DTW_4BIT;
+ }
+ else
+ {
+ regval |= SDHCI_PROCTL_DTW_1BIT;
+ }
+ putreg32(regval, CXD56_SDHCI_PROCTL);
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_frequency
+ *
+ * Description:
+ * Set the SD clock frequency
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * frequency - The frequency to use
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_sdio_frequency(uint32_t frequency)
+{
+ uint32_t baseclk;
+ uint16_t i;
+ uint32_t regval;
+ uint16_t divisor;
+
+ baseclk = cxd56_get_sdio_baseclock();
+ if (frequency >= baseclk)
+ {
+ divisor = 0;
+ }
+ else
+ {
+ for (i=1; i<0x3ff; i++)
+ {
+ if (baseclk / (2 * i) < frequency)
+ {
+ break;
+ }
+ }
+ divisor = i;
+ }
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval &= ~SDHCI_SYSCTL_GENSEL;
+ regval &= ~(SDHCI_SYSCTL_SDCLKFS_MASK | SDHCI_SYSCTL_SDCLKFSUP_MASK);
+ regval |= (divisor << SDHCI_SYSCTL_SDCLKFS_SHIFT) & SDHCI_SYSCTL_SDCLKFS_MASK;
+ regval |= ((divisor >> 8) << SDHCI_SYSCTL_SDCLKFSUP_SHIFT) & SDHCI_SYSCTL_SDCLKFSUP_MASK;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+}
+
+static void cxd56_sdio_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
+{
+ uint32_t regval;
+ uint32_t frequency = 0;
+ uint32_t i;
+
+ /* The SDCLK must be disabled before its frequency can be changed: "SDCLK
+ * frequency can be changed when this bit is 0. Then, the host controller
+ * shall maintain the same clock frequency until SDCLK is stopped (stop at
+ * SDCLK = 0).
+ */
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval &= ~SDHCI_SYSCTL_SDCLKEN;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+ mcinfo("SYSCTRL: %08x\n", getreg32(CXD56_SDHCI_SYSCTL));
+
+ /* sel_ttclk bit[16] */
+ if (cxd56_get_sdio_baseclock() < 48*1000*1000)
+ {
+ putreg32(getreg32(CXD56_SDHCI_USERDEF2CTL) | (0x1 << 16),
+ CXD56_SDHCI_USERDEF2CTL);
+ }
+ else
+ {
+ putreg32(getreg32(CXD56_SDHCI_USERDEF2CTL) & ~(0x1 << 16),
+ CXD56_SDHCI_USERDEF2CTL);
+ }
+
+ /* HS_SYNC_RISE bit[16] */
+ putreg32(0x01010100, CXD56_SDHCI_OTHERIOLL);
+
+ /* sdclk_dly_sel */
+ if (rate <= CLOCK_SD_TRANSFER_4BIT)
+ putreg32((getreg32(CXD56_SDHCI_USERDEF2CTL) & ~(0x7))| 0x1, CXD56_SDHCI_USERDEF2CTL);
+ else
+ putreg32((getreg32(CXD56_SDHCI_USERDEF2CTL) & ~(0x7))| 0x0, CXD56_SDHCI_USERDEF2CTL);
+
+ /* Select the new prescaler and divisor values based on the requested mode
+ * and the settings from the board.h file.
+ *
+ * TODO: Investigate using the automatically gated clocks to reduce power
+ * consumption.
+ */
+
+ switch (rate)
+ {
+ default:
+ case CLOCK_SDIO_DISABLED : /* Clock is disabled */
+ {
+ /* Clear the prescaler and divisor settings and other clock
+ * enables as well.
+ */
+ regval &= ~(SDHCI_SYSCTL_SDCLKFS_MASK | SDHCI_SYSCTL_SDCLKFSUP_MASK);
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+ cxd56_sdio_frequency(CONFIG_CXD56_IDMODE_FREQ);
+ mcinfo("SYSCTRL: %08x\n", getreg32(CXD56_SDHCI_SYSCTL));
+ return;
+ }
+
+ case CLOCK_IDMODE : /* Initial ID mode clocking (<400KHz) */
+ frequency = CONFIG_CXD56_IDMODE_FREQ;
+ break;
+
+ case CLOCK_MMC_TRANSFER : /* MMC normal operation clocking */
+ frequency = CONFIG_CXD56_MMCXFR_FREQ;
+ break;
+
+ case CLOCK_SD_TRANSFER_1BIT : /* SD normal operation clocking (narrow 1-bit mode) */
+#ifndef CONFIG_CXD56_SDIO_WIDTH_D1_ONLY
+ frequency = CONFIG_CXD56_SD1BIT_FREQ;
+ break;
+#endif
+
+ case CLOCK_SD_TRANSFER_4BIT : /* SD normal operation clocking (wide 4-bit mode) */
+ frequency = CONFIG_CXD56_SD4BIT_FREQ;
+ break;
+ }
+
+ cxd56_sdio_frequency(frequency);
+
+ putreg32(getreg32(CXD56_SDHCI_SYSCTL) | SDHCI_SYSCTL_ICLKEN, CXD56_SDHCI_SYSCTL);
+ for (i=0;i<20;i++)
+ {
+ up_mdelay(50);
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ if (regval & SDHCI_SYSCTL_ICLKSTA)
+ {
+ break;
+ }
+ }
+ do
+ {
+ putreg32(regval | SDHCI_SYSCTL_SDCLKEN, CXD56_SDHCI_SYSCTL);
+ }
+ while((getreg32(CXD56_SDHCI_SYSCTL) & SDHCI_SYSCTL_SDCLKEN) == 0);
+ mcinfo("SYSCTRL: %08x\n", getreg32(CXD56_SDHCI_SYSCTL));
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_attach
+ *
+ * Description:
+ * Attach and prepare interrupts
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ *
+ * Returned Value:
+ * OK on success; A negated errno on failure.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_attach(FAR struct sdio_dev_s *dev)
+{
+ int ret;
+
+ /* Attach the SDIO interrupt handler */
+ ret = irq_attach(CXD56_IRQ_SDIO, cxd56_interrupt, NULL);
+ if (ret == OK)
+ {
+ /* Disable all interrupts at the SDIO controller and clear all pending
+ * interrupts.
+ */
+
+ putreg32(0, CXD56_SDHCI_IRQSIGEN);
+ putreg32(SDHCI_INT_ALL, CXD56_SDHCI_IRQSTAT);
+
+#ifdef CONFIG_ARCH_IRQPRIO
+ /* Set the interrupt priority */
+
+ up_prioritize_irq(CXD56_IRQ_SDIO, CONFIG_CXD56_SDHCI_PRIO);
+#endif
+
+ /* Enable SDIO interrupts at the NVIC. They can now be enabled at
+ * the SDIO controller as needed.
+ */
+
+ up_enable_irq(CXD56_IRQ_SDIO);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_sendcmd
+ *
+ * Description:
+ * Send the SDIO command
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * cmd - The command to send (32-bits, encoded)
+ * arg - 32-bit argument required with some commands
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg)
+{
+#ifdef CONFIG_SDIO_DMA
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+#endif
+ uint32_t regval;
+ uint32_t cmdidx;
+ int32_t timeout;
+
+ /* Initialize the command index */
+
+ cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT;
+ regval = cmdidx << SDHCI_XFERTYP_CMDINX_SHIFT;
+
+ /* Does a data transfer accompany the command? */
+
+ if ((cmd & MMCSD_DATAXFR) != 0)
+ {
+ /* Yes.. Configure the data transfer */
+
+ switch (cmd & MMCSD_DATAXFR_MASK)
+ {
+ default:
+ case MMCSD_NODATAXFR : /* No.. no data transfer */
+ break;
+
+ /* The following two cases are probably missing some setup logic */
+
+ case MMCSD_RDSTREAM : /* Yes.. streaming read data transfer */
+ regval |= (SDHCI_XFERTYP_DPSEL | SDHCI_XFERTYP_DTDSEL);
+ break;
+
+ case MMCSD_WRSTREAM : /* Yes.. streaming write data transfer */
+ regval |= SDHCI_XFERTYP_DPSEL;
+ break;
+
+ case MMCSD_RDDATAXFR : /* Yes.. normal read data transfer */
+ regval |= (SDHCI_XFERTYP_DPSEL | SDHCI_XFERTYP_DTDSEL);
+ break;
+
+ case MMCSD_WRDATAXFR : /* Yes.. normal write data transfer */
+ regval |= SDHCI_XFERTYP_DPSEL;
+ break;
+ }
+
+ /* Is it a multi-block transfer? */
+
+ if ((cmd & MMCSD_MULTIBLOCK) != 0)
+ {
+ /* Yes.. should the transfer be stopped with ACMD12? */
+
+ if ((cmd & MMCSD_STOPXFR) != 0)
+ {
+ /* Yes.. Indefinite block transfer */
+
+ regval |= (SDHCI_XFERTYP_MSBSEL | SDHCI_XFERTYP_AC12EN);
+ }
+ else
+ {
+ /* No.. Fixed block transfer */
+
+ regval |= (SDHCI_XFERTYP_MSBSEL | SDHCI_XFERTYP_BCEN);
+ }
+ }
+ }
+
+ /* Configure response type bits */
+
+ switch (cmd & MMCSD_RESPONSE_MASK)
+ {
+ case MMCSD_NO_RESPONSE: /* No response */
+ regval |= SDHCI_XFERTYP_RSPTYP_NONE;
+ break;
+
+ case MMCSD_R1B_RESPONSE: /* Response length 48, check busy & cmdindex */
+ regval |= (SDHCI_XFERTYP_RSPTYP_LEN48BSY | SDHCI_XFERTYP_CICEN |
+ SDHCI_XFERTYP_CCCEN);
+ break;
+
+ case MMCSD_R1_RESPONSE: /* Response length 48, check cmdindex */
+ case MMCSD_R5_RESPONSE:
+ case MMCSD_R6_RESPONSE:
+ regval |= (SDHCI_XFERTYP_RSPTYP_LEN48 | SDHCI_XFERTYP_CICEN |
+ SDHCI_XFERTYP_CCCEN);
+ break;
+
+ case MMCSD_R2_RESPONSE: /* Response length 136, check CRC */
+ regval |= (SDHCI_XFERTYP_RSPTYP_LEN136 | SDHCI_XFERTYP_CCCEN);
+ break;
+
+ case MMCSD_R3_RESPONSE: /* Response length 48 */
+ case MMCSD_R4_RESPONSE:
+ case MMCSD_R7_RESPONSE:
+ regval |= SDHCI_XFERTYP_RSPTYP_LEN48;
+ break;
+ }
+
+ /* Enable DMA */
+
+#ifdef CONFIG_SDIO_DMA
+ /* Internal DMA is used */
+ priv->dmasend_prepare = false;
+ priv->dmasend_cmd = 0;
+ priv->dmasend_regcmd = 0;
+ if (((cmd & MMCSD_DATAXFR_MASK) != MMCSD_NODATAXFR) && priv->usedma)
+ {
+ regval |= SDHCI_XFERTYP_DMAEN;
+ }
+ else if (cmdidx == MMCSD_CMDIDX24 || cmdidx == MMCSD_CMDIDX25)
+ {
+ regval |= SDHCI_XFERTYP_DMAEN;
+ priv->usedma = true;
+ priv->dmasend_prepare = true;
+ }
+#endif
+
+ /* Other bits? What about CMDTYP? */
+
+ mcinfo("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval);
+
+ /* The Command Inhibit (CIHB) bit is set in the PRSSTAT bit immediately
+ * after the transfer type register is written. This bit is cleared when
+ * the command response is received. If this status bit is 0, it
+ * indicates that the CMD line is not in use and the SDHC can issue a
+ * SD/MMC Command using the CMD line.
+ *
+ * CIHB should always be set when this function is called.
+ */
+
+ timeout = SDHCI_CMDTIMEOUT;
+ while ((getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_CIHB) != 0)
+ {
+ if (--timeout <= 0)
+ {
+ mcerr("ERROR: Timeout cmd: %08x PRSSTAT: %08x\n",
+ cmd, getreg32(CXD56_SDHCI_PRSSTAT));
+
+ return -EBUSY;
+ }
+ }
+
+ if ((cmd & MMCSD_DATAXFR_MASK) != MMCSD_NODATAXFR)
+ {
+ timeout = SDHCI_CMDTIMEOUT;
+ while ((getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_CDIHB) != 0)
+ {
+ if (--timeout <= 0)
+ {
+ mcerr("ERROR: Timeout cmd data: %08x PRSSTAT: %08x\n",
+ cmd, getreg32(CXD56_SDHCI_PRSSTAT));
+
+ return -EBUSY;
+ }
+ }
+ }
+
+ /* Set the SDHC Argument value */
+ putreg32(arg, CXD56_SDHCI_CMDARG);
+
+ /* Clear interrupt status and write the SDHC CMD */
+ putreg32(SDHCI_RESPDONE_INTS, CXD56_SDHCI_IRQSTAT);
+#ifdef CONFIG_SDIO_DMA
+ priv->dma_cmd = cmd;
+ if (priv->dmasend_prepare)
+ {
+ priv->dmasend_regcmd = regval;
+ priv->dmasend_cmd = cmd;
+ }
+ else
+#endif
+ {
+ putreg32(regval, CXD56_SDHCI_XFERTYP);
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_blocksetup
+ *
+ * Description:
+ * Some hardward needs to be informed of the selected blocksize.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * blocklen - The selected block size.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_blocksetup(FAR struct sdio_dev_s *dev, unsigned int blocklen,
+ unsigned int nblocks)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ uint32_t regval;
+
+ DEBUGASSERT(dev != NULL && nblocks > 0 && nblocks < 65535);
+ DEBUGASSERT(blocklen < 65535);
+
+ priv->blocksize = blocklen;
+
+ /* Set the block size and count */
+
+ regval = (blocklen << SDHCI_BLKATTR_SIZE_SHIFT) |
+ (nblocks << SDHCI_BLKATTR_CNT_SHIFT);
+ putreg32(regval, CXD56_SDHCI_BLKATTR);
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_recvsetup
+ *
+ * Description:
+ * Setup hardware in preparation for data transfer from the card in non-DMA
+ * (interrupt driven mode). This method will do whatever controller setup
+ * is necessary. This would be called for SD memory just BEFORE sending
+ * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18
+ * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT
+ * will be called to receive the indication that the transfer is complete.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * buffer - Address of the buffer in which to receive the data
+ * nbytes - The number of bytes in the transfer
+ *
+ * Returned Value:
+ * Number of bytes sent on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
+ size_t nbytes)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+#ifdef CONFIG_SDIO_DMA
+ priv->usedma = false;
+#endif
+
+ /* Reset the DPSM configuration */
+
+ cxd56_datadisable();
+ cxd56_sampleinit();
+ cxd56_sample(priv, SAMPLENDX_BEFORE_SETUP);
+
+ /* Save the destination buffer information for use by the interrupt handler */
+
+ priv->buffer = (uint32_t *)buffer;
+ priv->remaining = nbytes;
+
+ /* Then set up the SDIO data path */
+
+ cxd56_dataconfig(priv, false, nbytes, 1, SDHCI_DTOCV_DATATIMEOUT);
+
+ /* And enable interrupts */
+
+ cxd56_configxfrints(priv, SDHCI_RCVDONE_INTS);
+ cxd56_sample(priv, SAMPLENDX_AFTER_SETUP);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_sendsetup
+ *
+ * Description:
+ * Setup hardware in preparation for data transfer from the card. This method
+ * will do whatever controller setup is necessary. This would be called
+ * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25
+ * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * buffer - Address of the buffer containing the data to send
+ * nbytes - The number of bytes in the transfer
+ *
+ * Returned Value:
+ * Number of bytes sent on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer,
+ size_t nbytes)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+#ifdef CONFIG_SDIO_DMA
+ priv->usedma = false;
+#endif
+
+ /* Reset the DPSM configuration */
+
+ cxd56_datadisable();
+ cxd56_sampleinit();
+ cxd56_sample(priv, SAMPLENDX_BEFORE_SETUP);
+
+ /* Save the source buffer information for use by the interrupt handler */
+
+ priv->buffer = (uint32_t *)buffer;
+ priv->remaining = nbytes;
+
+ /* Then set up the SDIO data path */
+
+ cxd56_dataconfig(priv, true, nbytes, 1, SDHCI_DTOCV_DATATIMEOUT);
+
+ /* Enable TX interrupts */
+
+ cxd56_configxfrints(priv, SDHCI_SNDDONE_INTS);
+ cxd56_sample(priv, SAMPLENDX_AFTER_SETUP);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_cancel
+ *
+ * Description:
+ * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP,
+ * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel
+ * the data transfer setup if, for some reason, you cannot perform the
+ * transfer.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ *
+ * Returned Value:
+ * OK is success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_cancel(FAR struct sdio_dev_s *dev)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ uint32_t regval;
+
+#ifdef CONFIG_SDIO_DMA
+ /* Release allocated buffer */
+ if (priv->aligned_buffer)
+ {
+ /* Free aligned buffer */
+
+ kmm_free(priv->aligned_buffer);
+
+ priv->aligned_buffer = NULL;
+ }
+#endif
+
+ /* Disable all transfer- and event- related interrupts */
+
+ cxd56_configxfrints(priv, 0);
+ cxd56_configwaitints(priv, 0, 0, 0);
+
+ /* Clearing pending interrupt status on all transfer- and event- related
+ * interrupts
+ */
+
+ putreg32(SDHCI_WAITALL_INTS, CXD56_SDHCI_IRQSTAT);
+
+ /* Cancel any watchdog timeout */
+
+ (void)wd_cancel(priv->waitwdog);
+
+ /* If this was a DMA transfer, make sure that DMA is stopped */
+
+#ifdef CONFIG_SDIO_DMA
+ /* Stop the DMA by resetting the data path */
+
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval |= SDHCI_SYSCTL_RSTD;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+ priv->usedma = false;
+ priv->dmasend_prepare = false;
+ priv->dmasend_cmd = 0;
+ priv->dmasend_regcmd = 0;
+ cxd56_sdhci_adma_dscr[0] = 0;
+ cxd56_sdhci_adma_dscr[1] = 0;
+ putreg32((uint32_t)cxd56_sdhci_adma_dscr, CXD56_SDHCI_ADSADDR);
+ putreg32(0, CXD56_SDHCI_ADSADDR_H);
+#endif
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval |= SDHCI_SYSCTL_RSTC;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ regval |= SDHCI_SYSCTL_RSTD;
+ putreg32(regval, CXD56_SDHCI_SYSCTL);
+
+ while ((getreg32(CXD56_SDHCI_SYSCTL) & SDHCI_SYSCTL_RSTC) != 0);
+ while ((getreg32(CXD56_SDHCI_SYSCTL) & SDHCI_SYSCTL_RSTD) != 0);
+
+ /* Mark no transfer in progress */
+ priv->remaining = 0;
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_waitresponse
+ *
+ * Description:
+ * Poll-wait for the response to the last command to be ready. This
+ * function should be called even after sending commands that have no
+ * response (such as CMD0) to make sure that the hardware is ready to
+ * receive the next command.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * cmd - The command that was sent. See 32-bit command definitions above.
+ *
+ * Returned Value:
+ * OK is success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd)
+{
+ uint32_t errors;
+ int32_t timeout = SDHCI_CMDTIMEOUT;
+ int ret = OK;
+
+#ifdef CONFIG_SDIO_DMA
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ if (priv->dmasend_prepare)
+ {
+ return OK;
+ }
+#endif
+
+ switch (cmd & MMCSD_RESPONSE_MASK)
+ {
+ case MMCSD_NO_RESPONSE:
+ timeout = SDHCI_CMDTIMEOUT;
+ errors = 0;
+ return OK;
+
+ case MMCSD_R1_RESPONSE:
+ case MMCSD_R1B_RESPONSE:
+ case MMCSD_R2_RESPONSE:
+ case MMCSD_R6_RESPONSE:
+ timeout = SDHCI_LONGTIMEOUT;
+ errors = SDHCI_RESPERR_INTS;
+ break;
+
+ case MMCSD_R4_RESPONSE:
+ case MMCSD_R5_RESPONSE:
+ case MMCSD_R3_RESPONSE:
+ case MMCSD_R7_RESPONSE:
+ timeout = SDHCI_CMDTIMEOUT;
+ errors = SDHCI_RESPERR_INTS;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ /* Then wait for the Command Complete (CC) indication (or timeout). The
+ * CC bit is set when the end bit of the command response is received
+ * (except Auto CMD12).
+ */
+
+ while ((getreg32(CXD56_SDHCI_IRQSTAT) & SDHCI_INT_CC) == 0)
+ {
+ timeout -= 1;
+ if (timeout <= 0)
+ {
+ mcerr("ERROR: Timeout cmd: %08x IRQSTAT: %08x\n",
+ cmd, getreg32(CXD56_SDHCI_IRQSTAT));
+ putreg32(0,CXD56_SDHCI_IRQSIGEN);
+
+ return -ETIMEDOUT;
+ }
+ }
+
+ /* Check for hardware detected errors */
+
+ if ((getreg32(CXD56_SDHCI_IRQSTAT) & errors) != 0)
+ {
+ mcerr("ERROR: cmd: %08x errors: %08x IRQSTAT: %08x\n",
+ cmd, errors, getreg32(CXD56_SDHCI_IRQSTAT));
+ ret = -EIO;
+ }
+
+ /* Clear the response wait status bits */
+ if ((cmd & MMCSD_DATAXFR_MASK) == MMCSD_NODATAXFR)
+ {
+ putreg32((SDHCI_INT_TC & getreg32(CXD56_SDHCI_IRQSTAT))| SDHCI_RESPDONE_INTS,
+ CXD56_SDHCI_IRQSTAT);
+ }
+ else
+ {
+ putreg32(SDHCI_RESPDONE_INTS, CXD56_SDHCI_IRQSTAT);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_recvRx
+ *
+ * Description:
+ * Receive response to SDIO command. Only the critical payload is
+ * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit
+ * status. The driver implementation should verify the correctness of
+ * the remaining, non-returned bits (CRCs, CMD index, etc.).
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * Rx - Buffer in which to receive the response
+ *
+ * Returned Value:
+ * Number of bytes sent on success; a negated errno on failure. Here a
+ * failure means only a faiure to obtain the requested reponse (due to
+ * transport problem -- timeout, CRC, etc.). The implementation only
+ * assures that the response is returned intacta and does not check errors
+ * within the response itself.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd,
+ uint32_t *rshort)
+{
+ uint32_t regval;
+ int ret = OK;
+#ifdef CONFIG_SDIO_DMA
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+#endif
+
+ /* R1 Command response (48-bit)
+ * 47 0 Start bit
+ * 46 0 Transmission bit (0=from card)
+ * 45:40 bit5 - bit0 Command index (0-63)
+ * 39:8 bit31 - bit0 32-bit card status
+ * 7:1 bit6 - bit0 CRC7
+ * 0 1 End bit
+ *
+ * R1b Identical to R1 with the additional busy signalling via the data
+ * line.
+ *
+ * R6 Published RCA Response (48-bit, SD card only)
+ * 47 0 Start bit
+ * 46 0 Transmission bit (0=from card)
+ * 45:40 bit5 - bit0 Command index (0-63)
+ * 39:8 bit31 - bit0 32-bit Argument Field, consisting of:
+ * [31:16] New published RCA of card
+ * [15:0] Card status bits {23,22,19,12:0}
+ * 7:1 bit6 - bit0 CRC7
+ * 0 1 End bit
+ */
+
+ if (rshort)
+ {
+ *rshort = 0;
+ }
+
+#ifdef CONFIG_SDIO_DMA
+ if (priv->dmasend_prepare)
+ {
+ return OK;
+ }
+#endif
+#ifdef CONFIG_DEBUG_FEATURES
+ if (!rshort)
+ {
+ mcerr("ERROR: rshort=NULL\n");
+ ret = -EINVAL;
+ }
+
+ /* Check that this is the correct response to this command */
+
+ else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE &&
+ (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE &&
+ (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE)
+ {
+ mcerr("ERROR: Wrong response CMD=%08x\n", cmd);
+ ret = -EINVAL;
+ }
+ else
+#endif
+ {
+ /* Check if a timeout or CRC error occurred */
+
+ regval = getreg32(CXD56_SDHCI_IRQSTAT);
+ if ((regval & SDHCI_INT_CTOE) != 0)
+ {
+ mcerr("ERROR: Command timeout: %08x\n", regval);
+ ret = -ETIMEDOUT;
+ }
+ else if ((regval & SDHCI_INT_CCE) != 0)
+ {
+ mcerr("ERROR: CRC failure: %08x\n", regval);
+ ret = -EIO;
+ }
+ }
+
+ /* Return the R1/R1b/R6 response. These responses are returned in
+ * CDMRSP0. NOTE: This is not true for R1b (Auto CMD12 response) which
+ * is returned in CMDRSP3.
+ */
+
+ *rshort = getreg32(CXD56_SDHCI_CMDRSP0);
+
+ return ret;
+}
+
+static int cxd56_sdio_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4])
+{
+ uint32_t regval;
+ int ret = OK;
+
+ /* R2 CID, CSD register (136-bit)
+ * 135 0 Start bit
+ * 134 0 Transmission bit (0=from card)
+ * 133:128 bit5 - bit0 Reserved
+ * 127:1 bit127 - bit1 127-bit CID or CSD register
+ * (including internal CRC)
+ * 0 1 End bit
+ */
+
+ if (rlong)
+ {
+ rlong[0] = 0;
+ rlong[1] = 0;
+ rlong[2] = 0;
+ rlong[3] = 0;
+ }
+#ifdef CONFIG_DEBUG_FEATURES
+ /* Check that R1 is the correct response to this command */
+
+ if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE)
+ {
+ mcerr("ERROR: Wrong response CMD=%08x\n", cmd);
+ ret = -EINVAL;
+ }
+ else
+#endif
+ {
+ /* Check if a timeout or CRC error occurred */
+
+ regval = getreg32(CXD56_SDHCI_IRQSTAT);
+ if (regval & SDHCI_INT_CTOE)
+ {
+ mcerr("ERROR: Timeout IRQSTAT: %08x\n", regval);
+ ret = -ETIMEDOUT;
+ }
+ else if (regval & SDHCI_INT_CCE)
+ {
+ mcerr("ERROR: CRC fail IRQSTAT: %08x\n", regval);
+ ret = -EIO;
+ }
+ }
+
+ /* Return the long response in CMDRSP3..0 */
+
+ if (rlong)
+ {
+ rlong[0] = getreg32(CXD56_SDHCI_CMDRSP3);
+ rlong[1] = getreg32(CXD56_SDHCI_CMDRSP2);
+ rlong[2] = getreg32(CXD56_SDHCI_CMDRSP1);
+ rlong[3] = getreg32(CXD56_SDHCI_CMDRSP0);
+ }
+ if (1)
+ {
+ rlong[0] = ((rlong[0] << 8) & 0xffffff00) | ((rlong[1] >> 24) & 0x000000FF);
+ rlong[1] = ((rlong[1] << 8) & 0xffffff00) | ((rlong[2] >> 24) & 0x000000FF);
+ rlong[2] = ((rlong[2] << 8) & 0xffffff00) | ((rlong[3] >> 24) & 0x000000FF);
+ rlong[3] = (rlong[3] << 8) & 0xffffff00;
+ }
+ return ret;
+}
+
+static int cxd56_sdio_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort)
+{
+ uint32_t regval;
+ int ret = OK;
+
+ /* R3 OCR (48-bit)
+ * 47 0 Start bit
+ * 46 0 Transmission bit (0=from card)
+ * 45:40 bit5 - bit0 Reserved
+ * 39:8 bit31 - bit0 32-bit OCR register
+ * 7:1 bit6 - bit0 Reserved
+ * 0 1 End bit
+ */
+
+ /* R4 Response (48-bit)
+ * 47 0 Start bit
+ * 46 0 Direction bit(0=card to host)
+ * 45:40 bit5 - bit0 Reserved
+ * 39 1 Set to 1 if Card is ready to operate after initialization
+ * 38:36 bit2 - bit0 Number of I/O functions
+ * 35 1 Memory Present
+ * 34:32 bit2 - bit0 Stuff Bits
+ * 31:8 bit23 - bit0 I/O OCR
+ * 7:1 bit6 - bit0 Reserved
+ * 0 1 End bit
+ */
+
+ /* R5 Response (48-bit)
+ * 47 0 Start bit
+ * 46 0 Direction bit(0=card to host)
+ * 45:40 bit5 - bit0 Command Index
+ * 39:24 bit15 - bit0 16-bit Stuff Bits
+ * 23:16 bit7 - bit0 Response Flags
+ * 15:8 bit7 - bit0 Read or Write Data
+ * 7:1 bit6 - bit0 CRC
+ * 0 1 End bit
+ */
+
+ if (!rshort)
+ {
+ *rshort = 0;
+ }
+ /* Check that this is the correct response to this command */
+#ifdef CONFIG_DEBUG_FEATURES
+ if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE &&
+ (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R4_RESPONSE &&
+ (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R5_RESPONSE &&
+ (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE)
+ {
+ mcerr("ERROR: Wrong response CMD=%08x\n", cmd);
+ ret = -EINVAL;
+ }
+ else
+#endif
+ {
+ /* Check if a timeout occurred (Apparently a CRC error can terminate
+ * a good response)
+ */
+
+ regval = getreg32(CXD56_SDHCI_IRQSTAT);
+ if (regval & SDHCI_INT_CTOE)
+ {
+ mcerr("ERROR: Timeout IRQSTAT: %08x\n", regval);
+ ret = -ETIMEDOUT;
+ }
+ }
+
+ /* Return the short response in CMDRSP0 */
+
+ if (rshort)
+ {
+ *rshort = getreg32(CXD56_SDHCI_CMDRSP0);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_waitenable
+ *
+ * Description:
+ * Enable/disable of a set of SDIO wait events. This is part of the
+ * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is
+ * configured before calling cxd56_eventwait. This is done in this way
+ * to help the driver to eliminate race conditions between the command
+ * setup and the subsequent events.
+ *
+ * The enabled events persist until either (1) SDIO_WAITENABLE is called
+ * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT
+ * returns.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * eventset - A bitset of events to enable or disable (see SDIOWAIT_*
+ * definitions). 0=disable; 1=enable.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_sdio_waitenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ uint32_t waitints;
+
+ DEBUGASSERT(priv != NULL);
+
+ /* Disable event-related interrupts */
+
+ cxd56_configwaitints(priv, 0, 0, 0);
+
+ /* Select the interrupt mask that will give us the appropriate wakeup
+ * interrupts.
+ */
+
+ waitints = 0;
+ if ((eventset & (SDIOWAIT_CMDDONE | SDIOWAIT_RESPONSEDONE)) != 0)
+ {
+ waitints |= SDHCI_RESPDONE_INTS;
+ }
+
+ if ((eventset & SDIOWAIT_TRANSFERDONE) != 0)
+ {
+ waitints |= SDHCI_XFRDONE_INTS;
+ }
+
+ /* Enable event-related interrupts */
+
+ cxd56_configwaitints(priv, waitints, eventset, 0);
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_eventwait
+ *
+ * Description:
+ * Wait for one of the enabled events to occur (or a timeout). Note that
+ * all events enabled by SDIO_WAITEVENTS are disabled when cxd56_eventwait
+ * returns. SDIO_WAITEVENTS must be called again before cxd56_eventwait
+ * can be used again.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * timeout - Maximum time in milliseconds to wait. Zero means immediate
+ * timeout with no wait. The timeout value is ignored if
+ * SDIOWAIT_TIMEOUT is not included in the waited-for eventset.
+ *
+ * Returned Value:
+ * Event set containing the event(s) that ended the wait. Should always
+ * be non-zero. All events are disabled after the wait concludes.
+ *
+ ****************************************************************************/
+
+static sdio_eventset_t cxd56_sdio_eventwait(FAR struct sdio_dev_s *dev,
+ uint32_t timeout)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ sdio_eventset_t wkupevent = 0;
+ int ret;
+
+ /* There is a race condition here... the event may have completed before
+ * we get here. In this case waitevents will be zero, but wkupevents will
+ * be non-zero (and, hopefully, the semaphore count will also be non-zero.
+ */
+
+ DEBUGASSERT((priv->waitevents != 0 && priv->wkupevent == 0) ||
+ (priv->waitevents == 0 && priv->wkupevent != 0));
+
+ /* Check if the timeout event is specified in the event set */
+
+ if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0)
+ {
+ int delay;
+
+ /* Yes.. Handle a corner case */
+
+ if (!timeout)
+ {
+ return SDIOWAIT_TIMEOUT;
+ }
+
+ /* Start the watchdog timer */
+
+ delay = MSEC2TICK(timeout);
+ ret = wd_start(priv->waitwdog, delay, (wdentry_t)cxd56_eventtimeout,
+ 1, (uint32_t)priv);
+ if (ret != OK)
+ {
+ mcerr("ERROR: wd_start failed: %d\n", ret);
+ }
+ }
+
+ /* Loop until the event (or the timeout occurs). Race conditions are avoided
+ * by calling cxd56_waitenable prior to triggering the logic that will cause
+ * the wait to terminate. Under certain race conditions, the waited-for
+ * may have already occurred before this function was called!
+ */
+
+ for (; ; )
+ {
+ /* Wait for an event in event set to occur. If this the event has already
+ * occurred, then the semaphore will already have been incremented and
+ * there will be no wait.
+ */
+
+ cxd56_takesem(priv);
+ wkupevent = priv->wkupevent;
+
+ /* Check if the event has occurred. When the event has occurred, then
+ * evenset will be set to 0 and wkupevent will be set to a non-zero value.
+ */
+
+ if (wkupevent != 0)
+ {
+ /* Yes... break out of the loop with wkupevent non-zero */
+ if (wkupevent & ( SDIOWAIT_RESPONSEDONE | SDIOWAIT_TRANSFERDONE))
+ {
+ if (priv->remaining > 0)
+ {
+ priv->remaining = 0;
+ }
+ }
+ if (wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR))
+ {
+ cxd56_sdio_cancel(&(priv->dev));
+ }
+ break;
+ }
+ }
+
+
+ /* Disable event-related interrupts */
+
+ cxd56_configwaitints(priv, 0, 0, 0);
+#ifdef CONFIG_SDIO_DMA
+ priv->xfrflags = 0;
+ if (priv->aligned_buffer)
+ {
+ if (priv->dma_cmd == MMCSD_CMD17 || priv->dma_cmd == MMCSD_CMD18)
+ {
+ /* Copy receive buffer from aligned address */
+
+ memcpy(priv->receive_buffer, priv->aligned_buffer, priv->receive_size);
+ }
+
+ /* Free aligned buffer */
+
+ kmm_free(priv->aligned_buffer);
+
+ priv->aligned_buffer = NULL;
+ }
+#endif
+
+ cxd56_dumpsamples(priv);
+ return wkupevent;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_callbackenable
+ *
+ * Description:
+ * Enable/disable of a set of SDIO callback events. This is part of the
+ * the SDIO callback sequence. The set of events is configured to enabled
+ * callbacks to the function provided in cxd56_registercallback.
+ *
+ * Events are automatically disabled once the callback is performed and no
+ * further callback events will occur until they are again enabled by
+ * calling this method.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * eventset - A bitset of events to enable or disable (see SDIOMEDIA_*
+ * definitions). 0=disable; 1=enable.
+ *
+ * Returned Value:
+ * None
+ *
+ ****************************************************************************/
+
+static void cxd56_sdio_callbackenable(FAR struct sdio_dev_s *dev,
+ sdio_eventset_t eventset)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ mcinfo("eventset: %02x\n", eventset);
+ DEBUGASSERT(priv != NULL);
+
+ priv->cbevents = eventset;
+ cxd56_sdio_callback(priv);
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_registercallback
+ *
+ * Description:
+ * Register a callback that that will be invoked on any media status
+ * change. Callbacks should not be made from interrupt handlers, rather
+ * interrupt level events should be handled by calling back on the work
+ * thread.
+ *
+ * When this method is called, all callbacks should be disabled until they
+ * are enabled via a call to SDIO_CALLBACKENABLE
+ *
+ * Input Parameters:
+ * dev - Device-specific state data
+ * callback - The function to call on the media change
+ * arg - A caller provided value to return with the callback
+ *
+ * Returned Value:
+ * 0 on success; negated errno on failure.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_registercallback(FAR struct sdio_dev_s *dev,
+ worker_t callback, void *arg)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ /* Disable callbacks and register this callback and is argument */
+
+ mcinfo("Register %p(%p)\n", callback, arg);
+ DEBUGASSERT(priv != NULL);
+
+ priv->cbevents = 0;
+ priv->cbarg = arg;
+ priv->callback = callback;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_admasetup
+ *
+ * Description:
+ * Setup to perform ADMA. If the processor supports a data cache,
+ * then this method will also make sure that the contents of the DMA memory
+ * and the data cache are coherent.
+ *
+ * Input Parameters:
+ * buffer - The memory to/from DMA
+ * buflen - The size of the DMA transfer in bytes
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_DMA
+static int cxd56_sdio_admasetup(FAR const uint8_t *buffer, size_t buflen)
+{
+ uint32_t dscr_top = (uint32_t)cxd56_sdhci_adma_dscr;
+ uint32_t dscr_l;
+ uint32_t i, remaining, len;
+ uint32_t data_addr = (uint32_t)buffer;
+ remaining = buflen;
+
+ putreg32(0x0, CXD56_SDHCI_ADSADDR_H);
+ putreg32(dscr_top, CXD56_SDHCI_ADSADDR);
+ for (i=0;i 0)
+ {
+ return -EIO;
+ }
+ else
+ {
+ return OK;
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_sdio_dmarecvsetup
+ *
+ * Description:
+ * Setup to perform a read DMA. If the processor supports a data cache,
+ * then this method will also make sure that the contents of the DMA memory
+ * and the data cache are coherent. For read transfers this may mean
+ * invalidating the data cache.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * buffer - The memory to DMA from
+ * buflen - The size of the DMA transfer in bytes
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_DMA
+static int cxd56_sdio_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
+ size_t buflen)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ unsigned int blocksize;
+ int ret = OK;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+ if ((uint32_t)buffer & 3)
+ {
+ if (priv->aligned_buffer)
+ {
+ /* If buffer not freed, free it */
+
+ kmm_free(priv->aligned_buffer);
+
+ priv->aligned_buffer = NULL;
+ }
+
+ /* Allocate aligned buffer */
+
+ priv->aligned_buffer = (uint8_t *) kmm_malloc(sizeof(uint8_t) * buflen);
+
+ /* Keep receive buffer address */
+
+ priv->receive_buffer = buffer;
+
+ /* Keep receive data size */
+
+ priv->receive_size = buflen;
+
+ /* Switch to aligned buffer */
+
+ buffer = priv->aligned_buffer;
+ }
+
+ /* Reset the DPSM configuration */
+
+ cxd56_datadisable();
+
+ /* Begin sampling register values */
+
+ cxd56_sampleinit();
+ cxd56_sample(priv, SAMPLENDX_BEFORE_SETUP);
+
+ /* Save the destination buffer information for use by the interrupt handler */
+
+ priv->buffer = (uint32_t *)buffer;
+ priv->remaining = buflen;
+
+ /* Then set up the SDIO data path */
+
+ blocksize = getreg32(CXD56_SDHCI_BLKATTR) & SDHCI_BLKATTR_SIZE_MASK;
+ if (blocksize == 0)
+ {
+ if (priv->blocksize != 0)
+ {
+ blocksize = priv->blocksize;
+ }
+ else
+ {
+ ret = -EIO;
+ goto error;
+ }
+ }
+ cxd56_dataconfig(priv, false, blocksize, buflen / blocksize, SDHCI_DTOCV_DATATIMEOUT);
+
+ /* Configure the RX DMA */
+
+ cxd56_sdio_admasetup(buffer, buflen);
+ priv->usedma = true;
+
+ cxd56_configxfrints(priv, SDHCI_DMADONE_INTS);
+ putreg32((uint32_t)buffer, CXD56_SDHCI_DSADDR);
+
+ /* Sample the register state */
+
+ cxd56_sample(priv, SAMPLENDX_AFTER_SETUP);
+ return OK;
+error:
+ /* Free allocated align buffer */
+
+ kmm_free(priv->aligned_buffer);
+
+ priv->aligned_buffer = NULL;
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Name: cxd56_sdio_dmasendsetup
+ *
+ * Description:
+ * Setup to perform a write DMA. If the processor supports a data cache,
+ * then this method will also make sure that the contents of the DMA memory
+ * and the data cache are coherent. For write transfers, this may mean
+ * flushing the data cache.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO device interface
+ * buffer - The memory to DMA into
+ * buflen - The size of the DMA transfer in bytes
+ *
+ * Returned Value:
+ * OK on success; a negated errno on failure
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SDIO_DMA
+static int cxd56_sdio_dmasendsetup(FAR struct sdio_dev_s *dev,
+ FAR const uint8_t *buffer, size_t buflen)
+{
+ uint32_t r1;
+ int ret = OK;
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ unsigned int blocksize;
+
+ DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
+ DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+
+ if ((uint32_t)buffer & 3)
+ {
+ if (priv->aligned_buffer)
+ {
+ /* If buffer not freed, free it */
+
+ kmm_free(priv->aligned_buffer);
+
+ priv->aligned_buffer = NULL;
+ }
+
+ /* Allocate aligned buffer */
+
+ priv->aligned_buffer = (uint8_t *) kmm_malloc(sizeof(uint8_t) * buflen);
+
+ /* Copy buffer to aligned address */
+
+ memcpy(priv->aligned_buffer, buffer, buflen);
+
+ /* Switch to aligned buffer */
+
+ buffer = priv->aligned_buffer;
+ }
+
+ /* Reset the DPSM configuration */
+
+ cxd56_datadisable();
+
+ /* Begin sampling register values */
+
+ cxd56_sampleinit();
+ cxd56_sample(priv, SAMPLENDX_BEFORE_SETUP);
+
+ /* Save the source buffer information for use by the interrupt handler */
+
+ priv->buffer = (uint32_t *)buffer;
+ priv->remaining = buflen;
+
+ /* Then set up the SDIO data path */
+
+ blocksize = getreg32(CXD56_SDHCI_BLKATTR) & SDHCI_BLKATTR_SIZE_MASK;
+ if (blocksize == 0)
+ {
+ if (priv->blocksize != 0)
+ {
+ blocksize = priv->blocksize;
+ }
+ else
+ {
+ ret = -EIO;
+ goto error;
+ }
+ }
+ cxd56_dataconfig(priv, true, blocksize, buflen / blocksize, SDHCI_DTOCV_DATATIMEOUT);
+
+ /* Configure the TX DMA */
+
+ cxd56_sdio_admasetup(buffer, buflen);
+ priv->usedma = true;
+ if (priv->dmasend_prepare)
+ {
+ putreg32(priv->dmasend_regcmd, CXD56_SDHCI_XFERTYP);
+ priv->dmasend_prepare = false;
+ cxd56_sdio_waitresponse(dev, priv->dmasend_cmd);
+ ret = cxd56_sdio_recvshortcrc(dev, priv->dmasend_cmd, &r1);
+ if (ret != OK)
+ {
+ goto error;
+ }
+ }
+
+ /* Sample the register state */
+
+ cxd56_sample(priv, SAMPLENDX_AFTER_SETUP);
+
+ /* Enable TX interrupts */
+
+ cxd56_configxfrints(priv, SDHCI_DMADONE_INTS);
+
+ return OK;
+error:
+ /* Free allocated align buffer */
+
+ kmm_free(priv->aligned_buffer);
+
+ priv->aligned_buffer = NULL;
+ return ret;
+}
+#endif
+
+/****************************************************************************
+ * Initialization/uninitialization/reset
+ ****************************************************************************/
+static inline void cxd56_sdio_poweron(void *arg)
+{
+ uint32_t regval;
+
+ /* Power ON for SDCARD */
+
+ regval = getreg32(CXD56_SDHCI_PROCTL);
+ regval |= 0xf << 8;
+ putreg32(regval, CXD56_SDHCI_PROCTL);
+
+ board_sdcard_pin_enable();
+}
+
+static inline void cxd56_sdio_poweroff(void *arg)
+{
+ uint32_t regval;
+
+ board_sdcard_pin_disable();
+
+ /* Power OFF for SDCARD */
+
+ regval = getreg32(CXD56_SDHCI_PROCTL);
+ regval &= ~(0x1 << 8);
+ putreg32(regval, CXD56_SDHCI_PROCTL);
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_callback
+ *
+ * Description:
+ * Perform callback.
+ *
+ * Assumptions:
+ * This function does not execute in the context of an interrupt handler.
+ * It may be invoked on any user thread or scheduled on the work thread
+ * from an interrupt handler.
+ *
+ ****************************************************************************/
+
+static void cxd56_sdio_callback(void *arg)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)arg;
+ uint32_t delay = 0;
+ irqstate_t flags;
+
+ /* Is a callback registered? */
+
+ DEBUGASSERT(priv != NULL);
+ mcinfo("Callback %p(%p) cbevents: %02x cdstatus: %02x\n",
+ priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus);
+
+ flags = enter_critical_section();
+ if (priv->callback)
+ {
+ /* Yes.. Check for enabled callback events */
+
+ if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0)
+ {
+ /* Media is present. Is the media inserted event enabled? */
+
+ if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0)
+ {
+ /* No... return without performing the callback */
+
+ leave_critical_section(flags);
+ return;
+ }
+ /* Power ON for SDCARD */
+ cxd56_sdio_poweron(priv);
+ putreg32(SDHCI_INT_CINS, CXD56_SDHCI_IRQSTAT);
+ delay = SDHCI_WAIT_POWERON;
+ }
+ else
+ {
+ /* Media is not present. Is the media eject event enabled? */
+
+ if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0)
+ {
+ /* No... return without performing the callback */
+
+ leave_critical_section(flags);
+ return;
+ }
+ /* Power OFF for SDCARD */
+ cxd56_sdio_poweroff(arg);
+ putreg32(SDHCI_INT_CRM | SDHCI_INT_CINT, CXD56_SDHCI_IRQSTAT);
+ delay = SDHCI_WAIT_POWEROFF;
+ }
+
+ /* Perform the callback, disabling further callbacks. Of course, the
+ * the callback can (and probably should) re-enable callbacks.
+ */
+
+ priv->cbevents = 0;
+ leave_critical_section(flags);
+
+ /* Callbacks cannot be performed in the context of an interrupt handler.
+ * If we are in an interrupt handler, then queue the callback to be
+ * performed later on the work thread.
+ */
+
+ if (up_interrupt_context())/* (1) */
+ {
+ /* Yes.. queue it */
+ work_cancel(HPWORK, &priv->cbwork);//
+ mcinfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg);
+ (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, delay);
+ }
+ else
+ {
+ /* No.. then just call the callback here */
+
+ up_mdelay(delay);
+ mcinfo("Callback to %p(%p)\n", priv->callback, priv->cbarg);
+ priv->callback(priv->cbarg);
+ }
+ }
+}
+
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+static void cxd56_sdio_takesem(FAR struct cxd56_sdiodev_s *priv)
+{
+ /* Take the semaphore, giving exclusive access to the driver (perhaps
+ * waiting)
+ */
+
+ while (sem_wait(&priv->sc.sem) != 0)
+ {
+ /* The only case that an error should occur here is if the wait was
+ * awakened by a signal.
+ */
+
+ ASSERT(errno == EINTR);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_make_cmd52arg
+ *
+ * Description:
+ * Create argument parameters for CMD52
+ *
+ ****************************************************************************/
+
+static uint32_t cxd56_sdio_make_cmd52arg(uint32_t addr, uint8_t val_w, FAR uint8_t * out,
+ int32_t write, uint32_t func_num)
+{
+ uint32_t arg = 0;
+
+ arg = write ? SDIO_CMD5253_WRITE : SDIO_CMD5253_READ;
+ arg |= func_num << SDIO_CMD5253_FUNC_SHIFT;
+ arg |= (write && out) ? 0x08000000 : 0x00000000;
+ arg |= addr << SDIO_CMD52_REG_SHIFT;
+ if (write)
+ {
+ arg |= (val_w & SDIO_CMD52_DATA_MASK) << 0;
+ }
+
+ return arg;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_make_cmd53arg
+ *
+ * Description:
+ * Create argument parameters for CMD53
+ *
+ ****************************************************************************/
+
+static uint32_t cxd56_sdio_make_cmd53arg(int32_t write, uint32_t func_num,
+ uint32_t addr, int32_t incr_addr,
+ uint32_t blocks, uint32_t bytesz)
+{
+ uint32_t arg = 0;
+
+ arg = write ? SDIO_CMD5253_WRITE : SDIO_CMD5253_READ;
+ arg |= func_num << SDIO_CMD5253_FUNC_SHIFT;
+ arg |= incr_addr ? 0x04000000 : 0x00000000;
+ arg |= addr << SDIO_CMD52_REG_SHIFT;
+ if (blocks == 0)
+ {
+ arg |= (bytesz == 512) ? 0 : bytesz; /* byte mode */
+ }
+ else
+ {
+ arg |= 0x08000000 | blocks; /* block mode */
+ }
+
+ return arg;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_sendcmdpoll
+ *
+ * Description:
+ * Send a command and poll-wait for the response.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_sendcmdpoll(FAR struct cxd56_sdiodev_s *priv, uint32_t cmd,
+ uint32_t arg)
+{
+ int ret;
+
+ /* Send the command */
+
+ ret = cxd56_sdio_sendcmd(&priv->dev, cmd, arg);
+ if (ret == OK)
+ {
+ /* Then poll-wait until the response is available */
+
+ ret = cxd56_sdio_waitresponse(&priv->dev, cmd);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Wait for response to cmd: %08x failed: %d\n", cmd, ret);
+ }
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_readb_internal
+ *
+ * Description:
+ * Read a byte of data.
+ *
+ ****************************************************************************/
+
+static uint32_t cxd56_sdio_readb_internal(FAR struct sdio_function_s * sf, uint32_t addr,
+ FAR uint8_t * rdata)
+{
+ uint32_t response;
+ uint32_t cmd52arg;
+ struct cxd56_sdiodev_s *priv = &g_sdhcdev;
+ int ret;
+
+ DEBUGASSERT((NULL != rdata) && (NULL != sf));
+
+ cmd52arg = cxd56_sdio_make_cmd52arg(addr, 0, NULL, 0, sf->number);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, cmd52arg /* SDIO_ADD16_RD_CMD52 */ );
+ if (ret == OK)
+ {
+ cxd56_sdio_recvshort(&priv->dev, SDIO_ACMD52, &response);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Addr:0x%x, recv R5 error\n", addr);
+ goto READB_ERR;
+ }
+ }
+ else
+ {
+ mcerr("ERROR: Send cmd52 addr:0x%x error\n", addr);
+ goto READB_ERR;
+ }
+ if ((!CMD52_RESP_OK(response)) || (response == 0xffffffff))
+ {
+ mcerr("ERROR: Fail resp %u\n", response);
+ goto READB_ERR;
+ }
+ if (rdata)
+ {
+ *rdata = response & 0xff;
+ }
+
+ return 0;
+
+READB_ERR:
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_writeb_internal
+ *
+ * Description:
+ * Write a byte of data.
+ *
+ ****************************************************************************/
+
+static uint32_t cxd56_sdio_writeb_internal(FAR struct sdio_function_s * sf, uint32_t addr, uint8_t data,
+ FAR uint8_t * rdata)
+{
+ uint32_t response;
+ uint32_t cmd52arg;
+ struct cxd56_sdiodev_s *priv = &g_sdhcdev;
+ int ret;
+
+ DEBUGASSERT(NULL != sf);
+
+ cmd52arg = cxd56_sdio_make_cmd52arg(addr, data, rdata, 1, 0);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, cmd52arg);
+ if (ret == OK)
+ {
+ cxd56_sdio_recvshort(&priv->dev, SDIO_ACMD52, &response);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Addr:0x%x, recv R5 error\n", addr);
+ goto WRITEB_ERR;
+ }
+ }
+ else
+ {
+ mcerr("ERROR: Send cmd52 addr:0x%x error\n", addr);
+ goto WRITEB_ERR;
+ }
+ if ((!CMD52_RESP_OK(response)) || (response == 0xffffffff))
+ {
+ mcerr("ERROR: Fail resp %u\n", response);
+ goto WRITEB_ERR;
+ }
+ if (rdata)
+ {
+ *rdata = response & 0xff;
+ }
+
+ return 0;
+WRITEB_ERR:
+ return ret;
+}
+
+/****************************************************************************
+ * Name: mmcsd_io_changeclock
+ *
+ * Description:
+ * change the sdio clock.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_changeclock(FAR struct cxd56_sdiodev_s *priv)
+{
+ int ret;
+ uint32_t response = 0;
+
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, 0x08<<9);
+ if (ret == OK)
+ {
+ cxd56_sdio_recvshort(&priv->dev, SDIO_ACMD52, &response);
+ }
+ else
+ {
+ mcerr("ERROR: Send cmd52, getclock error\n");
+ return ret;
+ }
+#if 0
+ mcinfo("Force 400Khz SDIO clock\n");
+ if (TRUE || (response & 0x40) != 0)
+#else
+ if ((response & 0x40) != 0)
+#endif
+ {
+ mcinfo("Set clock to 400KHz\n");
+ cxd56_sdio_clock(&priv->dev, CLOCK_IDMODE);
+ }
+ else
+ {
+ mcinfo("Set clock to 25MHz\n");
+ cxd56_sdio_clock(&priv->dev, CLOCK_SD_TRANSFER_4BIT);
+ }
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_function_alloc
+ *
+ * Description:
+ * Allocate space for each function.
+ *
+ ****************************************************************************/
+
+static FAR struct sdio_function_s *cxd56_sdio_function_alloc(FAR struct sdio_softc_s *sc)
+{
+ FAR struct sdio_function_s *sf;
+
+ DEBUGASSERT(sc);
+ sf = (FAR struct sdio_function_s *)kmm_malloc(sizeof(struct sdio_function_s));
+ if (!sf)
+ {
+ mcerr("ERROR: Failed\n");
+ return NULL;
+ }
+ memset(sf, 0, sizeof(struct sdio_function_s));
+ sf->sc = sc;
+ sf->number = -1;
+ sf->cis.manufacturer = 0xffff;
+ sf->cis.product = 0xffff;
+ sf->cis.function = 0xff;
+ sf->irq_callback = NULL;
+ return sf;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_read_cis
+ *
+ * Description:
+ * Read the card information structure.
+ *
+ ****************************************************************************/
+
+static uint32_t cxd56_sdio_read_cis(FAR struct sdio_function_s * sf, FAR struct sdio_cis_s * cis)
+{
+ int i;
+ FAR struct sdio_function_s *sf0;
+ uint8_t tplcode;
+ uint8_t tpllen;
+ uint32_t ret;
+ uint32_t cisptr = 0;
+ uint8_t response = 0;
+ uint32_t addr;
+
+ mcinfo("I/O func's num:%d\n", sf->number);
+
+ DEBUGASSERT(sf && cis);
+ sf0 = sf->sc->fn[0];
+ addr = SDIO_CCCR_CCP + (sf->number * SDIO_CCCR_SIZE);
+ for(i=0; i<3; i++)
+ {
+ ret = cxd56_sdio_readb_internal(sf0, (addr+i), &response);
+ if (ret == 0)
+ {
+ cisptr |= (response << (8*i));
+ }
+ }
+ if ((cisptr < SDIO_CIS_START) || (cisptr >= SDIO_CIS_END))
+ {
+ mcerr("ERROR: Bad cis ptr %#x\n", cisptr);
+ return 1;
+ }
+ for(;;)
+ {
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &tplcode);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ if (tplcode == SDIO_CISTPL_END)
+ {
+ break;
+ }
+ else if (tplcode == SDIO_CISTPL_NULL)
+ {
+ continue;
+ }
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &tpllen);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ if (tpllen == 0)
+ {
+ mcerr("ERROR: Cis error reg %d tpl %#x len %d\n", cisptr, tplcode, tpllen);
+ break;
+ }
+
+ switch (tplcode)
+ {
+ case SDIO_CISTPL_FUNCID:
+ if (tpllen < 2)
+ {
+ mcerr("ERROR: Bad funcid length\n");
+ cisptr += tpllen;
+ break;
+ }
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &response);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ cis->function = response;
+ cisptr += tpllen;
+ mcinfo("get funcid 0x%x, len %d\n", cis->function, tpllen);
+ break;
+ case SDIO_CISTPL_MANFID:
+ if (tpllen < 4)
+ {
+ mcerr("ERROR: Bad manfid length\n");
+ cisptr += tpllen;
+ break;
+ }
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &response);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ cis->manufacturer = response;
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &response);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ cis->manufacturer |= response << 8;
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &response);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ cis->product = response;
+ ret = cxd56_sdio_readb_internal(sf0, cisptr++, &response);
+ if (ret != 0)
+ {
+ return ret;
+ }
+ cis->product = response << 8;
+ mcinfo("manufacturer/product ID: %x:%x, len %d\n",
+ cis->manufacturer,
+ cis->product,
+ tpllen);
+ break;
+ default:
+ mcinfo("unknown tuple code %#x, length %d\n", tplcode, tpllen);
+ cisptr += tpllen;
+ break;
+ }
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_enable_cardint
+ *
+ * Description:
+ * Enable the card interrupt bit of the CXD56_SDHCI_IRQSIGEN and
+ * CXD56_SDHCI_IRQSTATEN register.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_enable_cardint(void)
+{
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+ putreg32(getreg32(CXD56_SDHCI_IRQSIGEN) | SDHCI_INT_CINT, CXD56_SDHCI_IRQSIGEN);
+ putreg32(getreg32(CXD56_SDHCI_IRQSTATEN) | SDHCI_INT_CINT, CXD56_SDHCI_IRQSTATEN);
+ leave_critical_section(flags);
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdhci_irq_handler
+ *
+ * Description:
+ * Wait for the card interrupt and run the function's irq callback.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdhci_irq_handler(FAR struct sdio_dev_s *dev)
+{
+ int ret = 0;
+ FAR struct sdio_softc_s *sc;
+ FAR struct sdio_function_s *sf0;
+ FAR struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ uint8_t response;
+ int i;
+
+ sc = &priv->sc;
+ sf0 = priv->sc.fn[0];
+ ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_INTPEND, &response);
+ for (i=1; i<8; i++)
+ {
+ if (response & (1<fn[i]->irq_callback)
+ {
+ sc->fn[i]->irq_callback(&priv->dev);
+ }
+ }
+ }
+ cxd56_sdio_enable_cardint();
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_register_irq
+ *
+ * Description:
+ * Register the func interrupt handler.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ * handler - The function's irq callback handler
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_register_irq(FAR struct sdio_dev_s *dev, int func_num,
+ FAR sdio_irqhandler_t * handler)
+{
+ int ret;
+ uint8_t reg, regorg;
+ FAR struct sdio_function_s *sf0;
+ FAR struct sdio_function_s *sf;
+ FAR struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ DEBUGASSERT(handler);
+
+ sf = priv->sc.fn[func_num];
+ sf0 = priv->sc.fn[0];
+
+ if (NULL != sf->irq_callback)
+ {
+ mcerr("ERROR: Already registered a sdio callback, fn number: %d\n",
+ sf->number);
+ return -EBUSY;
+ }
+ cxd56_sdio_takesem(priv);
+ /* enable irq in device side */
+ ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_INTEN, ®);
+ if (ret)
+ {
+ goto REG_IRQ_FAIL;
+ }
+
+ sf->irq_callback = handler;
+
+ regorg = reg;
+ reg |= ((1 << sf->number) | (1 << 0));
+
+ ret = cxd56_sdio_writeb_internal(sf0, SDIO_CCCR_INTEN, reg, NULL);
+ if (ret)
+ {
+ cxd56_sdio_writeb_internal(sf0, SDIO_CCCR_INTEN, regorg, NULL);
+ goto REG_IRQ_FAIL;
+ }
+ sem_post(&priv->sc.sem);
+ return ret;
+
+REG_IRQ_FAIL:
+ sf->irq_callback = NULL;
+ mcerr("ERROR: Ret: %d\n", ret);
+ sem_post(&priv->sc.sem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_blocksize
+ *
+ * Description:
+ * Set I/O block size for Function.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_blocksize(FAR struct sdio_function_s * sf, uint32_t size)
+{
+ uint32_t cmd52arg;
+ uint32_t blksz_addr;
+ struct cxd56_sdiodev_s *priv = &g_sdhcdev;
+
+ blksz_addr = sf->number * SDIO_FBR_START + 0x10;
+
+ cmd52arg = cxd56_sdio_make_cmd52arg(blksz_addr, (size & 0xFF), NULL, true, 0);
+ cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, cmd52arg);
+
+ cmd52arg = cxd56_sdio_make_cmd52arg(blksz_addr+1, ((size >> 8) & 0xFF), NULL, true, 0);
+ cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, cmd52arg);
+
+ return 0;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_func_ready
+ *
+ * Description:
+ * Function will become ready, and FN0 is always ready.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_func_ready(FAR struct sdio_function_s * sf)
+{
+ FAR struct sdio_softc_s *sc;
+ FAR struct sdio_function_s *sf0;
+ uint8_t rv;
+ int ret;
+
+ DEBUGASSERT(NULL != sf);
+ if (sf->number == 0)
+ {
+ return 1; /* FN0 is always ready */
+ }
+
+ sc = sf->sc;
+ sf0 = sc->fn[0];
+ ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_IORDY, &rv);
+ if (0 == ret)
+ {
+ return (rv & (1 << sf->number)) != 0;
+ }
+ return 0;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_function_disable
+ *
+ * Description:
+ * Function will be disabled, and FN0 is always enabled.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_function_disable(FAR struct sdio_dev_s *dev, int func_num)
+{
+ FAR struct sdio_function_s *sf0;
+ FAR struct sdio_function_s *sf;
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ uint8_t rv;
+ int ret;
+
+ sf = priv->sc.fn[func_num];
+ sf0 = priv->sc.fn[0];
+ mcinfo("I/O func's num:%d\n", sf->number);
+
+ cxd56_sdio_takesem(priv);
+ ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_IOEN, &rv);
+ if (ret)
+ {
+ goto FUNC_DIS_ERR;
+ }
+
+ rv &= ~(1 << sf->number);
+ ret = cxd56_sdio_writeb_internal(sf0, SDIO_CCCR_IOEN, rv, NULL);
+ if (ret)
+ {
+ goto FUNC_DIS_ERR;
+ }
+ sem_post(&priv->sc.sem);
+ return 0;
+FUNC_DIS_ERR:
+ mcerr("ERROR: Io fail ret %u\n", ret);
+ sem_post(&priv->sc.sem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_function_enable
+ *
+ * Description:
+ * Function will be enabled.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_function_enable(FAR struct sdio_dev_s *dev, int func_num)
+{
+ FAR struct sdio_function_s *sf0;
+ FAR struct sdio_function_s *sf;
+ uint8_t rv;
+ int retry = 10;
+ int ret = 0;
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ sf = priv->sc.fn[func_num];
+ sf0 = priv->sc.fn[0];
+ mcinfo("I/O func's num:%d\n", sf->number);
+ if (sf->number == 0)
+ {
+ return 0;
+ }
+ cxd56_sdio_takesem(priv);
+ ret = cxd56_sdio_readb_internal(sf0, SDIO_CCCR_IOEN, &rv);
+ if (ret)
+ {
+ goto FUNC_EN_ERR;
+ }
+ rv |= (1 << sf->number);
+ /* according to sdio_rw_direct(), set NULL to rdata */
+ ret = cxd56_sdio_writeb_internal(sf0, SDIO_CCCR_IOEN, rv, NULL);
+ if (ret)
+ {
+ goto FUNC_EN_ERR;
+ }
+ cxd56_sdio_blocksize(sf, priv->blocksize);/* Optimize SDIO transmission speed, so set blocksize here */
+
+ while (!cxd56_sdio_func_ready(sf) && retry-- > 0)
+ {
+ up_udelay(5 * 1000);
+ }
+ ret = (retry >= 0) ? 0 : -ETIMEDOUT;
+
+ if (0 == ret)
+ {
+ sem_post(&priv->sc.sem);
+ return 0;
+ }
+FUNC_EN_ERR:
+ mcerr("ERROR: Io fail ret %u\n", ret);
+ sem_post(&priv->sc.sem);
+ return -EIO;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_readb
+ *
+ * Description:
+ * Read a byte of data.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ * addr - This is the address of the byte of data inside of the selected
+ * function to read or write
+ * rdata - the actual value read from that I/O location is returned
+ * in this field
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_readb(FAR struct sdio_dev_s *dev, int func_num,
+ uint32_t addr, FAR uint8_t * rdata)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ int ret;
+
+ cxd56_sdio_takesem(priv);
+ ret = cxd56_sdio_readb_internal(priv->sc.fn[func_num], addr, rdata);
+ sem_post(&priv->sc.sem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_writeb
+ *
+ * Description:
+ * Write a byte of data.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ * addr - This is the address of the byte of data inside of the selected
+ * function to read or write
+ * data - This is the byte that is written to the selected address
+ * rdata - The value of the register after the write
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_writeb(FAR struct sdio_dev_s *dev, int func_num,
+ uint32_t addr, uint8_t data, FAR uint8_t * rdata)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ int ret;
+
+ cxd56_sdio_takesem(priv);
+ ret = cxd56_sdio_writeb_internal(priv->sc.fn[func_num], addr, data, rdata);
+ sem_post(&priv->sc.sem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_write
+ *
+ * Description:
+ * Write large number data.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ * addr - Start Address of I/O register to write
+ * data - This is the large number data that is written to the selected
+ * address
+ * size - The size of the written data
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_write(FAR struct sdio_dev_s *dev, int func_num, uint32_t addr,
+ FAR uint8_t * data, uint32_t size)
+{
+ uint32_t remainder = size;
+ int ret;
+ uint32_t cmd53arg;
+ sdio_eventset_t wkupevent;
+ FAR struct sdio_function_s *sf;
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ sf = priv->sc.fn[func_num];
+ mcinfo("sf->number = %d\n", sf->number);
+ /* Do the bulk of the transfer using block mode (if supported). */
+ cxd56_sdio_takesem(priv);
+ if (size >= SDIO_BLOCK_SIZE)
+ {
+ while (remainder >= SDIO_BLOCK_SIZE)
+ {
+ uint32_t blocks;
+ blocks = MIN(remainder / SDIO_BLOCK_SIZE, 8);
+ size = blocks * SDIO_BLOCK_SIZE;
+ cxd56_blocksetup(&priv->dev, SDIO_BLOCK_SIZE, blocks);
+ cxd56_sdio_waitenable(&priv->dev, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR);
+#ifdef CONFIG_SDIO_DMA
+ if (priv->sc.dma)
+ {
+ ret = cxd56_sdio_dmasendsetup(&priv->dev, data, size);
+ if (ret != OK)
+ {
+ mcerr("ERROR: SDIO_DMASENDSETUP: error %d\n", ret);
+ goto WRITE_ERR;
+ }
+ }
+ else
+#endif
+ {
+ cxd56_sdio_sendsetup(&priv->dev, data, size);
+ }
+ cmd53arg = cxd56_sdio_make_cmd53arg(1, sf->number, addr, 1, blocks, priv->blocksize);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD53 | MMCSD_MULTIBLOCK | MMCSD_WRDATAXFR, cmd53arg);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Send cmd53 error\n");
+ goto WRITE_ERR;
+ }
+ wkupevent = cxd56_sdio_eventwait(&priv->dev, SDIO_BLOCK_TIMEOUT * blocks);
+ if ((wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR)) != 0)
+ {
+ mcerr("ERROR: Sdio write time out %x\n", wkupevent);
+ goto WRITE_TIME_OUT;
+ }
+ remainder -= size;
+ data += size;
+ addr += size;
+ }
+ }
+
+ /* Write the remainder using byte mode. */
+ while (remainder > 0)
+ {
+ size = MIN(remainder, 64);
+ cxd56_blocksetup(&priv->dev, size, 1);
+ cxd56_sdio_waitenable(&priv->dev, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR);
+#ifdef CONFIG_SDIO_DMA
+ if (priv->sc.dma)
+ {
+ ret = cxd56_sdio_dmasendsetup(&priv->dev, data, size);
+ if (ret != OK)
+ {
+ mcerr("ERROR: SDIO_DMASENDSETUP: error %d\n", ret);
+ goto WRITE_ERR;
+ }
+ }
+ else
+#endif
+ {
+ cxd56_sdio_sendsetup(&priv->dev, data, size);
+ }
+ cmd53arg = cxd56_sdio_make_cmd53arg(1, sf->number, addr, 1, 0, size);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD53 | MMCSD_WRDATAXFR, cmd53arg);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Send cmd53 error\n");
+ goto WRITE_ERR;
+ }
+ wkupevent = cxd56_sdio_eventwait(&priv->dev, SDIO_BLOCK_TIMEOUT);
+ if ((wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR)) != 0)
+ {
+ mcerr("ERROR: Sdio write time out %x\n", wkupevent);
+ goto WRITE_TIME_OUT;
+ }
+ remainder -= size;
+ data += size;
+ addr += size;
+ }
+ sem_post(&priv->sc.sem);
+ return 0;
+WRITE_TIME_OUT:
+ sem_post(&priv->sc.sem);
+ return wkupevent & SDIOWAIT_TIMEOUT ? -ETIMEDOUT : -EIO;
+WRITE_ERR:
+ sem_post(&priv->sc.sem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_read
+ *
+ * Description:
+ * Read large number data.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * func_num - I/O Function's num
+ * addr - Start Address of I/O register to read
+ * data - the large number data read from that I/O location is returned
+ * in this field
+ * size - The size of the read data
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_read(FAR struct sdio_dev_s *dev, int func_num, uint32_t addr,
+ FAR uint8_t * data, uint32_t size)
+{
+ uint32_t remainder = size;
+ int ret;
+ uint32_t cmd53arg;
+ sdio_eventset_t wkupevent;
+ FAR struct sdio_function_s *sf;
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ sf = priv->sc.fn[func_num];
+ mcinfo("sf->number = %d\n", sf->number);
+ /* Do the bulk of the transfer using block mode (if supported). */
+ cxd56_sdio_takesem(priv);
+ if (size >= SDIO_BLOCK_SIZE)
+ {
+ while (remainder >= SDIO_BLOCK_SIZE)
+ {
+ uint32_t blocks;
+ blocks = MIN(remainder / SDIO_BLOCK_SIZE, 8);
+ size = blocks * SDIO_BLOCK_SIZE;
+ cxd56_blocksetup(&priv->dev, SDIO_BLOCK_SIZE, blocks);
+ cxd56_sdio_waitenable(&priv->dev, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR);
+#ifdef CONFIG_SDIO_DMA
+ if (priv->sc.dma)
+ {
+ ret = cxd56_sdio_dmarecvsetup(&priv->dev, data, size);
+ if (ret != OK)
+ {
+ mcerr("ERROR: SDIO_DMASENDSETUP: error %d\n", ret);
+ goto READ_ERR;
+ }
+ }
+ else
+#endif
+ {
+ cxd56_sdio_recvsetup(&priv->dev, data, size);
+ }
+ cmd53arg = cxd56_sdio_make_cmd53arg(0, sf->number, addr, 1, blocks, priv->blocksize);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD53 | MMCSD_MULTIBLOCK | MMCSD_RDDATAXFR, cmd53arg);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Send cmd53 error\n");
+ goto READ_ERR;
+ }
+ wkupevent = cxd56_sdio_eventwait(&priv->dev, SDIO_BLOCK_TIMEOUT * blocks);
+ if ((wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR)) != 0)
+ {
+ mcerr("ERROR: Sdio read time out %x\n", wkupevent);
+ goto READ_TIME_OUT;
+ }
+ remainder -= size;
+ data += size;
+ addr += size;
+ }
+ }
+
+ /* Write the remainder using byte mode. */
+ while (remainder > 0)
+ {
+ size = MIN(remainder, 64);
+ cxd56_blocksetup(&priv->dev, size, 1);
+ cxd56_sdio_waitenable(&priv->dev, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR);
+#ifdef CONFIG_SDIO_DMA
+ if (priv->sc.dma)
+ {
+ ret = cxd56_sdio_dmarecvsetup(&priv->dev, data, size);
+ if (ret != OK)
+ {
+ mcerr("ERROR: SDIO_DMASENDSETUP: error %d\n", ret);
+ goto READ_ERR;
+ }
+ }
+ else
+#endif
+ {
+ cxd56_sdio_recvsetup(&priv->dev, data, size);
+ }
+ cmd53arg = cxd56_sdio_make_cmd53arg(0, sf->number, addr, 1, 0, size);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD53 | MMCSD_RDDATAXFR, cmd53arg);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Send cmd53 error\n");
+ goto READ_ERR;
+ }
+ wkupevent = cxd56_sdio_eventwait(&priv->dev, SDIO_BLOCK_TIMEOUT);
+ if ((wkupevent & (SDIOWAIT_TIMEOUT | SDIOWAIT_ERROR)) != 0)
+ {
+ mcerr("ERROR: Sdio read time out %x\n", wkupevent);
+ goto READ_TIME_OUT;
+ }
+ remainder -= size;
+ data += size;
+ addr += size;
+ }
+ sem_post(&priv->sc.sem);
+ return 0;
+READ_TIME_OUT:
+ sem_post(&priv->sc.sem);
+ return wkupevent & SDIOWAIT_TIMEOUT ? -ETIMEDOUT : -EIO;
+READ_ERR:
+ sem_post(&priv->sc.sem);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_get_cis
+ *
+ * Description:
+ * get SDIO Card Information Structure.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_get_cis(FAR struct sdio_dev_s *dev, int func_num, FAR struct sdio_cis_s * cis)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+
+ if (cis)
+ {
+ *cis = priv->sc.fn[func_num]->cis;
+ }
+ return OK;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdio_initialize
+ *
+ * Description:
+ * We believe that there is A sdio device in the slot.initialize the sdio
+ * device.
+ *
+ ****************************************************************************/
+
+static int cxd56_sdio_initialize(struct cxd56_sdiodev_s *priv)
+{
+ int ret, i;
+ uint32_t response;
+ FAR struct sdio_function_s *fn;
+
+ priv->sc.func_num = 1;
+ priv->sc.full_speed = false;
+ priv->blocksize = SDIO_BLOCK_SIZE;
+
+ sem_init(&priv->sc.sem, 0, 1);
+#ifdef CONFIG_SDIO_DMA
+ priv->sc.dma = true;
+#endif
+ cxd56_sdio_attach(&priv->dev);
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_CMD5, 0x0);
+
+ if (ret == OK)
+ {
+ ret = cxd56_sdio_recvshort(&priv->dev, SDIO_CMD5, &response);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Recv R4 error\n");
+ return ret;
+ }
+ }
+ else
+ {
+ mcerr("ERROR: Send cmd5 error\n");
+ return ret;
+ }
+ mcinfo("response = 0x%x, card has %d function\n", response, (response >> 28) & 7);
+ mcinfo("send cmd5 again to set card ready\n");
+ if (response != 0xffffffff)
+ {
+ do
+ {
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_CMD5, 0x300000);
+ if (ret == OK)
+ {
+ cxd56_sdio_recvshort(&priv->dev, SDIO_CMD5, &response);
+ }
+ usleep(4000);
+ }
+ while ((response == 0xffffffff) ||
+ ((response & 0x80000000) == 0));
+ mcinfo("response = 0x%x, card is ready(MSB=1)\n", response);
+ priv->sc.func_num = SDIO_OCR_NUM_FUNCTIONS(response) + 1;
+ }
+ mcinfo("send CMD3 to enter standby state\n");
+ cxd56_sdio_sendcmdpoll(priv, SD_CMD3, 0);
+ ret = cxd56_sdio_recvshortcrc(&priv->dev, SD_CMD3, &response);
+ if (ret != OK)
+ {
+ return ret;
+ }
+
+ mcinfo("RCA: 0x%x\n", (response >> 16));
+ if (response & 0xffff)
+ {
+ mcerr("ERROR: CMD3 resp error: 0x%x\n", (response & 0xffff));
+ if (response & 0x8000)
+ mcerr("ERROR: CRC error on previous command\n");
+ }
+
+ cxd56_sdio_sendcmdpoll(priv, MMCSD_CMD7S, response & 0xffff0000);
+ mcinfo("send cmd7(RCA:%x, %x) OK\n", (response >> 16), response & 0xffff0000);
+ ret = cxd56_sdio_recvshortcrc(&priv->dev, MMCSD_CMD7S, &response);
+ if (ret != OK)
+ {
+ mcerr("ERROR: mmcsd_recvR1 for CMD7 failed: %d\n", ret);
+ return ret;
+ }
+
+ cxd56_sdio_changeclock(priv);
+
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, 0x7<<9);
+ if (ret == OK)
+ {
+ ret = cxd56_sdio_recvshort(&priv->dev, SDIO_ACMD52, &response);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Addr:0x7, recv R5 error\n");
+ return ret;
+ }
+ mcinfo("Bus interface ctrl (@0x7):0x%x\n", response);
+ // 0x80: CD disable = 1, we should set it be true before issue CMD53
+ cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, 0x7<<9 | (response & 0xFF) | 0x80);
+ mcinfo("set CD disable = 1\n");
+ }
+ else
+ {
+ mcerr("ERROR: Send cmd52 addr:0x7 error\n");
+ return ret;
+ }
+
+ ret = cxd56_sdio_sendcmdpoll(priv, SDIO_ACMD52, 0x8<<9);
+ if (ret == OK)
+ {
+ cxd56_sdio_recvshort(&priv->dev, SDIO_ACMD52, &response);
+ if (ret != OK)
+ {
+ mcerr("ERROR: Addr:0x8, recv R5 error\n");
+ return ret;
+ }
+ mcinfo("Card capability(@0x8):0x%x\n", response);
+
+ mcinfo("It's a %s card\n", (response & 0x40)? "low speed": "full speed");
+ if ((response & 0x40) == 0)
+ {
+ priv->sc.full_speed = true;
+ }
+ }
+ else
+ {
+ mcerr("ERROR: Send cmd52 addr:0x8 error\n");
+ return ret;
+ }
+
+ mcinfo("func_num = %d\n", priv->sc.func_num);
+ for (i = 0; i < priv->sc.func_num; i++)
+ {
+ fn = cxd56_sdio_function_alloc(&priv->sc);
+ if (!fn)
+ {
+ goto SDIO_INIT_ERR;
+ }
+ fn->number = i;
+
+ priv->sc.fn[i] = fn;
+ }
+
+ for (i = 1; i < priv->sc.func_num; i++)
+ {
+ fn = priv->sc.fn[i];
+ if (cxd56_sdio_read_cis(fn, &fn->cis) != 0)
+ {
+ mcerr("ERROR: Can't read CIS\n");
+ goto SDIO_INIT_CIS_ERR;
+ }
+ }
+
+ if (priv->sc.full_speed)
+ {
+ uint8_t bus_ctrl;
+
+ /* enable 4-bits bus */
+ cxd56_sdio_readb_internal(priv->sc.fn[0], SDIO_CCCR_BUS_IF, &bus_ctrl);
+ bus_ctrl = (bus_ctrl & ~0x3) | 0x2;
+ cxd56_sdio_writeb_internal(priv->sc.fn[0], SDIO_CCCR_BUS_IF, bus_ctrl, &bus_ctrl);
+
+ if ((bus_ctrl & 0x3) == 2)
+ {
+ mcinfo("Set card to 4-bits mode\n");
+ cxd56_sdio_widebus(&priv->dev, true);
+ mcinfo("Set controller to 4-bits mode\n");
+ }
+ else
+ {
+ mcinfo("Failed to enter 4-bits mode\n");
+ }
+ }
+
+ return OK;
+
+SDIO_INIT_ERR:
+ return -ENOMEM;
+
+SDIO_INIT_CIS_ERR:
+ return -EIO;
+}
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_sdhci_initialize
+ *
+ * Description:
+ * Initialize SDIO for operation.
+ *
+ * Input Parameters:
+ * slotno - Not used.
+ *
+ * Returned Values:
+ * A reference to an SDIO interface structure. NULL is returned on failures.
+ *
+ ****************************************************************************/
+
+FAR struct sdio_dev_s *cxd56_sdhci_initialize(int slotno)
+{
+ uint32_t regval;
+#ifdef CONFIG_SDIO_DMA
+ uint32_t i;
+#endif
+
+ /* There is only one slot */
+
+ struct cxd56_sdiodev_s *priv = &g_sdhcdev;
+ DEBUGASSERT(slotno == 0);
+
+ /* Initalize the pins */
+
+ board_sdcard_pin_initialize();
+
+ /* Enable clocking to the SDHC module. Clocking is still disabled in
+ * the SYSCTRL register.
+ */
+
+ cxd56_sdio_clock_enable();
+
+ //putreg32(getreg32(CXD56_SDHCI_BASE+0x230) >> 3 ,CXD56_SDHCI_BASE+0x230);
+ putreg32(getreg32(CXD56_SDHCI_SYSCTL) | SDHCI_SYSCTL_ICLKEN, CXD56_SDHCI_SYSCTL);
+
+ /* Command Line Pre Drive Enable */
+ regval = getreg32(CXD56_SDHCI_VENDSPEC);
+ putreg32(regval | 0x00000040, CXD56_SDHCI_VENDSPEC);
+
+ /* Configure the pins */
+
+ board_sdcard_pin_configuraton();
+
+ /* Software reset */
+ regval = getreg32(CXD56_SDHCI_SYSCTL);
+ putreg32(regval | SDHCI_SYSCTL_RSTA, CXD56_SDHCI_SYSCTL);
+ while ((getreg32(CXD56_SDHCI_SYSCTL) & SDHCI_SYSCTL_RSTA) != 0);
+
+ putreg32(0xffffffff, CXD56_SDHCI_IRQSTATEN);
+
+ cxd56_sdio_sdhci_reset(&(priv->dev));
+
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+ /* Power ON for SDIO */
+
+ regval = getreg32(CXD56_SDHCI_PROCTL);
+ regval |= 0xf << 8;
+ putreg32(regval, CXD56_SDHCI_PROCTL);
+
+ up_mdelay(25);
+
+ /* SD clock enable */
+
+ cxd56_sdio_clock(&(priv->dev), CLOCK_IDMODE);
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+
+#ifdef CONFIG_SDIO_DMA
+ for(i=0;iusedma = false;
+ priv->dmasend_prepare = false;
+ priv->dmasend_cmd = 0;
+ priv->dmasend_regcmd = 0;
+
+#endif
+
+#ifdef CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION
+ cxd56_sdio_initialize(priv);
+#endif /* CONFIG_CXD56_SDIO_ENABLE_MULTIFUNCTION */
+
+ /* In addition to the system clock, the SDHC module needs a clock for the
+ * base for the external card clock. There are four possible sources for
+ * this clock, selected by the SIM's SOPT2 register:
+ *
+ * - Core/system clock
+ * - MCGPLLCLK/MCGFLLCLK clock
+ * - OSCERCLK EXTAL clock
+ * - External bypass clock from off-chip (SCHC0_CLKINB)
+ */
+
+ return &g_sdhcdev.dev;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: cxd56_sdhci_finalize
+ *
+ * Description:
+ * Finalize SDIO for operation.
+ *
+ * Input Parameters:
+ * slotno - Not used.
+ *
+ * Returned Values:
+ * A reference to an SDIO interface structure. NULL is returned on failures.
+ *
+ ****************************************************************************/
+
+FAR struct sdio_dev_s *cxd56_sdhci_finalize(int slotno)
+{
+ uint32_t regval;
+
+ /* There is only one slot */
+
+ struct cxd56_sdiodev_s *priv = &g_sdhcdev;
+ DEBUGASSERT(slotno == 0);
+
+ /* Enable clocking to the SDHC module. Clocking is still disabled in
+ * the SYSCTRL register.
+ */
+
+ /* SD clock disable */
+
+ cxd56_sdio_clock(&(priv->dev), CLOCK_SDIO_DISABLED);
+
+ /* Power OFF for SDIO */
+
+ regval = getreg32(CXD56_SDHCI_PROCTL);
+ regval &= ~(0xf << 8);
+ putreg32(regval, CXD56_SDHCI_PROCTL);
+
+ /* Disable Internal Clock */
+
+ putreg32(getreg32(CXD56_SDHCI_SYSCTL) & ~SDHCI_SYSCTL_ICLKEN, CXD56_SDHCI_SYSCTL);
+
+ /* Command Line Pre Drive Disable */
+
+ regval = getreg32(CXD56_SDHCI_VENDSPEC);
+ putreg32(regval & ~0x00000040, CXD56_SDHCI_VENDSPEC);
+
+ /* SDIO Clock Disable */
+
+ cxd56_sdio_clock_disable();
+
+ return &g_sdhcdev.dev;
+}
+
+/****************************************************************************
+ * Name: cxd56_sdhci_mediachange
+ *
+ * Description:
+ * Called by board-specific logic -- possible from an interrupt handler --
+ * in order to signal to the driver that a card has been inserted or
+ * removed from the slot
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_sdhci_mediachange(FAR struct sdio_dev_s *dev)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ sdio_statset_t cdstatus;
+ irqstate_t flags;
+ uint8_t mediachange = 0;
+ int32_t timeout = SDHCI_CARDSTATETIMEOUT;
+
+ /* Update card status */
+ if (getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_SDCD)
+ {
+ while ((getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_CSTS) == 0)
+ {
+ if (timeout < 1)
+ {
+ break;
+ }
+ usleep(100000);
+ timeout -= 100000;
+ }
+ }
+
+ flags = enter_critical_section();
+ cdstatus = priv->cdstatus;
+
+ if (getreg32(CXD56_SDHCI_PRSSTAT) & SDHCI_PRSSTAT_CINS)
+ {
+ priv->cdstatus |= SDIO_STATUS_PRESENT;
+ }
+ else
+ {
+ priv->cdstatus &= ~SDIO_STATUS_PRESENT;
+ }
+
+ mcinfo("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus);
+
+ /* Perform any requested callback if the status has changed */
+
+ if (cdstatus != priv->cdstatus)
+ {
+ if (priv->cdstatus & SDIO_STATUS_PRESENT)
+ {
+ priv->cbevents &= SDIOMEDIA_INSERTED;
+ }
+ mediachange = 1;//cxd56_sdio_callback(priv);
+ }
+ leave_critical_section(flags);
+ if (mediachange)
+ {
+ cxd56_sdio_callback(priv);
+ }
+}
+
+/****************************************************************************
+ * Name: cxd56_sdhci_wrprotect
+ *
+ * Description:
+ * Called by board-specific logic to report if the card in the slot is
+ * mechanically write protected.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * wrprotect - true is a card is writeprotected.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+
+void cxd56_sdhci_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect)
+{
+ struct cxd56_sdiodev_s *priv = (struct cxd56_sdiodev_s *)dev;
+ irqstate_t flags;
+
+ /* Update card status */
+
+ flags = enter_critical_section();
+ if (wrprotect)
+ {
+ priv->cdstatus |= SDIO_STATUS_WRPROTECTED;
+ }
+ else
+ {
+ priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED;
+ }
+
+ mcinfo("cdstatus: %02x\n", priv->cdstatus);
+ leave_critical_section(flags);
+}
+#endif /* CONFIG_CXD56_SDIO */
diff --git a/arch/arm/src/cxd56xx/cxd56_sdhci.h b/arch/arm/src/cxd56xx/cxd56_sdhci.h
new file mode 100644
index 00000000000..e53807d08ea
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_sdhci.h
@@ -0,0 +1,463 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_sdhci.h
+ *
+ * Copyright (C) 2008-2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_ARM_SRC_CXD56XX_CXD56_SDHCI_H
+#define __ARCH_ARM_SRC_CXD56XX_CXD56_SDHCI_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include "chip.h"
+
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register Offsets *********************************************************/
+
+#define CXD56_SDHCI_DSADDR_OFFSET (0x0000) /* DMA System Address Register */
+#define CXD56_SDHCI_BLKATTR_OFFSET (0x0004) /* Block Attributes Register */
+#define CXD56_SDHCI_CMDARG_OFFSET (0x0008) /* Command Argument Register */
+#define CXD56_SDHCI_XFERTYP_OFFSET (0x000c) /* Transfer Type Register */
+#define CXD56_SDHCI_CMDRSP0_OFFSET (0x0010) /* Command Response 0 */
+#define CXD56_SDHCI_CMDRSP1_OFFSET (0x0014) /* Command Response 1 */
+#define CXD56_SDHCI_CMDRSP2_OFFSET (0x0018) /* Command Response 2 */
+#define CXD56_SDHCI_CMDRSP3_OFFSET (0x001c) /* Command Response 3 */
+#define CXD56_SDHCI_DATPORT_OFFSET (0x0020) /* Buffer Data Port Register */
+#define CXD56_SDHCI_PRSSTAT_OFFSET (0x0024) /* Present State Register */
+#define CXD56_SDHCI_PROCTL_OFFSET (0x0028) /* Protocol Control Register */
+#define CXD56_SDHCI_SYSCTL_OFFSET (0x002c) /* System Control Register */
+#define CXD56_SDHCI_IRQSTAT_OFFSET (0x0030) /* Interrupt Status Register */
+#define CXD56_SDHCI_IRQSTATEN_OFFSET (0x0034) /* Interrupt Status Enable Register */
+#define CXD56_SDHCI_IRQSIGEN_OFFSET (0x0038) /* Interrupt Signal Enable Register */
+#define CXD56_SDHCI_AC12ERR_OFFSET (0x003c) /* Auto CMD12 Error Status Register */
+#define CXD56_SDHCI_HTCAPBLT_OFFSET (0x0040) /* Host Controller Capabilities */
+#define CXD56_SDHCI_FEVT_OFFSET (0x0050) /* Force Event Register */
+#define CXD56_SDHCI_ADMAES_OFFSET (0x0054) /* ADMA Error Status Register */
+#define CXD56_SDHCI_ADSADDR_OFFSET (0x0058) /* ADMA System Address Register */
+#define CXD56_SDHCI_HOSTVER_OFFSET (0x00fc) /* Host Controller Version */
+#define CXD56_SDHCI_VENDSPEC_OFFSET (0x0110) /* Vender Specific Control */
+#define CXD56_SDHCI_OTHERIOLL_OFFSET (0x021C) /* IO Pin Control */
+#define CXD56_SDHCI_USERDEF1CTL_OFFSET (0x0270) /* User Define1 Control Register */
+#define CXD56_SDHCI_USERDEF2CTL_OFFSET (0x0274) /* User Define2 Control Register */
+
+/* Register Addresses *******************************************************/
+#define CXD56_SDHCI_BASE CXD56_SDIO_BASE
+
+#define CXD56_SDHCI_DSADDR (CXD56_SDHCI_BASE+CXD56_SDHCI_DSADDR_OFFSET)
+#define CXD56_SDHCI_BLKATTR (CXD56_SDHCI_BASE+CXD56_SDHCI_BLKATTR_OFFSET)
+#define CXD56_SDHCI_CMDARG (CXD56_SDHCI_BASE+CXD56_SDHCI_CMDARG_OFFSET)
+#define CXD56_SDHCI_XFERTYP (CXD56_SDHCI_BASE+CXD56_SDHCI_XFERTYP_OFFSET)
+#define CXD56_SDHCI_CMDRSP0 (CXD56_SDHCI_BASE+CXD56_SDHCI_CMDRSP0_OFFSET)
+#define CXD56_SDHCI_CMDRSP1 (CXD56_SDHCI_BASE+CXD56_SDHCI_CMDRSP1_OFFSET)
+#define CXD56_SDHCI_CMDRSP2 (CXD56_SDHCI_BASE+CXD56_SDHCI_CMDRSP2_OFFSET)
+#define CXD56_SDHCI_CMDRSP3 (CXD56_SDHCI_BASE+CXD56_SDHCI_CMDRSP3_OFFSET)
+#define CXD56_SDHCI_DATPORT (CXD56_SDHCI_BASE+CXD56_SDHCI_DATPORT_OFFSET)
+#define CXD56_SDHCI_PRSSTAT (CXD56_SDHCI_BASE+CXD56_SDHCI_PRSSTAT_OFFSET)
+#define CXD56_SDHCI_PROCTL (CXD56_SDHCI_BASE+CXD56_SDHCI_PROCTL_OFFSET)
+#define CXD56_SDHCI_SYSCTL (CXD56_SDHCI_BASE+CXD56_SDHCI_SYSCTL_OFFSET)
+#define CXD56_SDHCI_IRQSTAT (CXD56_SDHCI_BASE+CXD56_SDHCI_IRQSTAT_OFFSET)
+#define CXD56_SDHCI_IRQSTATEN (CXD56_SDHCI_BASE+CXD56_SDHCI_IRQSTATEN_OFFSET)
+#define CXD56_SDHCI_IRQSIGEN (CXD56_SDHCI_BASE+CXD56_SDHCI_IRQSIGEN_OFFSET)
+#define CXD56_SDHCI_AC12ERR (CXD56_SDHCI_BASE+CXD56_SDHCI_AC12ERR_OFFSET)
+#define CXD56_SDHCI_HTCAPBLT (CXD56_SDHCI_BASE+CXD56_SDHCI_HTCAPBLT_OFFSET)
+#define CXD56_SDHCI_FEVT (CXD56_SDHCI_BASE+CXD56_SDHCI_FEVT_OFFSET)
+#define CXD56_SDHCI_ADMAES (CXD56_SDHCI_BASE+CXD56_SDHCI_ADMAES_OFFSET)
+#define CXD56_SDHCI_ADSADDR (CXD56_SDHCI_BASE+CXD56_SDHCI_ADSADDR_OFFSET)
+#define CXD56_SDHCI_HOSTVER (CXD56_SDHCI_BASE+CXD56_SDHCI_HOSTVER_OFFSET)
+#define CXD56_SDHCI_VENDSPEC (CXD56_SDHCI_BASE+CXD56_SDHCI_VENDSPEC_OFFSET)
+#define CXD56_SDHCI_OTHERIOLL (CXD56_SDHCI_BASE+CXD56_SDHCI_OTHERIOLL_OFFSET)
+#define CXD56_SDHCI_USERDEF1CTL (CXD56_SDHCI_BASE+CXD56_SDHCI_USERDEF1CTL_OFFSET)
+#define CXD56_SDHCI_USERDEF2CTL (CXD56_SDHCI_BASE+CXD56_SDHCI_USERDEF2CTL_OFFSET)
+
+/* Register Bit Definitions *************************************************/
+
+/* DMA System Address Register */
+
+#define SDHCI_DSADDR_SHIFT (1) /* Bits 1-31: DMA System Address */
+#define SDHCI_DSADDR_MASK (0xfffffffe)
+ /* Bits 0-1: Reserved */
+/* Block Attributes Register */
+
+#define SDHCI_BLKATTR_SIZE_SHIFT (0) /* Bits 0-12: Transfer Block Size */
+#define SDHCI_BLKATTR_SIZE_MASK (0x1fff << SDHCI_BLKATTR_SIZE_SHIFT)
+ /* Bits 13-15: Reserved */
+#define SDHCI_BLKATTR_CNT_SHIFT (16) /* Bits 16-31: Blocks Count For Current Transfer */
+#define SDHCI_BLKATTR_CNT_MASK (0xffff << SDHCI_BLKATTR_CNT_SHIFT)
+
+/* Command Argument Register (32-bit cmd/arg data) */
+
+/* Transfer Type Register */
+
+#define SDHCI_XFERTYP_DMAEN (1 << 0) /* Bit 0: DMA Enable */
+#define SDHCI_XFERTYP_BCEN (1 << 1) /* Bit 1: Block Count Enable */
+#define SDHCI_XFERTYP_AC12EN (1 << 2) /* Bit 2: Auto CMD12 Enable */
+ /* Bit 3: Reserved */
+#define SDHCI_XFERTYP_DTDSEL (1 << 4) /* Bit 4: Data Transfer Direction Select */
+#define SDHCI_XFERTYP_MSBSEL (1 << 5) /* Bit 5: Multi/Single Block Select */
+ /* Bits 6-15: Reserved */
+#define SDHCI_XFERTYP_RSPTYP_SHIFT (16) /* Bits 16-17: Response Type Select */
+#define SDHCI_XFERTYP_RSPTYP_MASK (3 << SDHCI_XFERTYP_RSPTYP_SHIFT)
+# define SDHCI_XFERTYP_RSPTYP_NONE (0 << SDHCI_XFERTYP_RSPTYP_SHIFT) /* No response */
+# define SDHCI_XFERTYP_RSPTYP_LEN136 (1 << SDHCI_XFERTYP_RSPTYP_SHIFT) /* Response length 136 */
+# define SDHCI_XFERTYP_RSPTYP_LEN48 (2 << SDHCI_XFERTYP_RSPTYP_SHIFT) /* Response length 48 */
+# define SDHCI_XFERTYP_RSPTYP_LEN48BSY (3 << SDHCI_XFERTYP_RSPTYP_SHIFT) /* Response length 48, check busy */
+ /* Bit 18: Reserved */
+#define SDHCI_XFERTYP_CCCEN (1 << 19) /* Bit 19: Command CRC Check Enable */
+#define SDHCI_XFERTYP_CICEN (1 << 20) /* Bit 20: Command Index Check Enable */
+#define SDHCI_XFERTYP_DPSEL (1 << 21) /* Bit 21: Data Present Select */
+#define SDHCI_XFERTYP_CMDTYP_SHIFT (22) /* Bits 22-23: Command Type */
+#define SDHCI_XFERTYP_CMDTYP_MASK (3 << SDHCI_XFERTYP_CMDTYP_SHIFT)
+# define SDHCI_XFERTYP_CMDTYP_NORMAL (0 << SDHCI_XFERTYP_CMDTYP_SHIFT) /* Normal other commands */
+# define SDHCI_XFERTYP_CMDTYP_SUSPEND (1 << SDHCI_XFERTYP_CMDTYP_SHIFT) /* Suspend CMD52 for writing bus suspend in CCCR */
+# define SDHCI_XFERTYP_CMDTYP_RESUME (2 << SDHCI_XFERTYP_CMDTYP_SHIFT) /* Resume CMD52 for writing function select in CCCR */
+# define SDHCI_XFERTYP_CMDTYP_ABORT (3 << SDHCI_XFERTYP_CMDTYP_SHIFT) /* Abort CMD12, CMD52 for writing I/O abort in CCCR */
+#define SDHCI_XFERTYP_CMDINX_SHIFT (24) /* Bits 24-29: Command Index */
+#define SDHCI_XFERTYP_CMDINX_MASK (63 << SDHCI_XFERTYP_CMDINX_SHIFT)
+ /* Bits 30-31: Reserved */
+/* Command Response 0-3 (32-bit response data) */
+
+/* Buffer Data Port Register (32-bit data content) */
+
+/* Present State Register */
+
+#define SDHCI_PRSSTAT_CIHB (1 << 0) /* Bit 0: Command Inhibit (CMD) */
+#define SDHCI_PRSSTAT_CDIHB (1 << 1) /* Bit 1: Command Inhibit (DAT) */
+#define SDHCI_PRSSTAT_DLA (1 << 2) /* Bit 2: Data Line Active */
+#define SDHCI_PRSSTAT_SDSTB (1 << 3) /* Bit 3: SD Clock Stable */
+#define SDHCI_PRSSTAT_IPGOFF (1 << 4) /* Bit 4: Bus Clock */
+#define SDHCI_PRSSTAT_HCKOFF (1 << 5) /* Bit 5: System Clock */
+#define SDHCI_PRSSTAT_PEROFF (1 << 6) /* Bit 6: SDHC clock */
+#define SDHCI_PRSSTAT_SDOFF (1 << 7) /* Bit 7: SD Clock Gated Off Internally */
+#define SDHCI_PRSSTAT_WTA (1 << 8) /* Bit 8: Write Transfer Active */
+#define SDHCI_PRSSTAT_RTA (1 << 9) /* Bit 9: Read Transfer Active */
+#define SDHCI_PRSSTAT_BWEN (1 << 10) /* Bit 10: Buffer Write Enable */
+#define SDHCI_PRSSTAT_BREN (1 << 11) /* Bit 11: Buffer Read Enable */
+ /* Bits 12-15: Reserved */
+#define SDHCI_PRSSTAT_CINS (1 << 16) /* Bit 16: Card Inserted */
+#define SDHCI_PRSSTAT_CSTS (1 << 17) /* Bit 17: Card State Stable */
+#define SDHCI_PRSSTAT_SDCD (1 << 18) /* Bit 18: Card Detect Pin Level */
+#define SDHCI_PRSSTAT_SDWPN (1 << 19) /* Bit 19: Write Protect Switch Pin Level*/
+#define SDHCI_PRSSTAT_DLSL_SHIFT (20) /* Bits 20-23: DAT Line Signal Level */
+#define SDHCI_PRSSTAT_DLSL_MASK (0xf << SDHCI_PRSSTAT_DLSL_SHIFT)
+# define SDHCI_PRSSTAT_DLSL_DAT0 (0x1 << SDHCI_PRSSTAT_DLSL_SHIFT)
+# define SDHCI_PRSSTAT_DLSL_DAT1 (0x2 << SDHCI_PRSSTAT_DLSL_SHIFT)
+# define SDHCI_PRSSTAT_DLSL_DAT2 (0x4 << SDHCI_PRSSTAT_DLSL_SHIFT)
+# define SDHCI_PRSSTAT_DLSL_DAT3 (0x8 << SDHCI_PRSSTAT_DLSL_SHIFT)
+#define SDHCI_PRSSTAT_CLSL (1 << 24) /* Bit 23: CMD Line Signal Level */
+
+/* Protocol Control Register */
+
+#define SDHCI_PROCTL_LCTL (1 << 0) /* Bit 0: LED Control */
+#define SDHCI_PROCTL_DTW_SHIFT (1) /* Bits 1-2: Data Transfer Width */
+#define SDHCI_PROCTL_DTW_MASK (1 << SDHCI_PROCTL_DTW_SHIFT)
+# define SDHCI_PROCTL_DTW_1BIT (0 << SDHCI_PROCTL_DTW_SHIFT) /* 1-bit mode */
+# define SDHCI_PROCTL_DTW_4BIT (1 << SDHCI_PROCTL_DTW_SHIFT) /* 4-bit mode */
+#define SDHCI_PROCTL_DMAS_SHIFT (3) /* Bits 8-9: DMA Select */
+#define SDHCI_PROCTL_DMAS_MASK (3 << SDHCI_PROCTL_DMAS_SHIFT)
+# define SDHCI_PROCTL_DMAS_NODMA (0 << SDHCI_PROCTL_DMAS_SHIFT) /* No DMA or simple DMA is selected */
+# define SDHCI_PROCTL_DMAS_ADMA2 (2 << SDHCI_PROCTL_DMAS_SHIFT) /* ADMA2 is selected */
+#define SDHCI_PROCTL_CDTL (1 << 6) /* Bit 6: Card Detect Test Level */
+#define SDHCI_PROCTL_CDSS (1 << 7) /* Bit 7: Card Detect Signal Selection */
+ /* Bits 10-15: Reserved */
+#define SDHCI_PROCTL_SABGREQ (1 << 16) /* Bit 16: Stop At Block Gap Request */
+#define SDHCI_PROCTL_CREQ (1 << 17) /* Bit 17: Continue Request */
+#define SDHCI_PROCTL_RWCTL (1 << 18) /* Bit 18: Read Wait Control */
+#define SDHCI_PROCTL_IABG (1 << 19) /* Bit 19: Interrupt At Block Gap */
+ /* Bits 20-23: Reserved */
+#define SDHCI_PROCTL_WECINT (1 << 24) /* Bit 24: Wakeup Event Enable On Card Interrupt */
+#define SDHCI_PROCTL_WECINS (1 << 25) /* Bit 25: Wakeup Event Enable On SD Card Insertion */
+#define SDHCI_PROCTL_WECRM (1 << 26) /* Bit 26: Wakeup Event Enable On SD Card Removal */
+ /* Bits 27-31: Reserved */
+/* System Control Register */
+
+#define SDHCI_SYSCTL_ICLKEN (1 << 0) /* Bit 0: Internal Clock Enable */
+#define SDHCI_SYSCTL_ICLKSTA (1 << 1) /* Bit 1: Internal Clock Stable */
+#define SDHCI_SYSCTL_SDCLKEN (1 << 2) /* Bit 2: SD Clock Enable */
+#define SDHCI_SYSCTL_GENSEL (1 << 5) /* Bit 5: Clock Generetor Select */
+#define SDHCI_SYSCTL_SDCLKFSUP_SHIFT (6) /* Bits 6-7: Divisor */
+#define SDHCI_SYSCTL_SDCLKFSUP_MASK (3 << SDHCI_SYSCTL_SDCLKFSUP_SHIFT)
+#define SDHCI_SYSCTL_SDCLKFS_SHIFT (8) /* Bits 8-15: SDCLK Frequency Select */
+#define SDHCI_SYSCTL_SDCLKFS_MASK (0xff << SDHCI_SYSCTL_SDCLKFS_SHIFT)
+#define SDHCI_SYSCTL_DTOCV_SHIFT (16) /* Bits 16-19: Data Timeout Counter Value */
+#define SDHCI_SYSCTL_DTOCV_MASK (0xf << SDHCI_SYSCTL_DTOCV_SHIFT)
+# define SDHCI_SYSCTL_DTOCV_MUL(n) (((n)-213) << SDHCI_SYSCTL_DTOCV_SHIFT) /* SDCLK x n, n=213..227 */
+ /* Bits 20-23: Reserved */
+#define SDHCI_SYSCTL_RSTA (1 << 24) /* Bit 24: Software Reset For ALL */
+#define SDHCI_SYSCTL_RSTC (1 << 25) /* Bit 25: Software Reset For CMD Line */
+#define SDHCI_SYSCTL_RSTD (1 << 26) /* Bit 26: Software Reset For DAT Line */
+#define SDHCI_SYSCTL_INITA (1 << 27) /* Bit 27: Initialization Active */
+ /* Bits 28-31: Reserved */
+/* Interrupt Status Register, Interrupt Status Enable Register, and Interrupt Signal Enable Register
+ * Common interrupt bit definitions
+ */
+
+#define SDHCI_INT_CC (1 << 0) /* Bit 0: Command Complete */
+#define SDHCI_INT_TC (1 << 1) /* Bit 1: Transfer Complete */
+#define SDHCI_INT_BGE (1 << 2) /* Bit 2: Block Gap Event */
+#define SDHCI_INT_DINT (1 << 3) /* Bit 3: DMA Interrupt */
+#define SDHCI_INT_BWR (1 << 4) /* Bit 4: Buffer Write Ready */
+#define SDHCI_INT_BRR (1 << 5) /* Bit 5: Buffer Read Ready */
+#define SDHCI_INT_CINS (1 << 6) /* Bit 6: Card Insertion */
+#define SDHCI_INT_CRM (1 << 7) /* Bit 7: Card Removal */
+#define SDHCI_INT_CINT (1 << 8) /* Bit 8: Card Interrupt */
+ /* Bits 9-15: Reserved */
+#define SDHCI_INT_CTOE (1 << 16) /* Bit 16: Command Timeout Error */
+#define SDHCI_INT_CCE (1 << 17) /* Bit 17: Command CRC Error */
+#define SDHCI_INT_CEBE (1 << 18) /* Bit 18: Command End Bit Error */
+#define SDHCI_INT_CIE (1 << 19) /* Bit 19: Command Index Error */
+#define SDHCI_INT_DTOE (1 << 20) /* Bit 20: Data Timeout Error */
+#define SDHCI_INT_DCE (1 << 21) /* Bit 21: Data CRC Error */
+#define SDHCI_INT_DEBE (1 << 22) /* Bit 22: Data End Bit Error */
+ /* Bit 23: Reserved */
+#define SDHCI_INT_AC12E (1 << 24) /* Bit 24: Auto CMD12 Error */
+ /* Bits 25-27: Reserved */
+#define SDHCI_INT_DMAE (1 << 28) /* Bit 28: DMA Error */
+ /* Bits 29-31: Reserved */
+#define SDHCI_INT_ALL 0x117f01ff
+
+/* Auto CMD12 Error Status Register */
+
+#define SDHCI_AC12ERR_NE (1 << 0) /* Bit 0: Auto CMD12 Not Executed */
+#define SDHCI_AC12ERR_TOE (1 << 1) /* Bit 1: Auto CMD12 Timeout Error */
+#define SDHCI_AC12ERR_EBE (1 << 2) /* Bit 2: Auto CMD12 End Bit Error */
+#define SDHCI_AC12ERR_CE (1 << 3) /* Bit 3: Auto CMD12 CRC Error */
+#define SDHCI_AC12ERR_IE (1 << 4) /* Bit 4: Auto CMD12 Index Error */
+ /* Bits 5-6: Reserved */
+#define SDHCI_AC12ERR_CNI (1 << 7) /* Bit 7: Command Not Issued By Auto CMD12 Error */
+ /* Bits 8-31: Reserved */
+/* Host Controller Capabilities */
+ /* Bits 0-15: Reserved */
+#define SDHCI_HTCAPBLT_MBL_SHIFT (16) /* Bits 16-18: Max Block Length */
+#define SDHCI_HTCAPBLT_MBL_MASK (7 << SDHCI_HTCAPBLT_MBL_SHIFT)
+# define SDHCI_HTCAPBLT_MBL_512BYTES (0 << SDHCI_HTCAPBLT_MBL_SHIFT)
+# define SDHCI_HTCAPBLT_MBL_1KB (1 << SDHCI_HTCAPBLT_MBL_SHIFT)
+# define SDHCI_HTCAPBLT_MBL_2KB (2 << SDHCI_HTCAPBLT_MBL_SHIFT)
+# define SDHCI_HTCAPBLT_MBL_4KB (3 << SDHCI_HTCAPBLT_MBL_SHIFT)
+ /* Bit 19: Reserved */
+#define SDHCI_HTCAPBLT_ADMAS (1 << 20) /* Bit 20: ADMA Support */
+#define SDHCI_HTCAPBLT_HSS (1 << 21) /* Bit 21: High Speed Support */
+#define SDHCI_HTCAPBLT_DMAS (1 << 22) /* Bit 22: DMA Support */
+#define SDHCI_HTCAPBLT_SRS (1 << 23) /* Bit 23: Suspend/Resume Support */
+#define SDHCI_HTCAPBLT_VS33 (1 << 24) /* Bit 24: Voltage Support 3.3 V */
+#define SDHCI_HTCAPBLT_VS30 (1 << 25) /* Bit 25: Voltage Support 3.0 V */
+#define SDHCI_HTCAPBLT_VS18 (1 << 26) /* Bit 26: Voltage Support 1.8 */
+ /* Bits 27-31: Reserved */
+/* Force Event Register */
+
+#define SDHCI_FEVT_AC12NE (1 << 0) /* Bit 0: Force Event Auto Command 12 Not Executed */
+#define SDHCI_FEVT_AC12TOE (1 << 1) /* Bit 1: Force Event Auto Command 12 Time Out Error */
+#define SDHCI_FEVT_AC12CE (1 << 2) /* Bit 2: Force Event Auto Command 12 CRC Error */
+#define SDHCI_FEVT_AC12EBE (1 << 3) /* Bit 3: Force Event Auto Command 12 End Bit Error */
+#define SDHCI_FEVT_AC12IE (1 << 4) /* Bit 4: Force Event Auto Command 12 Index Error */
+ /* Bits 5-6: Reserved */
+#define SDHCI_FEVT_CNIBAC12E (1 << 7) /* Bit 7: Force Event Command Not Executed By Auto Command 12 Error */
+ /* Bits 8-15: Reserved */
+#define SDHCI_FEVT_CTOE (1 << 16) /* Bit 16: Force Event Command Time Out Error */
+#define SDHCI_FEVT_CCE (1 << 17) /* Bit 17: Force Event Command CRC Error */
+#define SDHCI_FEVT_CEBE (1 << 18) /* Bit 18: Force Event Command End Bit Error */
+#define SDHCI_FEVT_CIE (1 << 19) /* Bit 19: Force Event Command Index Error */
+#define SDHCI_FEVT_DTOE (1 << 20) /* Bit 20: Force Event Data Time Out Error */
+#define SDHCI_FEVT_DCE (1 << 21) /* Bit 21: Force Event Data CRC Error */
+#define SDHCI_FEVT_DEBE (1 << 22) /* Bit 22: Force Event Data End Bit Error */
+ /* Bit 23: Reserved */
+#define SDHCI_FEVT_AC12E (1 << 24) /* Bit 24: Force Event Auto Command 12 Error */
+ /* Bits 25-27: Reserved */
+#define SDHCI_FEVT_DMAE (1 << 28) /* Bit 28: Force Event DMA Error */
+ /* Bits 29-30: Reserved */
+#define SDHCI_FEVT_CINT (1 << 31) /* Bit 31: Force Event Card Interrupt */
+
+/* ADMA Error Status Register */
+
+#define SDHCI_ADMAES_SHIFT (0) /* Bits 0-1: ADMA Error State (when ADMA Error is occurred) */
+#define SDHCI_ADMAES_MASK (3 << SDHCI_ADMAES_ADMAES_SHIFT)
+# define SDHCI_ADMAES_STOP (0 << SDHCI_ADMAES_ADMAES_SHIFT) /* Stop DMA */
+# define SDHCI_ADMAES_FDS (1 << SDHCI_ADMAES_ADMAES_SHIFT) /* Fetch descriptor */
+# define SDHCI_ADMAES_CADR (2 << SDHCI_ADMAES_ADMAES_SHIFT) /* Change address */
+# define SDHCI_ADMAES_TFR (3 << SDHCI_ADMAES_ADMAES_SHIFT) /* Transfer data */
+#define SDHCI_ADMAES_LME (1 << 2) /* Bit 2: ADMA Length Mismatch Error */
+#define SDHCI_ADMAES_DCE (1 << 3) /* Bit 3: ADMA Descriptor Error */
+ /* Bits 4-31: Reserved */
+/* ADMA System Address Register */
+
+#define SDHCI_ADSADDR_SHIFT (1) /* Bits 1-31: ADMA System Address */
+#define SDHCI_ADSADDR_MASK (0xfffffffe)
+ /* Bits 0-1: Reserved */
+
+/* Vendor Specific Register */
+
+#define SDHCI_VENDOR_EXTDMAEN (1 << 0) /* Bit 0: External DMA Request Enable */
+#define SDHCI_VENDOR_EXBLKNU (1 << 1) /* Bit 1: Exact block number block read enable for SDIO CMD53 */
+ /* Bits 2-15: Reserved */
+#define SDHCI_VENDOR_INTSTVAL_SHIFT (16) /* Bits 16-23: Internal State Value */
+#define SDHCI_VENDOR_INTSTVAL_MASK (0xff << SDHCI_VENDOR_INTSTVAL_SHIFT)
+ /* Bits 24-31: Reserved */
+
+/* User Define1 Control Register */
+
+#define SDHCI_UDEF1_SDCLKI_SEL (1 << 0)
+#define SDHCI_UDEF1_SDCLKI_SEL_EXT (1 << 0)
+#define SDHCI_UDEF1_SDCLKI_SEL_INT (0 << 0)
+#define SDHCI_UDEF1_SDCLK_SEL (1 << 1)
+#define SDHCI_UDEF1_SDCLK_SEL_EXT (1 << 1)
+#define SDHCI_UDEF1_SDCLK_SEL_INT (0 << 1)
+#define SDHCI_UDEF1_TAP_SEL_SHIFT (4)
+#define SDHCI_UDEF1_TAP_SEL_MASK (0x1f << SDHCI_UDEF1_TAP_SEL_SHIFT)
+#define SDHCI_UDEF1_TAP_SEL (1 << 12)
+#define SDHCI_UDEF1_TAP_SEL_SW (1 << 12)
+#define SDHCI_UDEF1_TAP_SEL_HW (0 << 12)
+#define SDHCI_UDEF1_DAT_DLY_BUF (1 << 24)
+#define SDHCI_UDEF1_DAT_DLY_BUF_ON (1 << 24)
+#define SDHCI_UDEF1_DAT_DLY_BUF_OFF (0 << 24)
+
+/* User Define2 Control Register */
+
+#define SDHCI_UDEF2_CLK_DLY_SHIFT (0)
+#define SDHCI_UDEF2_CLK_DLY_MASK (0x7 << SDHCI_UDEF2_CLK_DLY_SHIFT)
+#define SDHCI_UDEF2_CMD_EDGE_DET_ON (1 << 4)
+#define SDHCI_UDEF2_CMD_EDGE_DET_OFF (0 << 4)
+#define SDHCI_UDEF2_DAT_DIR_ACT_HI (0x0 << 8)
+#define SDHCI_UDEF2_DAT_DIR_ACT_LOW (0x7 << 8)
+#define SDHCI_UDEF2_TTCLK_DIV1 (1 << 16)
+#define SDHCI_UDEF2_TTCLK_DIV2 (0 << 16)
+#define SDHCI_UDEF2_CLKI_SEL (1 << 20)
+#define SDHCI_UDEF2_CLKI_SEL_EXT (1 << 20)
+#define SDHCI_UDEF2_CLKI_SEL_INT (0 << 20)
+#define SDHCI_UDEF2_CMD_SEL (1 << 24)
+#define SDHCI_UDEF2_CMD_SEL_CLKI (1 << 24)
+#define SDHCI_UDEF2_CMD_SEL_INT (0 << 24)
+#define SDHCI_UDEF2_FORCE_1p8V_EN (1 << 31)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+struct sdio_dev_s;
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+
+/****************************************************************************
+ * Name: cxd56_sdhci_initialize
+ *
+ * Description:
+ * Initialize SDIO for operation.
+ *
+ * Input Parameters:
+ * slotno - Not used.
+ *
+ * Returned Values:
+ * A reference to an SDIO interface structure. NULL is returned on failures.
+ *
+ ****************************************************************************/
+
+FAR struct sdio_dev_s *cxd56_sdhci_initialize(int slotno);
+
+/****************************************************************************
+ * Name: cxd56_sdhci_finalize
+ *
+ * Description:
+ * Finalize SDIO for operation.
+ *
+ * Input Parameters:
+ * slotno - Not used.
+ *
+ * Returned Values:
+ * A reference to an SDIO interface structure. NULL is returned on failures.
+ *
+ ****************************************************************************/
+
+FAR struct sdio_dev_s *cxd56_sdhci_finalize(int slotno);
+
+/****************************************************************************
+ * Name: cxd56_sdhci_mediachange
+ *
+ * Description:
+ * Called by board-specific logic -- posssible from an interrupt handler --
+ * in order to signal to the driver that a card has been inserted or
+ * removed from the slot
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+void cxd56_sdhci_mediachange(FAR struct sdio_dev_s *dev);
+
+/****************************************************************************
+ * Name: sdio_wrprotect
+ *
+ * Description:
+ * Called by board-specific logic to report if the card in the slot is
+ * mechanically write protected.
+ *
+ * Input Parameters:
+ * dev - An instance of the SDIO driver device state structure.
+ * wrprotect - true is a card is writeprotected.
+ *
+ * Returned Values:
+ * None
+ *
+ ****************************************************************************/
+void cxd56_sdhci_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARCH_ARM_SRC_CXD56XX_CXD56_SDHCI_H */
diff --git a/arch/arm/src/cxd56xx/cxd56_serial.c b/arch/arm/src/cxd56xx/cxd56_serial.c
new file mode 100644
index 00000000000..8c3811c3f98
--- /dev/null
+++ b/arch/arm/src/cxd56xx/cxd56_serial.c
@@ -0,0 +1,997 @@
+/****************************************************************************
+ * arch/arm/src/cxd56xx/cxd56_serial.c
+ *
+ * Copyright 2018 Sony Semiconductor Solutions Corporation
+ *
+ * Copyright (C) 2012-2013, 2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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