sound/soc/codecs/nau8540.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/nau8540.c
Extension
.c
Size
30864 bytes
Lines
994
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 (!val) {
			regmap_update_bits(regmap, NAU8540_REG_MUTE,
					   NAU8540_PGA_CH_ALL_MUTE, NAU8540_PGA_CH_ALL_MUTE);
			regmap_update_bits(regmap, NAU8540_REG_MUTE,
					   NAU8540_PGA_CH_ALL_MUTE, 0);
			regmap_write(regmap, NAU8540_REG_RST, 0x1);
			regmap_write(regmap, NAU8540_REG_RST, 0);
			regmap_read(regmap, NAU8540_REG_PEAK_CH1, &val);
			dev_dbg(nau8540->dev, "2.ADC CH1 peak data %x", val);
			if (!val) {
				dev_err(nau8540->dev, "Channel recovery failed!!");
				ret = -EIO;
			}
		}
		regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL,
				   NAU8540_CLK_AGC_EN, 0);
		regmap_update_bits(regmap, NAU8540_REG_ALC_CONTROL_3,
				   NAU8540_ALC_CH_ALL_EN, 0);
		break;

	default:
		break;
	}

	return ret;
}

static const struct snd_soc_dai_ops nau8540_dai_ops = {
	.startup = nau8540_dai_startup,
	.hw_params = nau8540_hw_params,
	.set_fmt = nau8540_set_fmt,
	.set_tdm_slot = nau8540_set_tdm_slot,
	.trigger = nau8540_dai_trigger,
};

#define NAU8540_RATES SNDRV_PCM_RATE_8000_48000
#define NAU8540_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \
	 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)

static struct snd_soc_dai_driver nau8540_dai = {
	.name = "nau8540-hifi",
	.capture = {
		.stream_name = "Capture",
		.channels_min = 1,
		.channels_max = 4,
		.rates = NAU8540_RATES,
		.formats = NAU8540_FORMATS,
	},
	.ops = &nau8540_dai_ops,
};

/**
 * nau8540_calc_fll_param - Calculate FLL parameters.
 * @fll_in: external clock provided to codec.
 * @fs: sampling rate.
 * @fll_param: Pointer to structure of FLL parameters.
 *
 * Calculate FLL parameters to configure codec.
 *
 * Returns 0 for success or negative error code.
 */
static int nau8540_calc_fll_param(unsigned int fll_in,
	unsigned int fs, struct nau8540_fll *fll_param)
{
	u64 fvco, fvco_max;
	unsigned int fref, i, fvco_sel;

	/* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing
	 * freq_in by 1, 2, 4, or 8 using FLL pre-scalar.
	 * FREF = freq_in / NAU8540_FLL_REF_DIV_MASK
	 */
	for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) {
		fref = fll_in / fll_pre_scalar[i].param;
		if (fref <= NAU_FREF_MAX)
			break;
	}
	if (i == ARRAY_SIZE(fll_pre_scalar))
		return -EINVAL;
	fll_param->clk_ref_div = fll_pre_scalar[i].val;

	/* Choose the FLL ratio based on FREF */
	for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) {
		if (fref >= fll_ratio[i].param)
			break;
	}
	if (i == ARRAY_SIZE(fll_ratio))
		return -EINVAL;
	fll_param->ratio = fll_ratio[i].val;

	/* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs.

Annotation

Implementation Notes