]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/media/platform/vivid/vivid-sdr-cap.c
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
[karo-tx-linux.git] / drivers / media / platform / vivid / vivid-sdr-cap.c
1 /*
2  * vivid-sdr-cap.c - software defined radio support functions.
3  *
4  * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5  *
6  * This program is free software; you may redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
11  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
12  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
13  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
14  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
15  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17  * SOFTWARE.
18  */
19
20 #include <linux/errno.h>
21 #include <linux/kernel.h>
22 #include <linux/delay.h>
23 #include <linux/kthread.h>
24 #include <linux/freezer.h>
25 #include <linux/videodev2.h>
26 #include <linux/v4l2-dv-timings.h>
27 #include <media/v4l2-common.h>
28 #include <media/v4l2-event.h>
29 #include <media/v4l2-dv-timings.h>
30 #include <linux/fixp-arith.h>
31
32 #include "vivid-core.h"
33 #include "vivid-ctrls.h"
34 #include "vivid-sdr-cap.h"
35
36 /* stream formats */
37 struct vivid_format {
38         u32     pixelformat;
39         u32     buffersize;
40 };
41
42 /* format descriptions for capture and preview */
43 static struct vivid_format formats[] = {
44         {
45                 .pixelformat    = V4L2_SDR_FMT_CU8,
46                 .buffersize     = SDR_CAP_SAMPLES_PER_BUF * 2,
47         }, {
48                 .pixelformat    = V4L2_SDR_FMT_CS8,
49                 .buffersize     = SDR_CAP_SAMPLES_PER_BUF * 2,
50         },
51 };
52
53 static const unsigned int NUM_FORMATS = ARRAY_SIZE(formats);
54
55 static const struct v4l2_frequency_band bands_adc[] = {
56         {
57                 .tuner = 0,
58                 .type = V4L2_TUNER_ADC,
59                 .index = 0,
60                 .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
61                 .rangelow   =  300000,
62                 .rangehigh  =  300000,
63         },
64         {
65                 .tuner = 0,
66                 .type = V4L2_TUNER_ADC,
67                 .index = 1,
68                 .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
69                 .rangelow   =  900001,
70                 .rangehigh  = 2800000,
71         },
72         {
73                 .tuner = 0,
74                 .type = V4L2_TUNER_ADC,
75                 .index = 2,
76                 .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
77                 .rangelow   = 3200000,
78                 .rangehigh  = 3200000,
79         },
80 };
81
82 /* ADC band midpoints */
83 #define BAND_ADC_0 ((bands_adc[0].rangehigh + bands_adc[1].rangelow) / 2)
84 #define BAND_ADC_1 ((bands_adc[1].rangehigh + bands_adc[2].rangelow) / 2)
85
86 static const struct v4l2_frequency_band bands_fm[] = {
87         {
88                 .tuner = 1,
89                 .type = V4L2_TUNER_RF,
90                 .index = 0,
91                 .capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS,
92                 .rangelow   =    50000000,
93                 .rangehigh  =  2000000000,
94         },
95 };
96
97 static void vivid_thread_sdr_cap_tick(struct vivid_dev *dev)
98 {
99         struct vivid_buffer *sdr_cap_buf = NULL;
100
101         dprintk(dev, 1, "SDR Capture Thread Tick\n");
102
103         /* Drop a certain percentage of buffers. */
104         if (dev->perc_dropped_buffers &&
105             prandom_u32_max(100) < dev->perc_dropped_buffers)
106                 return;
107
108         spin_lock(&dev->slock);
109         if (!list_empty(&dev->sdr_cap_active)) {
110                 sdr_cap_buf = list_entry(dev->sdr_cap_active.next,
111                                          struct vivid_buffer, list);
112                 list_del(&sdr_cap_buf->list);
113         }
114         spin_unlock(&dev->slock);
115
116         if (sdr_cap_buf) {
117                 sdr_cap_buf->vb.v4l2_buf.sequence = dev->sdr_cap_seq_count;
118                 vivid_sdr_cap_process(dev, sdr_cap_buf);
119                 v4l2_get_timestamp(&sdr_cap_buf->vb.v4l2_buf.timestamp);
120                 sdr_cap_buf->vb.v4l2_buf.timestamp.tv_sec += dev->time_wrap_offset;
121                 vb2_buffer_done(&sdr_cap_buf->vb, dev->dqbuf_error ?
122                                 VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
123                 dev->dqbuf_error = false;
124         }
125 }
126
127 static int vivid_thread_sdr_cap(void *data)
128 {
129         struct vivid_dev *dev = data;
130         u64 samples_since_start;
131         u64 buffers_since_start;
132         u64 next_jiffies_since_start;
133         unsigned long jiffies_since_start;
134         unsigned long cur_jiffies;
135         unsigned wait_jiffies;
136
137         dprintk(dev, 1, "SDR Capture Thread Start\n");
138
139         set_freezable();
140
141         /* Resets frame counters */
142         dev->sdr_cap_seq_offset = 0;
143         if (dev->seq_wrap)
144                 dev->sdr_cap_seq_offset = 0xffffff80U;
145         dev->jiffies_sdr_cap = jiffies;
146         dev->sdr_cap_seq_resync = false;
147
148         for (;;) {
149                 try_to_freeze();
150                 if (kthread_should_stop())
151                         break;
152
153                 mutex_lock(&dev->mutex);
154                 cur_jiffies = jiffies;
155                 if (dev->sdr_cap_seq_resync) {
156                         dev->jiffies_sdr_cap = cur_jiffies;
157                         dev->sdr_cap_seq_offset = dev->sdr_cap_seq_count + 1;
158                         dev->sdr_cap_seq_count = 0;
159                         dev->sdr_cap_seq_resync = false;
160                 }
161                 /* Calculate the number of jiffies since we started streaming */
162                 jiffies_since_start = cur_jiffies - dev->jiffies_sdr_cap;
163                 /* Get the number of buffers streamed since the start */
164                 buffers_since_start = (u64)jiffies_since_start * dev->sdr_adc_freq +
165                                       (HZ * SDR_CAP_SAMPLES_PER_BUF) / 2;
166                 do_div(buffers_since_start, HZ * SDR_CAP_SAMPLES_PER_BUF);
167
168                 /*
169                  * After more than 0xf0000000 (rounded down to a multiple of
170                  * 'jiffies-per-day' to ease jiffies_to_msecs calculation)
171                  * jiffies have passed since we started streaming reset the
172                  * counters and keep track of the sequence offset.
173                  */
174                 if (jiffies_since_start > JIFFIES_RESYNC) {
175                         dev->jiffies_sdr_cap = cur_jiffies;
176                         dev->sdr_cap_seq_offset = buffers_since_start;
177                         buffers_since_start = 0;
178                 }
179                 dev->sdr_cap_seq_count = buffers_since_start + dev->sdr_cap_seq_offset;
180
181                 vivid_thread_sdr_cap_tick(dev);
182                 mutex_unlock(&dev->mutex);
183
184                 /*
185                  * Calculate the number of samples streamed since we started,
186                  * not including the current buffer.
187                  */
188                 samples_since_start = buffers_since_start * SDR_CAP_SAMPLES_PER_BUF;
189
190                 /* And the number of jiffies since we started */
191                 jiffies_since_start = jiffies - dev->jiffies_sdr_cap;
192
193                 /* Increase by the number of samples in one buffer */
194                 samples_since_start += SDR_CAP_SAMPLES_PER_BUF;
195                 /*
196                  * Calculate when that next buffer is supposed to start
197                  * in jiffies since we started streaming.
198                  */
199                 next_jiffies_since_start = samples_since_start * HZ +
200                                            dev->sdr_adc_freq / 2;
201                 do_div(next_jiffies_since_start, dev->sdr_adc_freq);
202                 /* If it is in the past, then just schedule asap */
203                 if (next_jiffies_since_start < jiffies_since_start)
204                         next_jiffies_since_start = jiffies_since_start;
205
206                 wait_jiffies = next_jiffies_since_start - jiffies_since_start;
207                 schedule_timeout_interruptible(wait_jiffies ? wait_jiffies : 1);
208         }
209         dprintk(dev, 1, "SDR Capture Thread End\n");
210         return 0;
211 }
212
213 static int sdr_cap_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
214                        unsigned *nbuffers, unsigned *nplanes,
215                        unsigned sizes[], void *alloc_ctxs[])
216 {
217         /* 2 = max 16-bit sample returned */
218         sizes[0] = SDR_CAP_SAMPLES_PER_BUF * 2;
219         *nplanes = 1;
220         return 0;
221 }
222
223 static int sdr_cap_buf_prepare(struct vb2_buffer *vb)
224 {
225         struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
226         unsigned size = SDR_CAP_SAMPLES_PER_BUF * 2;
227
228         dprintk(dev, 1, "%s\n", __func__);
229
230         if (dev->buf_prepare_error) {
231                 /*
232                  * Error injection: test what happens if buf_prepare() returns
233                  * an error.
234                  */
235                 dev->buf_prepare_error = false;
236                 return -EINVAL;
237         }
238         if (vb2_plane_size(vb, 0) < size) {
239                 dprintk(dev, 1, "%s data will not fit into plane (%lu < %u)\n",
240                                 __func__, vb2_plane_size(vb, 0), size);
241                 return -EINVAL;
242         }
243         vb2_set_plane_payload(vb, 0, size);
244
245         return 0;
246 }
247
248 static void sdr_cap_buf_queue(struct vb2_buffer *vb)
249 {
250         struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
251         struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb);
252
253         dprintk(dev, 1, "%s\n", __func__);
254
255         spin_lock(&dev->slock);
256         list_add_tail(&buf->list, &dev->sdr_cap_active);
257         spin_unlock(&dev->slock);
258 }
259
260 static int sdr_cap_start_streaming(struct vb2_queue *vq, unsigned count)
261 {
262         struct vivid_dev *dev = vb2_get_drv_priv(vq);
263         int err = 0;
264
265         dprintk(dev, 1, "%s\n", __func__);
266         dev->sdr_cap_seq_count = 0;
267         if (dev->start_streaming_error) {
268                 dev->start_streaming_error = false;
269                 err = -EINVAL;
270         } else if (dev->kthread_sdr_cap == NULL) {
271                 dev->kthread_sdr_cap = kthread_run(vivid_thread_sdr_cap, dev,
272                                 "%s-sdr-cap", dev->v4l2_dev.name);
273
274                 if (IS_ERR(dev->kthread_sdr_cap)) {
275                         v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
276                         err = PTR_ERR(dev->kthread_sdr_cap);
277                         dev->kthread_sdr_cap = NULL;
278                 }
279         }
280         if (err) {
281                 struct vivid_buffer *buf, *tmp;
282
283                 list_for_each_entry_safe(buf, tmp, &dev->sdr_cap_active, list) {
284                         list_del(&buf->list);
285                         vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED);
286                 }
287         }
288         return err;
289 }
290
291 /* abort streaming and wait for last buffer */
292 static void sdr_cap_stop_streaming(struct vb2_queue *vq)
293 {
294         struct vivid_dev *dev = vb2_get_drv_priv(vq);
295
296         if (dev->kthread_sdr_cap == NULL)
297                 return;
298
299         while (!list_empty(&dev->sdr_cap_active)) {
300                 struct vivid_buffer *buf;
301
302                 buf = list_entry(dev->sdr_cap_active.next, struct vivid_buffer, list);
303                 list_del(&buf->list);
304                 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
305         }
306
307         /* shutdown control thread */
308         mutex_unlock(&dev->mutex);
309         kthread_stop(dev->kthread_sdr_cap);
310         dev->kthread_sdr_cap = NULL;
311         mutex_lock(&dev->mutex);
312 }
313
314 const struct vb2_ops vivid_sdr_cap_qops = {
315         .queue_setup            = sdr_cap_queue_setup,
316         .buf_prepare            = sdr_cap_buf_prepare,
317         .buf_queue              = sdr_cap_buf_queue,
318         .start_streaming        = sdr_cap_start_streaming,
319         .stop_streaming         = sdr_cap_stop_streaming,
320         .wait_prepare           = vb2_ops_wait_prepare,
321         .wait_finish            = vb2_ops_wait_finish,
322 };
323
324 int vivid_sdr_enum_freq_bands(struct file *file, void *fh, struct v4l2_frequency_band *band)
325 {
326         switch (band->tuner) {
327         case 0:
328                 if (band->index >= ARRAY_SIZE(bands_adc))
329                         return -EINVAL;
330                 *band = bands_adc[band->index];
331                 return 0;
332         case 1:
333                 if (band->index >= ARRAY_SIZE(bands_fm))
334                         return -EINVAL;
335                 *band = bands_fm[band->index];
336                 return 0;
337         default:
338                 return -EINVAL;
339         }
340 }
341
342 int vivid_sdr_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
343 {
344         struct vivid_dev *dev = video_drvdata(file);
345
346         switch (vf->tuner) {
347         case 0:
348                 vf->frequency = dev->sdr_adc_freq;
349                 vf->type = V4L2_TUNER_ADC;
350                 return 0;
351         case 1:
352                 vf->frequency = dev->sdr_fm_freq;
353                 vf->type = V4L2_TUNER_RF;
354                 return 0;
355         default:
356                 return -EINVAL;
357         }
358 }
359
360 int vivid_sdr_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
361 {
362         struct vivid_dev *dev = video_drvdata(file);
363         unsigned freq = vf->frequency;
364         unsigned band;
365
366         switch (vf->tuner) {
367         case 0:
368                 if (vf->type != V4L2_TUNER_ADC)
369                         return -EINVAL;
370                 if (freq < BAND_ADC_0)
371                         band = 0;
372                 else if (freq < BAND_ADC_1)
373                         band = 1;
374                 else
375                         band = 2;
376
377                 freq = clamp_t(unsigned, freq,
378                                 bands_adc[band].rangelow,
379                                 bands_adc[band].rangehigh);
380
381                 if (vb2_is_streaming(&dev->vb_sdr_cap_q) &&
382                     freq != dev->sdr_adc_freq) {
383                         /* resync the thread's timings */
384                         dev->sdr_cap_seq_resync = true;
385                 }
386                 dev->sdr_adc_freq = freq;
387                 return 0;
388         case 1:
389                 if (vf->type != V4L2_TUNER_RF)
390                         return -EINVAL;
391                 dev->sdr_fm_freq = clamp_t(unsigned, freq,
392                                 bands_fm[0].rangelow,
393                                 bands_fm[0].rangehigh);
394                 return 0;
395         default:
396                 return -EINVAL;
397         }
398 }
399
400 int vivid_sdr_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
401 {
402         switch (vt->index) {
403         case 0:
404                 strlcpy(vt->name, "ADC", sizeof(vt->name));
405                 vt->type = V4L2_TUNER_ADC;
406                 vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
407                 vt->rangelow = bands_adc[0].rangelow;
408                 vt->rangehigh = bands_adc[2].rangehigh;
409                 return 0;
410         case 1:
411                 strlcpy(vt->name, "RF", sizeof(vt->name));
412                 vt->type = V4L2_TUNER_RF;
413                 vt->capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS;
414                 vt->rangelow = bands_fm[0].rangelow;
415                 vt->rangehigh = bands_fm[0].rangehigh;
416                 return 0;
417         default:
418                 return -EINVAL;
419         }
420 }
421
422 int vivid_sdr_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
423 {
424         if (vt->index > 1)
425                 return -EINVAL;
426         return 0;
427 }
428
429 int vidioc_enum_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
430 {
431         if (f->index >= ARRAY_SIZE(formats))
432                 return -EINVAL;
433         f->pixelformat = formats[f->index].pixelformat;
434         return 0;
435 }
436
437 int vidioc_g_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
438 {
439         struct vivid_dev *dev = video_drvdata(file);
440
441         f->fmt.sdr.pixelformat = dev->sdr_pixelformat;
442         f->fmt.sdr.buffersize = dev->sdr_buffersize;
443         memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
444         return 0;
445 }
446
447 int vidioc_s_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
448 {
449         struct vivid_dev *dev = video_drvdata(file);
450         struct vb2_queue *q = &dev->vb_sdr_cap_q;
451         int i;
452
453         if (vb2_is_busy(q))
454                 return -EBUSY;
455
456         memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
457         for (i = 0; i < ARRAY_SIZE(formats); i++) {
458                 if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
459                         dev->sdr_pixelformat = formats[i].pixelformat;
460                         dev->sdr_buffersize = formats[i].buffersize;
461                         f->fmt.sdr.buffersize = formats[i].buffersize;
462                         return 0;
463                 }
464         }
465         dev->sdr_pixelformat = formats[0].pixelformat;
466         dev->sdr_buffersize = formats[0].buffersize;
467         f->fmt.sdr.pixelformat = formats[0].pixelformat;
468         f->fmt.sdr.buffersize = formats[0].buffersize;
469         return 0;
470 }
471
472 int vidioc_try_fmt_sdr_cap(struct file *file, void *fh, struct v4l2_format *f)
473 {
474         int i;
475
476         memset(f->fmt.sdr.reserved, 0, sizeof(f->fmt.sdr.reserved));
477         for (i = 0; i < ARRAY_SIZE(formats); i++) {
478                 if (formats[i].pixelformat == f->fmt.sdr.pixelformat) {
479                         f->fmt.sdr.buffersize = formats[i].buffersize;
480                         return 0;
481                 }
482         }
483         f->fmt.sdr.pixelformat = formats[0].pixelformat;
484         f->fmt.sdr.buffersize = formats[0].buffersize;
485         return 0;
486 }
487
488 #define FIXP_N    (15)
489 #define FIXP_FRAC (1 << FIXP_N)
490 #define FIXP_2PI  ((int)(2 * 3.141592653589 * FIXP_FRAC))
491
492 void vivid_sdr_cap_process(struct vivid_dev *dev, struct vivid_buffer *buf)
493 {
494         u8 *vbuf = vb2_plane_vaddr(&buf->vb, 0);
495         unsigned long i;
496         unsigned long plane_size = vb2_plane_size(&buf->vb, 0);
497         s32 src_phase_step;
498         s32 mod_phase_step;
499         s32 fixp_i;
500         s32 fixp_q;
501
502         /*
503          * TODO: Generated beep tone goes very crackly when sample rate is
504          * increased to ~1Msps or more. That is because of huge rounding error
505          * of phase angle caused by used cosine implementation.
506          */
507
508         /* calculate phase step */
509         #define BEEP_FREQ 1000 /* 1kHz beep */
510         src_phase_step = DIV_ROUND_CLOSEST(FIXP_2PI * BEEP_FREQ,
511                         dev->sdr_adc_freq);
512
513         for (i = 0; i < plane_size; i += 2) {
514                 mod_phase_step = fixp_cos32_rad(dev->sdr_fixp_src_phase,
515                                                 FIXP_2PI) >> (31 - FIXP_N);
516
517                 dev->sdr_fixp_src_phase += src_phase_step;
518                 dev->sdr_fixp_mod_phase += mod_phase_step / 4;
519
520                 /*
521                  * Transfer phases to [0 / 2xPI] in order to avoid variable
522                  * overflow and make it suitable for cosine implementation
523                  * used, which does not support negative angles.
524                  */
525                 while (dev->sdr_fixp_mod_phase < FIXP_2PI)
526                         dev->sdr_fixp_mod_phase += FIXP_2PI;
527                 while (dev->sdr_fixp_mod_phase > FIXP_2PI)
528                         dev->sdr_fixp_mod_phase -= FIXP_2PI;
529
530                 while (dev->sdr_fixp_src_phase > FIXP_2PI)
531                         dev->sdr_fixp_src_phase -= FIXP_2PI;
532
533                 fixp_i = fixp_cos32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
534                 fixp_q = fixp_sin32_rad(dev->sdr_fixp_mod_phase, FIXP_2PI);
535
536                 /* Normalize fraction values represented with 32 bit precision
537                  * to fixed point representation with FIXP_N bits */
538                 fixp_i >>= (31 - FIXP_N);
539                 fixp_q >>= (31 - FIXP_N);
540
541                 switch (dev->sdr_pixelformat) {
542                 case V4L2_SDR_FMT_CU8:
543                         /* convert 'fixp float' to u8 */
544                         /* u8 = X * 127.5 + 127.5; X is float [-1.0, +1.0] */
545                         fixp_i = fixp_i * 1275 + FIXP_FRAC * 1275;
546                         fixp_q = fixp_q * 1275 + FIXP_FRAC * 1275;
547                         *vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
548                         *vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
549                         break;
550                 case V4L2_SDR_FMT_CS8:
551                         /* convert 'fixp float' to s8 */
552                         fixp_i = fixp_i * 1275;
553                         fixp_q = fixp_q * 1275;
554                         *vbuf++ = DIV_ROUND_CLOSEST(fixp_i, FIXP_FRAC * 10);
555                         *vbuf++ = DIV_ROUND_CLOSEST(fixp_q, FIXP_FRAC * 10);
556                         break;
557                 default:
558                         break;
559                 }
560         }
561 }