sound/hda/codecs/side-codecs/tas2781_hda_spi.c

Source file repositories/reference/linux-study-clean/sound/hda/codecs/side-codecs/tas2781_hda_spi.c

File Facts

System
Linux kernel
Corpus path
sound/hda/codecs/side-codecs/tas2781_hda_spi.c
Extension
.c
Size
25828 bytes
Lines
960
Domain
Driver Families
Bucket
sound/hda
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 tas2781_hda_spi_priv {
	struct snd_kcontrol *snd_ctls[3];
};

static const struct regmap_range_cfg tasdevice_ranges[] = {
	{
		.range_min = 0,
		.range_max = TASDEVICE_RANGE_MAX_SIZE,
		.selector_reg = TASDEVICE_PAGE_SELECT,
		.selector_mask = GENMASK(7, 0),
		.selector_shift = 0,
		.window_start = 0,
		.window_len = TASDEVICE_WIN_LEN,
	},
};

static const struct regmap_config tasdevice_regmap = {
	.reg_bits = 8,
	.val_bits = 8,
	.zero_flag_mask = true,
	.read_flag_mask = 0x01,
	.reg_shift = -1,
	.cache_type = REGCACHE_NONE,
	.ranges = tasdevice_ranges,
	.num_ranges = ARRAY_SIZE(tasdevice_ranges),
	.max_register = TASDEVICE_RANGE_MAX_SIZE,
};

static int tasdevice_spi_dev_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned int *val)
{
	int ret;

	/*
	 * In our TAS2781 SPI mode, if read from other book (not book 0),
	 * or read from page number larger than 1 in book 0, one more byte
	 * read is needed, and first byte is a dummy byte, need to be ignored.
	 */
	if ((TASDEVICE_BOOK_ID(reg) > 0) || (TASDEVICE_PAGE_ID(reg) > 1)) {
		unsigned char data[2];

		ret = tasdevice_dev_bulk_read(tas_priv, chn, reg,
			data, sizeof(data));
		*val = data[1];
	} else {
		ret = tasdevice_dev_read(tas_priv, chn, reg, val);
	}
	if (ret < 0)
		dev_err(tas_priv->dev, "%s, E=%d\n", __func__, ret);

	return ret;
}

static int tasdevice_spi_dev_bulk_read(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned char *data,
	unsigned int len)
{
	int ret;

	/*
	 * In our TAS2781 SPI mode, if read from other book (not book 0),
	 * or read from page number larger than 1 in book 0, one more byte
	 * read is needed, and first byte is a dummy byte, need to be ignored.
	 */
	if ((TASDEVICE_BOOK_ID(reg) > 0) || (TASDEVICE_PAGE_ID(reg) > 1)) {
		unsigned char buf[TASDEVICE_WIN_LEN + 1];

		ret = tasdevice_dev_bulk_read(tas_priv, chn, reg,
			buf, len + 1);
		memcpy(data, buf + 1, len);
	} else {
		ret = tasdevice_dev_bulk_read(tas_priv, chn, reg, data, len);
	}
	if (ret < 0)
		dev_err(tas_priv->dev, "%s, E=%d\n", __func__, ret);

	return ret;
}

static int tasdevice_spi_dev_update_bits(struct tasdevice_priv *tas_priv,
	unsigned short chn, unsigned int reg, unsigned int mask,
	unsigned int value)
{
	int ret, val;

	/*
	 * In TAS2781 SPI mode, when accessing non-book-zero or page numbers
	 * greater than 1 in book 0, an additional byte must be read. The
	 * first byte in such cases is a dummy byte and should be ignored.
	 */

Annotation

Implementation Notes