drivers/i2c/busses/i2c-robotfuzz-osif.c

Source file repositories/reference/linux-study-clean/drivers/i2c/busses/i2c-robotfuzz-osif.c

File Facts

System
Linux kernel
Corpus path
drivers/i2c/busses/i2c-robotfuzz-osif.c
Extension
.c
Size
5108 bytes
Lines
201
Domain
Driver Families
Bucket
drivers/i2c
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 osif_priv {
	struct usb_device *usb_dev;
	struct usb_interface *interface;
	struct i2c_adapter adapter;
	unsigned char status;
};

static int osif_usb_read(struct i2c_adapter *adapter, int cmd,
			 int value, int index, void *data, int len)
{
	struct osif_priv *priv = adapter->algo_data;

	return usb_control_msg(priv->usb_dev, usb_rcvctrlpipe(priv->usb_dev, 0),
			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE |
			       USB_DIR_IN, value, index, data, len, 2000);
}

static int osif_usb_write(struct i2c_adapter *adapter, int cmd,
			  int value, int index, void *data, int len)
{

	struct osif_priv *priv = adapter->algo_data;

	return usb_control_msg(priv->usb_dev, usb_sndctrlpipe(priv->usb_dev, 0),
			       cmd, USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
			       value, index, data, len, 2000);
}

static int osif_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
			 int num)
{
	struct osif_priv *priv = adapter->algo_data;
	struct i2c_msg *pmsg;
	int ret;
	int i;

	for (i = 0; i < num; i++) {
		pmsg = &msgs[i];

		if (pmsg->flags & I2C_M_RD) {
			ret = osif_usb_read(adapter, OSIFI2C_READ,
					    pmsg->flags, pmsg->addr,
					    pmsg->buf, pmsg->len);
			if (ret != pmsg->len) {
				dev_err(&adapter->dev, "failure reading data\n");
				return -EREMOTEIO;
			}
		} else {
			ret = osif_usb_write(adapter, OSIFI2C_WRITE,
					     pmsg->flags, pmsg->addr,
					     pmsg->buf, pmsg->len);
			if (ret != pmsg->len) {
				dev_err(&adapter->dev, "failure writing data\n");
				return -EREMOTEIO;
			}
		}

		ret = osif_usb_write(adapter, OSIFI2C_STOP, 0, 0, NULL, 0);
		if (ret) {
			dev_err(&adapter->dev, "failure sending STOP\n");
			return -EREMOTEIO;
		}

		/* read status */
		ret = osif_usb_read(adapter, OSIFI2C_STATUS, 0, 0,
				    &priv->status, 1);
		if (ret != 1) {
			dev_err(&adapter->dev, "failure reading status\n");
			return -EREMOTEIO;
		}

		if (priv->status != STATUS_ADDRESS_ACK) {
			dev_dbg(&adapter->dev, "status = %d\n", priv->status);
			return -EREMOTEIO;
		}
	}

	return i;
}

static u32 osif_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

/* prevent invalid 0-length usb_control_msg */
static const struct i2c_adapter_quirks osif_quirks = {
	.flags = I2C_AQ_NO_ZERO_LEN_READ,
};

Annotation

Implementation Notes