drivers/media/dvb-frontends/horus3a.c

Source file repositories/reference/linux-study-clean/drivers/media/dvb-frontends/horus3a.c

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/horus3a.c
Extension
.c
Size
9901 bytes
Lines
403
Domain
Driver Families
Bucket
drivers/media
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

struct horus3a_priv {
	u32			frequency;
	u8			i2c_address;
	struct i2c_adapter	*i2c;
	enum horus3a_state	state;
	void			*set_tuner_data;
	int			(*set_tuner)(void *, int);
};

static void horus3a_i2c_debug(struct horus3a_priv *priv,
			      u8 reg, u8 write, const u8 *data, u32 len)
{
	dev_dbg(&priv->i2c->dev, "horus3a: I2C %s reg 0x%02x size %d\n",
		(write == 0 ? "read" : "write"), reg, len);
	print_hex_dump_bytes("horus3a: I2C data: ",
		DUMP_PREFIX_OFFSET, data, len);
}

static int horus3a_write_regs(struct horus3a_priv *priv,
			      u8 reg, const u8 *data, u32 len)
{
	int ret;
	u8 buf[MAX_WRITE_REGSIZE + 1];
	struct i2c_msg msg[1] = {
		{
			.addr = priv->i2c_address,
			.flags = 0,
			.len = len + 1,
			.buf = buf,
		}
	};

	if (len + 1 > sizeof(buf)) {
		dev_warn(&priv->i2c->dev,"wr reg=%04x: len=%d is too big!\n",
			 reg, len + 1);
		return -E2BIG;
	}

	horus3a_i2c_debug(priv, reg, 1, data, len);
	buf[0] = reg;
	memcpy(&buf[1], data, len);
	ret = i2c_transfer(priv->i2c, msg, 1);
	if (ret >= 0 && ret != 1)
		ret = -EREMOTEIO;
	if (ret < 0) {
		dev_warn(&priv->i2c->dev,
			"%s: i2c wr failed=%d reg=%02x len=%d\n",
			KBUILD_MODNAME, ret, reg, len);
		return ret;
	}
	return 0;
}

static int horus3a_write_reg(struct horus3a_priv *priv, u8 reg, u8 val)
{
	u8 tmp = val; /* see gcc.gnu.org/bugzilla/show_bug.cgi?id=81715 */

	return horus3a_write_regs(priv, reg, &tmp, 1);
}

static int horus3a_enter_power_save(struct horus3a_priv *priv)
{
	u8 data[2];

	dev_dbg(&priv->i2c->dev, "%s()\n", __func__);
	if (priv->state == STATE_SLEEP)
		return 0;
	/* IQ Generator disable */
	horus3a_write_reg(priv, 0x2a, 0x79);
	/* MDIV_EN = 0 */
	horus3a_write_reg(priv, 0x29, 0x70);
	/* VCO disable preparation */
	horus3a_write_reg(priv, 0x28, 0x3e);
	/* VCO buffer disable */
	horus3a_write_reg(priv, 0x2a, 0x19);
	/* VCO calibration disable */
	horus3a_write_reg(priv, 0x1c, 0x00);
	/* Power save setting (xtal is not stopped) */
	data[0] = 0xC0;
	/* LNA is Disabled */
	data[1] = 0xA7;
	/* 0x11 - 0x12 */
	horus3a_write_regs(priv, 0x11, data, sizeof(data));
	priv->state = STATE_SLEEP;
	return 0;
}

static int horus3a_leave_power_save(struct horus3a_priv *priv)
{
	u8 data[2];

Annotation

Implementation Notes