diff options
author | Antti Palosaari <crope@iki.fi> | 2013-08-08 14:39:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2013-08-20 15:08:25 -0400 |
commit | 61198dfd08969a662767072aafeebcb493909338 (patch) | |
tree | de9946dfd860dc76177e90914e81bd80bfc3967a /drivers/staging | |
parent | 00e049b05a4fe4c7a1503f2a46aced2548867631 (diff) |
[media] msi3101: implement stream format 504
That stream format carries 504 x I+Q samples per 1024 USB frame.
Sample resolution is 8-bit signed. Default it when sampling rate
is 9Msps or over.
Signed-off-by: Antti Palosaari <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/media/msi3101/sdr-msi3101.c | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c index a3cc4c6ebbc8..bf735f9b5db9 100644 --- a/drivers/staging/media/msi3101/sdr-msi3101.c +++ b/drivers/staging/media/msi3101/sdr-msi3101.c | |||
@@ -448,7 +448,7 @@ leave: | |||
448 | 448 | ||
449 | /* | 449 | /* |
450 | * +=========================================================================== | 450 | * +=========================================================================== |
451 | * | 00-1023 | USB packet | 451 | * | 00-1023 | USB packet type '384' |
452 | * +=========================================================================== | 452 | * +=========================================================================== |
453 | * | 00- 03 | sequence number of first sample in that USB packet | 453 | * | 00- 03 | sequence number of first sample in that USB packet |
454 | * +--------------------------------------------------------------------------- | 454 | * +--------------------------------------------------------------------------- |
@@ -502,6 +502,93 @@ leave: | |||
502 | #define I2F_MASK ((1 << I2F_FRAC_BITS) - 1) | 502 | #define I2F_MASK ((1 << I2F_FRAC_BITS) - 1) |
503 | 503 | ||
504 | /* | 504 | /* |
505 | * Converts signed 8-bit integer into 32-bit IEEE floating point | ||
506 | * representation. | ||
507 | */ | ||
508 | static u32 msi3101_convert_sample_504(struct msi3101_state *s, u16 x) | ||
509 | { | ||
510 | u32 msb, exponent, fraction, sign; | ||
511 | |||
512 | /* Zero is special */ | ||
513 | if (!x) | ||
514 | return 0; | ||
515 | |||
516 | /* Negative / positive value */ | ||
517 | if (x & (1 << 7)) { | ||
518 | x = -x; | ||
519 | x &= 0x7f; /* result is 7 bit ... + sign */ | ||
520 | sign = 1 << 31; | ||
521 | } else { | ||
522 | sign = 0 << 31; | ||
523 | } | ||
524 | |||
525 | /* Get location of the most significant bit */ | ||
526 | msb = __fls(x); | ||
527 | |||
528 | fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK; | ||
529 | exponent = (127 + msb) << I2F_FRAC_BITS; | ||
530 | |||
531 | return (fraction + exponent) | sign; | ||
532 | } | ||
533 | |||
534 | static int msi3101_convert_stream_504(struct msi3101_state *s, u32 *dst, | ||
535 | u8 *src, unsigned int src_len) | ||
536 | { | ||
537 | int i, j, i_max, dst_len = 0; | ||
538 | u16 sample[2]; | ||
539 | u32 sample_num[3]; | ||
540 | |||
541 | /* There could be 1-3 1024 bytes URB frames */ | ||
542 | i_max = src_len / 1024; | ||
543 | |||
544 | for (i = 0; i < i_max; i++) { | ||
545 | sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0; | ||
546 | if (i == 0 && s->next_sample != sample_num[0]) { | ||
547 | dev_dbg_ratelimited(&s->udev->dev, | ||
548 | "%d samples lost, %d %08x:%08x\n", | ||
549 | sample_num[0] - s->next_sample, | ||
550 | src_len, s->next_sample, sample_num[0]); | ||
551 | } | ||
552 | |||
553 | /* | ||
554 | * Dump all unknown 'garbage' data - maybe we will discover | ||
555 | * someday if there is something rational... | ||
556 | */ | ||
557 | dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]); | ||
558 | |||
559 | src += 16; | ||
560 | for (j = 0; j < 1008; j += 2) { | ||
561 | sample[0] = src[j + 0]; | ||
562 | sample[1] = src[j + 1]; | ||
563 | |||
564 | *dst++ = msi3101_convert_sample_504(s, sample[0]); | ||
565 | *dst++ = msi3101_convert_sample_504(s, sample[1]); | ||
566 | } | ||
567 | /* 504 x I+Q 32bit float samples */ | ||
568 | dst_len += 504 * 2 * 4; | ||
569 | src += 1008; | ||
570 | } | ||
571 | |||
572 | /* calculate samping rate and output it in 10 seconds intervals */ | ||
573 | if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) { | ||
574 | unsigned long jiffies_now = jiffies; | ||
575 | unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies); | ||
576 | unsigned int samples = sample_num[i_max - 1] - s->sample; | ||
577 | s->jiffies = jiffies_now; | ||
578 | s->sample = sample_num[i_max - 1]; | ||
579 | dev_dbg(&s->udev->dev, | ||
580 | "slen=%d samples=%u msecs=%lu sampling rate=%lu\n", | ||
581 | src_len, samples, msecs, | ||
582 | samples * 1000UL / msecs); | ||
583 | } | ||
584 | |||
585 | /* next sample (sample = sample + i * 504) */ | ||
586 | s->next_sample = sample_num[i_max - 1] + 504; | ||
587 | |||
588 | return dst_len; | ||
589 | } | ||
590 | |||
591 | /* | ||
505 | * Converts signed ~10+3-bit integer into 32-bit IEEE floating point | 592 | * Converts signed ~10+3-bit integer into 32-bit IEEE floating point |
506 | * representation. | 593 | * representation. |
507 | */ | 594 | */ |
@@ -1134,9 +1221,12 @@ static int msi3101_set_usb_adc(struct msi3101_state *s) | |||
1134 | } else if (f_sr < 8000000) { | 1221 | } else if (f_sr < 8000000) { |
1135 | s->convert_stream = msi3101_convert_stream_336; | 1222 | s->convert_stream = msi3101_convert_stream_336; |
1136 | reg7 = 0x00008507; | 1223 | reg7 = 0x00008507; |
1137 | } else { | 1224 | } else if (f_sr < 9000000) { |
1138 | s->convert_stream = msi3101_convert_stream_384; | 1225 | s->convert_stream = msi3101_convert_stream_384; |
1139 | reg7 = 0x0000a507; | 1226 | reg7 = 0x0000a507; |
1227 | } else { | ||
1228 | s->convert_stream = msi3101_convert_stream_504; | ||
1229 | reg7 = 0x000c9407; | ||
1140 | } | 1230 | } |
1141 | 1231 | ||
1142 | /* | 1232 | /* |