sound/soc/codecs/cs35l56-shared.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/cs35l56-shared.c
Extension
.c
Size
55438 bytes
Lines
1940
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 cs35l56_pte {
	u8 x;
	u8 wafer_id;
	u8 pte[2];
	u8 lot[3];
	u8 y;
	u8 unused[3];
	u8 dvs;
} __packed;
static_assert((sizeof(struct cs35l56_pte) % sizeof(u32)) == 0);

static int cs35l56_read_silicon_uid(struct cs35l56_base *cs35l56_base)
{
	struct cs35l56_pte pte;
	u64 unique_id;
	int ret;

	ret = regmap_raw_read(cs35l56_base->regmap, CS35L56_OTP_MEM_53, &pte, sizeof(pte));
	if (ret) {
		dev_err(cs35l56_base->dev, "Failed to read OTP: %d\n", ret);
		return ret;
	}

	unique_id = (u32)pte.lot[2] | ((u32)pte.lot[1] << 8) | ((u32)pte.lot[0] << 16);
	unique_id <<= 32;
	unique_id |= (u32)pte.x | ((u32)pte.y << 8) | ((u32)pte.wafer_id << 16) |
		     ((u32)pte.dvs << 24);

	cs35l56_base->silicon_uid = unique_id;

	return 0;
}

static int cs35l63_read_silicon_uid(struct cs35l56_base *cs35l56_base)
{
	u32 tmp[2];
	u64 unique_id;
	int ret;

	ret = regmap_bulk_read(cs35l56_base->regmap, CS35L56_DIE_STS1, tmp, ARRAY_SIZE(tmp));
	if (ret) {
		dev_err(cs35l56_base->dev, "Cannot obtain CS35L56_DIE_STS: %d\n", ret);
		return ret;
	}

	unique_id = tmp[1];
	unique_id <<= 32;
	unique_id |= tmp[0];

	cs35l56_base->silicon_uid = unique_id;

	return 0;
}

/* Firmware calibration controls */
const struct cirrus_amp_cal_controls cs35l56_calibration_controls = {
	.alg_id =	0x9f210,
	.mem_region =	WMFW_ADSP2_YM,
	.ambient =	"CAL_AMBIENT",
	.calr =		"CAL_R",
	.status =	"CAL_STATUS",
	.checksum =	"CAL_CHECKSUM",
};
EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls, "SND_SOC_CS35L56_SHARED");

static const struct cirrus_amp_cal_controls cs35l63_calibration_controls = {
	.alg_id =	0xbf210,
	.mem_region =	WMFW_ADSP2_YM,
	.ambient =	"CAL_AMBIENT",
	.calr =		"CAL_R",
	.status =	"CAL_STATUS",
	.checksum =	"CAL_CHECKSUM",
};

int cs35l56_get_calibration(struct cs35l56_base *cs35l56_base)
{
	int ret;

	/* Driver can't apply calibration to a secured part, so skip */
	if (cs35l56_base->secured)
		return 0;

	ret = cs_amp_get_efi_calibration_data(cs35l56_base->dev,
					      cs35l56_base->silicon_uid,
					      cs35l56_base->cal_index,
					      &cs35l56_base->cal_data);

	/* Only return an error status if probe should be aborted */
	if ((ret == -ENOENT) || (ret == -EOVERFLOW))
		return 0;

Annotation

Implementation Notes