1142 lines · 29.1 KB · C
RawDownload
/* * HackRF driver * * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> * *    This program is free software; you can redistribute it and/or modify *    it under the terms of the GNU General Public License as published by *    the Free Software Foundation; either version 2 of the License, or *    (at your option) any later version. * *    This program is distributed in the hope that it will be useful, *    but WITHOUT ANY WARRANTY; without even the implied warranty of *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *    GNU General Public License for more details. */ #include <linux/module.h>#include <linux/slab.h>#include <linux/usb.h>#include <media/v4l2-device.h>#include <media/v4l2-ioctl.h>#include <media/v4l2-ctrls.h>#include <media/v4l2-event.h>#include <media/videobuf2-vmalloc.h> /* HackRF USB API commands (from HackRF Library) */enum {	CMD_SET_TRANSCEIVER_MODE           = 0x01,	CMD_SAMPLE_RATE_SET                = 0x06,	CMD_BASEBAND_FILTER_BANDWIDTH_SET  = 0x07,	CMD_BOARD_ID_READ                  = 0x0e,	CMD_VERSION_STRING_READ            = 0x0f,	CMD_SET_FREQ                       = 0x10,	CMD_SET_LNA_GAIN                   = 0x13,	CMD_SET_VGA_GAIN                   = 0x14,}; /* *       bEndpointAddress     0x81  EP 1 IN *         Transfer Type            Bulk *       wMaxPacketSize     0x0200  1x 512 bytes */#define MAX_BULK_BUFS            (6)#define BULK_BUFFER_SIZE         (128 * 512) static const struct v4l2_frequency_band bands_adc[] = {	{		.tuner = 0,		.type = V4L2_TUNER_ADC,		.index = 0,		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,		.rangelow   =   200000,		.rangehigh  = 24000000,	},}; static const struct v4l2_frequency_band bands_rf[] = {	{		.tuner = 1,		.type = V4L2_TUNER_RF,		.index = 0,		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,		.rangelow   =          1,		.rangehigh  = 4294967294LL, /* max u32, hw goes over 7GHz */	},}; /* stream formats */struct hackrf_format {	char	*name;	u32	pixelformat;	u32	buffersize;}; /* format descriptions for capture and preview */static struct hackrf_format formats[] = {	{		.name		= "Complex S8",		.pixelformat	= V4L2_SDR_FMT_CS8,		.buffersize	= BULK_BUFFER_SIZE,	},}; static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats); /* intermediate buffers with raw data from the USB device */struct hackrf_frame_buf {	struct vb2_buffer vb;   /* common v4l buffer stuff -- must be first */	struct list_head list;}; struct hackrf_dev {#define POWER_ON           (1 << 1)#define URB_BUF            (1 << 2)#define USB_STATE_URB_BUF  (1 << 3)	unsigned long flags; 	struct device *dev;	struct usb_device *udev;	struct video_device vdev;	struct v4l2_device v4l2_dev; 	/* videobuf2 queue and queued buffers list */	struct vb2_queue vb_queue;	struct list_head queued_bufs;	spinlock_t queued_bufs_lock; /* Protects queued_bufs */	unsigned sequence;	     /* Buffer sequence counter */	unsigned int vb_full;        /* vb is full and packets dropped */ 	/* 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 */ 	struct urb     *urb_list[MAX_BULK_BUFS];	int            buf_num;	unsigned long  buf_size;	u8             *buf_list[MAX_BULK_BUFS];	dma_addr_t     dma_addr[MAX_BULK_BUFS];	int            urbs_initialized;	int            urbs_submitted; 	/* USB control message buffer */	#define BUF_SIZE 24	u8 buf[BUF_SIZE]; 	/* Current configuration */	unsigned int f_adc;	unsigned int f_rf;	u32 pixelformat;	u32 buffersize; 	/* Controls */	struct v4l2_ctrl_handler hdl;	struct v4l2_ctrl *bandwidth_auto;	struct v4l2_ctrl *bandwidth;	struct v4l2_ctrl *lna_gain;	struct v4l2_ctrl *if_gain; 	/* Sample rate calc */	unsigned long jiffies_next;	unsigned int sample;	unsigned int sample_measured;}; #define hackrf_dbg_usb_control_msg(_dev, _r, _t, _v, _i, _b, _l) { \	char *_direction; \	if (_t & USB_DIR_IN) \		_direction = "<<<"; \	else \		_direction = ">>>"; \	dev_dbg(_dev, "%02x %02x %02x %02x %02x %02x %02x %02x %s %*ph\n", \			_t, _r, _v & 0xff, _v >> 8, _i & 0xff, \			_i >> 8, _l & 0xff, _l >> 8, _direction, _l, _b); \} /* execute firmware command */static int hackrf_ctrl_msg(struct hackrf_dev *dev, u8 request, u16 value,		u16 index, u8 *data, u16 size){	int ret;	unsigned int pipe;	u8 requesttype; 	switch (request) {	case CMD_SET_TRANSCEIVER_MODE:	case CMD_SET_FREQ:	case CMD_SAMPLE_RATE_SET:	case CMD_BASEBAND_FILTER_BANDWIDTH_SET:		pipe = usb_sndctrlpipe(dev->udev, 0);		requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);		break;	case CMD_BOARD_ID_READ:	case CMD_VERSION_STRING_READ:	case CMD_SET_LNA_GAIN:	case CMD_SET_VGA_GAIN:		pipe = usb_rcvctrlpipe(dev->udev, 0);		requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);		break;	default:		dev_err(dev->dev, "Unknown command %02x\n", request);		ret = -EINVAL;		goto err;	} 	/* write request */	if (!(requesttype & USB_DIR_IN))		memcpy(dev->buf, data, size); 	ret = usb_control_msg(dev->udev, pipe, request, requesttype, value,			index, dev->buf, size, 1000);	hackrf_dbg_usb_control_msg(dev->dev, request, requesttype, value,			index, dev->buf, size);	if (ret < 0) {		dev_err(dev->dev, "usb_control_msg() failed %d request %02x\n",				ret, request);		goto err;	} 	/* read request */	if (requesttype & USB_DIR_IN)		memcpy(data, dev->buf, size); 	return 0;err:	return ret;} /* Private functions */static struct hackrf_frame_buf *hackrf_get_next_fill_buf(struct hackrf_dev *dev){	unsigned long flags;	struct hackrf_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 hackrf_frame_buf, list);	list_del(&buf->list);leave:	spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);	return buf;} static unsigned int hackrf_convert_stream(struct hackrf_dev *dev,		void *dst, void *src, unsigned int src_len){	memcpy(dst, src, src_len); 	/* calculate sample rate and output it in 10 seconds intervals */	if (unlikely(time_is_before_jiffies(dev->jiffies_next))) {		#define MSECS 10000UL		unsigned int msecs = jiffies_to_msecs(jiffies -				dev->jiffies_next + msecs_to_jiffies(MSECS));		unsigned int samples = dev->sample - dev->sample_measured; 		dev->jiffies_next = jiffies + msecs_to_jiffies(MSECS);		dev->sample_measured = dev->sample;		dev_dbg(dev->dev, "slen=%u samples=%u msecs=%u sample rate=%lu\n",				src_len, samples, msecs,				samples * 1000UL / msecs);	} 	/* total number of samples */	dev->sample += src_len / 2; 	return src_len;} /* * This gets called for the bulk stream pipe. This is done in interrupt * time, so it has to be fast, not crash, and not stall. Neat. */static void hackrf_urb_complete(struct urb *urb){	struct hackrf_dev *dev = urb->context;	struct hackrf_frame_buf *fbuf; 	dev_dbg_ratelimited(dev->dev, "status=%d length=%d/%d errors=%d\n",			urb->status, urb->actual_length,			urb->transfer_buffer_length, urb->error_count); 	switch (urb->status) {	case 0:             /* success */	case -ETIMEDOUT:    /* NAK */		break;	case -ECONNRESET:   /* kill */	case -ENOENT:	case -ESHUTDOWN:		return;	default:            /* error */		dev_err_ratelimited(dev->dev, "URB failed %d\n", urb->status);		break;	} 	if (likely(urb->actual_length > 0)) {		void *ptr;		unsigned int len;		/* get free framebuffer */		fbuf = hackrf_get_next_fill_buf(dev);		if (unlikely(fbuf == NULL)) {			dev->vb_full++;			dev_notice_ratelimited(dev->dev,					"videobuf is full, %d packets dropped\n",					dev->vb_full);			goto skip;		} 		/* fill framebuffer */		ptr = vb2_plane_vaddr(&fbuf->vb, 0);		len = hackrf_convert_stream(dev, ptr, urb->transfer_buffer,				urb->actual_length);		vb2_set_plane_payload(&fbuf->vb, 0, len);		v4l2_get_timestamp(&fbuf->vb.v4l2_buf.timestamp);		fbuf->vb.v4l2_buf.sequence = dev->sequence++;		vb2_buffer_done(&fbuf->vb, VB2_BUF_STATE_DONE);	}skip:	usb_submit_urb(urb, GFP_ATOMIC);} static int hackrf_kill_urbs(struct hackrf_dev *dev){	int i; 	for (i = dev->urbs_submitted - 1; i >= 0; i--) {		dev_dbg(dev->dev, "kill urb=%d\n", i);		/* stop the URB */		usb_kill_urb(dev->urb_list[i]);	}	dev->urbs_submitted = 0; 	return 0;} static int hackrf_submit_urbs(struct hackrf_dev *dev){	int i, ret; 	for (i = 0; i < dev->urbs_initialized; i++) {		dev_dbg(dev->dev, "submit urb=%d\n", i);		ret = usb_submit_urb(dev->urb_list[i], GFP_ATOMIC);		if (ret) {			dev_err(dev->dev, "Could not submit URB no. %d - get them all back\n",					i);			hackrf_kill_urbs(dev);			return ret;		}		dev->urbs_submitted++;	} 	return 0;} static int hackrf_free_stream_bufs(struct hackrf_dev *dev){	if (dev->flags & USB_STATE_URB_BUF) {		while (dev->buf_num) {			dev->buf_num--;			dev_dbg(dev->dev, "free buf=%d\n", dev->buf_num);			usb_free_coherent(dev->udev, dev->buf_size,					  dev->buf_list[dev->buf_num],					  dev->dma_addr[dev->buf_num]);		}	}	dev->flags &= ~USB_STATE_URB_BUF; 	return 0;} static int hackrf_alloc_stream_bufs(struct hackrf_dev *dev){	dev->buf_num = 0;	dev->buf_size = BULK_BUFFER_SIZE; 	dev_dbg(dev->dev, "all in all I will use %u bytes for streaming\n",			MAX_BULK_BUFS * BULK_BUFFER_SIZE); 	for (dev->buf_num = 0; dev->buf_num < MAX_BULK_BUFS; dev->buf_num++) {		dev->buf_list[dev->buf_num] = usb_alloc_coherent(dev->udev,				BULK_BUFFER_SIZE, GFP_ATOMIC,				&dev->dma_addr[dev->buf_num]);		if (!dev->buf_list[dev->buf_num]) {			dev_dbg(dev->dev, "alloc buf=%d failed\n",					dev->buf_num);			hackrf_free_stream_bufs(dev);			return -ENOMEM;		} 		dev_dbg(dev->dev, "alloc buf=%d %p (dma %llu)\n", dev->buf_num,				dev->buf_list[dev->buf_num],				(long long)dev->dma_addr[dev->buf_num]);		dev->flags |= USB_STATE_URB_BUF;	} 	return 0;} static int hackrf_free_urbs(struct hackrf_dev *dev){	int i; 	hackrf_kill_urbs(dev); 	for (i = dev->urbs_initialized - 1; i >= 0; i--) {		if (dev->urb_list[i]) {			dev_dbg(dev->dev, "free urb=%d\n", i);			/* free the URBs */			usb_free_urb(dev->urb_list[i]);		}	}	dev->urbs_initialized = 0; 	return 0;} static int hackrf_alloc_urbs(struct hackrf_dev *dev){	int i, j; 	/* allocate the URBs */	for (i = 0; i < MAX_BULK_BUFS; i++) {		dev_dbg(dev->dev, "alloc urb=%d\n", i);		dev->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC);		if (!dev->urb_list[i]) {			dev_dbg(dev->dev, "failed\n");			for (j = 0; j < i; j++)				usb_free_urb(dev->urb_list[j]);			return -ENOMEM;		}		usb_fill_bulk_urb(dev->urb_list[i],				dev->udev,				usb_rcvbulkpipe(dev->udev, 0x81),				dev->buf_list[i],				BULK_BUFFER_SIZE,				hackrf_urb_complete, dev); 		dev->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;		dev->urb_list[i]->transfer_dma = dev->dma_addr[i];		dev->urbs_initialized++;	} 	return 0;} /* Must be called with vb_queue_lock hold */static void hackrf_cleanup_queued_bufs(struct hackrf_dev *dev){	unsigned long flags; 	dev_dbg(dev->dev, "\n"); 	spin_lock_irqsave(&dev->queued_bufs_lock, flags);	while (!list_empty(&dev->queued_bufs)) {		struct hackrf_frame_buf *buf; 		buf = list_entry(dev->queued_bufs.next,				struct hackrf_frame_buf, list);		list_del(&buf->list);		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);	}	spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);} /* The user yanked out the cable... */static void hackrf_disconnect(struct usb_interface *intf){	struct v4l2_device *v = usb_get_intfdata(intf);	struct hackrf_dev *dev = container_of(v, struct hackrf_dev, v4l2_dev); 	dev_dbg(dev->dev, "\n"); 	mutex_lock(&dev->vb_queue_lock);	mutex_lock(&dev->v4l2_lock);	/* No need to keep the urbs around after disconnection */	dev->udev = NULL;	v4l2_device_disconnect(&dev->v4l2_dev);	video_unregister_device(&dev->vdev);	mutex_unlock(&dev->v4l2_lock);	mutex_unlock(&dev->vb_queue_lock); 	v4l2_device_put(&dev->v4l2_dev);} /* Videobuf2 operations */static int hackrf_queue_setup(struct vb2_queue *vq,		const struct v4l2_format *fmt, unsigned int *nbuffers,		unsigned int *nplanes, unsigned int sizes[], void *alloc_ctxs[]){	struct hackrf_dev *dev = vb2_get_drv_priv(vq); 	dev_dbg(dev->dev, "nbuffers=%d\n", *nbuffers); 	/* Need at least 8 buffers */	if (vq->num_buffers + *nbuffers < 8)		*nbuffers = 8 - vq->num_buffers;	*nplanes = 1;	sizes[0] = PAGE_ALIGN(dev->buffersize); 	dev_dbg(dev->dev, "nbuffers=%d sizes[0]=%d\n", *nbuffers, sizes[0]);	return 0;} static void hackrf_buf_queue(struct vb2_buffer *vb){	struct hackrf_dev *dev = vb2_get_drv_priv(vb->vb2_queue);	struct hackrf_frame_buf *buf =			container_of(vb, struct hackrf_frame_buf, vb);	unsigned long flags; 	spin_lock_irqsave(&dev->queued_bufs_lock, flags);	list_add_tail(&buf->list, &dev->queued_bufs);	spin_unlock_irqrestore(&dev->queued_bufs_lock, flags);} static int hackrf_start_streaming(struct vb2_queue *vq, unsigned int count){	struct hackrf_dev *dev = vb2_get_drv_priv(vq);	int ret; 

Lines 1–500 of 1142.