drivers/media/usb/msi2500/msi2500.c

Source file repositories/reference/linux-study-clean/drivers/media/usb/msi2500/msi2500.c

File Facts

System
Linux kernel
Corpus path
drivers/media/usb/msi2500/msi2500.c
Extension
.c
Size
36926 bytes
Lines
1325
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 msi2500_format {
	u32	pixelformat;
	u32	buffersize;
};

/* format descriptions for capture and preview */
static struct msi2500_format formats[] = {
	{
		.pixelformat	= V4L2_SDR_FMT_CS8,
		.buffersize	= 3 * 1008,
#if 0
	}, {
		.pixelformat	= MSI2500_PIX_FMT_SDR_MSI2500_384,
	}, {
		.pixelformat	= MSI2500_PIX_FMT_SDR_S12,
#endif
	}, {
		.pixelformat	= V4L2_SDR_FMT_CS14LE,
		.buffersize	= 3 * 1008,
	}, {
		.pixelformat	= V4L2_SDR_FMT_CU8,
		.buffersize	= 3 * 1008,
	}, {
		.pixelformat	=  V4L2_SDR_FMT_CU16LE,
		.buffersize	= 3 * 1008,
	},
};

static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);

/* intermediate buffers with raw data from the USB device */
struct msi2500_frame_buf {
	/* common v4l buffer stuff -- must be first */
	struct vb2_v4l2_buffer vb;
	struct list_head list;
};

struct msi2500_dev {
	struct device *dev;
	struct video_device vdev;
	struct v4l2_device v4l2_dev;
	struct v4l2_subdev *v4l2_subdev;
	struct spi_controller *ctlr;

	/* videobuf2 queue and queued buffers list */
	struct vb2_queue vb_queue;
	struct list_head queued_bufs;
	spinlock_t queued_bufs_lock; /* Protects queued_bufs */

	/* Note if taking both locks v4l2_lock must always be locked first! */
	struct mutex v4l2_lock;      /* Protects everything else */
	struct mutex vb_queue_lock;  /* Protects vb_queue and capt_file */

	/* Pointer to our usb_device, will be NULL after unplug */
	struct usb_device *udev; /* Both mutexes most be hold when setting! */

	unsigned int f_adc;
	u32 pixelformat;
	u32 buffersize;
	unsigned int num_formats;

	unsigned int isoc_errors; /* number of contiguous ISOC errors */
	unsigned int vb_full; /* vb is full and packets dropped */

	struct urb *urbs[MAX_ISO_BUFS];

	/* Controls */
	struct v4l2_ctrl_handler hdl;

	u32 next_sample; /* for track lost packets */
	u32 sample; /* for sample rate calc */
	unsigned long jiffies_next;
};

/* Private functions */
static struct msi2500_frame_buf *msi2500_get_next_fill_buf(
							struct msi2500_dev *dev)
{
	unsigned long flags;
	struct msi2500_frame_buf *buf = NULL;

	spin_lock_irqsave(&dev->queued_bufs_lock, flags);
	if (list_empty(&dev->queued_bufs))
		goto leave;

	buf = list_entry(dev->queued_bufs.next, struct msi2500_frame_buf, list);
	list_del(&buf->list);
leave:
	spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);
	return buf;

Annotation

Implementation Notes