sound/soc/codecs/nau8325.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/nau8325.c
Extension
.c
Size
26377 bytes
Lines
907
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_256] == mclk_src) {
			ratio = NAU8325_MCLK_FS_RATIO_256;
			break;
		} else if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_400] == mclk_src) {
			ratio = NAU8325_MCLK_FS_RATIO_400;
			break;
		} else if (srate_table->mclk_src[NAU8325_MCLK_FS_RATIO_500] == mclk_src) {
			ratio = NAU8325_MCLK_FS_RATIO_500;
			break;
		}
	}
	if (ratio != NAU8325_MCLK_FS_RATIO_NUM)
		*n2_sel = i;

	return ratio;
}

static const struct nau8325_srate_attr *target_srate_attribute(int srate)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(target_srate_table); i++)
		if (target_srate_table[i].fs == srate)
			break;

	if (i == ARRAY_SIZE(target_srate_table))
		goto proc_err;

	return &target_srate_table[i];

proc_err:
	return NULL;
}

static int nau8325_clksrc_choose(struct nau8325 *nau8325,
				 const struct nau8325_srate_attr **srate_table,
				 int *n1_sel, int *mult_sel, int *n2_sel)
{
	int i, j, mclk, ratio;
	int mclk_max = 0, ratio_sel = 0, n2_max = 0;

	if (!nau8325->mclk || !nau8325->fs)
		goto proc_err;

	/* select sampling rate and MCLK_SRC */
	*srate_table = target_srate_attribute(nau8325->fs);
	if (!*srate_table)
		goto proc_err;

	/* First check clock from MCLK directly, decide N2 for MCLK_SRC.
	 * If not good, consider 1/N1 and Multiplier.
	 */
	ratio = nau8325_clksrc_n2(nau8325, *srate_table, nau8325->mclk, n2_sel);
	if (ratio != NAU8325_MCLK_FS_RATIO_NUM) {
		*n1_sel = 0;
		*mult_sel = CLK_PROC_BYPASS;
		*n2_sel = MCLK_SRC;
		goto proc_done;
	}

	/* Get MCLK_SRC through 1/N, Multiplier, and then 1/N2. */
	for (i = 0; i < ARRAY_SIZE(mclk_n1_div); i++) {
		for (j = 0; j < ARRAY_SIZE(mclk_n3_mult); j++) {
			mclk = nau8325->mclk << mclk_n3_mult[j].param;
			mclk = mclk / mclk_n1_div[i].param;
			ratio = nau8325_clksrc_n2(nau8325,
						  *srate_table, mclk, n2_sel);
			if (ratio != NAU8325_MCLK_FS_RATIO_NUM &&
			    (mclk_max < mclk || i > *n1_sel)) {
				mclk_max = mclk;
				n2_max = *n2_sel;
				*n1_sel = i;
				*mult_sel = j;
				ratio_sel = ratio;
				goto proc_done;
			}
		}
	}
	if (mclk_max) {
		*n2_sel = n2_max;
		ratio = ratio_sel;
		goto proc_done;
	}

proc_err:
	dev_dbg(nau8325->dev, "The MCLK %d is invalid. It can't get MCLK_SRC of 256/400/500 FS (%d)",
		nau8325->mclk, nau8325->fs);
	return -EINVAL;
proc_done:
	dev_dbg(nau8325->dev, "nau8325->fs=%d,range=0x%x, %s, (n1,mu,n2,dmu):(%d,%d,%d), MCLK_SRC=%uHz (%d)",

Annotation

Implementation Notes