sound/soc/codecs/cs42l42.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/cs42l42.c
Extension
.c
Size
76808 bytes
Lines
2496
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

struct cs42l42_pll_params {
	u32 sclk;
	u8 mclk_src_sel;
	u8 sclk_prediv;
	u8 pll_div_int;
	u32 pll_div_frac;
	u8 pll_mode;
	u8 pll_divout;
	u32 mclk_int;
	u8 pll_cal_ratio;
	u8 n;
};

/*
 * Common PLL Settings for given SCLK
 * Table 4-5 from the Datasheet
 */
static const struct cs42l42_pll_params pll_ratio_table[] = {
	{ 1411200,  1, 0x00, 0x80, 0x000000, 0x03, 0x10, 11289600, 128, 2},
	{ 1536000,  1, 0x00, 0x7D, 0x000000, 0x03, 0x10, 12000000, 125, 2},
	{ 2304000,  1, 0x00, 0x55, 0xC00000, 0x02, 0x10, 12288000,  85, 2},
	{ 2400000,  1, 0x00, 0x50, 0x000000, 0x03, 0x10, 12000000,  80, 2},
	{ 2822400,  1, 0x00, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
	{ 3000000,  1, 0x00, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
	{ 3072000,  1, 0x00, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
	{ 4000000,  1, 0x00, 0x30, 0x800000, 0x03, 0x10, 12000000,  96, 1},
	{ 4096000,  1, 0x00, 0x2E, 0xE00000, 0x03, 0x10, 12000000,  94, 1},
	{ 4800000,  1, 0x01, 0x50, 0x000000, 0x03, 0x10, 12000000,  80, 2},
	{ 4800000,  1, 0x01, 0x50, 0x000000, 0x01, 0x10, 12288000,  82, 2},
	{ 5644800,  1, 0x01, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
	{ 6000000,  1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
	{ 6144000,  1, 0x01, 0x3E, 0x800000, 0x03, 0x10, 12000000, 125, 1},
	{ 6144000,  1, 0x01, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1},
	{ 9600000,  1, 0x02, 0x50, 0x000000, 0x03, 0x10, 12000000,  80, 2},
	{ 9600000,  1, 0x02, 0x50, 0x000000, 0x01, 0x10, 12288000,  82, 2},
	{ 11289600, 0, 0, 0, 0, 0, 0, 11289600, 0, 1},
	{ 12000000, 0, 0, 0, 0, 0, 0, 12000000, 0, 1},
	{ 12288000, 0, 0, 0, 0, 0, 0, 12288000, 0, 1},
	{ 19200000, 1, 0x03, 0x50, 0x000000, 0x03, 0x10, 12000000,  80, 2},
	{ 19200000, 1, 0x03, 0x50, 0x000000, 0x01, 0x10, 12288000,  82, 2},
	{ 22579200, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 11289600, 128, 1},
	{ 24000000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12000000, 128, 1},
	{ 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1}
};

int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk,
		       unsigned int sample_rate)
{
	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component);
	int i;

	/* Don't reconfigure if there is an audio stream running */
	if (cs42l42->stream_use) {
		if (pll_ratio_table[cs42l42->pll_config].sclk == clk)
			return 0;
		else
			return -EBUSY;
	}

	for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {
		/* MCLKint must be a multiple of the sample rate */
		if (pll_ratio_table[i].mclk_int % sample_rate)
			continue;

		if (pll_ratio_table[i].sclk == clk) {
			cs42l42->pll_config = i;

			/* Configure the internal sample rate */
			snd_soc_component_update_bits(component, CS42L42_MCLK_CTL,
					CS42L42_INTERNAL_FS_MASK,
					((pll_ratio_table[i].mclk_int !=
					12000000) &&
					(pll_ratio_table[i].mclk_int !=
					24000000)) <<
					CS42L42_INTERNAL_FS_SHIFT);
			if (pll_ratio_table[i].mclk_src_sel == 0) {
				/* Pass the clock straight through */
				snd_soc_component_update_bits(component,
					CS42L42_PLL_CTL1,
					CS42L42_PLL_START_MASK,	0);
			} else {
				/* Configure PLL per table 4-5 */
				snd_soc_component_update_bits(component,
					CS42L42_PLL_DIV_CFG1,
					CS42L42_SCLK_PREDIV_MASK,
					pll_ratio_table[i].sclk_prediv
					<< CS42L42_SCLK_PREDIV_SHIFT);
				snd_soc_component_update_bits(component,
					CS42L42_PLL_DIV_INT,
					CS42L42_PLL_DIV_INT_MASK,

Annotation

Implementation Notes