/* * Used to indicate the tx/rx status. * I2S controller hopes to start the tx and rx together, * also to stop them when they are both try to stop.
*/ bool tx_start; bool rx_start; bool is_master_mode; conststruct rk_i2s_pins *pins; unsignedint bclk_ratio;
spinlock_t lock; /* tx/rx lock */ struct pinctrl *pinctrl; struct pinctrl_state *bclk_on; struct pinctrl_state *bclk_off;
};
staticint i2s_pinctrl_select_bclk_on(struct rk_i2s_dev *i2s)
{ int ret = 0;
if (!IS_ERR(i2s->pinctrl) && !IS_ERR_OR_NULL(i2s->bclk_on))
ret = pinctrl_select_state(i2s->pinctrl, i2s->bclk_on);
if (ret)
dev_err(i2s->dev, "bclk enable failed %d\n", ret);
mask = I2S_TXCR_IBM_MASK | I2S_TXCR_TFS_MASK | I2S_TXCR_PBM_MASK; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J:
val = I2S_TXCR_IBM_RSJM; break; case SND_SOC_DAIFMT_LEFT_J:
val = I2S_TXCR_IBM_LSJM; break; case SND_SOC_DAIFMT_I2S:
val = I2S_TXCR_IBM_NORMAL; break; case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */
val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); break; case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */
val = I2S_TXCR_TFS_PCM; break; default:
ret = -EINVAL; goto err_pm_put;
}
mask = I2S_RXCR_IBM_MASK | I2S_RXCR_TFS_MASK | I2S_RXCR_PBM_MASK; switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J:
val = I2S_RXCR_IBM_RSJM; break; case SND_SOC_DAIFMT_LEFT_J:
val = I2S_RXCR_IBM_LSJM; break; case SND_SOC_DAIFMT_I2S:
val = I2S_RXCR_IBM_NORMAL; break; case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */
val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); break; case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */
val = I2S_RXCR_TFS_PCM; break; default:
ret = -EINVAL; goto err_pm_put;
}
switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8:
val |= I2S_TXCR_VDW(8); break; case SNDRV_PCM_FORMAT_S16_LE:
val |= I2S_TXCR_VDW(16); break; case SNDRV_PCM_FORMAT_S20_3LE:
val |= I2S_TXCR_VDW(20); break; case SNDRV_PCM_FORMAT_S24_LE:
val |= I2S_TXCR_VDW(24); break; case SNDRV_PCM_FORMAT_S32_LE:
val |= I2S_TXCR_VDW(32); break; default: return -EINVAL;
}
switch (params_channels(params)) { case8:
val |= I2S_CHN_8; break; case6:
val |= I2S_CHN_6; break; case4:
val |= I2S_CHN_4; break; case2:
val |= I2S_CHN_2; break; default:
dev_err(i2s->dev, "invalid channel: %d\n",
params_channels(params)); return -EINVAL;
}
if (!IS_ERR(i2s->grf) && i2s->pins) {
regmap_read(i2s->regmap, I2S_TXCR, &val);
val &= I2S_TXCR_CSR_MASK;
switch (val) { case I2S_CHN_4:
val = I2S_IO_4CH_OUT_6CH_IN; break; case I2S_CHN_6:
val = I2S_IO_6CH_OUT_4CH_IN; break; case I2S_CHN_8:
val = I2S_IO_8CH_OUT_2CH_IN; break; default:
val = I2S_IO_2CH_OUT_8CH_IN; break;
}
val <<= i2s->pins->shift;
val |= (I2S_IO_DIRECTION_MASK << i2s->pins->shift) << 16;
regmap_write(i2s->grf, i2s->pins->reg_offset, val);
}
staticint rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
{ struct rk_i2s_dev *i2s = to_info(dai); int ret = 0;
switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
ret = rockchip_snd_rxctrl(i2s, 1); else
ret = rockchip_snd_txctrl(i2s, 1); if (ret < 0) return ret;
i2s_pinctrl_select_bclk_on(i2s); break; case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { if (!i2s->tx_start)
i2s_pinctrl_select_bclk_off(i2s);
ret = rockchip_snd_rxctrl(i2s, 0);
} else { if (!i2s->rx_start)
i2s_pinctrl_select_bclk_off(i2s);
ret = rockchip_snd_txctrl(i2s, 0);
} break; default:
ret = -EINVAL; break;
}
staticbool rockchip_i2s_wr_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case I2S_TXCR: case I2S_RXCR: case I2S_CKR: case I2S_DMACR: case I2S_INTCR: case I2S_XFER: case I2S_CLR: case I2S_TXDR: returntrue; default: returnfalse;
}
}
staticbool rockchip_i2s_rd_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case I2S_TXCR: case I2S_RXCR: case I2S_CKR: case I2S_DMACR: case I2S_INTCR: case I2S_XFER: case I2S_CLR: case I2S_TXDR: case I2S_RXDR: case I2S_FIFOLR: case I2S_INTSR: returntrue; default: returnfalse;
}
}
staticbool rockchip_i2s_volatile_reg(struct device *dev, unsignedint reg)
{ switch (reg) { case I2S_INTSR: case I2S_CLR: case I2S_FIFOLR: case I2S_TXDR: case I2S_RXDR: returntrue; default: returnfalse;
}
}
¤ 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.12Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-07)
¤
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.