sound/soc/codecs/cs35l41-lib.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/cs35l41-lib.c
Extension
.c
Size
50464 bytes
Lines
1593
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

if (bit_offset + otp_map[i].size - 1 >= 32) {
			otp_val = (otp_mem[word_offset] &
					GENMASK(31, bit_offset)) >> bit_offset;
			otp_val |= (otp_mem[++word_offset] &
					GENMASK(bit_offset + otp_map[i].size - 33, 0)) <<
					(32 - bit_offset);
			bit_offset += otp_map[i].size - 32;
		} else if (bit_offset + otp_map[i].size - 1 >= 0) {
			otp_val = (otp_mem[word_offset] &
				   GENMASK(bit_offset + otp_map[i].size - 1, bit_offset)
				  ) >> bit_offset;
			bit_offset += otp_map[i].size;
		} else /* both bit_offset and otp_map[i].size are 0 */
			otp_val = 0;

		bit_sum += otp_map[i].size;

		if (bit_offset == 32) {
			bit_offset = 0;
			word_offset++;
		}

		if (otp_map[i].reg != 0) {
			ret = regmap_update_bits(regmap, otp_map[i].reg,
						 GENMASK(otp_map[i].shift + otp_map[i].size - 1,
							 otp_map[i].shift),
						 otp_val << otp_map[i].shift);
			if (ret < 0) {
				dev_err(dev, "Write OTP val failed: %d\n", ret);
				goto err_otp_unpack;
			}
		}
	}

	ret = 0;

err_otp_unpack:
	kfree(otp_mem);

	return ret;
}
EXPORT_SYMBOL_GPL(cs35l41_otp_unpack);

/* Must be called with the TEST_KEY unlocked */
int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsigned int reg_revid)
{
	char *rev;
	int ret;

	switch (reg_revid) {
	case CS35L41_REVID_A0:
		ret = regmap_register_patch(reg, cs35l41_reva0_errata_patch,
					    ARRAY_SIZE(cs35l41_reva0_errata_patch));
		rev = "A0";
		break;
	case CS35L41_REVID_B0:
		ret = regmap_register_patch(reg, cs35l41_revb0_errata_patch,
					    ARRAY_SIZE(cs35l41_revb0_errata_patch));
		rev = "B0";
		break;
	case CS35L41_REVID_B2:
		ret = regmap_register_patch(reg, cs35l41_revb2_errata_patch,
					    ARRAY_SIZE(cs35l41_revb2_errata_patch));
		rev = "B2";
		break;
	default:
		ret = -EINVAL;
		rev = "XX";
		break;
	}

	if (ret)
		dev_err(dev, "Failed to apply %s errata patch: %d\n", rev, ret);

	ret = regmap_write(reg, CS35L41_DSP1_CCM_CORE_CTRL, 0);
	if (ret < 0)
		dev_err(dev, "Write CCM_CORE_CTRL failed: %d\n", ret);

	return ret;
}
EXPORT_SYMBOL_GPL(cs35l41_register_errata_patch);

int cs35l41_set_channels(struct device *dev, struct regmap *reg,
			 unsigned int tx_num, const unsigned int *tx_slot,
			 unsigned int rx_num, const unsigned int *rx_slot)
{
	unsigned int val, mask;
	int i;

	if (tx_num > 4 || rx_num > 2)

Annotation

Implementation Notes