drivers/media/dvb-frontends/sp2.c

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

File Facts

System
Linux kernel
Corpus path
drivers/media/dvb-frontends/sp2.c
Extension
.c
Size
8932 bytes
Lines
429
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

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * CIMaX SP2/SP2HF (Atmel T90FJR) CI driver
 *
 * Copyright (C) 2014 Olli Salonen <olli.salonen@iki.fi>
 *
 * Heavily based on CIMax2(R) SP2 driver in conjunction with NetUp Dual
 * DVB-S2 CI card (cimax2) with following copyrights:
 *
 *  Copyright (C) 2009 NetUP Inc.
 *  Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
 *  Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
 */

#include "sp2_priv.h"

static int sp2_read_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
{
	int ret;
	struct i2c_client *client = s->client;
	struct i2c_adapter *adap = client->adapter;
	struct i2c_msg msg[] = {
		{
			.addr = client->addr,
			.flags = 0,
			.buf = &reg,
			.len = 1
		}, {
			.addr = client->addr,
			.flags	= I2C_M_RD,
			.buf = buf,
			.len = len
		}
	};

	ret = i2c_transfer(adap, msg, 2);

	if (ret != 2) {
		dev_err(&client->dev, "i2c read error, reg = 0x%02x, status = %d\n",
				reg, ret);
		if (ret < 0)
			return ret;
		else
			return -EIO;
	}

	dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %02x\n",
				client->addr, reg, buf[0]);

	return 0;
}

static int sp2_write_i2c(struct sp2 *s, u8 reg, u8 *buf, int len)
{
	int ret;
	u8 buffer[35];
	struct i2c_client *client = s->client;
	struct i2c_adapter *adap = client->adapter;
	struct i2c_msg msg = {
		.addr = client->addr,
		.flags = 0,
		.buf = &buffer[0],
		.len = len + 1
	};

	if ((len + 1) > sizeof(buffer)) {
		dev_err(&client->dev, "i2c wr reg=%02x: len=%d is too big!\n",
				reg, len);
		return -EINVAL;
	}

	buffer[0] = reg;
	memcpy(&buffer[1], buf, len);

	ret = i2c_transfer(adap, &msg, 1);

	if (ret != 1) {
		dev_err(&client->dev, "i2c write error, reg = 0x%02x, status = %d\n",
				reg, ret);
		if (ret < 0)
			return ret;
		else
			return -EIO;
	}

	dev_dbg(&s->client->dev, "addr=0x%04x, reg = 0x%02x, data = %*ph\n",
				client->addr, reg, len, buf);

	return 0;
}

Annotation

Implementation Notes