nxp: sai: add support for passing TX/RX data line through DTS
Some SAI instances are mutliline, meaning they can have multiple TX/RX data lines (channels). Depending on the board, the index of the TX/RX data lines that are connected to the consumer (e.g: the codec) may not always be 0. This commit fixes this issue by adding support for passing the index of the used TX/RX data lines through the DTS. Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
This commit is contained in:
parent
f4972347d4
commit
0ff402657b
3 changed files with 64 additions and 7 deletions
|
@ -744,7 +744,8 @@ out_enable_dline:
|
|||
*
|
||||
* TODO: for now we only support 1 data line per direction.
|
||||
*/
|
||||
sai_tx_rx_set_dline_mask(dir, data->regmap, 0x1);
|
||||
sai_tx_rx_set_dline_mask(dir, data->regmap,
|
||||
SAI_TX_RX_DLINE_MASK(dir, cfg));
|
||||
|
||||
/* this will also enable the async side */
|
||||
SAI_TX_RX_ENABLE_DISABLE(dir, data->regmap, true);
|
||||
|
@ -862,14 +863,25 @@ BUILD_ASSERT(SAI_TX_SYNC_MODE(inst) != SAI_RX_SYNC_MODE(inst) || \
|
|||
SAI_TX_SYNC_MODE(inst) != kSAI_ModeSync, \
|
||||
"transmitter and receiver can't be both SYNC with each other"); \
|
||||
\
|
||||
BUILD_ASSERT(SAI_DLINE_COUNT(inst) != -1, \
|
||||
"bad or unsupported SAI instance. Is the base address correct?"); \
|
||||
\
|
||||
BUILD_ASSERT(SAI_TX_DLINE_INDEX(inst) >= 0 && \
|
||||
(SAI_TX_DLINE_INDEX(inst) < SAI_DLINE_COUNT(inst)), \
|
||||
"invalid TX data line index"); \
|
||||
\
|
||||
BUILD_ASSERT(SAI_RX_DLINE_INDEX(inst) >= 0 && \
|
||||
(SAI_RX_DLINE_INDEX(inst) < SAI_DLINE_COUNT(inst)), \
|
||||
"invalid RX data line index"); \
|
||||
\
|
||||
static const struct dai_properties sai_tx_props_##inst = { \
|
||||
.fifo_address = SAI_TX_FIFO_BASE(inst), \
|
||||
.fifo_address = SAI_TX_FIFO_BASE(inst, SAI_TX_DLINE_INDEX(inst)), \
|
||||
.fifo_depth = SAI_FIFO_DEPTH(inst) * CONFIG_SAI_FIFO_WORD_SIZE, \
|
||||
.dma_hs_id = SAI_TX_RX_DMA_HANDSHAKE(inst, tx), \
|
||||
}; \
|
||||
\
|
||||
static const struct dai_properties sai_rx_props_##inst = { \
|
||||
.fifo_address = SAI_RX_FIFO_BASE(inst), \
|
||||
.fifo_address = SAI_RX_FIFO_BASE(inst, SAI_RX_DLINE_INDEX(inst)), \
|
||||
.fifo_depth = SAI_FIFO_DEPTH(inst) * CONFIG_SAI_FIFO_WORD_SIZE, \
|
||||
.dma_hs_id = SAI_TX_RX_DMA_HANDSHAKE(inst, rx), \
|
||||
}; \
|
||||
|
@ -896,6 +908,8 @@ static struct sai_config sai_config_##inst = { \
|
|||
.irq_config = irq_config_##inst, \
|
||||
.tx_sync_mode = SAI_TX_SYNC_MODE(inst), \
|
||||
.rx_sync_mode = SAI_RX_SYNC_MODE(inst), \
|
||||
.tx_dline = SAI_TX_DLINE_INDEX(inst), \
|
||||
.rx_dline = SAI_RX_DLINE_INDEX(inst), \
|
||||
}; \
|
||||
\
|
||||
static struct sai_data sai_data_##inst = { \
|
||||
|
|
|
@ -102,12 +102,12 @@ LOG_MODULE_REGISTER(nxp_dai_sai);
|
|||
FSL_FEATURE_SAI_FIFO_COUNTn(UINT_TO_I2S(DT_INST_REG_ADDR(inst))) / 2)
|
||||
|
||||
/* used to retrieve TDR0's address based on SAI's physical address */
|
||||
#define SAI_TX_FIFO_BASE(inst)\
|
||||
POINTER_TO_UINT(&(UINT_TO_I2S(DT_INST_REG_ADDR(inst))->TDR[0]))
|
||||
#define SAI_TX_FIFO_BASE(inst, idx)\
|
||||
POINTER_TO_UINT(&(UINT_TO_I2S(DT_INST_REG_ADDR(inst))->TDR[idx]))
|
||||
|
||||
/* used to retrieve RDR0's address based on SAI's physical address */
|
||||
#define SAI_RX_FIFO_BASE(inst)\
|
||||
POINTER_TO_UINT(&(UINT_TO_I2S(DT_INST_REG_ADDR(inst))->RDR[0]))
|
||||
#define SAI_RX_FIFO_BASE(inst, idx)\
|
||||
POINTER_TO_UINT(&(UINT_TO_I2S(DT_INST_REG_ADDR(inst))->RDR[idx]))
|
||||
|
||||
/* internal macro used to retrieve the default TX/RX FIFO's size (in FIFO words) */
|
||||
#define _SAI_FIFO_DEPTH(inst)\
|
||||
|
@ -146,6 +146,16 @@ LOG_MODULE_REGISTER(nxp_dai_sai);
|
|||
((DT_INST_DMAS_CELL_BY_NAME(inst, dir, channel) & GENMASK(7, 0)) |\
|
||||
((DT_INST_DMAS_CELL_BY_NAME(inst, dir, mux) << 8) & GENMASK(15, 8)))
|
||||
|
||||
/* used to retrieve the number of supported transmission/receive lines */
|
||||
#define SAI_DLINE_COUNT(inst)\
|
||||
FSL_FEATURE_SAI_CHANNEL_COUNTn(UINT_TO_I2S(DT_INST_REG_ADDR(inst)))
|
||||
|
||||
/* used to retrieve the index of the transmission line */
|
||||
#define SAI_TX_DLINE_INDEX(inst) DT_INST_PROP_OR(inst, tx_dataline, 0)
|
||||
|
||||
/* used to retrieve the index of the receive line */
|
||||
#define SAI_RX_DLINE_INDEX(inst) DT_INST_PROP_OR(inst, rx_dataline, 0)
|
||||
|
||||
/* utility macros */
|
||||
|
||||
/* invert a clock's polarity. This works because a clock's polarity is expressed
|
||||
|
@ -215,6 +225,12 @@ LOG_MODULE_REGISTER(nxp_dai_sai);
|
|||
#define SAI_TX_RX_DIR_IS_SW_ENABLED(dir, data)\
|
||||
((dir) == DAI_DIR_TX ? data->tx_enabled : data->rx_enabled)
|
||||
|
||||
/* used to compute the mask for the transmission/receive lines based on
|
||||
* the index passed from the DTS.
|
||||
*/
|
||||
#define SAI_TX_RX_DLINE_MASK(dir, cfg)\
|
||||
((dir) == DAI_DIR_TX ? BIT((cfg)->tx_dline) : BIT((cfg)->rx_dline))
|
||||
|
||||
struct sai_clock_data {
|
||||
uint32_t *clocks;
|
||||
uint32_t clock_num;
|
||||
|
@ -253,6 +269,8 @@ struct sai_config {
|
|||
/* TX synchronization mode - may be SYNC or ASYNC */
|
||||
sai_sync_mode_t tx_sync_mode;
|
||||
void (*irq_config)(void);
|
||||
uint32_t tx_dline;
|
||||
uint32_t rx_dline;
|
||||
};
|
||||
|
||||
/* this needs to perfectly match SOF's struct sof_ipc_dai_sai_params */
|
||||
|
|
|
@ -84,3 +84,28 @@ properties:
|
|||
If this property is not specified, the receiver will be set to ASYNC.
|
||||
If one side is SYNC then the other MUST be ASYNC. Failing to meet this
|
||||
condition will result in a failed BUILD_ASSERT().
|
||||
tx-dataline:
|
||||
type: int
|
||||
description: |
|
||||
Use this property to specify which transmission data line the SAI should
|
||||
use. To find out which transmission line you should use you can:
|
||||
1) Check the TRM and see if your SAI instance is multiline. If not then
|
||||
you're going to use transmission line 0.
|
||||
2) If your SAI is multiline then you need to check the datasheet and see
|
||||
the index of the transmission line that's connected to your consumer
|
||||
(e.g: the codec).
|
||||
The indexing of the data line starts at 0. If this property is not specified
|
||||
then the index of the transmission data line will be 0.
|
||||
Please note that "channel" and "data line" are synnonyms in this context.
|
||||
rx-dataline:
|
||||
type: int
|
||||
description: |
|
||||
Use this property to specify which receive transmission data line the SAI should
|
||||
use. To find out which receive line you should use you can:
|
||||
1) Check the TRM and see if your SAI instance is multiline. If not then
|
||||
you're going to use receive line 0.
|
||||
2) If your SAI is multiline then you need to check the datasheet and see
|
||||
the index of the receive line that's connected to your consumer (e.g: the codec).
|
||||
The indexing of the data line starts at 0. If this property is not specified
|
||||
then the index of the receive data line will be 0.
|
||||
Please note that "channel" and "data line" are synnonyms in this context.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue