Commit | Line | Data |
---|---|---|
969ec1f6 AP |
1 | /* |
2 | * HackRF driver | |
3 | * | |
4 | * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | */ | |
16 | ||
17 | #include <linux/module.h> | |
18 | #include <linux/slab.h> | |
19 | #include <linux/usb.h> | |
20 | #include <media/v4l2-device.h> | |
21 | #include <media/v4l2-ioctl.h> | |
22 | #include <media/v4l2-ctrls.h> | |
23 | #include <media/v4l2-event.h> | |
2d700715 | 24 | #include <media/videobuf2-v4l2.h> |
969ec1f6 AP |
25 | #include <media/videobuf2-vmalloc.h> |
26 | ||
d47fa531 AP |
27 | /* |
28 | * Used Avago MGA-81563 RF amplifier could be destroyed pretty easily with too | |
29 | * strong signal or transmitting to bad antenna. | |
30 | * Set RF gain control to 'grabbed' state by default for sure. | |
31 | */ | |
32 | static bool hackrf_enable_rf_gain_ctrl; | |
33 | module_param_named(enable_rf_gain_ctrl, hackrf_enable_rf_gain_ctrl, bool, 0644); | |
34 | MODULE_PARM_DESC(enable_rf_gain_ctrl, "enable RX/TX RF amplifier control (warn: could damage amplifier)"); | |
35 | ||
969ec1f6 AP |
36 | /* HackRF USB API commands (from HackRF Library) */ |
37 | enum { | |
38 | CMD_SET_TRANSCEIVER_MODE = 0x01, | |
39 | CMD_SAMPLE_RATE_SET = 0x06, | |
40 | CMD_BASEBAND_FILTER_BANDWIDTH_SET = 0x07, | |
41 | CMD_BOARD_ID_READ = 0x0e, | |
42 | CMD_VERSION_STRING_READ = 0x0f, | |
43 | CMD_SET_FREQ = 0x10, | |
b3ae2966 | 44 | CMD_AMP_ENABLE = 0x11, |
969ec1f6 AP |
45 | CMD_SET_LNA_GAIN = 0x13, |
46 | CMD_SET_VGA_GAIN = 0x14, | |
8bc4a9ed | 47 | CMD_SET_TXVGA_GAIN = 0x15, |
969ec1f6 AP |
48 | }; |
49 | ||
50 | /* | |
51 | * bEndpointAddress 0x81 EP 1 IN | |
52 | * Transfer Type Bulk | |
53 | * wMaxPacketSize 0x0200 1x 512 bytes | |
54 | */ | |
55 | #define MAX_BULK_BUFS (6) | |
56 | #define BULK_BUFFER_SIZE (128 * 512) | |
57 | ||
8bc4a9ed | 58 | static const struct v4l2_frequency_band bands_adc_dac[] = { |
969ec1f6 AP |
59 | { |
60 | .tuner = 0, | |
8bc4a9ed | 61 | .type = V4L2_TUNER_SDR, |
969ec1f6 AP |
62 | .index = 0, |
63 | .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, | |
64 | .rangelow = 200000, | |
65 | .rangehigh = 24000000, | |
66 | }, | |
67 | }; | |
68 | ||
8bc4a9ed | 69 | static const struct v4l2_frequency_band bands_rx_tx[] = { |
969ec1f6 AP |
70 | { |
71 | .tuner = 1, | |
72 | .type = V4L2_TUNER_RF, | |
73 | .index = 0, | |
74 | .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS, | |
75 | .rangelow = 1, | |
720b055d | 76 | .rangehigh = 4294967294LL, /* max u32, hw goes over 7GHz */ |
969ec1f6 AP |
77 | }, |
78 | }; | |
79 | ||
80 | /* stream formats */ | |
81 | struct hackrf_format { | |
969ec1f6 AP |
82 | u32 pixelformat; |
83 | u32 buffersize; | |
84 | }; | |
85 | ||
86 | /* format descriptions for capture and preview */ | |
87 | static struct hackrf_format formats[] = { | |
88 | { | |
969ec1f6 AP |
89 | .pixelformat = V4L2_SDR_FMT_CS8, |
90 | .buffersize = BULK_BUFFER_SIZE, | |
91 | }, | |
92 | }; | |
93 | ||
94 | static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats); | |
95 | ||
96 | /* intermediate buffers with raw data from the USB device */ | |
8bc4a9ed | 97 | struct hackrf_buffer { |
2d700715 | 98 | struct vb2_v4l2_buffer vb; |
969ec1f6 AP |
99 | struct list_head list; |
100 | }; | |
101 | ||
102 | struct hackrf_dev { | |
8bc4a9ed AP |
103 | #define USB_STATE_URB_BUF 1 /* XXX: set manually */ |
104 | #define RX_ON 4 | |
105 | #define TX_ON 5 | |
106 | #define RX_ADC_FREQUENCY 11 | |
107 | #define TX_DAC_FREQUENCY 12 | |
108 | #define RX_BANDWIDTH 13 | |
109 | #define TX_BANDWIDTH 14 | |
110 | #define RX_RF_FREQUENCY 15 | |
111 | #define TX_RF_FREQUENCY 16 | |
112 | #define RX_RF_GAIN 17 | |
113 | #define TX_RF_GAIN 18 | |
114 | #define RX_IF_GAIN 19 | |
115 | #define RX_LNA_GAIN 20 | |
116 | #define TX_LNA_GAIN 21 | |
969ec1f6 AP |
117 | unsigned long flags; |
118 | ||
eec20f06 | 119 | struct usb_interface *intf; |
969ec1f6 AP |
120 | struct device *dev; |
121 | struct usb_device *udev; | |
8bc4a9ed AP |
122 | struct video_device rx_vdev; |
123 | struct video_device tx_vdev; | |
969ec1f6 AP |
124 | struct v4l2_device v4l2_dev; |
125 | ||
126 | /* videobuf2 queue and queued buffers list */ | |
8bc4a9ed AP |
127 | struct vb2_queue rx_vb2_queue; |
128 | struct vb2_queue tx_vb2_queue; | |
129 | struct list_head rx_buffer_list; | |
130 | struct list_head tx_buffer_list; | |
131 | spinlock_t buffer_list_lock; /* Protects buffer_list */ | |
a769de07 | 132 | unsigned int sequence; /* Buffer sequence counter */ |
969ec1f6 | 133 | unsigned int vb_full; /* vb is full and packets dropped */ |
8bc4a9ed | 134 | unsigned int vb_empty; /* vb is empty and packets dropped */ |
969ec1f6 AP |
135 | |
136 | /* Note if taking both locks v4l2_lock must always be locked first! */ | |
137 | struct mutex v4l2_lock; /* Protects everything else */ | |
138 | struct mutex vb_queue_lock; /* Protects vb_queue */ | |
139 | ||
140 | struct urb *urb_list[MAX_BULK_BUFS]; | |
141 | int buf_num; | |
142 | unsigned long buf_size; | |
143 | u8 *buf_list[MAX_BULK_BUFS]; | |
144 | dma_addr_t dma_addr[MAX_BULK_BUFS]; | |
145 | int urbs_initialized; | |
146 | int urbs_submitted; | |
147 | ||
148 | /* USB control message buffer */ | |
149 | #define BUF_SIZE 24 | |
150 | u8 buf[BUF_SIZE]; | |
151 | ||
152 | /* Current configuration */ | |
153 | unsigned int f_adc; | |
8bc4a9ed AP |
154 | unsigned int f_dac; |
155 | unsigned int f_rx; | |
156 | unsigned int f_tx; | |
969ec1f6 AP |
157 | u32 pixelformat; |
158 | u32 buffersize; | |
159 | ||
160 | /* Controls */ | |
8bc4a9ed AP |
161 | struct v4l2_ctrl_handler rx_ctrl_handler; |
162 | struct v4l2_ctrl *rx_bandwidth_auto; | |
163 | struct v4l2_ctrl *rx_bandwidth; | |
164 | struct v4l2_ctrl *rx_rf_gain; | |
165 | struct v4l2_ctrl *rx_lna_gain; | |
166 | struct v4l2_ctrl *rx_if_gain; | |
167 | struct v4l2_ctrl_handler tx_ctrl_handler; | |
168 | struct v4l2_ctrl *tx_bandwidth_auto; | |
169 | struct v4l2_ctrl *tx_bandwidth; | |
170 | struct v4l2_ctrl *tx_rf_gain; | |
171 | struct v4l2_ctrl *tx_lna_gain; | |
969ec1f6 AP |
172 | |
173 | /* Sample rate calc */ | |
174 | unsigned long jiffies_next; | |
175 | unsigned int sample; | |
176 | unsigned int sample_measured; | |
177 | }; | |
178 | ||
179 | #define hackrf_dbg_usb_control_msg(_dev, _r, _t, _v, _i, _b, _l) { \ | |
180 | char *_direction; \ | |
181 | if (_t & USB_DIR_IN) \ | |
182 | _direction = "<<<"; \ | |
183 | else \ | |
184 | _direction = ">>>"; \ | |
185 | dev_dbg(_dev, "%02x %02x %02x %02x %02x %02x %02x %02x %s %*ph\n", \ | |
186 | _t, _r, _v & 0xff, _v >> 8, _i & 0xff, \ | |
187 | _i >> 8, _l & 0xff, _l >> 8, _direction, _l, _b); \ | |
188 | } | |
189 | ||
190 | /* execute firmware command */ | |
191 | static int hackrf_ctrl_msg(struct hackrf_dev *dev, u8 request, u16 value, | |
192 | u16 index, u8 *data, u16 size) | |
193 | { | |
194 | int ret; | |
195 | unsigned int pipe; | |
196 | u8 requesttype; | |
197 | ||
198 | switch (request) { | |
199 | case CMD_SET_TRANSCEIVER_MODE: | |
200 | case CMD_SET_FREQ: | |
b3ae2966 | 201 | case CMD_AMP_ENABLE: |
969ec1f6 AP |
202 | case CMD_SAMPLE_RATE_SET: |
203 | case CMD_BASEBAND_FILTER_BANDWIDTH_SET: | |
204 | pipe = usb_sndctrlpipe(dev->udev, 0); | |
205 | requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT); | |
206 | break; | |
207 | case CMD_BOARD_ID_READ: | |
208 | case CMD_VERSION_STRING_READ: | |
209 | case CMD_SET_LNA_GAIN: | |
210 | case CMD_SET_VGA_GAIN: | |
8bc4a9ed | 211 | case CMD_SET_TXVGA_GAIN: |
969ec1f6 AP |
212 | pipe = usb_rcvctrlpipe(dev->udev, 0); |
213 | requesttype = (USB_TYPE_VENDOR | USB_DIR_IN); | |
214 | break; | |
215 | default: | |
216 | dev_err(dev->dev, "Unknown command %02x\n", request); | |
217 | ret = -EINVAL; | |
218 | goto err; | |
219 | } | |
220 | ||
221 | /* write request */ | |
222 | if (!(requesttype & USB_DIR_IN)) | |
223 | memcpy(dev->buf, data, size); | |
224 | ||
225 | ret = usb_control_msg(dev->udev, pipe, request, requesttype, value, | |
226 | index, dev->buf, size, 1000); | |
227 | hackrf_dbg_usb_control_msg(dev->dev, request, requesttype, value, | |
228 | index, dev->buf, size); | |
229 | if (ret < 0) { | |
230 | dev_err(dev->dev, "usb_control_msg() failed %d request %02x\n", | |
231 | ret, request); | |
232 | goto err; | |
233 | } | |
234 | ||
235 | /* read request */ | |
236 | if (requesttype & USB_DIR_IN) | |
237 | memcpy(data, dev->buf, size); | |
238 | ||
239 | return 0; | |
240 | err: | |
241 | return ret; | |
242 | } | |
243 | ||
eec20f06 AP |
244 | static int hackrf_set_params(struct hackrf_dev *dev) |
245 | { | |
246 | struct usb_interface *intf = dev->intf; | |
247 | int ret, i; | |
248 | u8 buf[8], u8tmp; | |
249 | unsigned int uitmp, uitmp1, uitmp2; | |
8bc4a9ed AP |
250 | const bool rx = test_bit(RX_ON, &dev->flags); |
251 | const bool tx = test_bit(TX_ON, &dev->flags); | |
252 | static const struct { | |
253 | u32 freq; | |
254 | } bandwidth_lut[] = { | |
255 | { 1750000}, /* 1.75 MHz */ | |
256 | { 2500000}, /* 2.5 MHz */ | |
257 | { 3500000}, /* 3.5 MHz */ | |
258 | { 5000000}, /* 5 MHz */ | |
259 | { 5500000}, /* 5.5 MHz */ | |
260 | { 6000000}, /* 6 MHz */ | |
261 | { 7000000}, /* 7 MHz */ | |
262 | { 8000000}, /* 8 MHz */ | |
263 | { 9000000}, /* 9 MHz */ | |
264 | {10000000}, /* 10 MHz */ | |
265 | {12000000}, /* 12 MHz */ | |
266 | {14000000}, /* 14 MHz */ | |
267 | {15000000}, /* 15 MHz */ | |
268 | {20000000}, /* 20 MHz */ | |
269 | {24000000}, /* 24 MHz */ | |
270 | {28000000}, /* 28 MHz */ | |
271 | }; | |
272 | ||
273 | if (!rx && !tx) { | |
eec20f06 AP |
274 | dev_dbg(&intf->dev, "device is sleeping\n"); |
275 | return 0; | |
276 | } | |
277 | ||
8bc4a9ed AP |
278 | /* ADC / DAC frequency */ |
279 | if (rx && test_and_clear_bit(RX_ADC_FREQUENCY, &dev->flags)) { | |
280 | dev_dbg(&intf->dev, "RX ADC frequency=%u Hz\n", dev->f_adc); | |
eec20f06 AP |
281 | uitmp1 = dev->f_adc; |
282 | uitmp2 = 1; | |
8bc4a9ed AP |
283 | set_bit(TX_DAC_FREQUENCY, &dev->flags); |
284 | } else if (tx && test_and_clear_bit(TX_DAC_FREQUENCY, &dev->flags)) { | |
285 | dev_dbg(&intf->dev, "TX DAC frequency=%u Hz\n", dev->f_dac); | |
286 | uitmp1 = dev->f_dac; | |
287 | uitmp2 = 1; | |
288 | set_bit(RX_ADC_FREQUENCY, &dev->flags); | |
289 | } else { | |
290 | uitmp1 = uitmp2 = 0; | |
291 | } | |
292 | if (uitmp1 || uitmp2) { | |
eec20f06 AP |
293 | buf[0] = (uitmp1 >> 0) & 0xff; |
294 | buf[1] = (uitmp1 >> 8) & 0xff; | |
295 | buf[2] = (uitmp1 >> 16) & 0xff; | |
296 | buf[3] = (uitmp1 >> 24) & 0xff; | |
297 | buf[4] = (uitmp2 >> 0) & 0xff; | |
298 | buf[5] = (uitmp2 >> 8) & 0xff; | |
299 | buf[6] = (uitmp2 >> 16) & 0xff; | |
300 | buf[7] = (uitmp2 >> 24) & 0xff; | |
301 | ret = hackrf_ctrl_msg(dev, CMD_SAMPLE_RATE_SET, 0, 0, buf, 8); | |
302 | if (ret) | |
303 | goto err; | |
304 | } | |
305 | ||
8bc4a9ed AP |
306 | /* bandwidth */ |
307 | if (rx && test_and_clear_bit(RX_BANDWIDTH, &dev->flags)) { | |
308 | if (dev->rx_bandwidth_auto->val == true) | |
eec20f06 AP |
309 | uitmp = dev->f_adc; |
310 | else | |
8bc4a9ed | 311 | uitmp = dev->rx_bandwidth->val; |
eec20f06 AP |
312 | |
313 | for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) { | |
314 | if (uitmp <= bandwidth_lut[i].freq) { | |
315 | uitmp = bandwidth_lut[i].freq; | |
316 | break; | |
317 | } | |
318 | } | |
8bc4a9ed AP |
319 | dev->rx_bandwidth->val = uitmp; |
320 | dev->rx_bandwidth->cur.val = uitmp; | |
321 | dev_dbg(&intf->dev, "RX bandwidth selected=%u\n", uitmp); | |
322 | set_bit(TX_BANDWIDTH, &dev->flags); | |
323 | } else if (tx && test_and_clear_bit(TX_BANDWIDTH, &dev->flags)) { | |
324 | if (dev->tx_bandwidth_auto->val == true) | |
325 | uitmp = dev->f_dac; | |
326 | else | |
327 | uitmp = dev->tx_bandwidth->val; | |
eec20f06 | 328 | |
8bc4a9ed AP |
329 | for (i = 0; i < ARRAY_SIZE(bandwidth_lut); i++) { |
330 | if (uitmp <= bandwidth_lut[i].freq) { | |
331 | uitmp = bandwidth_lut[i].freq; | |
332 | break; | |
333 | } | |
334 | } | |
335 | dev->tx_bandwidth->val = uitmp; | |
336 | dev->tx_bandwidth->cur.val = uitmp; | |
337 | dev_dbg(&intf->dev, "TX bandwidth selected=%u\n", uitmp); | |
338 | set_bit(RX_BANDWIDTH, &dev->flags); | |
339 | } else { | |
340 | uitmp = 0; | |
341 | } | |
342 | if (uitmp) { | |
343 | uitmp1 = uitmp2 = 0; | |
344 | uitmp1 |= ((uitmp >> 0) & 0xff) << 0; | |
345 | uitmp1 |= ((uitmp >> 8) & 0xff) << 8; | |
eec20f06 AP |
346 | uitmp2 |= ((uitmp >> 16) & 0xff) << 0; |
347 | uitmp2 |= ((uitmp >> 24) & 0xff) << 8; | |
eec20f06 AP |
348 | ret = hackrf_ctrl_msg(dev, CMD_BASEBAND_FILTER_BANDWIDTH_SET, |
349 | uitmp1, uitmp2, NULL, 0); | |
350 | if (ret) | |
351 | goto err; | |
352 | } | |
353 | ||
8bc4a9ed AP |
354 | /* RX / TX RF frequency */ |
355 | if (rx && test_and_clear_bit(RX_RF_FREQUENCY, &dev->flags)) { | |
356 | dev_dbg(&intf->dev, "RX RF frequency=%u Hz\n", dev->f_rx); | |
357 | uitmp1 = dev->f_rx / 1000000; | |
358 | uitmp2 = dev->f_rx % 1000000; | |
359 | set_bit(TX_RF_FREQUENCY, &dev->flags); | |
360 | } else if (tx && test_and_clear_bit(TX_RF_FREQUENCY, &dev->flags)) { | |
361 | dev_dbg(&intf->dev, "TX RF frequency=%u Hz\n", dev->f_tx); | |
362 | uitmp1 = dev->f_tx / 1000000; | |
363 | uitmp2 = dev->f_tx % 1000000; | |
364 | set_bit(RX_RF_FREQUENCY, &dev->flags); | |
365 | } else { | |
366 | uitmp1 = uitmp2 = 0; | |
367 | } | |
368 | if (uitmp1 || uitmp2) { | |
eec20f06 AP |
369 | buf[0] = (uitmp1 >> 0) & 0xff; |
370 | buf[1] = (uitmp1 >> 8) & 0xff; | |
371 | buf[2] = (uitmp1 >> 16) & 0xff; | |
372 | buf[3] = (uitmp1 >> 24) & 0xff; | |
373 | buf[4] = (uitmp2 >> 0) & 0xff; | |
374 | buf[5] = (uitmp2 >> 8) & 0xff; | |
375 | buf[6] = (uitmp2 >> 16) & 0xff; | |
376 | buf[7] = (uitmp2 >> 24) & 0xff; | |
377 | ret = hackrf_ctrl_msg(dev, CMD_SET_FREQ, 0, 0, buf, 8); | |
378 | if (ret) | |
379 | goto err; | |
380 | } | |
381 | ||
8bc4a9ed AP |
382 | /* RX RF gain */ |
383 | if (rx && test_and_clear_bit(RX_RF_GAIN, &dev->flags)) { | |
384 | dev_dbg(&intf->dev, "RX RF gain val=%d->%d\n", | |
385 | dev->rx_rf_gain->cur.val, dev->rx_rf_gain->val); | |
386 | ||
387 | u8tmp = (dev->rx_rf_gain->val) ? 1 : 0; | |
388 | ret = hackrf_ctrl_msg(dev, CMD_AMP_ENABLE, u8tmp, 0, NULL, 0); | |
389 | if (ret) | |
390 | goto err; | |
391 | set_bit(TX_RF_GAIN, &dev->flags); | |
392 | } | |
393 | ||
394 | /* TX RF gain */ | |
395 | if (tx && test_and_clear_bit(TX_RF_GAIN, &dev->flags)) { | |
396 | dev_dbg(&intf->dev, "TX RF gain val=%d->%d\n", | |
397 | dev->tx_rf_gain->cur.val, dev->tx_rf_gain->val); | |
eec20f06 | 398 | |
8bc4a9ed | 399 | u8tmp = (dev->tx_rf_gain->val) ? 1 : 0; |
eec20f06 AP |
400 | ret = hackrf_ctrl_msg(dev, CMD_AMP_ENABLE, u8tmp, 0, NULL, 0); |
401 | if (ret) | |
402 | goto err; | |
8bc4a9ed | 403 | set_bit(RX_RF_GAIN, &dev->flags); |
eec20f06 AP |
404 | } |
405 | ||
8bc4a9ed AP |
406 | /* RX LNA gain */ |
407 | if (rx && test_and_clear_bit(RX_LNA_GAIN, &dev->flags)) { | |
408 | dev_dbg(dev->dev, "RX LNA gain val=%d->%d\n", | |
409 | dev->rx_lna_gain->cur.val, dev->rx_lna_gain->val); | |
eec20f06 AP |
410 | |
411 | ret = hackrf_ctrl_msg(dev, CMD_SET_LNA_GAIN, 0, | |
8bc4a9ed | 412 | dev->rx_lna_gain->val, &u8tmp, 1); |
eec20f06 AP |
413 | if (ret) |
414 | goto err; | |
415 | } | |
416 | ||
8bc4a9ed AP |
417 | /* RX IF gain */ |
418 | if (rx && test_and_clear_bit(RX_IF_GAIN, &dev->flags)) { | |
eec20f06 | 419 | dev_dbg(&intf->dev, "IF gain val=%d->%d\n", |
8bc4a9ed | 420 | dev->rx_if_gain->cur.val, dev->rx_if_gain->val); |
eec20f06 AP |
421 | |
422 | ret = hackrf_ctrl_msg(dev, CMD_SET_VGA_GAIN, 0, | |
8bc4a9ed AP |
423 | dev->rx_if_gain->val, &u8tmp, 1); |
424 | if (ret) | |
425 | goto err; | |
426 | } | |
427 | ||
428 | /* TX LNA gain */ | |
429 | if (tx && test_and_clear_bit(TX_LNA_GAIN, &dev->flags)) { | |
430 | dev_dbg(&intf->dev, "TX LNA gain val=%d->%d\n", | |
431 | dev->tx_lna_gain->cur.val, dev->tx_lna_gain->val); | |
432 | ||
433 | ret = hackrf_ctrl_msg(dev, CMD_SET_TXVGA_GAIN, 0, | |
434 | dev->tx_lna_gain->val, &u8tmp, 1); | |
eec20f06 AP |
435 | if (ret) |
436 | goto err; | |
437 | } | |
438 | ||
439 | return 0; | |
440 | err: | |
441 | dev_dbg(&intf->dev, "failed=%d\n", ret); | |
442 | return ret; | |
443 | } | |
444 | ||
969ec1f6 | 445 | /* Private functions */ |
8bc4a9ed AP |
446 | static struct hackrf_buffer *hackrf_get_next_buffer(struct hackrf_dev *dev, |
447 | struct list_head *buffer_list) | |
969ec1f6 AP |
448 | { |
449 | unsigned long flags; | |
8bc4a9ed | 450 | struct hackrf_buffer *buffer = NULL; |
969ec1f6 | 451 | |
8bc4a9ed AP |
452 | spin_lock_irqsave(&dev->buffer_list_lock, flags); |
453 | if (list_empty(buffer_list)) | |
969ec1f6 AP |
454 | goto leave; |
455 | ||
8bc4a9ed AP |
456 | buffer = list_entry(buffer_list->next, struct hackrf_buffer, list); |
457 | list_del(&buffer->list); | |
969ec1f6 | 458 | leave: |
8bc4a9ed AP |
459 | spin_unlock_irqrestore(&dev->buffer_list_lock, flags); |
460 | return buffer; | |
969ec1f6 AP |
461 | } |
462 | ||
8bc4a9ed AP |
463 | static void hackrf_copy_stream(struct hackrf_dev *dev, void *dst, void *src, |
464 | unsigned int src_len) | |
969ec1f6 AP |
465 | { |
466 | memcpy(dst, src, src_len); | |
467 | ||
468 | /* calculate sample rate and output it in 10 seconds intervals */ | |
469 | if (unlikely(time_is_before_jiffies(dev->jiffies_next))) { | |
470 | #define MSECS 10000UL | |
471 | unsigned int msecs = jiffies_to_msecs(jiffies - | |
472 | dev->jiffies_next + msecs_to_jiffies(MSECS)); | |
473 | unsigned int samples = dev->sample - dev->sample_measured; | |
474 | ||
475 | dev->jiffies_next = jiffies + msecs_to_jiffies(MSECS); | |
476 | dev->sample_measured = dev->sample; | |
477 | dev_dbg(dev->dev, "slen=%u samples=%u msecs=%u sample rate=%lu\n", | |
478 | src_len, samples, msecs, | |
479 | samples * 1000UL / msecs); | |
480 | } | |
481 | ||
482 | /* total number of samples */ | |
483 | dev->sample += src_len / 2; | |
969ec1f6 AP |
484 | } |
485 | ||
486 | /* | |
487 | * This gets called for the bulk stream pipe. This is done in interrupt | |
488 | * time, so it has to be fast, not crash, and not stall. Neat. | |
489 | */ | |
8bc4a9ed | 490 | static void hackrf_urb_complete_in(struct urb *urb) |
969ec1f6 AP |
491 | { |
492 | struct hackrf_dev *dev = urb->context; | |
8bc4a9ed AP |
493 | struct usb_interface *intf = dev->intf; |
494 | struct hackrf_buffer *buffer; | |
495 | unsigned int len; | |
969ec1f6 | 496 | |
8bc4a9ed AP |
497 | dev_dbg_ratelimited(&intf->dev, "status=%d length=%u/%u\n", urb->status, |
498 | urb->actual_length, urb->transfer_buffer_length); | |
969ec1f6 AP |
499 | |
500 | switch (urb->status) { | |
501 | case 0: /* success */ | |
502 | case -ETIMEDOUT: /* NAK */ | |
503 | break; | |
504 | case -ECONNRESET: /* kill */ | |
505 | case -ENOENT: | |
506 | case -ESHUTDOWN: | |
507 | return; | |
508 | default: /* error */ | |
8bc4a9ed AP |
509 | dev_err_ratelimited(&intf->dev, "URB failed %d\n", urb->status); |
510 | goto exit_usb_submit_urb; | |
969ec1f6 AP |
511 | } |
512 | ||
8bc4a9ed AP |
513 | /* get buffer to write */ |
514 | buffer = hackrf_get_next_buffer(dev, &dev->rx_buffer_list); | |
515 | if (unlikely(buffer == NULL)) { | |
516 | dev->vb_full++; | |
517 | dev_notice_ratelimited(&intf->dev, | |
518 | "buffer is full - %u packets dropped\n", | |
519 | dev->vb_full); | |
520 | goto exit_usb_submit_urb; | |
521 | } | |
522 | ||
523 | len = min_t(unsigned long, vb2_plane_size(&buffer->vb.vb2_buf, 0), | |
524 | urb->actual_length); | |
525 | hackrf_copy_stream(dev, vb2_plane_vaddr(&buffer->vb.vb2_buf, 0), | |
526 | urb->transfer_buffer, len); | |
527 | vb2_set_plane_payload(&buffer->vb.vb2_buf, 0, len); | |
528 | buffer->vb.sequence = dev->sequence++; | |
d6dd645e | 529 | buffer->vb.vb2_buf.timestamp = ktime_get_ns(); |
8bc4a9ed AP |
530 | vb2_buffer_done(&buffer->vb.vb2_buf, VB2_BUF_STATE_DONE); |
531 | exit_usb_submit_urb: | |
532 | usb_submit_urb(urb, GFP_ATOMIC); | |
533 | } | |
969ec1f6 | 534 | |
8bc4a9ed AP |
535 | static void hackrf_urb_complete_out(struct urb *urb) |
536 | { | |
537 | struct hackrf_dev *dev = urb->context; | |
538 | struct usb_interface *intf = dev->intf; | |
539 | struct hackrf_buffer *buffer; | |
540 | unsigned int len; | |
541 | ||
542 | dev_dbg_ratelimited(&intf->dev, "status=%d length=%u/%u\n", urb->status, | |
543 | urb->actual_length, urb->transfer_buffer_length); | |
544 | ||
545 | switch (urb->status) { | |
546 | case 0: /* success */ | |
547 | case -ETIMEDOUT: /* NAK */ | |
548 | break; | |
549 | case -ECONNRESET: /* kill */ | |
550 | case -ENOENT: | |
551 | case -ESHUTDOWN: | |
552 | return; | |
553 | default: /* error */ | |
554 | dev_err_ratelimited(&intf->dev, "URB failed %d\n", urb->status); | |
555 | } | |
556 | ||
557 | /* get buffer to read */ | |
558 | buffer = hackrf_get_next_buffer(dev, &dev->tx_buffer_list); | |
559 | if (unlikely(buffer == NULL)) { | |
560 | dev->vb_empty++; | |
561 | dev_notice_ratelimited(&intf->dev, | |
562 | "buffer is empty - %u packets dropped\n", | |
563 | dev->vb_empty); | |
564 | urb->actual_length = 0; | |
565 | goto exit_usb_submit_urb; | |
969ec1f6 | 566 | } |
8bc4a9ed AP |
567 | |
568 | len = min_t(unsigned long, urb->transfer_buffer_length, | |
569 | vb2_get_plane_payload(&buffer->vb.vb2_buf, 0)); | |
570 | hackrf_copy_stream(dev, urb->transfer_buffer, | |
571 | vb2_plane_vaddr(&buffer->vb.vb2_buf, 0), len); | |
572 | urb->actual_length = len; | |
573 | buffer->vb.sequence = dev->sequence++; | |
d6dd645e | 574 | buffer->vb.vb2_buf.timestamp = ktime_get_ns(); |
8bc4a9ed AP |
575 | vb2_buffer_done(&buffer->vb.vb2_buf, VB2_BUF_STATE_DONE); |
576 | exit_usb_submit_urb: | |
969ec1f6 AP |
577 | usb_submit_urb(urb, GFP_ATOMIC); |
578 | } | |
579 | ||
580 | static int hackrf_kill_urbs(struct hackrf_dev *dev) | |
581 | { | |
582 | int i; | |
583 | ||
584 | for (i = dev->urbs_submitted - 1; i >= 0; i--) { | |
585 | dev_dbg(dev->dev, "kill urb=%d\n", i); | |
586 | /* stop the URB */ | |
587 | usb_kill_urb(dev->urb_list[i]); | |
588 | } | |
589 | dev->urbs_submitted = 0; | |
590 | ||
591 | return 0; | |
592 | } | |
593 | ||
594 | static int hackrf_submit_urbs(struct hackrf_dev *dev) | |
595 | { | |
596 | int i, ret; | |
597 | ||
598 | for (i = 0; i < dev->urbs_initialized; i++) { | |
599 | dev_dbg(dev->dev, "submit urb=%d\n", i); | |
600 | ret = usb_submit_urb(dev->urb_list[i], GFP_ATOMIC); | |
601 | if (ret) { | |
602 | dev_err(dev->dev, "Could not submit URB no. %d - get them all back\n", | |
603 | i); | |
604 | hackrf_kill_urbs(dev); | |
605 | return ret; | |
606 | } | |
607 | dev->urbs_submitted++; | |
608 | } | |
609 | ||
610 | return 0; | |
611 | } | |
612 | ||
613 | static int hackrf_free_stream_bufs(struct hackrf_dev *dev) | |
614 | { | |
615 | if (dev->flags & USB_STATE_URB_BUF) { | |
616 | while (dev->buf_num) { | |
617 | dev->buf_num--; | |
618 | dev_dbg(dev->dev, "free buf=%d\n", dev->buf_num); | |
619 | usb_free_coherent(dev->udev, dev->buf_size, | |
620 | dev->buf_list[dev->buf_num], | |
621 | dev->dma_addr[dev->buf_num]); | |
622 | } | |
623 | } | |
624 | dev->flags &= ~USB_STATE_URB_BUF; | |
625 | ||
626 | return 0; | |
627 | } | |
628 | ||
629 | static int hackrf_alloc_stream_bufs(struct hackrf_dev *dev) | |
630 | { | |
631 | dev->buf_num = 0; | |
632 | dev->buf_size = BULK_BUFFER_SIZE; | |
633 | ||
634 | dev_dbg(dev->dev, "all in all I will use %u bytes for streaming\n", | |
635 | MAX_BULK_BUFS * BULK_BUFFER_SIZE); | |
636 | ||
637 | for (dev->buf_num = 0; dev->buf_num < MAX_BULK_BUFS; dev->buf_num++) { | |
638 | dev->buf_list[dev->buf_num] = usb_alloc_coherent(dev->udev, | |
639 | BULK_BUFFER_SIZE, GFP_ATOMIC, | |
640 | &dev->dma_addr[dev->buf_num]); | |
641 | if (!dev->buf_list[dev->buf_num]) { | |
642 | dev_dbg(dev->dev, "alloc buf=%d failed\n", | |
643 | dev->buf_num); | |
644 | hackrf_free_stream_bufs(dev); | |
645 | return -ENOMEM; | |
646 | } | |
647 | ||
648 | dev_dbg(dev->dev, "alloc buf=%d %p (dma %llu)\n", dev->buf_num, | |
649 | dev->buf_list[dev->buf_num], | |
650 | (long long)dev->dma_addr[dev->buf_num]); | |
651 | dev->flags |= USB_STATE_URB_BUF; | |
652 | } | |
653 | ||
654 | return 0; | |
655 | } | |
656 | ||
657 | static int hackrf_free_urbs(struct hackrf_dev *dev) | |
658 | { | |
659 | int i; | |
660 | ||
661 | hackrf_kill_urbs(dev); | |
662 | ||
663 | for (i = dev->urbs_initialized - 1; i >= 0; i--) { | |
664 | if (dev->urb_list[i]) { | |
665 | dev_dbg(dev->dev, "free urb=%d\n", i); | |
666 | /* free the URBs */ | |
667 | usb_free_urb(dev->urb_list[i]); | |
668 | } | |
669 | } | |
670 | dev->urbs_initialized = 0; | |
671 | ||
672 | return 0; | |
673 | } | |
674 | ||
8bc4a9ed | 675 | static int hackrf_alloc_urbs(struct hackrf_dev *dev, bool rcv) |
969ec1f6 AP |
676 | { |
677 | int i, j; | |
8bc4a9ed AP |
678 | unsigned int pipe; |
679 | usb_complete_t complete; | |
680 | ||
681 | if (rcv) { | |
682 | pipe = usb_rcvbulkpipe(dev->udev, 0x81); | |
683 | complete = &hackrf_urb_complete_in; | |
684 | } else { | |
685 | pipe = usb_sndbulkpipe(dev->udev, 0x02); | |
686 | complete = &hackrf_urb_complete_out; | |
687 | } | |
969ec1f6 AP |
688 | |
689 | /* allocate the URBs */ | |
690 | for (i = 0; i < MAX_BULK_BUFS; i++) { | |
691 | dev_dbg(dev->dev, "alloc urb=%d\n", i); | |
692 | dev->urb_list[i] = usb_alloc_urb(0, GFP_ATOMIC); | |
693 | if (!dev->urb_list[i]) { | |
969ec1f6 AP |
694 | for (j = 0; j < i; j++) |
695 | usb_free_urb(dev->urb_list[j]); | |
696 | return -ENOMEM; | |
697 | } | |
698 | usb_fill_bulk_urb(dev->urb_list[i], | |
699 | dev->udev, | |
8bc4a9ed | 700 | pipe, |
969ec1f6 AP |
701 | dev->buf_list[i], |
702 | BULK_BUFFER_SIZE, | |
8bc4a9ed | 703 | complete, dev); |
969ec1f6 AP |
704 | |
705 | dev->urb_list[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; | |
706 | dev->urb_list[i]->transfer_dma = dev->dma_addr[i]; | |
707 | dev->urbs_initialized++; | |
708 | } | |
709 | ||
710 | return 0; | |
711 | } | |
712 | ||
969ec1f6 AP |
713 | /* The user yanked out the cable... */ |
714 | static void hackrf_disconnect(struct usb_interface *intf) | |
715 | { | |
716 | struct v4l2_device *v = usb_get_intfdata(intf); | |
717 | struct hackrf_dev *dev = container_of(v, struct hackrf_dev, v4l2_dev); | |
718 | ||
719 | dev_dbg(dev->dev, "\n"); | |
720 | ||
721 | mutex_lock(&dev->vb_queue_lock); | |
722 | mutex_lock(&dev->v4l2_lock); | |
723 | /* No need to keep the urbs around after disconnection */ | |
724 | dev->udev = NULL; | |
725 | v4l2_device_disconnect(&dev->v4l2_dev); | |
8bc4a9ed AP |
726 | video_unregister_device(&dev->tx_vdev); |
727 | video_unregister_device(&dev->rx_vdev); | |
969ec1f6 AP |
728 | mutex_unlock(&dev->v4l2_lock); |
729 | mutex_unlock(&dev->vb_queue_lock); | |
730 | ||
731 | v4l2_device_put(&dev->v4l2_dev); | |
732 | } | |
733 | ||
734 | /* Videobuf2 operations */ | |
8bc4a9ed AP |
735 | static void hackrf_return_all_buffers(struct vb2_queue *vq, |
736 | enum vb2_buffer_state state) | |
737 | { | |
738 | struct hackrf_dev *dev = vb2_get_drv_priv(vq); | |
739 | struct usb_interface *intf = dev->intf; | |
740 | struct hackrf_buffer *buffer, *node; | |
741 | struct list_head *buffer_list; | |
742 | unsigned long flags; | |
743 | ||
744 | dev_dbg(&intf->dev, "\n"); | |
745 | ||
746 | if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE) | |
747 | buffer_list = &dev->rx_buffer_list; | |
748 | else | |
749 | buffer_list = &dev->tx_buffer_list; | |
750 | ||
751 | spin_lock_irqsave(&dev->buffer_list_lock, flags); | |
752 | list_for_each_entry_safe(buffer, node, buffer_list, list) { | |
753 | dev_dbg(&intf->dev, "list_for_each_entry_safe\n"); | |
754 | vb2_buffer_done(&buffer->vb.vb2_buf, state); | |
755 | list_del(&buffer->list); | |
756 | } | |
757 | spin_unlock_irqrestore(&dev->buffer_list_lock, flags); | |
758 | } | |
759 | ||
969ec1f6 | 760 | static int hackrf_queue_setup(struct vb2_queue *vq, |
df9ecb0c | 761 | unsigned int *nbuffers, |
36c0f8b3 | 762 | unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[]) |
969ec1f6 AP |
763 | { |
764 | struct hackrf_dev *dev = vb2_get_drv_priv(vq); | |
765 | ||
766 | dev_dbg(dev->dev, "nbuffers=%d\n", *nbuffers); | |
767 | ||
768 | /* Need at least 8 buffers */ | |
769 | if (vq->num_buffers + *nbuffers < 8) | |
770 | *nbuffers = 8 - vq->num_buffers; | |
771 | *nplanes = 1; | |
772 | sizes[0] = PAGE_ALIGN(dev->buffersize); | |
773 | ||
774 | dev_dbg(dev->dev, "nbuffers=%d sizes[0]=%d\n", *nbuffers, sizes[0]); | |
775 | return 0; | |
776 | } | |
777 | ||
778 | static void hackrf_buf_queue(struct vb2_buffer *vb) | |
779 | { | |
2d700715 | 780 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
8bc4a9ed AP |
781 | struct vb2_queue *vq = vb->vb2_queue; |
782 | struct hackrf_dev *dev = vb2_get_drv_priv(vq); | |
783 | struct hackrf_buffer *buffer = container_of(vbuf, struct hackrf_buffer, vb); | |
784 | struct list_head *buffer_list; | |
969ec1f6 AP |
785 | unsigned long flags; |
786 | ||
8bc4a9ed AP |
787 | dev_dbg_ratelimited(&dev->intf->dev, "\n"); |
788 | ||
789 | if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE) | |
790 | buffer_list = &dev->rx_buffer_list; | |
791 | else | |
792 | buffer_list = &dev->tx_buffer_list; | |
793 | ||
794 | spin_lock_irqsave(&dev->buffer_list_lock, flags); | |
795 | list_add_tail(&buffer->list, buffer_list); | |
796 | spin_unlock_irqrestore(&dev->buffer_list_lock, flags); | |
969ec1f6 AP |
797 | } |
798 | ||
799 | static int hackrf_start_streaming(struct vb2_queue *vq, unsigned int count) | |
800 | { | |
801 | struct hackrf_dev *dev = vb2_get_drv_priv(vq); | |
8bc4a9ed | 802 | struct usb_interface *intf = dev->intf; |
969ec1f6 | 803 | int ret; |
8bc4a9ed | 804 | unsigned int mode; |
969ec1f6 | 805 | |
8bc4a9ed | 806 | dev_dbg(&intf->dev, "count=%i\n", count); |
969ec1f6 AP |
807 | |
808 | mutex_lock(&dev->v4l2_lock); | |
809 | ||
8bc4a9ed AP |
810 | /* Allow only RX or TX, not both same time */ |
811 | if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE) { | |
812 | if (test_bit(TX_ON, &dev->flags)) { | |
813 | ret = -EBUSY; | |
814 | goto err_hackrf_return_all_buffers; | |
815 | } | |
969ec1f6 | 816 | |
8bc4a9ed AP |
817 | mode = 1; |
818 | set_bit(RX_ON, &dev->flags); | |
819 | } else { | |
820 | if (test_bit(RX_ON, &dev->flags)) { | |
821 | ret = -EBUSY; | |
822 | goto err_hackrf_return_all_buffers; | |
823 | } | |
824 | ||
825 | mode = 2; | |
826 | set_bit(TX_ON, &dev->flags); | |
827 | } | |
828 | ||
829 | dev->sequence = 0; | |
969ec1f6 AP |
830 | |
831 | ret = hackrf_alloc_stream_bufs(dev); | |
832 | if (ret) | |
833 | goto err; | |
834 | ||
8bc4a9ed | 835 | ret = hackrf_alloc_urbs(dev, (mode == 1)); |
969ec1f6 AP |
836 | if (ret) |
837 | goto err; | |
838 | ||
839 | ret = hackrf_submit_urbs(dev); | |
840 | if (ret) | |
841 | goto err; | |
842 | ||
eec20f06 AP |
843 | ret = hackrf_set_params(dev); |
844 | if (ret) | |
845 | goto err; | |
846 | ||
969ec1f6 | 847 | /* start hardware streaming */ |
8bc4a9ed | 848 | ret = hackrf_ctrl_msg(dev, CMD_SET_TRANSCEIVER_MODE, mode, 0, NULL, 0); |
969ec1f6 AP |
849 | if (ret) |
850 | goto err; | |
851 | ||
8bc4a9ed AP |
852 | mutex_unlock(&dev->v4l2_lock); |
853 | ||
854 | return 0; | |
969ec1f6 AP |
855 | err: |
856 | hackrf_kill_urbs(dev); | |
857 | hackrf_free_urbs(dev); | |
858 | hackrf_free_stream_bufs(dev); | |
8bc4a9ed AP |
859 | clear_bit(RX_ON, &dev->flags); |
860 | clear_bit(TX_ON, &dev->flags); | |
861 | err_hackrf_return_all_buffers: | |
862 | hackrf_return_all_buffers(vq, VB2_BUF_STATE_QUEUED); | |
969ec1f6 | 863 | mutex_unlock(&dev->v4l2_lock); |
8bc4a9ed | 864 | dev_dbg(&intf->dev, "failed=%d\n", ret); |
969ec1f6 AP |
865 | return ret; |
866 | } | |
867 | ||
868 | static void hackrf_stop_streaming(struct vb2_queue *vq) | |
869 | { | |
870 | struct hackrf_dev *dev = vb2_get_drv_priv(vq); | |
8bc4a9ed | 871 | struct usb_interface *intf = dev->intf; |
969ec1f6 | 872 | |
8bc4a9ed | 873 | dev_dbg(&intf->dev, "\n"); |
969ec1f6 AP |
874 | |
875 | mutex_lock(&dev->v4l2_lock); | |
876 | ||
877 | /* stop hardware streaming */ | |
878 | hackrf_ctrl_msg(dev, CMD_SET_TRANSCEIVER_MODE, 0, 0, NULL, 0); | |
879 | ||
880 | hackrf_kill_urbs(dev); | |
881 | hackrf_free_urbs(dev); | |
882 | hackrf_free_stream_bufs(dev); | |
883 | ||
8bc4a9ed | 884 | hackrf_return_all_buffers(vq, VB2_BUF_STATE_ERROR); |
969ec1f6 | 885 | |
8bc4a9ed AP |
886 | if (vq->type == V4L2_BUF_TYPE_SDR_CAPTURE) |
887 | clear_bit(RX_ON, &dev->flags); | |
888 | else | |
889 | clear_bit(TX_ON, &dev->flags); | |
969ec1f6 AP |
890 | |
891 | mutex_unlock(&dev->v4l2_lock); | |
892 | } | |
893 | ||
894 | static struct vb2_ops hackrf_vb2_ops = { | |
895 | .queue_setup = hackrf_queue_setup, | |
896 | .buf_queue = hackrf_buf_queue, | |
897 | .start_streaming = hackrf_start_streaming, | |
898 | .stop_streaming = hackrf_stop_streaming, | |
899 | .wait_prepare = vb2_ops_wait_prepare, | |
900 | .wait_finish = vb2_ops_wait_finish, | |
901 | }; | |
902 | ||
903 | static int hackrf_querycap(struct file *file, void *fh, | |
904 | struct v4l2_capability *cap) | |
905 | { | |
906 | struct hackrf_dev *dev = video_drvdata(file); | |
8bc4a9ed AP |
907 | struct usb_interface *intf = dev->intf; |
908 | struct video_device *vdev = video_devdata(file); | |
969ec1f6 | 909 | |
8bc4a9ed AP |
910 | dev_dbg(&intf->dev, "\n"); |
911 | ||
912 | if (vdev->vfl_dir == VFL_DIR_RX) | |
913 | cap->device_caps = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER | | |
914 | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; | |
969ec1f6 | 915 | |
8bc4a9ed AP |
916 | else |
917 | cap->device_caps = V4L2_CAP_SDR_OUTPUT | V4L2_CAP_MODULATOR | | |
918 | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; | |
919 | ||
920 | cap->capabilities = V4L2_CAP_SDR_CAPTURE | V4L2_CAP_TUNER | | |
921 | V4L2_CAP_SDR_OUTPUT | V4L2_CAP_MODULATOR | | |
922 | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE | | |
923 | V4L2_CAP_DEVICE_CAPS; | |
969ec1f6 | 924 | strlcpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); |
8bc4a9ed | 925 | strlcpy(cap->card, dev->rx_vdev.name, sizeof(cap->card)); |
969ec1f6 | 926 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); |
969ec1f6 AP |
927 | |
928 | return 0; | |
929 | } | |
930 | ||
8bc4a9ed AP |
931 | static int hackrf_s_fmt_sdr(struct file *file, void *priv, |
932 | struct v4l2_format *f) | |
969ec1f6 AP |
933 | { |
934 | struct hackrf_dev *dev = video_drvdata(file); | |
8bc4a9ed AP |
935 | struct video_device *vdev = video_devdata(file); |
936 | struct vb2_queue *q; | |
969ec1f6 AP |
937 | int i; |
938 | ||
939 | dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", | |
940 | (char *)&f->fmt.sdr.pixelformat); | |
941 | ||
8bc4a9ed AP |
942 | if (vdev->vfl_dir == VFL_DIR_RX) |
943 | q = &dev->rx_vb2_queue; | |
944 | else | |
945 | q = &dev->tx_vb2_queue; | |
946 | ||
969ec1f6 AP |
947 | if (vb2_is_busy(q)) |
948 | return -EBUSY; | |
949 | ||
950 | memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); | |
951 | for (i = 0; i < NUM_FORMATS; i++) { | |
952 | if (f->fmt.sdr.pixelformat == formats[i].pixelformat) { | |
953 | dev->pixelformat = formats[i].pixelformat; | |
954 | dev->buffersize = formats[i].buffersize; | |
955 | f->fmt.sdr.buffersize = formats[i].buffersize; | |
956 | return 0; | |
957 | } | |
958 | } | |
959 | ||
960 | dev->pixelformat = formats[0].pixelformat; | |
961 | dev->buffersize = formats[0].buffersize; | |
962 | f->fmt.sdr.pixelformat = formats[0].pixelformat; | |
963 | f->fmt.sdr.buffersize = formats[0].buffersize; | |
964 | ||
965 | return 0; | |
966 | } | |
967 | ||
8bc4a9ed AP |
968 | static int hackrf_g_fmt_sdr(struct file *file, void *priv, |
969 | struct v4l2_format *f) | |
969ec1f6 AP |
970 | { |
971 | struct hackrf_dev *dev = video_drvdata(file); | |
972 | ||
973 | dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", | |
974 | (char *)&dev->pixelformat); | |
975 | ||
976 | memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); | |
977 | f->fmt.sdr.pixelformat = dev->pixelformat; | |
978 | f->fmt.sdr.buffersize = dev->buffersize; | |
979 | ||
980 | return 0; | |
981 | } | |
982 | ||
8bc4a9ed AP |
983 | static int hackrf_try_fmt_sdr(struct file *file, void *priv, |
984 | struct v4l2_format *f) | |
969ec1f6 AP |
985 | { |
986 | struct hackrf_dev *dev = video_drvdata(file); | |
987 | int i; | |
988 | ||
989 | dev_dbg(dev->dev, "pixelformat fourcc %4.4s\n", | |
990 | (char *)&f->fmt.sdr.pixelformat); | |
991 | ||
992 | memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved)); | |
993 | for (i = 0; i < NUM_FORMATS; i++) { | |
994 | if (formats[i].pixelformat == f->fmt.sdr.pixelformat) { | |
995 | f->fmt.sdr.buffersize = formats[i].buffersize; | |
996 | return 0; | |
997 | } | |
998 | } | |
999 | ||
1000 | f->fmt.sdr.pixelformat = formats[0].pixelformat; | |
1001 | f->fmt.sdr.buffersize = formats[0].buffersize; | |
1002 | ||
1003 | return 0; | |
1004 | } | |
1005 | ||
8bc4a9ed AP |
1006 | static int hackrf_enum_fmt_sdr(struct file *file, void *priv, |
1007 | struct v4l2_fmtdesc *f) | |
969ec1f6 AP |
1008 | { |
1009 | struct hackrf_dev *dev = video_drvdata(file); | |
1010 | ||
1011 | dev_dbg(dev->dev, "index=%d\n", f->index); | |
1012 | ||
1013 | if (f->index >= NUM_FORMATS) | |
1014 | return -EINVAL; | |
1015 | ||
969ec1f6 AP |
1016 | f->pixelformat = formats[f->index].pixelformat; |
1017 | ||
1018 | return 0; | |
1019 | } | |
1020 | ||
1021 | static int hackrf_s_tuner(struct file *file, void *priv, | |
1022 | const struct v4l2_tuner *v) | |
1023 | { | |
1024 | struct hackrf_dev *dev = video_drvdata(file); | |
1025 | int ret; | |
1026 | ||
1027 | dev_dbg(dev->dev, "index=%d\n", v->index); | |
1028 | ||
1029 | if (v->index == 0) | |
1030 | ret = 0; | |
1031 | else if (v->index == 1) | |
1032 | ret = 0; | |
1033 | else | |
1034 | ret = -EINVAL; | |
1035 | ||
1036 | return ret; | |
1037 | } | |
1038 | ||
1039 | static int hackrf_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v) | |
1040 | { | |
1041 | struct hackrf_dev *dev = video_drvdata(file); | |
1042 | int ret; | |
1043 | ||
1044 | dev_dbg(dev->dev, "index=%d\n", v->index); | |
1045 | ||
1046 | if (v->index == 0) { | |
1047 | strlcpy(v->name, "HackRF ADC", sizeof(v->name)); | |
8bc4a9ed | 1048 | v->type = V4L2_TUNER_SDR; |
969ec1f6 | 1049 | v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; |
8bc4a9ed AP |
1050 | v->rangelow = bands_adc_dac[0].rangelow; |
1051 | v->rangehigh = bands_adc_dac[0].rangehigh; | |
969ec1f6 AP |
1052 | ret = 0; |
1053 | } else if (v->index == 1) { | |
1054 | strlcpy(v->name, "HackRF RF", sizeof(v->name)); | |
1055 | v->type = V4L2_TUNER_RF; | |
1056 | v->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; | |
8bc4a9ed AP |
1057 | v->rangelow = bands_rx_tx[0].rangelow; |
1058 | v->rangehigh = bands_rx_tx[0].rangehigh; | |
1059 | ret = 0; | |
1060 | } else { | |
1061 | ret = -EINVAL; | |
1062 | } | |
1063 | ||
1064 | return ret; | |
1065 | } | |
1066 | ||
1067 | static int hackrf_s_modulator(struct file *file, void *fh, | |
1068 | const struct v4l2_modulator *a) | |
1069 | { | |
1070 | struct hackrf_dev *dev = video_drvdata(file); | |
1071 | ||
1072 | dev_dbg(dev->dev, "index=%d\n", a->index); | |
1073 | ||
1074 | return a->index > 1 ? -EINVAL : 0; | |
1075 | } | |
1076 | ||
1077 | static int hackrf_g_modulator(struct file *file, void *fh, | |
1078 | struct v4l2_modulator *a) | |
1079 | { | |
1080 | struct hackrf_dev *dev = video_drvdata(file); | |
1081 | int ret; | |
1082 | ||
1083 | dev_dbg(dev->dev, "index=%d\n", a->index); | |
1084 | ||
1085 | if (a->index == 0) { | |
1086 | strlcpy(a->name, "HackRF DAC", sizeof(a->name)); | |
1087 | a->type = V4L2_TUNER_SDR; | |
1088 | a->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; | |
1089 | a->rangelow = bands_adc_dac[0].rangelow; | |
1090 | a->rangehigh = bands_adc_dac[0].rangehigh; | |
1091 | ret = 0; | |
1092 | } else if (a->index == 1) { | |
1093 | strlcpy(a->name, "HackRF RF", sizeof(a->name)); | |
1094 | a->type = V4L2_TUNER_RF; | |
1095 | a->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS; | |
1096 | a->rangelow = bands_rx_tx[0].rangelow; | |
1097 | a->rangehigh = bands_rx_tx[0].rangehigh; | |
969ec1f6 AP |
1098 | ret = 0; |
1099 | } else { | |
1100 | ret = -EINVAL; | |
1101 | } | |
1102 | ||
1103 | return ret; | |
1104 | } | |
1105 | ||
1106 | static int hackrf_s_frequency(struct file *file, void *priv, | |
1107 | const struct v4l2_frequency *f) | |
1108 | { | |
1109 | struct hackrf_dev *dev = video_drvdata(file); | |
eec20f06 | 1110 | struct usb_interface *intf = dev->intf; |
8bc4a9ed | 1111 | struct video_device *vdev = video_devdata(file); |
969ec1f6 | 1112 | int ret; |
8bc4a9ed | 1113 | unsigned int uitmp; |
969ec1f6 | 1114 | |
eec20f06 | 1115 | dev_dbg(&intf->dev, "tuner=%d type=%d frequency=%u\n", |
969ec1f6 AP |
1116 | f->tuner, f->type, f->frequency); |
1117 | ||
1118 | if (f->tuner == 0) { | |
8bc4a9ed AP |
1119 | uitmp = clamp(f->frequency, bands_adc_dac[0].rangelow, |
1120 | bands_adc_dac[0].rangehigh); | |
1121 | if (vdev->vfl_dir == VFL_DIR_RX) { | |
1122 | dev->f_adc = uitmp; | |
1123 | set_bit(RX_ADC_FREQUENCY, &dev->flags); | |
1124 | } else { | |
1125 | dev->f_dac = uitmp; | |
1126 | set_bit(TX_DAC_FREQUENCY, &dev->flags); | |
1127 | } | |
969ec1f6 | 1128 | } else if (f->tuner == 1) { |
8bc4a9ed AP |
1129 | uitmp = clamp(f->frequency, bands_rx_tx[0].rangelow, |
1130 | bands_rx_tx[0].rangehigh); | |
1131 | if (vdev->vfl_dir == VFL_DIR_RX) { | |
1132 | dev->f_rx = uitmp; | |
1133 | set_bit(RX_RF_FREQUENCY, &dev->flags); | |
1134 | } else { | |
1135 | dev->f_tx = uitmp; | |
1136 | set_bit(TX_RF_FREQUENCY, &dev->flags); | |
1137 | } | |
969ec1f6 AP |
1138 | } else { |
1139 | ret = -EINVAL; | |
eec20f06 | 1140 | goto err; |
969ec1f6 AP |
1141 | } |
1142 | ||
eec20f06 AP |
1143 | ret = hackrf_set_params(dev); |
1144 | if (ret) | |
1145 | goto err; | |
1146 | ||
1147 | return 0; | |
1148 | err: | |
1149 | dev_dbg(&intf->dev, "failed=%d\n", ret); | |
969ec1f6 AP |
1150 | return ret; |
1151 | } | |
1152 | ||
1153 | static int hackrf_g_frequency(struct file *file, void *priv, | |
1154 | struct v4l2_frequency *f) | |
1155 | { | |
1156 | struct hackrf_dev *dev = video_drvdata(file); | |
8bc4a9ed AP |
1157 | struct usb_interface *intf = dev->intf; |
1158 | struct video_device *vdev = video_devdata(file); | |
969ec1f6 AP |
1159 | int ret; |
1160 | ||
1161 | dev_dbg(dev->dev, "tuner=%d type=%d\n", f->tuner, f->type); | |
1162 | ||
1163 | if (f->tuner == 0) { | |
8bc4a9ed AP |
1164 | f->type = V4L2_TUNER_SDR; |
1165 | if (vdev->vfl_dir == VFL_DIR_RX) | |
1166 | f->frequency = dev->f_adc; | |
1167 | else | |
1168 | f->frequency = dev->f_dac; | |
969ec1f6 AP |
1169 | } else if (f->tuner == 1) { |
1170 | f->type = V4L2_TUNER_RF; | |
8bc4a9ed AP |
1171 | if (vdev->vfl_dir == VFL_DIR_RX) |
1172 | f->frequency = dev->f_rx; | |
1173 | else | |
1174 | f->frequency = dev->f_tx; | |
969ec1f6 AP |
1175 | } else { |
1176 | ret = -EINVAL; | |
8bc4a9ed | 1177 | goto err; |
969ec1f6 AP |
1178 | } |
1179 | ||
8bc4a9ed AP |
1180 | return 0; |
1181 | err: | |
1182 | dev_dbg(&intf->dev, "failed=%d\n", ret); | |
969ec1f6 AP |
1183 | return ret; |
1184 | } | |
1185 | ||
1186 | static int hackrf_enum_freq_bands(struct file *file, void *priv, | |
1187 | struct v4l2_frequency_band *band) | |
1188 | { | |
1189 | struct hackrf_dev *dev = video_drvdata(file); | |
1190 | int ret; | |
1191 | ||
1192 | dev_dbg(dev->dev, "tuner=%d type=%d index=%d\n", | |
1193 | band->tuner, band->type, band->index); | |
1194 | ||
1195 | if (band->tuner == 0) { | |
8bc4a9ed | 1196 | if (band->index >= ARRAY_SIZE(bands_adc_dac)) { |
969ec1f6 AP |
1197 | ret = -EINVAL; |
1198 | } else { | |
8bc4a9ed | 1199 | *band = bands_adc_dac[band->index]; |
969ec1f6 AP |
1200 | ret = 0; |
1201 | } | |
1202 | } else if (band->tuner == 1) { | |
8bc4a9ed | 1203 | if (band->index >= ARRAY_SIZE(bands_rx_tx)) { |
969ec1f6 AP |
1204 | ret = -EINVAL; |
1205 | } else { | |
8bc4a9ed | 1206 | *band = bands_rx_tx[band->index]; |
969ec1f6 AP |
1207 | ret = 0; |
1208 | } | |
1209 | } else { | |
1210 | ret = -EINVAL; | |
1211 | } | |
1212 | ||
1213 | return ret; | |
1214 | } | |
1215 | ||
1216 | static const struct v4l2_ioctl_ops hackrf_ioctl_ops = { | |
1217 | .vidioc_querycap = hackrf_querycap, | |
1218 | ||
8bc4a9ed AP |
1219 | .vidioc_s_fmt_sdr_cap = hackrf_s_fmt_sdr, |
1220 | .vidioc_g_fmt_sdr_cap = hackrf_g_fmt_sdr, | |
1221 | .vidioc_enum_fmt_sdr_cap = hackrf_enum_fmt_sdr, | |
1222 | .vidioc_try_fmt_sdr_cap = hackrf_try_fmt_sdr, | |
1223 | ||
1224 | .vidioc_s_fmt_sdr_out = hackrf_s_fmt_sdr, | |
1225 | .vidioc_g_fmt_sdr_out = hackrf_g_fmt_sdr, | |
1226 | .vidioc_enum_fmt_sdr_out = hackrf_enum_fmt_sdr, | |
1227 | .vidioc_try_fmt_sdr_out = hackrf_try_fmt_sdr, | |
969ec1f6 AP |
1228 | |
1229 | .vidioc_reqbufs = vb2_ioctl_reqbufs, | |
1230 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | |
1231 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, | |
1232 | .vidioc_querybuf = vb2_ioctl_querybuf, | |
1233 | .vidioc_qbuf = vb2_ioctl_qbuf, | |
1234 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | |
8bc4a9ed | 1235 | .vidioc_expbuf = vb2_ioctl_expbuf, |
969ec1f6 AP |
1236 | |
1237 | .vidioc_streamon = vb2_ioctl_streamon, | |
1238 | .vidioc_streamoff = vb2_ioctl_streamoff, | |
1239 | ||
1240 | .vidioc_s_tuner = hackrf_s_tuner, | |
1241 | .vidioc_g_tuner = hackrf_g_tuner, | |
1242 | ||
8bc4a9ed AP |
1243 | .vidioc_s_modulator = hackrf_s_modulator, |
1244 | .vidioc_g_modulator = hackrf_g_modulator, | |
1245 | ||
969ec1f6 AP |
1246 | .vidioc_s_frequency = hackrf_s_frequency, |
1247 | .vidioc_g_frequency = hackrf_g_frequency, | |
1248 | .vidioc_enum_freq_bands = hackrf_enum_freq_bands, | |
1249 | ||
1250 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | |
1251 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | |
1252 | .vidioc_log_status = v4l2_ctrl_log_status, | |
1253 | }; | |
1254 | ||
1255 | static const struct v4l2_file_operations hackrf_fops = { | |
1256 | .owner = THIS_MODULE, | |
1257 | .open = v4l2_fh_open, | |
1258 | .release = vb2_fop_release, | |
1259 | .read = vb2_fop_read, | |
8bc4a9ed | 1260 | .write = vb2_fop_write, |
969ec1f6 AP |
1261 | .poll = vb2_fop_poll, |
1262 | .mmap = vb2_fop_mmap, | |
1263 | .unlocked_ioctl = video_ioctl2, | |
1264 | }; | |
1265 | ||
1266 | static struct video_device hackrf_template = { | |
1267 | .name = "HackRF One", | |
1268 | .release = video_device_release_empty, | |
1269 | .fops = &hackrf_fops, | |
1270 | .ioctl_ops = &hackrf_ioctl_ops, | |
1271 | }; | |
1272 | ||
1273 | static void hackrf_video_release(struct v4l2_device *v) | |
1274 | { | |
1275 | struct hackrf_dev *dev = container_of(v, struct hackrf_dev, v4l2_dev); | |
1276 | ||
8bc4a9ed AP |
1277 | dev_dbg(dev->dev, "\n"); |
1278 | ||
1279 | v4l2_ctrl_handler_free(&dev->rx_ctrl_handler); | |
1280 | v4l2_ctrl_handler_free(&dev->tx_ctrl_handler); | |
969ec1f6 AP |
1281 | v4l2_device_unregister(&dev->v4l2_dev); |
1282 | kfree(dev); | |
1283 | } | |
1284 | ||
8bc4a9ed | 1285 | static int hackrf_s_ctrl_rx(struct v4l2_ctrl *ctrl) |
969ec1f6 AP |
1286 | { |
1287 | struct hackrf_dev *dev = container_of(ctrl->handler, | |
8bc4a9ed | 1288 | struct hackrf_dev, rx_ctrl_handler); |
eec20f06 | 1289 | struct usb_interface *intf = dev->intf; |
969ec1f6 AP |
1290 | int ret; |
1291 | ||
1292 | switch (ctrl->id) { | |
1293 | case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: | |
1294 | case V4L2_CID_RF_TUNER_BANDWIDTH: | |
eec20f06 | 1295 | set_bit(RX_BANDWIDTH, &dev->flags); |
969ec1f6 | 1296 | break; |
b3ae2966 | 1297 | case V4L2_CID_RF_TUNER_RF_GAIN: |
eec20f06 | 1298 | set_bit(RX_RF_GAIN, &dev->flags); |
b3ae2966 | 1299 | break; |
969ec1f6 | 1300 | case V4L2_CID_RF_TUNER_LNA_GAIN: |
eec20f06 | 1301 | set_bit(RX_LNA_GAIN, &dev->flags); |
969ec1f6 AP |
1302 | break; |
1303 | case V4L2_CID_RF_TUNER_IF_GAIN: | |
eec20f06 | 1304 | set_bit(RX_IF_GAIN, &dev->flags); |
969ec1f6 AP |
1305 | break; |
1306 | default: | |
eec20f06 AP |
1307 | dev_dbg(&intf->dev, "unknown ctrl: id=%d name=%s\n", |
1308 | ctrl->id, ctrl->name); | |
969ec1f6 | 1309 | ret = -EINVAL; |
eec20f06 | 1310 | goto err; |
969ec1f6 AP |
1311 | } |
1312 | ||
eec20f06 AP |
1313 | ret = hackrf_set_params(dev); |
1314 | if (ret) | |
1315 | goto err; | |
1316 | ||
1317 | return 0; | |
1318 | err: | |
1319 | dev_dbg(&intf->dev, "failed=%d\n", ret); | |
969ec1f6 AP |
1320 | return ret; |
1321 | } | |
1322 | ||
8bc4a9ed AP |
1323 | static int hackrf_s_ctrl_tx(struct v4l2_ctrl *ctrl) |
1324 | { | |
1325 | struct hackrf_dev *dev = container_of(ctrl->handler, | |
1326 | struct hackrf_dev, tx_ctrl_handler); | |
1327 | struct usb_interface *intf = dev->intf; | |
1328 | int ret; | |
1329 | ||
1330 | switch (ctrl->id) { | |
1331 | case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: | |
1332 | case V4L2_CID_RF_TUNER_BANDWIDTH: | |
1333 | set_bit(TX_BANDWIDTH, &dev->flags); | |
1334 | break; | |
1335 | case V4L2_CID_RF_TUNER_LNA_GAIN: | |
1336 | set_bit(TX_LNA_GAIN, &dev->flags); | |
1337 | break; | |
1338 | case V4L2_CID_RF_TUNER_RF_GAIN: | |
1339 | set_bit(TX_RF_GAIN, &dev->flags); | |
1340 | break; | |
1341 | default: | |
1342 | dev_dbg(&intf->dev, "unknown ctrl: id=%d name=%s\n", | |
1343 | ctrl->id, ctrl->name); | |
1344 | ret = -EINVAL; | |
1345 | goto err; | |
1346 | } | |
1347 | ||
1348 | ret = hackrf_set_params(dev); | |
1349 | if (ret) | |
1350 | goto err; | |
1351 | ||
1352 | return 0; | |
1353 | err: | |
1354 | dev_dbg(&intf->dev, "failed=%d\n", ret); | |
1355 | return ret; | |
1356 | } | |
1357 | ||
1358 | static const struct v4l2_ctrl_ops hackrf_ctrl_ops_rx = { | |
1359 | .s_ctrl = hackrf_s_ctrl_rx, | |
1360 | }; | |
1361 | ||
1362 | static const struct v4l2_ctrl_ops hackrf_ctrl_ops_tx = { | |
1363 | .s_ctrl = hackrf_s_ctrl_tx, | |
969ec1f6 AP |
1364 | }; |
1365 | ||
1366 | static int hackrf_probe(struct usb_interface *intf, | |
1367 | const struct usb_device_id *id) | |
1368 | { | |
1369 | struct hackrf_dev *dev; | |
1370 | int ret; | |
1371 | u8 u8tmp, buf[BUF_SIZE]; | |
1372 | ||
1373 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | |
8bc4a9ed AP |
1374 | if (!dev) { |
1375 | ret = -ENOMEM; | |
1376 | goto err; | |
1377 | } | |
969ec1f6 AP |
1378 | |
1379 | mutex_init(&dev->v4l2_lock); | |
1380 | mutex_init(&dev->vb_queue_lock); | |
8bc4a9ed AP |
1381 | spin_lock_init(&dev->buffer_list_lock); |
1382 | INIT_LIST_HEAD(&dev->rx_buffer_list); | |
1383 | INIT_LIST_HEAD(&dev->tx_buffer_list); | |
eec20f06 | 1384 | dev->intf = intf; |
969ec1f6 AP |
1385 | dev->dev = &intf->dev; |
1386 | dev->udev = interface_to_usbdev(intf); | |
969ec1f6 AP |
1387 | dev->pixelformat = formats[0].pixelformat; |
1388 | dev->buffersize = formats[0].buffersize; | |
8bc4a9ed AP |
1389 | dev->f_adc = bands_adc_dac[0].rangelow; |
1390 | dev->f_dac = bands_adc_dac[0].rangelow; | |
1391 | dev->f_rx = bands_rx_tx[0].rangelow; | |
1392 | dev->f_tx = bands_rx_tx[0].rangelow; | |
1393 | set_bit(RX_ADC_FREQUENCY, &dev->flags); | |
1394 | set_bit(TX_DAC_FREQUENCY, &dev->flags); | |
1395 | set_bit(RX_RF_FREQUENCY, &dev->flags); | |
1396 | set_bit(TX_RF_FREQUENCY, &dev->flags); | |
969ec1f6 AP |
1397 | |
1398 | /* Detect device */ | |
1399 | ret = hackrf_ctrl_msg(dev, CMD_BOARD_ID_READ, 0, 0, &u8tmp, 1); | |
1400 | if (ret == 0) | |
1401 | ret = hackrf_ctrl_msg(dev, CMD_VERSION_STRING_READ, 0, 0, | |
1402 | buf, BUF_SIZE); | |
1403 | if (ret) { | |
1404 | dev_err(dev->dev, "Could not detect board\n"); | |
8bc4a9ed | 1405 | goto err_kfree; |
969ec1f6 AP |
1406 | } |
1407 | ||
1408 | buf[BUF_SIZE - 1] = '\0'; | |
969ec1f6 AP |
1409 | dev_info(dev->dev, "Board ID: %02x\n", u8tmp); |
1410 | dev_info(dev->dev, "Firmware version: %s\n", buf); | |
1411 | ||
8bc4a9ed AP |
1412 | /* Init vb2 queue structure for receiver */ |
1413 | dev->rx_vb2_queue.type = V4L2_BUF_TYPE_SDR_CAPTURE; | |
1414 | dev->rx_vb2_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | | |
1415 | VB2_READ; | |
1416 | dev->rx_vb2_queue.ops = &hackrf_vb2_ops; | |
1417 | dev->rx_vb2_queue.mem_ops = &vb2_vmalloc_memops; | |
1418 | dev->rx_vb2_queue.drv_priv = dev; | |
1419 | dev->rx_vb2_queue.buf_struct_size = sizeof(struct hackrf_buffer); | |
1420 | dev->rx_vb2_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | |
1421 | ret = vb2_queue_init(&dev->rx_vb2_queue); | |
969ec1f6 | 1422 | if (ret) { |
8bc4a9ed AP |
1423 | dev_err(dev->dev, "Could not initialize rx vb2 queue\n"); |
1424 | goto err_kfree; | |
969ec1f6 AP |
1425 | } |
1426 | ||
8bc4a9ed AP |
1427 | /* Init vb2 queue structure for transmitter */ |
1428 | dev->tx_vb2_queue.type = V4L2_BUF_TYPE_SDR_OUTPUT; | |
1429 | dev->tx_vb2_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | | |
1430 | VB2_WRITE; | |
1431 | dev->tx_vb2_queue.ops = &hackrf_vb2_ops; | |
1432 | dev->tx_vb2_queue.mem_ops = &vb2_vmalloc_memops; | |
1433 | dev->tx_vb2_queue.drv_priv = dev; | |
1434 | dev->tx_vb2_queue.buf_struct_size = sizeof(struct hackrf_buffer); | |
1435 | dev->tx_vb2_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; | |
1436 | ret = vb2_queue_init(&dev->tx_vb2_queue); | |
1437 | if (ret) { | |
1438 | dev_err(dev->dev, "Could not initialize tx vb2 queue\n"); | |
1439 | goto err_kfree; | |
1440 | } | |
1441 | ||
1442 | /* Register controls for receiver */ | |
1443 | v4l2_ctrl_handler_init(&dev->rx_ctrl_handler, 5); | |
1444 | dev->rx_bandwidth_auto = v4l2_ctrl_new_std(&dev->rx_ctrl_handler, | |
1445 | &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, | |
1446 | 0, 1, 0, 1); | |
1447 | dev->rx_bandwidth = v4l2_ctrl_new_std(&dev->rx_ctrl_handler, | |
1448 | &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_BANDWIDTH, | |
1449 | 1750000, 28000000, 50000, 1750000); | |
1450 | v4l2_ctrl_auto_cluster(2, &dev->rx_bandwidth_auto, 0, false); | |
1451 | dev->rx_rf_gain = v4l2_ctrl_new_std(&dev->rx_ctrl_handler, | |
1452 | &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_RF_GAIN, 0, 12, 12, 0); | |
1453 | dev->rx_lna_gain = v4l2_ctrl_new_std(&dev->rx_ctrl_handler, | |
1454 | &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 40, 8, 0); | |
1455 | dev->rx_if_gain = v4l2_ctrl_new_std(&dev->rx_ctrl_handler, | |
1456 | &hackrf_ctrl_ops_rx, V4L2_CID_RF_TUNER_IF_GAIN, 0, 62, 2, 0); | |
1457 | if (dev->rx_ctrl_handler.error) { | |
1458 | ret = dev->rx_ctrl_handler.error; | |
1459 | dev_err(dev->dev, "Could not initialize controls\n"); | |
1460 | goto err_v4l2_ctrl_handler_free_rx; | |
1461 | } | |
d47fa531 | 1462 | v4l2_ctrl_grab(dev->rx_rf_gain, !hackrf_enable_rf_gain_ctrl); |
8bc4a9ed AP |
1463 | v4l2_ctrl_handler_setup(&dev->rx_ctrl_handler); |
1464 | ||
1465 | /* Register controls for transmitter */ | |
1466 | v4l2_ctrl_handler_init(&dev->tx_ctrl_handler, 4); | |
1467 | dev->tx_bandwidth_auto = v4l2_ctrl_new_std(&dev->tx_ctrl_handler, | |
1468 | &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, | |
1469 | 0, 1, 0, 1); | |
1470 | dev->tx_bandwidth = v4l2_ctrl_new_std(&dev->tx_ctrl_handler, | |
1471 | &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_BANDWIDTH, | |
1472 | 1750000, 28000000, 50000, 1750000); | |
1473 | v4l2_ctrl_auto_cluster(2, &dev->tx_bandwidth_auto, 0, false); | |
1474 | dev->tx_lna_gain = v4l2_ctrl_new_std(&dev->tx_ctrl_handler, | |
1475 | &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_LNA_GAIN, 0, 47, 1, 0); | |
1476 | dev->tx_rf_gain = v4l2_ctrl_new_std(&dev->tx_ctrl_handler, | |
1477 | &hackrf_ctrl_ops_tx, V4L2_CID_RF_TUNER_RF_GAIN, 0, 15, 15, 0); | |
1478 | if (dev->tx_ctrl_handler.error) { | |
1479 | ret = dev->tx_ctrl_handler.error; | |
1480 | dev_err(dev->dev, "Could not initialize controls\n"); | |
1481 | goto err_v4l2_ctrl_handler_free_tx; | |
1482 | } | |
d47fa531 | 1483 | v4l2_ctrl_grab(dev->tx_rf_gain, !hackrf_enable_rf_gain_ctrl); |
8bc4a9ed | 1484 | v4l2_ctrl_handler_setup(&dev->tx_ctrl_handler); |
969ec1f6 AP |
1485 | |
1486 | /* Register the v4l2_device structure */ | |
1487 | dev->v4l2_dev.release = hackrf_video_release; | |
1488 | ret = v4l2_device_register(&intf->dev, &dev->v4l2_dev); | |
1489 | if (ret) { | |
1490 | dev_err(dev->dev, "Failed to register v4l2-device (%d)\n", ret); | |
8bc4a9ed | 1491 | goto err_v4l2_ctrl_handler_free_tx; |
969ec1f6 AP |
1492 | } |
1493 | ||
8bc4a9ed AP |
1494 | /* Init video_device structure for receiver */ |
1495 | dev->rx_vdev = hackrf_template; | |
1496 | dev->rx_vdev.queue = &dev->rx_vb2_queue; | |
1497 | dev->rx_vdev.queue->lock = &dev->vb_queue_lock; | |
1498 | dev->rx_vdev.v4l2_dev = &dev->v4l2_dev; | |
1499 | dev->rx_vdev.ctrl_handler = &dev->rx_ctrl_handler; | |
1500 | dev->rx_vdev.lock = &dev->v4l2_lock; | |
1501 | dev->rx_vdev.vfl_dir = VFL_DIR_RX; | |
1502 | video_set_drvdata(&dev->rx_vdev, dev); | |
1503 | ret = video_register_device(&dev->rx_vdev, VFL_TYPE_SDR, -1); | |
1504 | if (ret) { | |
1505 | dev_err(dev->dev, | |
1506 | "Failed to register as video device (%d)\n", ret); | |
1507 | goto err_v4l2_device_unregister; | |
969ec1f6 | 1508 | } |
8bc4a9ed AP |
1509 | dev_info(dev->dev, "Registered as %s\n", |
1510 | video_device_node_name(&dev->rx_vdev)); | |
1511 | ||
1512 | /* Init video_device structure for transmitter */ | |
1513 | dev->tx_vdev = hackrf_template; | |
1514 | dev->tx_vdev.queue = &dev->tx_vb2_queue; | |
1515 | dev->tx_vdev.queue->lock = &dev->vb_queue_lock; | |
1516 | dev->tx_vdev.v4l2_dev = &dev->v4l2_dev; | |
1517 | dev->tx_vdev.ctrl_handler = &dev->tx_ctrl_handler; | |
1518 | dev->tx_vdev.lock = &dev->v4l2_lock; | |
1519 | dev->tx_vdev.vfl_dir = VFL_DIR_TX; | |
1520 | video_set_drvdata(&dev->tx_vdev, dev); | |
1521 | ret = video_register_device(&dev->tx_vdev, VFL_TYPE_SDR, -1); | |
969ec1f6 | 1522 | if (ret) { |
8bc4a9ed AP |
1523 | dev_err(dev->dev, |
1524 | "Failed to register as video device (%d)\n", ret); | |
1525 | goto err_video_unregister_device_rx; | |
969ec1f6 AP |
1526 | } |
1527 | dev_info(dev->dev, "Registered as %s\n", | |
8bc4a9ed AP |
1528 | video_device_node_name(&dev->tx_vdev)); |
1529 | ||
969ec1f6 AP |
1530 | dev_notice(dev->dev, "SDR API is still slightly experimental and functionality changes may follow\n"); |
1531 | return 0; | |
8bc4a9ed AP |
1532 | err_video_unregister_device_rx: |
1533 | video_unregister_device(&dev->rx_vdev); | |
1534 | err_v4l2_device_unregister: | |
969ec1f6 | 1535 | v4l2_device_unregister(&dev->v4l2_dev); |
8bc4a9ed AP |
1536 | err_v4l2_ctrl_handler_free_tx: |
1537 | v4l2_ctrl_handler_free(&dev->tx_ctrl_handler); | |
1538 | err_v4l2_ctrl_handler_free_rx: | |
1539 | v4l2_ctrl_handler_free(&dev->rx_ctrl_handler); | |
1540 | err_kfree: | |
969ec1f6 | 1541 | kfree(dev); |
8bc4a9ed | 1542 | err: |
eb35cf47 | 1543 | dev_dbg(&intf->dev, "failed=%d\n", ret); |
969ec1f6 AP |
1544 | return ret; |
1545 | } | |
1546 | ||
1547 | /* USB device ID list */ | |
1548 | static struct usb_device_id hackrf_id_table[] = { | |
1549 | { USB_DEVICE(0x1d50, 0x6089) }, /* HackRF One */ | |
1550 | { } | |
1551 | }; | |
1552 | MODULE_DEVICE_TABLE(usb, hackrf_id_table); | |
1553 | ||
1554 | /* USB subsystem interface */ | |
1555 | static struct usb_driver hackrf_driver = { | |
1556 | .name = KBUILD_MODNAME, | |
1557 | .probe = hackrf_probe, | |
1558 | .disconnect = hackrf_disconnect, | |
1559 | .id_table = hackrf_id_table, | |
1560 | }; | |
1561 | ||
1562 | module_usb_driver(hackrf_driver); | |
1563 | ||
1564 | MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); | |
1565 | MODULE_DESCRIPTION("HackRF"); | |
1566 | MODULE_LICENSE("GPL"); |