SAMA5 SSC: Start Delay is now configurable
This commit is contained in:
parent
d68a6059e0
commit
5e92347d60
@ -2163,6 +2163,15 @@ config SAMA5_SSC0_RX_FSLEN
|
||||
This setting determines the pulse length of the Receive Frame Sync
|
||||
signal in units of receive clock periods.
|
||||
|
||||
config SAMA5_SSC0_RX_STTDLY
|
||||
int "Receive Start Delay Length"
|
||||
default 0
|
||||
range 0 255
|
||||
---help---
|
||||
This setting determines the pulse length to the start of data in
|
||||
receive clock periods. It must be greater than or equal to the RX
|
||||
frame synch length. Zero means no start delay.
|
||||
|
||||
endif # SAMA5_SSC0_RX
|
||||
|
||||
config SAMA5_SSC0_TX
|
||||
@ -2224,6 +2233,15 @@ config SAMA5_SSC0_TX_FSLEN
|
||||
feature. In that case the TD line is driven with the default value
|
||||
during the Transmit Frame Sync signal.
|
||||
|
||||
config SAMA5_SSC0_TX_STTDLY
|
||||
int "Transmit Start Delay Length"
|
||||
default 0
|
||||
range 0 255
|
||||
---help---
|
||||
This setting determines the pulse length to the start of data in
|
||||
transmit clock periods. It must be greater than or equal to the RX
|
||||
frame synch length. Zero means no start delay.
|
||||
|
||||
endif # SAMA5_SSC0_TX
|
||||
|
||||
config SAMA5_SSC0_MCKDIV_SAMPLERATE
|
||||
@ -2317,6 +2335,15 @@ config SAMA5_SSC1_RX_FSLEN
|
||||
This setting determines the pulse length of the Receive Frame Sync
|
||||
signal in units of receive clock periods.
|
||||
|
||||
config SAMA5_SSC1_RX_STTDLY
|
||||
int "Receive Start Delay Length"
|
||||
default 0
|
||||
range 0 255
|
||||
---help---
|
||||
This setting determines the pulse length to the start of data of
|
||||
receive clock periods. It must be greater than or equal to the RX
|
||||
frame synch length. Zero means no start delay.
|
||||
|
||||
endif # SAMA5_SSC1_RX
|
||||
|
||||
config SAMA5_SSC1_TX
|
||||
@ -2378,6 +2405,15 @@ config SAMA5_SSC1_TX_FSLEN
|
||||
feature. In that case the TD line is driven with the default value
|
||||
during the Transmit Frame Sync signal.
|
||||
|
||||
config SAMA5_SSC1_TX_STTDLY
|
||||
int "Transmit Start Delay Length"
|
||||
default 0
|
||||
range 0 255
|
||||
---help---
|
||||
This setting determines the pulse length to the start of data in
|
||||
transmit clock periods. It must be greater than or equal to the RX
|
||||
frame synch length. Zero means no start delay.
|
||||
|
||||
endif # SAMA5_SSC1_TX
|
||||
|
||||
config SAMA5_SSC1_MCKDIV_SAMPLERATE
|
||||
|
@ -84,11 +84,15 @@
|
||||
# error Work queue support is required (CONFIG_SCHED_WORKQUEUE)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_AUDIO
|
||||
# error CONFIG_AUDIO required by this driver
|
||||
#endif
|
||||
|
||||
#ifndef SAMA5_SSC_MAXINFLIGHT
|
||||
# define SAMA5_SSC_MAXINFLIGHT 16
|
||||
#endif
|
||||
|
||||
/* Assume no RX/TX support */
|
||||
/* Assume no RX/TX support until we learn better */
|
||||
|
||||
#undef SSC_HAVE_RX
|
||||
#undef SSC_HAVE_TX
|
||||
@ -117,7 +121,7 @@
|
||||
|
||||
/* Check for SSC0 RX support */
|
||||
|
||||
# if (defined(CONFIG_SAMA5_SSC0) && defined(CONFIG_SAMA5_SSC0_RX))
|
||||
# if defined(CONFIG_SAMA5_SSC0_RX)
|
||||
# define SSC_HAVE_RX 1
|
||||
|
||||
# ifndef CONFIG_SSC0_RX_FSLEN
|
||||
@ -127,11 +131,21 @@
|
||||
# if CONFIG_SSC0_RX_FSLEN < 1 || CONFIG_SSC0_RX_FSLEN > 255
|
||||
# error Invalid value for CONFIG_SSC0_RX_FSLEN
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SSC0_RX_STTDLY
|
||||
# define CONFIG_SSC0_RX_STTDLY CONFIG_SSC0_RX_FSLEN
|
||||
# endif
|
||||
|
||||
# if CONFIG_SSC0_RX_STTDLY < 0 || \
|
||||
CONFIG_SSC0_RX_STTDLY < CONFIG_SSC0_RX_FSLEN || \
|
||||
CONFIG_SSC0_RX_STTDLY > 255
|
||||
# error Invalid value for CONFIG_SSC0_RX_STTDLY
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Check for SSC0 TX support */
|
||||
|
||||
# if (defined(CONFIG_SAMA5_SSC0) && defined(CONFIG_SAMA5_SSC0_TX))
|
||||
# if defined(CONFIG_SAMA5_SSC0_TX)
|
||||
# define SSC_HAVE_TX 1
|
||||
|
||||
# ifndef CONFIG_SSC0_TX_FSLEN
|
||||
@ -141,6 +155,20 @@
|
||||
# if CONFIG_SSC0_TX_FSLEN < 0 || CONFIG_SSC0_TX_FSLEN > 255
|
||||
# error Invalid value for CONFIG_SSC0_TX_FSLEN
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SSC0_TX_STTDLY
|
||||
# if CONFIG_SSC0_TX_FSLEN > 0
|
||||
# define CONFIG_SSC0_TX_STTDLY CONFIG_SSC0_TX_FSLEN
|
||||
# else
|
||||
# define CONFIG_SSC0_TX_STTDLY 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if CONFIG_SSC0_TX_STTDLY < 0 || \
|
||||
CONFIG_SSC0_TX_STTDLY < CONFIG_SSC0_TX_FSLEN || \
|
||||
CONFIG_SSC0_TX_STTDLY > 255
|
||||
# error Invalid value for CONFIG_SSC0_TX_STTDLY
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
@ -169,7 +197,7 @@
|
||||
|
||||
/* Check for SSC1 RX support */
|
||||
|
||||
# if (defined(CONFIG_SAMA5_SSC1) && defined(CONFIG_SAMA5_SSC1_RX))
|
||||
# if defined(CONFIG_SAMA5_SSC1_RX)
|
||||
# define SSC_HAVE_RX 1
|
||||
|
||||
# ifndef CONFIG_SSC1_RX_FSLEN
|
||||
@ -179,11 +207,22 @@
|
||||
# if CONFIG_SSC1_RX_FSLEN < 1 || CONFIG_SSC1_RX_FSLEN > 255
|
||||
# error Invalid value for CONFIG_SSC1_RX_FSLEN
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SSC1_RX_STTDLY
|
||||
# define CONFIG_SSC1_RX_STTDLY CONFIG_SSC1_RX_FSLEN
|
||||
# endif
|
||||
|
||||
# if CONFIG_SSC1_RX_STTDLY < 0 || \
|
||||
CONFIG_SSC1_RX_STTDLY < CONFIG_SSC1_RX_FSLEN || \
|
||||
CONFIG_SSC1_RX_STTDLY > 255
|
||||
# error Invalid value for CONFIG_SSC1_RX_STTDLY
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
/* Check for SSC0 TX support */
|
||||
/* Check for SSC1 TX support */
|
||||
|
||||
# if (defined(CONFIG_SAMA5_SSC1) && defined(CONFIG_SAMA5_SSC1_TX))
|
||||
# if defined(CONFIG_SAMA5_SSC1_TX)
|
||||
# define SSC_HAVE_TX 1
|
||||
|
||||
# ifndef CONFIG_SSC1_TX_FSLEN
|
||||
@ -193,14 +232,24 @@
|
||||
# if CONFIG_SSC1_TX_FSLEN < 0 || CONFIG_SSC1_TX_FSLEN > 255
|
||||
# error Invalid value for CONFIG_SSC1_TX_FSLEN
|
||||
# endif
|
||||
|
||||
# ifndef CONFIG_SSC1_TX_STTDLY
|
||||
# if CONFIG_SSC1_TX_FSLEN > 0
|
||||
# define CONFIG_SSC1_TX_STTDLY CONFIG_SSC1_TX_FSLEN
|
||||
# else
|
||||
# define CONFIG_SSC1_TX_STTDLY 0
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if CONFIG_SSC1_TX_STTDLY < 0 || \
|
||||
CONFIG_SSC1_TX_STTDLY < CONFIG_SSC1_TX_FSLEN || \
|
||||
CONFIG_SSC1_TX_STTDLY > 255
|
||||
# error Invalid value for CONFIG_SSC1_TX_STTDLY
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_AUDIO
|
||||
# error CONFIG_AUDIO required by this driver
|
||||
#endif
|
||||
|
||||
/* Check if we need to build RX and/or TX support */
|
||||
|
||||
#if defined(SSC_HAVE_RX) || defined(SSC_HAVE_TX)
|
||||
@ -244,7 +293,6 @@
|
||||
* REVISIT: These will probably need to be configurable
|
||||
*/
|
||||
|
||||
#define SSC_STTDLY(f) (f) /* Delay to data start in clocks (same as FSLEN) */
|
||||
#define SSC_DATNB (1) /* Number words per per frame */
|
||||
#define SCC_PERIOD(s,d) ((s) + (d) * SSC_DATNB)
|
||||
|
||||
@ -294,7 +342,7 @@
|
||||
DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_8BITS | \
|
||||
DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \
|
||||
DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_16BITS | \
|
||||
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_4| \
|
||||
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1| \
|
||||
DMACH_FLAG_MEMBURST_4)
|
||||
|
||||
#define DMA16_FLAGS \
|
||||
@ -302,7 +350,7 @@
|
||||
DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_16BITS | \
|
||||
DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \
|
||||
DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_16BITS | \
|
||||
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_4 | \
|
||||
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \
|
||||
DMACH_FLAG_MEMBURST_4)
|
||||
|
||||
#define DMA32_FLAGS \
|
||||
@ -310,7 +358,7 @@
|
||||
DMACH_FLAG_PERIPHISPERIPH | DMACH_FLAG_PERIPHWIDTH_32BITS | \
|
||||
DMACH_FLAG_PERIPHCHUNKSIZE_1 | DMACH_FLAG_MEMPID_MAX | \
|
||||
DMACH_FLAG_MEM_IF | DMACH_FLAG_MEMWIDTH_32BITS | \
|
||||
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_4 | \
|
||||
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_1 | \
|
||||
DMACH_FLAG_MEMBURST_4)
|
||||
|
||||
/* DMA timeout. The value is not critical; we just don't want the system to
|
||||
@ -407,6 +455,8 @@ struct sam_ssc_s
|
||||
uint8_t pid; /* Peripheral ID */
|
||||
uint8_t rxfslen; /* RX frame sync length */
|
||||
uint8_t txfslen; /* TX frame sync length */
|
||||
uint8_t rxsttdly; /* RX start delay */
|
||||
uint8_t txsttdly; /* TX start delay */
|
||||
uint8_t rxenab:1; /* True: RX transfers enabled */
|
||||
uint8_t txenab:1; /* True: TX transfers enabled */
|
||||
uint8_t loopback:1; /* True: Loopback mode */
|
||||
@ -2390,23 +2440,12 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
|
||||
#ifdef SSC_HAVE_RX
|
||||
uint32_t regval;
|
||||
uint32_t fslen;
|
||||
uint32_t sttdly;
|
||||
|
||||
/* Get transfer waveform. First get the RX sync time (in RX clocks) */
|
||||
/* Get the RX sync time (in RX clocks) */
|
||||
|
||||
DEBUGASSERT(priv->rxfslen > 0);
|
||||
fslen = priv->rxfslen - 1;
|
||||
|
||||
/* Start delay extends to sometime after RX synch */
|
||||
|
||||
sttdly = SSC_STTDLY(fslen);
|
||||
if (sttdly > 0)
|
||||
{
|
||||
/* Decrement as need by the register file */
|
||||
|
||||
sttdly--;
|
||||
}
|
||||
|
||||
/* RCMR settings */
|
||||
/* Configure the receiver input clock */
|
||||
|
||||
@ -2470,7 +2509,7 @@ static int ssc_rx_configure(struct sam_ssc_s *priv)
|
||||
*/
|
||||
|
||||
regval |= (SSC_RCMR_CKI | SSC_RCMR_CKG_CONT | SSC_RCMR_START_EDGE |
|
||||
SSC_RCMR_STTDLY(sttdly) | SSC_RCMR_PERIOD(0));
|
||||
SSC_RCMR_STTDLY(priv->rxsttdly) | SSC_RCMR_PERIOD(0));
|
||||
ssc_putreg(priv, SAM_SSC_RCMR_OFFSET, regval);
|
||||
|
||||
/* RFMR settings. Some of these settings will need to be configurable as well.
|
||||
@ -2521,26 +2560,16 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
|
||||
uint32_t regval;
|
||||
uint32_t fslen;
|
||||
uint32_t period;
|
||||
uint32_t sttdly;
|
||||
|
||||
/* Get transfer waveform. Get the TX synch in (in TX clocks) */
|
||||
/* Get the TX synch in (in TX clocks) */
|
||||
|
||||
fslen = priv->txfslen > 0 ? priv->txfslen - 1 : 0;
|
||||
|
||||
/* Start delay extends to sometime after the TX synch */
|
||||
/* From the start delay and the datalength , we can get the full
|
||||
* period of the waveform.
|
||||
*/
|
||||
|
||||
sttdly = SSC_STTDLY(fslen);
|
||||
|
||||
/* From these, we can get the full period of the waveform */
|
||||
|
||||
period = SCC_PERIOD(sttdly, priv->datalen);
|
||||
|
||||
/* Decrement the start delay as required by the register field */
|
||||
|
||||
if (sttdly > 0)
|
||||
{
|
||||
sttdly--;
|
||||
}
|
||||
period = SCC_PERIOD(priv->txsttdly, priv->datalen);
|
||||
|
||||
/* TCMR settings */
|
||||
/* Configure the transmitter input clock */
|
||||
@ -2612,12 +2641,12 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
|
||||
if (priv->txclk == SSC_CLKSRC_MCKDIV)
|
||||
{
|
||||
regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_CONT |
|
||||
SSC_TCMR_STTDLY(sttdly) | SSC_TCMR_PERIOD(period / 2 - 1));
|
||||
SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(period / 2 - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
regval |= (SSC_TCMR_CKG_CONT | SSC_TCMR_START_EDGE |
|
||||
SSC_TCMR_STTDLY(sttdly) | SSC_TCMR_PERIOD(0));
|
||||
SSC_TCMR_STTDLY(priv->txsttdly) | SSC_TCMR_PERIOD(0));
|
||||
}
|
||||
|
||||
ssc_putreg(priv, SAM_SSC_TCMR_OFFSET, regval);
|
||||
@ -2652,7 +2681,7 @@ static int ssc_tx_configure(struct sam_ssc_s *priv)
|
||||
SSC_TFMR_MSBF | SSC_TFMR_DATNB(SSC_DATNB - 1) |
|
||||
SSC_TFMR_FSOS_NONE);
|
||||
}
|
||||
dbg("##### TFMR BEFORE: datalen=%d regval=%08x txfslen=%02x\n", priv->datalen, regval, priv->txfslen);
|
||||
|
||||
/* Is the TX frame synch enabled? */
|
||||
|
||||
if (priv->txfslen > 0)
|
||||
@ -2662,7 +2691,6 @@ dbg("##### TFMR BEFORE: datalen=%d regval=%08x txfslen=%02x\n", priv->datalen, r
|
||||
regval |= (SSC_TFMR_FSDEN | SSC_TFMR_FSLEN(fslen & 0x0f) |
|
||||
SSC_TFMR_FSLENEXT((fslen >> 4) & 0x0f));
|
||||
}
|
||||
dbg("##### TFMR AFTER: regval=%08x\n", regval);
|
||||
|
||||
ssc_putreg(priv, SAM_SSC_TFMR_OFFSET, regval);
|
||||
|
||||
@ -3038,9 +3066,10 @@ static void ssc0_configure(struct sam_ssc_s *priv)
|
||||
|
||||
#endif
|
||||
|
||||
/* Remember the configured RX frame synch length */
|
||||
/* Remember parameters of the configured waveform */
|
||||
|
||||
priv->rxfslen = CONFIG_SSC0_RX_FSLEN;
|
||||
priv->rxfslen = CONFIG_SSC0_RX_FSLEN;
|
||||
priv->rxsttdly = CONFIG_SSC0_RX_STTDLY;
|
||||
|
||||
/* Remember the configured RX clock output */
|
||||
|
||||
@ -3108,9 +3137,10 @@ static void ssc0_configure(struct sam_ssc_s *priv)
|
||||
|
||||
#endif /* CONFIG_SAMA5_SSC0_TX */
|
||||
|
||||
/* Remember the configured TX frame synch length */
|
||||
/* Remember parameters of the configured waveform */
|
||||
|
||||
priv->txfslen = CONFIG_SSC0_TX_FSLEN;
|
||||
priv->txfslen = CONFIG_SSC0_TX_FSLEN;
|
||||
priv->txsttdly = CONFIG_SSC0_TX_STTDLY;
|
||||
|
||||
/* Set/clear loopback mode */
|
||||
|
||||
@ -3174,9 +3204,10 @@ static void ssc1_configure(struct sam_ssc_s *priv)
|
||||
|
||||
#endif
|
||||
|
||||
/* Remember the configured RX frame synch length */
|
||||
/* Remember parameters of the configured waveform */
|
||||
|
||||
priv->rxfslen = CONFIG_SSC1_RX_FSLEN;
|
||||
priv->rxfslen = CONFIG_SSC1_RX_FSLEN;
|
||||
priv->rxsttdly = CONFIG_SSC1_RX_STTDLY;
|
||||
|
||||
/* Remember the configured RX clock output */
|
||||
|
||||
@ -3244,9 +3275,10 @@ static void ssc1_configure(struct sam_ssc_s *priv)
|
||||
|
||||
#endif /* CONFIG_SAMA5_SSC1_TX */
|
||||
|
||||
/* Remember the configured TX frame synch length */
|
||||
/* Remember parameters of the configured waveform */
|
||||
|
||||
priv->txfslen = CONFIG_SSC1_TX_FSLEN;
|
||||
priv->txfslen = CONFIG_SSC1_TX_FSLEN;
|
||||
priv->txsttdly = CONFIG_SSC1_TX_STTDLY;
|
||||
|
||||
/* Set/clear loopback mode */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user