sound/soc/codecs/rt5640.c

Source file repositories/reference/linux-study-clean/sound/soc/codecs/rt5640.c

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/rt5640.c
Extension
.c
Size
96222 bytes
Lines
3075
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (val) {
		case RT5640_IF_123:
		case RT5640_IF_132:
			ret |= RT5640_U_IF1;
			break;
		case RT5640_IF_113:
			ret |= RT5640_U_IF1;
			fallthrough;
		case RT5640_IF_312:
		case RT5640_IF_213:
			ret |= RT5640_U_IF2;
			break;
		}
		break;

	case RT5640_AIF2:
		switch (val) {
		case RT5640_IF_231:
		case RT5640_IF_213:
			ret |= RT5640_U_IF1;
			break;
		case RT5640_IF_223:
			ret |= RT5640_U_IF1;
			fallthrough;
		case RT5640_IF_123:
		case RT5640_IF_321:
			ret |= RT5640_U_IF2;
			break;
		}
		break;

	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

static int rt5640_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct rt5640_priv *rt5640 = snd_soc_component_get_drvdata(component);
	unsigned int val_len = 0, val_clk, mask_clk;
	int dai_sel, pre_div, bclk_ms, frame_size;

	rt5640->lrck[dai->id] = params_rate(params);
	pre_div = rl6231_get_clk_info(rt5640->sysclk, rt5640->lrck[dai->id]);
	if (pre_div < 0) {
		dev_err(component->dev, "Unsupported clock setting %d for DAI %d\n",
			rt5640->lrck[dai->id], dai->id);
		return -EINVAL;
	}
	frame_size = snd_soc_params_to_frame_size(params);
	if (frame_size < 0) {
		dev_err(component->dev, "Unsupported frame size: %d\n", frame_size);
		return frame_size;
	}
	if (frame_size > 32)
		bclk_ms = 1;
	else
		bclk_ms = 0;
	rt5640->bclk[dai->id] = rt5640->lrck[dai->id] * (32 << bclk_ms);

	dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n",
		rt5640->bclk[dai->id], rt5640->lrck[dai->id]);
	dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n",
				bclk_ms, pre_div, dai->id);

	switch (params_width(params)) {
	case 16:
		break;
	case 20:
		val_len |= RT5640_I2S_DL_20;
		break;
	case 24:
		val_len |= RT5640_I2S_DL_24;
		break;
	case 8:
		val_len |= RT5640_I2S_DL_8;
		break;
	default:
		return -EINVAL;
	}

	dai_sel = get_sdp_info(component, dai->id);
	if (dai_sel < 0) {
		dev_err(component->dev, "Failed to get sdp info: %d\n", dai_sel);
		return -EINVAL;

Annotation

Implementation Notes