drivers/comedi/drivers/vmk80xx.c

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

File Facts

System
Linux kernel
Corpus path
drivers/comedi/drivers/vmk80xx.c
Extension
.c
Size
20292 bytes
Lines
871
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 vmk80xx_board {
	const char *name;
	enum vmk80xx_model model;
	const struct comedi_lrange *range;
	int ai_nchans;
	unsigned int ai_maxdata;
	int ao_nchans;
	int di_nchans;
	unsigned int cnt_maxdata;
	int pwm_nchans;
	unsigned int pwm_maxdata;
};

static const struct vmk80xx_board vmk80xx_boardinfo[] = {
	[DEVICE_VMK8055] = {
		.name		= "K8055 (VM110)",
		.model		= VMK8055_MODEL,
		.range		= &range_unipolar5,
		.ai_nchans	= 2,
		.ai_maxdata	= 0x00ff,
		.ao_nchans	= 2,
		.di_nchans	= 6,
		.cnt_maxdata	= 0xffff,
	},
	[DEVICE_VMK8061] = {
		.name		= "K8061 (VM140)",
		.model		= VMK8061_MODEL,
		.range		= &vmk8061_range,
		.ai_nchans	= 8,
		.ai_maxdata	= 0x03ff,
		.ao_nchans	= 8,
		.di_nchans	= 8,
		.cnt_maxdata	= 0,	/* unknown, device is not writeable */
		.pwm_nchans	= 1,
		.pwm_maxdata	= 0x03ff,
	},
};

struct vmk80xx_private {
	struct usb_endpoint_descriptor *ep_rx;
	struct usb_endpoint_descriptor *ep_tx;
	struct semaphore limit_sem;
	unsigned char *usb_rx_buf;
	unsigned char *usb_tx_buf;
	enum vmk80xx_model model;
};

static void vmk80xx_do_bulk_msg(struct comedi_device *dev)
{
	struct vmk80xx_private *devpriv = dev->private;
	struct usb_device *usb = comedi_to_usb_dev(dev);
	__u8 tx_addr;
	__u8 rx_addr;
	unsigned int tx_pipe;
	unsigned int rx_pipe;
	size_t tx_size;
	size_t rx_size;

	tx_addr = devpriv->ep_tx->bEndpointAddress;
	rx_addr = devpriv->ep_rx->bEndpointAddress;
	tx_pipe = usb_sndbulkpipe(usb, tx_addr);
	rx_pipe = usb_rcvbulkpipe(usb, rx_addr);
	tx_size = usb_endpoint_maxp(devpriv->ep_tx);
	rx_size = usb_endpoint_maxp(devpriv->ep_rx);

	usb_bulk_msg(usb, tx_pipe, devpriv->usb_tx_buf, tx_size, NULL,
		     PACKET_TIMEOUT);

	usb_bulk_msg(usb, rx_pipe, devpriv->usb_rx_buf, rx_size, NULL,
		     PACKET_TIMEOUT);
}

static int vmk80xx_read_packet(struct comedi_device *dev)
{
	struct vmk80xx_private *devpriv = dev->private;
	struct usb_device *usb = comedi_to_usb_dev(dev);
	struct usb_endpoint_descriptor *ep;
	unsigned int pipe;

	if (devpriv->model == VMK8061_MODEL) {
		vmk80xx_do_bulk_msg(dev);
		return 0;
	}

	ep = devpriv->ep_rx;
	pipe = usb_rcvintpipe(usb, ep->bEndpointAddress);
	return usb_interrupt_msg(usb, pipe, devpriv->usb_rx_buf,
				 usb_endpoint_maxp(ep), NULL,
				 PACKET_TIMEOUT);
}

Annotation

Implementation Notes