/* * [NOTE] * * This driver doesn't support Clock/Frame Provider Mode * * Basically MSIOF is created for SPI, but we can use it as I2S (Sound), etc. Because of it, when * we use it as I2S (Sound) with Provider Mode, we need to send dummy TX data even though it was * used for RX. Because SPI HW needs TX Clock/Frame output for RX purpose. * But it makes driver code complex in I2S (Sound). * * And when we use it as I2S (Sound) as Provider Mode, the clock source is [MSO clock] (= 133.33MHz) * SoC internal clock. It is not for 48kHz/44.1kHz base clock. Thus the output/input will not be * accurate sound. * * Because of these reasons, this driver doesn't support Clock/Frame Provider Mode. Use it as * Clock/Frame Consumer Mode.
*/
/* * [NOTE-RESET] * * MSIOF has TXRST/RXRST to reset FIFO, but it shouldn't be used during SYNC signal was asserted, * because it will be cause of HW issue. * * When MSIOF is used as Sound driver, this driver is assuming it is used as clock consumer mode * (= Codec is clock provider). This means, it can't control SYNC signal by itself. * * We need to use SW reset (= reset_control_xxx()) instead of TXRST/RXRST.
*/
/* * The data on memory in 24bit case is located at <right> side * [ xxxxxx] * [ xxxxxx] * [ xxxxxx] * * HW assuming signal in 24bit case is located at <left> side * ---+ +---------+ * +---------+ +---------+... * [xxxxxx ][xxxxxx ][xxxxxx ] * * When we use 24bit data, it will be transferred via 32bit width via DMA, * and MSIOF/DMA doesn't support data shift, we can't use 24bit data correctly. * There is no such issue on 16/32bit data case.
*/ #define MSIOF_RATES SNDRV_PCM_RATE_8000_192000 #define MSIOF_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\
SNDRV_PCM_FMTBIT_S32_LE)
staticint msiof_hw_start(struct snd_soc_component *component, struct snd_pcm_substream *substream, int cmd)
{ struct msiof_priv *priv = snd_soc_component_get_drvdata(component); struct snd_pcm_runtime *runtime = substream->runtime; int is_play = msiof_is_play(substream); int width = snd_pcm_format_width(runtime->format);
u32 val;
/* * see * [NOTE] on top of this driver
*/ /* * see * Datasheet 109.3.6 [Transmit and Receive Procedures] * * TX: Fig 109.14 - Fig 109.23 * RX: Fig 109.15
*/
/* * Use reset_control_xx() instead of TXRST/RXRST. * see * [NOTE-RESET]
*/ if (!priv->count)
reset_control_deassert(priv->reset);
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { /* * It supports Clock/Frame Consumer Mode only * see * [NOTE] on top of this driver
*/ case SND_SOC_DAIFMT_BC_FC: break; /* others are error */ default: return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) { /* it supports NB_NF only */ case SND_SOC_DAIFMT_NB_NF: default: break; /* others are error */ case SND_SOC_DAIFMT_NB_IF: case SND_SOC_DAIFMT_IB_NF: case SND_SOC_DAIFMT_IB_IF: return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S:
msiof_flag_set(priv, MSIOF_FLAGS_NEED_DELAY); break; case SND_SOC_DAIFMT_LEFT_J: break; default: return -EINVAL;
}
return 0;
}
/* * Select below from Sound Card, not auto * SND_SOC_DAIFMT_CBC_CFC * SND_SOC_DAIFMT_CBP_CFP
*/ staticconst u64 msiof_dai_formats = SND_SOC_POSSIBLE_DAIFMT_I2S |
SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
SND_SOC_POSSIBLE_DAIFMT_NB_NF;
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.2Bemerkung:
(vorverarbeitet am 2026-04-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.