drivers/media/pci/mgb4/mgb4_trigger.c

Source file repositories/reference/linux-study-clean/drivers/media/pci/mgb4/mgb4_trigger.c

File Facts

System
Linux kernel
Corpus path
drivers/media/pci/mgb4/mgb4_trigger.c
Extension
.c
Size
5423 bytes
Lines
210
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 trigger_data {
	struct mgb4_dev *mgbdev;
	struct iio_trigger *trig;
};

static int trigger_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int *val,
			    int *val2, long mask)
{
	struct trigger_data *st = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		if (iio_buffer_enabled(indio_dev))
			return -EBUSY;
		*val = mgb4_read_reg(&st->mgbdev->video, 0xA0);

		return IIO_VAL_INT;
	}

	return -EINVAL;
}

static int trigger_set_state(struct iio_trigger *trig, bool state)
{
	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
	struct trigger_data *st = iio_priv(indio_dev);
	int irq = xdma_get_user_irq(st->mgbdev->xdev, 11);

	if (state)
		xdma_enable_user_irq(st->mgbdev->xdev, irq);
	else
		xdma_disable_user_irq(st->mgbdev->xdev, irq);

	return 0;
}

static const struct iio_trigger_ops trigger_ops = {
	.set_trigger_state = &trigger_set_state,
};

static const struct iio_info trigger_info = {
	.read_raw         = trigger_read_raw,
};

#define TRIGGER_CHANNEL(_si) {                    \
	.type = IIO_ACTIVITY,                         \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
	.scan_index = _si,                            \
	.scan_type = {                                \
		.sign = 'u',                              \
		.realbits = 32,                           \
		.storagebits = 32,                        \
		.shift = 0,                               \
		.endianness = IIO_CPU                     \
	},                                            \
}

static const struct iio_chan_spec trigger_channels[] = {
	TRIGGER_CHANNEL(0),
	IIO_CHAN_SOFT_TIMESTAMP(1),
};

static irqreturn_t trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct trigger_data *st = iio_priv(indio_dev);
	struct {
		u32 data;
		aligned_s64 ts;
	} scan = { };

	scan.data = mgb4_read_reg(&st->mgbdev->video, 0xA0);
	mgb4_write_reg(&st->mgbdev->video, 0xA0, scan.data);

	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan), pf->timestamp);
	iio_trigger_notify_done(indio_dev->trig);

	mgb4_write_reg(&st->mgbdev->video, 0xB4, 1U << 11);

	return IRQ_HANDLED;
}

static int probe_trigger(struct iio_dev *indio_dev, int irq)
{
	int ret;
	struct trigger_data *st = iio_priv(indio_dev);

	st->trig = iio_trigger_alloc(&st->mgbdev->pdev->dev, "%s-dev%d",

Annotation

Implementation Notes