root/drivers/media/platform/vivid/vivid-sdr-cap.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vivid_thread_sdr_cap_tick
  2. vivid_thread_sdr_cap
  3. sdr_cap_queue_setup
  4. sdr_cap_buf_prepare
  5. sdr_cap_buf_queue
  6. sdr_cap_start_streaming
  7. sdr_cap_stop_streaming
  8. sdr_cap_buf_request_complete
  9. vivid_sdr_enum_freq_bands
  10. vivid_sdr_g_frequency
  11. vivid_sdr_s_frequency
  12. vivid_sdr_g_tuner
  13. vivid_sdr_s_tuner
  14. vidioc_enum_fmt_sdr_cap
  15. vidioc_g_fmt_sdr_cap
  16. vidioc_s_fmt_sdr_cap
  17. vidioc_try_fmt_sdr_cap
  18. vivid_sdr_cap_process

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

/* [<][>][^][v][top][bottom][index][help] */