1549 lines · 42.0 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-or-later/* * HackRF driver * * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> */ #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-v4l2.h>#include <media/videobuf2-vmalloc.h> /* * Used Avago MGA-81563 RF amplifier could be destroyed pretty easily with too * strong signal or transmitting to bad antenna. * Set RF gain control to 'grabbed' state by default for sure. */static bool hackrf_enable_rf_gain_ctrl;module_param_named(enable_rf_gain_ctrl, hackrf_enable_rf_gain_ctrl, bool, 0644);MODULE_PARM_DESC(enable_rf_gain_ctrl, "enable RX/TX RF amplifier control (warn: could damage amplifier)"); /* 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_AMP_ENABLE                     = 0x11,	CMD_SET_LNA_GAIN                   = 0x13,	CMD_SET_VGA_GAIN                   = 0x14,	CMD_SET_TXVGA_GAIN                 = 0x15,}; /* *       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_dac[] = {	{		.tuner = 0,		.type = V4L2_TUNER_SDR,		.index = 0,		.capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,		.rangelow   =   200000,		.rangehigh  = 24000000,	},}; static const struct v4l2_frequency_band bands_rx_tx[] = {	{		.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 {	u32	pixelformat;	u32	buffersize;}; /* format descriptions for capture and preview */static struct hackrf_format formats[] = {	{		.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_buffer {	struct vb2_v4l2_buffer vb;	struct list_head list;}; struct hackrf_dev {#define USB_STATE_URB_BUF                1 /* XXX: set manually */#define RX_ON                            4#define TX_ON                            5#define RX_ADC_FREQUENCY                11#define TX_DAC_FREQUENCY                12#define RX_BANDWIDTH                    13#define TX_BANDWIDTH                    14#define RX_RF_FREQUENCY                 15#define TX_RF_FREQUENCY                 16#define RX_RF_GAIN                      17#define TX_RF_GAIN                      18#define RX_IF_GAIN                      19#define RX_LNA_GAIN                     20#define TX_LNA_GAIN                     21	unsigned long flags; 	struct usb_interface *intf;	struct device *dev;	struct usb_device *udev;	struct video_device rx_vdev;	struct video_device tx_vdev;	struct v4l2_device v4l2_dev; 	/* videobuf2 queue and queued buffers list */	struct vb2_queue rx_vb2_queue;	struct vb2_queue tx_vb2_queue;	struct list_head rx_buffer_list;	struct list_head tx_buffer_list;	spinlock_t buffer_list_lock; /* Protects buffer_list */	unsigned int sequence;	     /* Buffer sequence counter */	unsigned int vb_full;        /* vb is full and packets dropped */	unsigned int vb_empty;       /* vb is empty 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_dac;	unsigned int f_rx;	unsigned int f_tx;	u32 pixelformat;	u32 buffersize; 	/* Controls */	struct v4l2_ctrl_handler rx_ctrl_handler;	struct v4l2_ctrl *rx_bandwidth_auto;	struct v4l2_ctrl *rx_bandwidth;	struct v4l2_ctrl *rx_rf_gain;	struct v4l2_ctrl *rx_lna_gain;	struct v4l2_ctrl *rx_if_gain;	struct v4l2_ctrl_handler tx_ctrl_handler;	struct v4l2_ctrl *tx_bandwidth_auto;	struct v4l2_ctrl *tx_bandwidth;	struct v4l2_ctrl *tx_rf_gain;	struct v4l2_ctrl *tx_lna_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_AMP_ENABLE:	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:	case CMD_SET_TXVGA_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;} static int hackrf_set_params(struct hackrf_dev *dev){	struct usb_interface *intf = dev->intf;	int ret, i;	u8 buf[8], u8tmp;	unsigned int uitmp, uitmp1, uitmp2;	const bool rx = test_bit(RX_ON, &dev->flags);	const bool tx = test_bit(TX_ON, &dev->flags);	static const struct {		u32 freq;	} bandwidth_lut[] = {		{ 1750000}, /*  1.75 MHz */		{ 2500000}, /*  2.5  MHz */		{ 3500000}, /*  3.5  MHz */		{ 5000000}, /*  5    MHz */		{ 5500000}, /*  5.5  MHz */		{ 6000000}, /*  6    MHz */		{ 7000000}, /*  7    MHz */		{ 8000000}, /*  8    MHz */		{ 9000000}, /*  9    MHz */		{10000000}, /* 10    MHz */		{12000000}, /* 12    MHz */		{14000000}, /* 14    MHz */		{15000000}, /* 15    MHz */		{20000000}, /* 20    MHz */		{24000000}, /* 24    MHz */		{28000000}, /* 28    MHz */	}; 	if (!rx && !tx) {		dev_dbg(&intf->dev, "device is sleeping\n");		return 0;	} 	/* ADC / DAC frequency */	if (rx && test_and_clear_bit(RX_ADC_FREQUENCY, &dev->flags)) {		dev_dbg(&intf->dev, "RX ADC frequency=%u Hz\n", dev->f_adc);		uitmp1 = dev->f_adc;		uitmp2 = 1;		set_bit(TX_DAC_FREQUENCY, &dev->flags);	} else if (tx && test_and_clear_bit(TX_DAC_FREQUENCY, &dev->flags)) {		dev_dbg(&intf->dev, "TX DAC frequency=%u Hz\n", dev->f_dac);		uitmp1 = dev->f_dac;		uitmp2 = 1;		set_bit(RX_ADC_FREQUENCY, &dev->flags);	} else {		uitmp1 = uitmp2 = 0;	}	if (uitmp1 || uitmp2) {		buf[0] = (uitmp1 >>  0) & 0xff;		buf[1] = (uitmp1 >>  8) & 0xff;		buf[2] = (uitmp1 >> 16) & 0xff;		buf[3] = (uitmp1 >> 24) & 0xff;		buf[4] = (uitmp2 >>  0) & 0xff;		buf[5] = (uitmp2 >>  8) & 0xff;		buf[6] = (uitmp2 >> 16) & 0xff;		buf[7] = (uitmp2 >> 24) & 0xff;		ret = hackrf_ctrl_msg(dev, CMD_SAMPLE_RATE_SET, 0, 0, buf, 8);		if (ret)			goto err;	} 	/* bandwidth */	if (rx && test_and_clear_bit(RX_BANDWIDTH, &dev->flags)) {		if (dev->rx_bandwidth_auto->val == true)			uitmp = dev->f_adc;		else			uitmp = dev->rx_bandwidth->val; 		for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {			if (uitmp <= bandwidth_lut[i].freq) {				uitmp = bandwidth_lut[i].freq;				break;			}		}		dev->rx_bandwidth->val = uitmp;		dev->rx_bandwidth->cur.val = uitmp;		dev_dbg(&intf->dev, "RX bandwidth selected=%u\n", uitmp);		set_bit(TX_BANDWIDTH, &dev->flags);	} else if (tx && test_and_clear_bit(TX_BANDWIDTH, &dev->flags)) {		if (dev->tx_bandwidth_auto->val == true)			uitmp = dev->f_dac;		else			uitmp = dev->tx_bandwidth->val; 		for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) {			if (uitmp <= bandwidth_lut[i].freq) {				uitmp = bandwidth_lut[i].freq;				break;			}		}		dev->tx_bandwidth->val = uitmp;		dev->tx_bandwidth->cur.val = uitmp;		dev_dbg(&intf->dev, "TX bandwidth selected=%u\n", uitmp);		set_bit(RX_BANDWIDTH, &dev->flags);	} else {		uitmp = 0;	}	if (uitmp) {		uitmp1 = uitmp2 = 0;		uitmp1 |= ((uitmp >>  0) & 0xff) << 0;		uitmp1 |= ((uitmp >>  8) & 0xff) << 8;		uitmp2 |= ((uitmp >> 16) & 0xff) << 0;		uitmp2 |= ((uitmp >> 24) & 0xff) << 8;		ret = hackrf_ctrl_msg(dev, CMD_BASEBAND_FILTER_BANDWIDTH_SET,				      uitmp1, uitmp2, NULL, 0);		if (ret)			goto err;	} 	/* RX / TX RF frequency */	if (rx && test_and_clear_bit(RX_RF_FREQUENCY, &dev->flags)) {		dev_dbg(&intf->dev, "RX RF frequency=%u Hz\n", dev->f_rx);		uitmp1 = dev->f_rx / 1000000;		uitmp2 = dev->f_rx % 1000000;		set_bit(TX_RF_FREQUENCY, &dev->flags);	} else if (tx && test_and_clear_bit(TX_RF_FREQUENCY, &dev->flags)) {		dev_dbg(&intf->dev, "TX RF frequency=%u Hz\n", dev->f_tx);		uitmp1 = dev->f_tx / 1000000;		uitmp2 = dev->f_tx % 1000000;		set_bit(RX_RF_FREQUENCY, &dev->flags);	} else {		uitmp1 = uitmp2 = 0;	}	if (uitmp1 || uitmp2) {		buf[0] = (uitmp1 >>  0) & 0xff;		buf[1] = (uitmp1 >>  8) & 0xff;		buf[2] = (uitmp1 >> 16) & 0xff;		buf[3] = (uitmp1 >> 24) & 0xff;		buf[4] = (uitmp2 >>  0) & 0xff;		buf[5] = (uitmp2 >>  8) & 0xff;		buf[6] = (uitmp2 >> 16) & 0xff;		buf[7] = (uitmp2 >> 24) & 0xff;		ret = hackrf_ctrl_msg(dev, CMD_SET_FREQ, 0, 0, buf, 8);		if (ret)			goto err;	} 	/* RX RF gain */	if (rx && test_and_clear_bit(RX_RF_GAIN, &dev->flags)) {		dev_dbg(&intf->dev, "RX RF gain val=%d->%d\n",			dev->rx_rf_gain->cur.val, dev->rx_rf_gain->val); 		u8tmp = (dev->rx_rf_gain->val) ? 1 : 0;		ret = hackrf_ctrl_msg(dev, CMD_AMP_ENABLE, u8tmp, 0, NULL, 0);		if (ret)			goto err;		set_bit(TX_RF_GAIN, &dev->flags);	} 	/* TX RF gain */	if (tx && test_and_clear_bit(TX_RF_GAIN, &dev->flags)) {		dev_dbg(&intf->dev, "TX RF gain val=%d->%d\n",			dev->tx_rf_gain->cur.val, dev->tx_rf_gain->val); 		u8tmp = (dev->tx_rf_gain->val) ? 1 : 0;		ret = hackrf_ctrl_msg(dev, CMD_AMP_ENABLE, u8tmp, 0, NULL, 0);		if (ret)			goto err;		set_bit(RX_RF_GAIN, &dev->flags);	} 	/* RX LNA gain */	if (rx && test_and_clear_bit(RX_LNA_GAIN, &dev->flags)) {		dev_dbg(dev->dev, "RX LNA gain val=%d->%d\n",			dev->rx_lna_gain->cur.val, dev->rx_lna_gain->val); 		ret = hackrf_ctrl_msg(dev, CMD_SET_LNA_GAIN, 0,				      dev->rx_lna_gain->val, &u8tmp, 1);		if (ret)			goto err;	} 	/* RX IF gain */	if (rx && test_and_clear_bit(RX_IF_GAIN, &dev->flags)) {		dev_dbg(&intf->dev, "IF gain val=%d->%d\n",			dev->rx_if_gain->cur.val, dev->rx_if_gain->val); 		ret = hackrf_ctrl_msg(dev, CMD_SET_VGA_GAIN, 0,				      dev->rx_if_gain->val, &u8tmp, 1);		if (ret)			goto err;	} 	/* TX LNA gain */	if (tx && test_and_clear_bit(TX_LNA_GAIN, &dev->flags)) {		dev_dbg(&intf->dev, "TX LNA gain val=%d->%d\n",			dev->tx_lna_gain->cur.val, dev->tx_lna_gain->val); 		ret = hackrf_ctrl_msg(dev, CMD_SET_TXVGA_GAIN, 0,				      dev->tx_lna_gain->val, &u8tmp, 1);		if (ret)			goto err;	} 	return 0;err:	dev_dbg(&intf->dev, "failed=%d\n", ret);	return ret;} /* Private functions */static struct hackrf_buffer *hackrf_get_next_buffer(struct hackrf_dev *dev,						    struct list_head *buffer_list){	unsigned long flags;	struct hackrf_buffer *buffer = NULL; 	spin_lock_irqsave(&dev->buffer_list_lock, flags);	if (list_empty(buffer_list))		goto leave; 	buffer = list_entry(buffer_list->next, struct hackrf_buffer, list);	list_del(&buffer->list);leave:	spin_unlock_irqrestore(&dev->buffer_list_lock, flags);	return buffer;} static void hackrf_copy_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;} /* * 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_in(struct urb *urb){	struct hackrf_dev *dev = urb->context;	struct usb_interface *intf = dev->intf;	struct hackrf_buffer *buffer;	unsigned int len; 	dev_dbg_ratelimited(&intf->dev, "status=%d length=%u/%u\n", urb->status,			    urb->actual_length, urb->transfer_buffer_length); 	switch (urb->status) {	case 0:             /* success */	case -ETIMEDOUT:    /* NAK */		break;	case -ECONNRESET:   /* kill */	case -ENOENT:	case -ESHUTDOWN:		return;	default:            /* error */		dev_err_ratelimited(&intf->dev, "URB failed %d\n", urb->status);

Lines 1–500 of 1549.