sound/soc/codecs/zl38060.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/zl38060.c
Extension
.c
Size
16150 bytes
Lines
640
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

struct zl38_codec_priv {
	struct device *dev;
	struct regmap *regmap;
	bool is_stream_in_use[2];
	struct gpio_chip *gpio_chip;
};

static int zl38_fw_issue_command(struct regmap *regmap, u16 cmd)
{
	unsigned int val;
	int err;

	err = regmap_read_poll_timeout(regmap, REG_SEMA_FLAGS, val,
				       !(val & SEMA_FLAGS_BOOT_CMD), 10000,
				       10000 * 100);
	if (err)
		return err;
	err = regmap_write(regmap, REG_CMD, cmd);
	if (err)
		return err;
	err = regmap_update_bits(regmap, REG_SEMA_FLAGS, SEMA_FLAGS_BOOT_CMD,
				 SEMA_FLAGS_BOOT_CMD);
	if (err)
		return err;

	return regmap_read_poll_timeout(regmap, REG_CMD, val, !val, 10000,
					10000 * 100);
}

static int zl38_fw_go(struct regmap *regmap)
{
	int err;

	err = zl38_fw_issue_command(regmap, BOOTCMD_LOAD_COMPLETE);
	if (err)
		return err;

	return zl38_fw_issue_command(regmap, BOOTCMD_FW_GO);
}

static int zl38_fw_enter_boot_mode(struct regmap *regmap)
{
	unsigned int val;
	int err;

	err = regmap_update_bits(regmap, REG_CLK_STATUS, CLK_STATUS_HWRST,
				 CLK_STATUS_HWRST);
	if (err)
		return err;

	return regmap_read_poll_timeout(regmap, REG_PARAM_RESULT, val,
					val == PARAM_RESULT_READY, 1000, 50000);
}

static int
zl38_fw_send_data(struct regmap *regmap, u32 addr, const void *data, u16 len)
{
	__be32 addr_base = cpu_to_be32(addr & ~0xFF);
	int err;

	err = regmap_raw_write(regmap, REG_PG255_BASE_HI, &addr_base,
			       sizeof(addr_base));
	if (err)
		return err;
	return regmap_raw_write(regmap, REG_PG255_OFFS(addr), data, len);
}

static int zl38_fw_send_xaddr(struct regmap *regmap, const void *data)
{
	/* execution address from ihex: 32-bit little endian.
	 * device register expects 32-bit big endian.
	 */
	u32 addr = le32_to_cpup(data);
	__be32 baddr = cpu_to_be32(addr);

	return regmap_raw_write(regmap, REG_FWR_EXEC, &baddr, sizeof(baddr));
}

static int zl38_load_firmware(struct device *dev, struct regmap *regmap)
{
	const struct ihex_binrec *rec;
	const struct firmware *fw;
	u32 addr;
	u16 len;
	int err;

	/* how to get this firmware:
	 * 1. request and download chip firmware from Microsemi
	 *    (provided by Microsemi in srec format)
	 * 2. convert downloaded firmware from srec to ihex. Simple tool:

Annotation

Implementation Notes