drivers/media/i2c/adv748x/adv748x-core.c

Source file repositories/reference/linux-study-clean/drivers/media/i2c/adv748x/adv748x-core.c

File Facts

System
Linux kernel
Corpus path
drivers/media/i2c/adv748x/adv748x-core.c
Extension
.c
Size
23053 bytes
Lines
859
Domain
Driver Families
Bucket
drivers/media
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 adv748x_register_map {
	const char *name;
	u8 default_addr;
};

static const struct adv748x_register_map adv748x_default_addresses[] = {
	[ADV748X_PAGE_IO] = { "main", 0x70 },
	[ADV748X_PAGE_DPLL] = { "dpll", 0x26 },
	[ADV748X_PAGE_CP] = { "cp", 0x22 },
	[ADV748X_PAGE_HDMI] = { "hdmi", 0x34 },
	[ADV748X_PAGE_EDID] = { "edid", 0x36 },
	[ADV748X_PAGE_REPEATER] = { "repeater", 0x32 },
	[ADV748X_PAGE_INFOFRAME] = { "infoframe", 0x31 },
	[ADV748X_PAGE_CBUS] = { "cbus", 0x30 },
	[ADV748X_PAGE_CEC] = { "cec", 0x41 },
	[ADV748X_PAGE_SDP] = { "sdp", 0x79 },
	[ADV748X_PAGE_TXB] = { "txb", 0x48 },
	[ADV748X_PAGE_TXA] = { "txa", 0x4a },
};

static int adv748x_read_check(struct adv748x_state *state,
			      int client_page, u8 reg)
{
	struct i2c_client *client = state->i2c_clients[client_page];
	int err;
	unsigned int val;

	err = regmap_read(state->regmap[client_page], reg, &val);

	if (err) {
		adv_err(state, "error reading %02x, %02x\n",
				client->addr, reg);
		return err;
	}

	return val;
}

int adv748x_read(struct adv748x_state *state, u8 page, u8 reg)
{
	return adv748x_read_check(state, page, reg);
}

int adv748x_write(struct adv748x_state *state, u8 page, u8 reg, u8 value)
{
	return regmap_write(state->regmap[page], reg, value);
}

static int adv748x_write_check(struct adv748x_state *state, u8 page, u8 reg,
			       u8 value, int *error)
{
	if (*error)
		return *error;

	*error = adv748x_write(state, page, reg, value);
	return *error;
}

/* adv748x_write_block(): Write raw data with a maximum of I2C_SMBUS_BLOCK_MAX
 * size to one or more registers.
 *
 * A value of zero will be returned on success, a negative errno will
 * be returned in error cases.
 */
int adv748x_write_block(struct adv748x_state *state, int client_page,
			unsigned int init_reg, const void *val,
			size_t val_len)
{
	struct regmap *regmap = state->regmap[client_page];

	if (val_len > I2C_SMBUS_BLOCK_MAX)
		val_len = I2C_SMBUS_BLOCK_MAX;

	return regmap_raw_write(regmap, init_reg, val, val_len);
}

static int adv748x_set_slave_addresses(struct adv748x_state *state)
{
	struct i2c_client *client;
	unsigned int i;
	u8 io_reg;

	for (i = ADV748X_PAGE_DPLL; i < ADV748X_PAGE_MAX; ++i) {
		io_reg = ADV748X_IO_SLAVE_ADDR_BASE + i;
		client = state->i2c_clients[i];

		io_write(state, io_reg, client->addr << 1);
	}

	return 0;

Annotation

Implementation Notes