sound/soc/tegra/tegra210_i2s.c
Source file repositories/reference/linux-study-clean/sound/soc/tegra/tegra210_i2s.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/tegra/tegra210_i2s.c- Extension
.c- Size
- 34731 bytes
- Lines
- 1176
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/device.hlinux/mod_devicetable.hlinux/module.hlinux/of_graph.hlinux/platform_device.hlinux/pm_runtime.hlinux/regmap.hsound/core.hsound/pcm_params.hsound/simple_card_utils.hsound/soc.htegra210_i2s.htegra_cif.h
Detected Declarations
function tegra210_i2s_set_slot_ctrlfunction tegra210_i2s_set_clock_ratefunction tegra210_i2s_sw_resetfunction tegra210_i2s_initfunction tegra210_i2s_runtime_suspendfunction tegra210_i2s_runtime_resumefunction tegra210_i2s_set_data_offsetfunction tegra210_i2s_set_fmtfunction tegra210_i2s_set_tdm_slotfunction tegra210_i2s_get_loopbackfunction tegra210_i2s_put_loopbackfunction tegra210_i2s_get_fsync_widthfunction tegra210_i2s_put_fsync_widthfunction tegra210_i2s_cget_stereo_to_monofunction tegra210_i2s_cput_stereo_to_monofunction tegra210_i2s_cget_mono_to_stereofunction tegra210_i2s_cput_mono_to_stereofunction tegra210_i2s_pget_stereo_to_monofunction tegra210_i2s_pput_stereo_to_monofunction tegra210_i2s_pget_mono_to_stereofunction tegra210_i2s_pput_mono_to_stereofunction tegra210_i2s_pget_fifo_thfunction tegra210_i2s_pput_fifo_thfunction tegra210_i2s_get_bclk_ratiofunction tegra210_i2s_put_bclk_ratiofunction tegra210_i2s_set_dai_bclk_ratiofunction tegra210_i2s_set_timing_paramsfunction tegra210_i2s_hw_paramsfunction tegra210_i2s_wr_regfunction tegra210_i2s_rd_regfunction tegra210_i2s_volatile_regfunction tegra264_i2s_wr_regfunction tegra264_i2s_rd_regfunction tegra264_i2s_volatile_regfunction params_channelsfunction tegra210_i2s_probefunction tegra210_i2s_remove
Annotated Snippet
if (err) {
dev_err(dev,
"can't set I2S sync input rate %u, err = %d\n",
clock_rate, err);
return err;
}
}
return 0;
}
static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt,
int stream)
{
struct device *dev = compnt->dev;
struct tegra210_i2s *i2s = dev_get_drvdata(dev);
unsigned int reset_mask = I2S_SOFT_RESET_MASK;
unsigned int reset_en = I2S_SOFT_RESET_EN;
unsigned int reset_reg, cif_reg, stream_reg;
unsigned int cif_ctrl, stream_ctrl, i2s_ctrl, val;
int err;
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
reset_reg = TEGRA210_I2S_RX_SOFT_RESET;
cif_reg = TEGRA210_I2S_RX_CIF_CTRL;
stream_reg = TEGRA210_I2S_RX_CTRL;
} else {
reset_reg = TEGRA210_I2S_TX_SOFT_RESET + i2s->soc_data->tx_offset;
cif_reg = TEGRA210_I2S_TX_CIF_CTRL + i2s->soc_data->tx_offset;
stream_reg = TEGRA210_I2S_TX_CTRL + i2s->soc_data->tx_offset;
}
/* Store CIF and I2S control values */
regmap_read(i2s->regmap, cif_reg, &cif_ctrl);
regmap_read(i2s->regmap, stream_reg, &stream_ctrl);
regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &i2s_ctrl);
/* Reset to make sure the previous transactions are clean */
regmap_update_bits(i2s->regmap, reset_reg, reset_mask, reset_en);
err = regmap_read_poll_timeout(i2s->regmap, reset_reg, val,
!(val & reset_mask & reset_en),
10, 10000);
if (err) {
dev_err(dev, "timeout: failed to reset I2S for %s\n",
snd_pcm_direction_name(stream));
return err;
}
/* Restore CIF and I2S control values */
regmap_write(i2s->regmap, cif_reg, cif_ctrl);
regmap_write(i2s->regmap, stream_reg, stream_ctrl);
regmap_write(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, i2s_ctrl);
return 0;
}
static int tegra210_i2s_init(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *compnt = snd_soc_dapm_to_component(w->dapm);
struct device *dev = compnt->dev;
struct tegra210_i2s *i2s = dev_get_drvdata(dev);
unsigned int val, status_reg;
int stream;
int err;
if (w->reg == TEGRA210_I2S_RX_ENABLE) {
stream = SNDRV_PCM_STREAM_PLAYBACK;
status_reg = TEGRA210_I2S_RX_STATUS;
} else if (w->reg == (TEGRA210_I2S_TX_ENABLE + i2s->soc_data->tx_offset)) {
stream = SNDRV_PCM_STREAM_CAPTURE;
status_reg = TEGRA210_I2S_TX_STATUS + i2s->soc_data->tx_offset;
} else {
dev_err(dev, "invalid I2S direction register 0x%x\n", w->reg);
return -EINVAL;
}
/* Ensure I2S is in disabled state before new session */
err = regmap_read_poll_timeout(i2s->regmap, status_reg, val,
!(val & I2S_EN_MASK & I2S_EN),
10, 10000);
if (err) {
dev_err(dev, "timeout: previous I2S %s is still active\n",
snd_pcm_direction_name(stream));
return err;
}
return tegra210_i2s_sw_reset(compnt, stream);
}
Annotation
- Immediate include surface: `linux/clk.h`, `linux/device.h`, `linux/mod_devicetable.h`, `linux/module.h`, `linux/of_graph.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `linux/regmap.h`.
- Detected declarations: `function tegra210_i2s_set_slot_ctrl`, `function tegra210_i2s_set_clock_rate`, `function tegra210_i2s_sw_reset`, `function tegra210_i2s_init`, `function tegra210_i2s_runtime_suspend`, `function tegra210_i2s_runtime_resume`, `function tegra210_i2s_set_data_offset`, `function tegra210_i2s_set_fmt`, `function tegra210_i2s_set_tdm_slot`, `function tegra210_i2s_get_loopback`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.