sound/soc/codecs/tas571x.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/codecs/tas571x.c
Extension
.c
Size
32653 bytes
Lines
1092
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 tas571x_chip {
	const char			*const *supply_names;
	int				num_supply_names;
	const struct snd_kcontrol_new	*controls;
	int				num_controls;
	const struct regmap_config	*regmap_config;
	int				vol_reg_size;
};

struct tas571x_private {
	const struct tas571x_chip	*chip;
	struct regmap			*regmap;
	struct regulator_bulk_data	supplies[TAS571X_MAX_SUPPLIES];
	struct clk			*mclk;
	unsigned int			format;
	struct gpio_desc		*reset_gpio;
	struct gpio_desc		*pdn_gpio;
	struct snd_soc_component_driver	component_driver;
};

static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
{
	switch (reg) {
	case TAS571X_MVOL_REG:
	case TAS571X_CH1_VOL_REG:
	case TAS571X_CH2_VOL_REG:
		return priv->chip->vol_reg_size;
	case TAS571X_INPUT_MUX_REG:
	case TAS571X_CH4_SRC_SELECT_REG:
	case TAS571X_PWM_MUX_REG:
	case TAS5717_CH1_RIGHT_CH_MIX_REG:
	case TAS5717_CH1_LEFT_CH_MIX_REG:
	case TAS5717_CH2_LEFT_CH_MIX_REG:
	case TAS5717_CH2_RIGHT_CH_MIX_REG:
		return 4;
	default:
		return 1;
	}
}

static int tas571x_reg_write(void *context, unsigned int reg,
			     unsigned int value)
{
	struct i2c_client *client = context;
	struct tas571x_private *priv = i2c_get_clientdata(client);
	unsigned int i, size;
	uint8_t buf[5];
	int ret;

	size = tas571x_register_size(priv, reg);
	buf[0] = reg;

	for (i = size; i >= 1; --i) {
		buf[i] = value;
		value >>= 8;
	}

	ret = i2c_master_send(client, buf, size + 1);
	if (ret == size + 1)
		return 0;
	else if (ret < 0)
		return ret;
	else
		return -EIO;
}

static int tas571x_reg_read(void *context, unsigned int reg,
			    unsigned int *value)
{
	struct i2c_client *client = context;
	struct tas571x_private *priv = i2c_get_clientdata(client);
	uint8_t send_buf, recv_buf[4];
	struct i2c_msg msgs[2];
	unsigned int size;
	unsigned int i;
	int ret;

	size = tas571x_register_size(priv, reg);
	send_buf = reg;

	msgs[0].addr = client->addr;
	msgs[0].len = sizeof(send_buf);
	msgs[0].buf = &send_buf;
	msgs[0].flags = 0;

	msgs[1].addr = client->addr;
	msgs[1].len = size;
	msgs[1].buf = recv_buf;
	msgs[1].flags = I2C_M_RD;

Annotation

Implementation Notes