// SPDX-License-Identifier: GPL-2.0-or-later /* * Mirics MSi2500 driver * Mirics MSi3101 SDR Dongle driver * * Copyright (C) 2013 Antti Palosaari <[email protected]> * * That driver is somehow based of pwc driver: * (C) 1999-2004 Nemosoft Unv. * (C) 2004-2006 Luc Saillard ([email protected]) * (C) 2011 Hans de Goede <[email protected]> */ #include <linux/module.h> #include <linux/slab.h> #include <asm/div64.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-event.h> #include <linux/usb.h> #include <media/videobuf2-v4l2.h> #include <media/videobuf2-vmalloc.h> #include <linux/spi/spi.h> static bool msi2500_emulated_fmt; module_param_named(emulated_formats, msi2500_emulated_fmt, bool, 0644); MODULE_PARM_DESC(…) …; /* * iConfiguration 0 * bInterfaceNumber 0 * bAlternateSetting 1 * bNumEndpoints 1 * bEndpointAddress 0x81 EP 1 IN * bmAttributes 1 * Transfer Type Isochronous * wMaxPacketSize 0x1400 3x 1024 bytes * bInterval 1 */ #define MAX_ISO_BUFS … #define ISO_FRAMES_PER_DESC … #define ISO_MAX_FRAME_SIZE … #define ISO_BUFFER_SIZE … #define MAX_ISOC_ERRORS … /* * TODO: These formats should be moved to V4L2 API. Formats are currently * disabled from formats[] table, not visible to userspace. */ /* signed 12-bit */ #define MSI2500_PIX_FMT_SDR_S12 … /* Mirics MSi2500 format 384 */ #define MSI2500_PIX_FMT_SDR_MSI2500_384 … static const struct v4l2_frequency_band bands[] = …; /* stream formats */ struct msi2500_format { … }; /* format descriptions for capture and preview */ static struct msi2500_format formats[] = …; static const unsigned int NUM_FORMATS = …; /* intermediate buffers with raw data from the USB device */ struct msi2500_frame_buf { … }; struct msi2500_dev { … }; /* Private functions */ static struct msi2500_frame_buf *msi2500_get_next_fill_buf( struct msi2500_dev *dev) { … } /* * +=========================================================================== * | 00-1023 | USB packet type '504' * +=========================================================================== * | 00- 03 | sequence number of first sample in that USB packet * +--------------------------------------------------------------------------- * | 04- 15 | garbage * +--------------------------------------------------------------------------- * | 16-1023 | samples * +--------------------------------------------------------------------------- * signed 8-bit sample * 504 * 2 = 1008 samples * * * +=========================================================================== * | 00-1023 | USB packet type '384' * +=========================================================================== * | 00- 03 | sequence number of first sample in that USB packet * +--------------------------------------------------------------------------- * | 04- 15 | garbage * +--------------------------------------------------------------------------- * | 16- 175 | samples * +--------------------------------------------------------------------------- * | 176- 179 | control bits for previous samples * +--------------------------------------------------------------------------- * | 180- 339 | samples * +--------------------------------------------------------------------------- * | 340- 343 | control bits for previous samples * +--------------------------------------------------------------------------- * | 344- 503 | samples * +--------------------------------------------------------------------------- * | 504- 507 | control bits for previous samples * +--------------------------------------------------------------------------- * | 508- 667 | samples * +--------------------------------------------------------------------------- * | 668- 671 | control bits for previous samples * +--------------------------------------------------------------------------- * | 672- 831 | samples * +--------------------------------------------------------------------------- * | 832- 835 | control bits for previous samples * +--------------------------------------------------------------------------- * | 836- 995 | samples * +--------------------------------------------------------------------------- * | 996- 999 | control bits for previous samples * +--------------------------------------------------------------------------- * | 1000-1023 | garbage * +--------------------------------------------------------------------------- * * Bytes 4 - 7 could have some meaning? * * Control bits for previous samples is 32-bit field, containing 16 x 2-bit * numbers. This results one 2-bit number for 8 samples. It is likely used for * bit shifting sample by given bits, increasing actual sampling resolution. * Number 2 (0b10) was never seen. * * 6 * 16 * 2 * 4 = 768 samples. 768 * 4 = 3072 bytes * * * +=========================================================================== * | 00-1023 | USB packet type '336' * +=========================================================================== * | 00- 03 | sequence number of first sample in that USB packet * +--------------------------------------------------------------------------- * | 04- 15 | garbage * +--------------------------------------------------------------------------- * | 16-1023 | samples * +--------------------------------------------------------------------------- * signed 12-bit sample * * * +=========================================================================== * | 00-1023 | USB packet type '252' * +=========================================================================== * | 00- 03 | sequence number of first sample in that USB packet * +--------------------------------------------------------------------------- * | 04- 15 | garbage * +--------------------------------------------------------------------------- * | 16-1023 | samples * +--------------------------------------------------------------------------- * signed 14-bit sample */ static int msi2500_convert_stream(struct msi2500_dev *dev, u8 *dst, u8 *src, unsigned int src_len) { … } /* * This gets called for the Isochronous pipe (stream). This is done in interrupt * time, so it has to be fast, not crash, and not stall. Neat. */ static void msi2500_isoc_handler(struct urb *urb) { … } static void msi2500_iso_stop(struct msi2500_dev *dev) { … } static void msi2500_iso_free(struct msi2500_dev *dev) { … } /* Both v4l2_lock and vb_queue_lock should be locked when calling this */ static void msi2500_isoc_cleanup(struct msi2500_dev *dev) { … } /* Both v4l2_lock and vb_queue_lock should be locked when calling this */ static int msi2500_isoc_init(struct msi2500_dev *dev) { … } /* Must be called with vb_queue_lock hold */ static void msi2500_cleanup_queued_bufs(struct msi2500_dev *dev) { … } /* The user yanked out the cable... */ static void msi2500_disconnect(struct usb_interface *intf) { … } static int msi2500_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { … } /* Videobuf2 operations */ static int msi2500_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[]) { … } static void msi2500_buf_queue(struct vb2_buffer *vb) { … } #define CMD_WREG … #define CMD_START_STREAMING … #define CMD_STOP_STREAMING … #define CMD_READ_UNKNOWN … #define msi2500_dbg_usb_control_msg(_dev, _r, _t, _v, _i, _b, _l) … static int msi2500_ctrl_msg(struct msi2500_dev *dev, u8 cmd, u32 data) { … } static int msi2500_set_usb_adc(struct msi2500_dev *dev) { … } static int msi2500_start_streaming(struct vb2_queue *vq, unsigned int count) { … } static void msi2500_stop_streaming(struct vb2_queue *vq) { … } static const struct vb2_ops msi2500_vb2_ops = …; static int msi2500_enum_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { … } static int msi2500_g_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f) { … } static int msi2500_s_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f) { … } static int msi2500_try_fmt_sdr_cap(struct file *file, void *priv, struct v4l2_format *f) { … } static int msi2500_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *v) { … } static int msi2500_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) { … } static int msi2500_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { … } static int msi2500_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { … } static int msi2500_enum_freq_bands(struct file *file, void *priv, struct v4l2_frequency_band *band) { … } static const struct v4l2_ioctl_ops msi2500_ioctl_ops = …; static const struct v4l2_file_operations msi2500_fops = …; static const struct video_device msi2500_template = …; static void msi2500_video_release(struct v4l2_device *v) { … } static int msi2500_transfer_one_message(struct spi_controller *ctlr, struct spi_message *m) { … } static int msi2500_probe(struct usb_interface *intf, const struct usb_device_id *id) { … } /* USB device ID list */ static const struct usb_device_id msi2500_id_table[] = …; MODULE_DEVICE_TABLE(usb, msi2500_id_table); /* USB subsystem interface */ static struct usb_driver msi2500_driver = …; module_usb_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;