drivers/comedi/drivers/dt9812.c

Source file repositories/reference/linux-study-clean/drivers/comedi/drivers/dt9812.c

File Facts

System
Linux kernel
Corpus path
drivers/comedi/drivers/dt9812.c
Extension
.c
Size
22671 bytes
Lines
928
Domain
Driver Families
Bucket
drivers/comedi
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 dt9812_flash_data {
	__le16 numbytes;
	__le16 address;
};

#define DT9812_MAX_NUM_MULTI_BYTE_RDS  \
	((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / sizeof(u8))

struct dt9812_read_multi {
	u8 count;
	u8 address[DT9812_MAX_NUM_MULTI_BYTE_RDS];
};

struct dt9812_write_byte {
	u8 address;
	u8 value;
};

#define DT9812_MAX_NUM_MULTI_BYTE_WRTS  \
	((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
	 sizeof(struct dt9812_write_byte))

struct dt9812_write_multi {
	u8 count;
	struct dt9812_write_byte write[DT9812_MAX_NUM_MULTI_BYTE_WRTS];
};

struct dt9812_rmw_byte {
	u8 address;
	u8 and_mask;
	u8 or_value;
};

#define DT9812_MAX_NUM_MULTI_BYTE_RMWS  \
	((DT9812_MAX_WRITE_CMD_PIPE_SIZE - 4 - 1) / \
	 sizeof(struct dt9812_rmw_byte))

struct dt9812_rmw_multi {
	u8 count;
	struct dt9812_rmw_byte rmw[DT9812_MAX_NUM_MULTI_BYTE_RMWS];
};

struct dt9812_usb_cmd {
	__le32 cmd;
	union {
		struct dt9812_flash_data flash_data_info;
		struct dt9812_read_multi read_multi_info;
		struct dt9812_write_multi write_multi_info;
		struct dt9812_rmw_multi rmw_multi_info;
	} u;
};

struct dt9812_private {
	struct mutex mut;
	struct {
		__u8 addr;
		size_t size;
	} cmd_wr, cmd_rd;
	u16 device;
};

static int dt9812_read_info(struct comedi_device *dev,
			    int offset, void *buf, size_t buf_size)
{
	struct usb_device *usb = comedi_to_usb_dev(dev);
	struct dt9812_private *devpriv = dev->private;
	struct dt9812_usb_cmd *cmd;
	size_t tbuf_size;
	int count, ret;
	void *tbuf;

	tbuf_size = max(sizeof(*cmd), buf_size);

	tbuf = kzalloc(tbuf_size, GFP_KERNEL);
	if (!tbuf)
		return -ENOMEM;

	cmd = tbuf;

	cmd->cmd = cpu_to_le32(DT9812_R_FLASH_DATA);
	cmd->u.flash_data_info.address =
	    cpu_to_le16(DT9812_DIAGS_BOARD_INFO_ADDR + offset);
	cmd->u.flash_data_info.numbytes = cpu_to_le16(buf_size);

	/* DT9812 only responds to 32 byte writes!! */
	ret = usb_bulk_msg(usb, usb_sndbulkpipe(usb, devpriv->cmd_wr.addr),
			   cmd, sizeof(*cmd), &count, DT9812_USB_TIMEOUT);
	if (ret)
		goto out;

Annotation

Implementation Notes