drivers/media/usb/dvb-usb-v2/zd1301.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/dvb-usb-v2/zd1301.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/dvb-usb-v2/zd1301.c
Extension
.c
Size
7091 bytes
Lines
290
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 zd1301_dev {
	#define BUF_LEN 8
	u8 buf[BUF_LEN]; /* bulk USB control message */
	struct zd1301_demod_platform_data demod_pdata;
	struct mt2060_platform_data mt2060_pdata;
	struct platform_device *platform_device_demod;
	struct i2c_client *i2c_client_tuner;
};

static int zd1301_ctrl_msg(struct dvb_usb_device *d, const u8 *wbuf,
			   unsigned int wlen, u8 *rbuf, unsigned int rlen)
{
	struct zd1301_dev *dev = d_to_priv(d);
	struct usb_interface *intf = d->intf;
	int ret, actual_length;

	mutex_lock(&d->usb_mutex);

	memcpy(&dev->buf, wbuf, wlen);

	dev_dbg(&intf->dev, ">>> %*ph\n", wlen, dev->buf);

	ret = usb_bulk_msg(d->udev, usb_sndbulkpipe(d->udev, 0x04), dev->buf,
			   wlen, &actual_length, 1000);
	if (ret) {
		dev_err(&intf->dev, "1st usb_bulk_msg() failed %d\n", ret);
		goto err_mutex_unlock;
	}

	if (rlen) {
		ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, 0x83),
				   dev->buf, rlen, &actual_length, 1000);
		if (ret) {
			dev_err(&intf->dev,
				"2nd usb_bulk_msg() failed %d\n", ret);
			goto err_mutex_unlock;
		}

		dev_dbg(&intf->dev, "<<< %*ph\n", actual_length, dev->buf);

		if (actual_length != rlen) {
			/*
			 * Chip replies often with 3 byte len stub. On that case
			 * we have to query new reply.
			 */
			dev_dbg(&intf->dev, "repeating reply message\n");

			ret = usb_bulk_msg(d->udev,
					   usb_rcvbulkpipe(d->udev, 0x83),
					   dev->buf, rlen, &actual_length,
					   1000);
			if (ret) {
				dev_err(&intf->dev,
					"3rd usb_bulk_msg() failed %d\n", ret);
				goto err_mutex_unlock;
			}

			dev_dbg(&intf->dev,
				"<<< %*ph\n", actual_length, dev->buf);
		}

		memcpy(rbuf, dev->buf, rlen);
	}

err_mutex_unlock:
	mutex_unlock(&d->usb_mutex);
	return ret;
}

static int zd1301_demod_wreg(void *reg_priv, u16 reg, u8 val)
{
	struct dvb_usb_device *d = reg_priv;
	struct usb_interface *intf = d->intf;
	int ret;
	u8 buf[7] = {0x07, 0x00, 0x03, 0x01,
		     (reg >> 0) & 0xff, (reg >> 8) & 0xff, val};

	ret = zd1301_ctrl_msg(d, buf, 7, NULL, 0);
	if (ret)
		goto err;

	return 0;
err:
	dev_dbg(&intf->dev, "failed=%d\n", ret);
	return ret;
}

static int zd1301_demod_rreg(void *reg_priv, u16 reg, u8 *val)
{
	struct dvb_usb_device *d = reg_priv;

Annotation

Implementation Notes