drivers/comedi/drivers/das6402.c

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

File Facts

System
Linux kernel
Corpus path
drivers/comedi/drivers/das6402.c
Extension
.c
Size
17873 bytes
Lines
670
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 das6402_boardinfo {
	const char *name;
	unsigned int maxdata;
};

static struct das6402_boardinfo das6402_boards[] = {
	{
		.name		= "das6402-12",
		.maxdata	= 0x0fff,
	}, {
		.name		= "das6402-16",
		.maxdata	= 0xffff,
	},
};

struct das6402_private {
	unsigned int irq;
	unsigned int ao_range;
};

static void das6402_set_mode(struct comedi_device *dev,
			     unsigned int mode)
{
	outb(DAS6402_MODE_ENHANCED | mode, dev->iobase + DAS6402_MODE_REG);
}

static void das6402_set_extended(struct comedi_device *dev,
				 unsigned int val)
{
	outb(DAS6402_STATUS_W_EXTEND, dev->iobase + DAS6402_STATUS_REG);
	outb(DAS6402_STATUS_W_EXTEND | val, dev->iobase + DAS6402_STATUS_REG);
	outb(val, dev->iobase + DAS6402_STATUS_REG);
}

static void das6402_clear_all_interrupts(struct comedi_device *dev)
{
	outb(DAS6402_STATUS_W_CLRINT |
	     DAS6402_STATUS_W_CLRXTR |
	     DAS6402_STATUS_W_CLRXIN, dev->iobase + DAS6402_STATUS_REG);
}

static void das6402_ai_clear_eoc(struct comedi_device *dev)
{
	outb(DAS6402_STATUS_W_CLRINT, dev->iobase + DAS6402_STATUS_REG);
}

static unsigned int das6402_ai_read_sample(struct comedi_device *dev,
					   struct comedi_subdevice *s)
{
	unsigned int val;

	val = inw(dev->iobase + DAS6402_AI_DATA_REG);
	if (s->maxdata == 0x0fff)
		val >>= 4;
	return val;
}

static irqreturn_t das6402_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	struct comedi_subdevice *s = dev->read_subdev;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	unsigned int status;

	status = inb(dev->iobase + DAS6402_STATUS_REG);
	if ((status & DAS6402_STATUS_INT) == 0)
		return IRQ_NONE;

	if (status & DAS6402_STATUS_FFULL) {
		async->events |= COMEDI_CB_OVERFLOW;
	} else if (status & DAS6402_STATUS_FFNE) {
		unsigned short val;

		val = das6402_ai_read_sample(dev, s);
		comedi_buf_write_samples(s, &val, 1);

		if (cmd->stop_src == TRIG_COUNT &&
		    async->scans_done >= cmd->stop_arg)
			async->events |= COMEDI_CB_EOA;
	}

	das6402_clear_all_interrupts(dev);

	comedi_handle_events(dev, s);

	return IRQ_HANDLED;
}

static void das6402_ai_set_mode(struct comedi_device *dev,

Annotation

Implementation Notes