aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorAntti Palosaari <crope@iki.fi>2013-08-05 19:43:36 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-08-20 15:06:33 -0400
commit554cbfbe3b99d25caa3ab794a8619ccdea2b2935 (patch)
treeb0debca878b71cbc91e8f1f87ed601003a06f1ee /drivers/staging
parent23df427e3333882beea2e65d27fd2a581e37fae4 (diff)
[media] msi3101: add support for stream format "252" I+Q per frame
That one seems to have 14-bit ADC resolution, wow! It is now used when sampling rate is below 6 Msps. 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.c139
1 files changed, 125 insertions, 14 deletions
diff --git a/drivers/staging/media/msi3101/sdr-msi3101.c b/drivers/staging/media/msi3101/sdr-msi3101.c
index 4ff6030bc950..a937d00ed153 100644
--- a/drivers/staging/media/msi3101/sdr-msi3101.c
+++ b/drivers/staging/media/msi3101/sdr-msi3101.c
@@ -397,6 +397,8 @@ struct msi3101_state {
397 unsigned int vb_full; /* vb is full and packets dropped */ 397 unsigned int vb_full; /* vb is full and packets dropped */
398 398
399 struct urb *urbs[MAX_ISO_BUFS]; 399 struct urb *urbs[MAX_ISO_BUFS];
400 int (*convert_stream) (struct msi3101_state *s, u32 *dst, u8 *src,
401 unsigned int src_len);
400 402
401 /* Controls */ 403 /* Controls */
402 struct v4l2_ctrl_handler ctrl_handler; 404 struct v4l2_ctrl_handler ctrl_handler;
@@ -484,7 +486,7 @@ leave:
484 */ 486 */
485#define I2F_FRAC_BITS 23 487#define I2F_FRAC_BITS 23
486#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1) 488#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
487static u32 msi3101_convert_sample(struct msi3101_state *s, u16 x, int shift) 489static u32 msi3101_convert_sample_384(struct msi3101_state *s, u16 x, int shift)
488{ 490{
489 u32 msb, exponent, fraction, sign; 491 u32 msb, exponent, fraction, sign;
490 s->sample_ctrl_bit[shift]++; 492 s->sample_ctrl_bit[shift]++;
@@ -521,7 +523,7 @@ static u32 msi3101_convert_sample(struct msi3101_state *s, u16 x, int shift)
521 523
522#define MSI3101_CONVERT_IN_URB_HANDLER 524#define MSI3101_CONVERT_IN_URB_HANDLER
523#define MSI3101_EXTENSIVE_DEBUG 525#define MSI3101_EXTENSIVE_DEBUG
524static int msi3101_convert_stream(struct msi3101_state *s, u32 *dst, 526static int msi3101_convert_stream_384(struct msi3101_state *s, u32 *dst,
525 u8 *src, unsigned int src_len) 527 u8 *src, unsigned int src_len)
526{ 528{
527 int i, j, k, l, i_max, dst_len = 0; 529 int i, j, k, l, i_max, dst_len = 0;
@@ -561,10 +563,10 @@ static int msi3101_convert_stream(struct msi3101_state *s, u32 *dst,
561 sample[2] = (src[l + 2] & 0xf0) >> 4 | (src[l + 3] & 0x3f) << 4; 563 sample[2] = (src[l + 2] & 0xf0) >> 4 | (src[l + 3] & 0x3f) << 4;
562 sample[3] = (src[l + 3] & 0xc0) >> 6 | (src[l + 4] & 0xff) << 2; 564 sample[3] = (src[l + 3] & 0xc0) >> 6 | (src[l + 4] & 0xff) << 2;
563 565
564 *dst++ = msi3101_convert_sample(s, sample[0], (bits >> (2 * k)) & 0x3); 566 *dst++ = msi3101_convert_sample_384(s, sample[0], (bits >> (2 * k)) & 0x3);
565 *dst++ = msi3101_convert_sample(s, sample[1], (bits >> (2 * k)) & 0x3); 567 *dst++ = msi3101_convert_sample_384(s, sample[1], (bits >> (2 * k)) & 0x3);
566 *dst++ = msi3101_convert_sample(s, sample[2], (bits >> (2 * k)) & 0x3); 568 *dst++ = msi3101_convert_sample_384(s, sample[2], (bits >> (2 * k)) & 0x3);
567 *dst++ = msi3101_convert_sample(s, sample[3], (bits >> (2 * k)) & 0x3); 569 *dst++ = msi3101_convert_sample_384(s, sample[3], (bits >> (2 * k)) & 0x3);
568 570
569 /* 4 x 32bit float samples */ 571 /* 4 x 32bit float samples */
570 dst_len += 4 * 4; 572 dst_len += 4 * 4;
@@ -603,6 +605,103 @@ static int msi3101_convert_stream(struct msi3101_state *s, u32 *dst,
603} 605}
604 606
605/* 607/*
608 * Converts signed 14-bit integer into 32-bit IEEE floating point
609 * representation.
610 * Will be exact from 0 to 2^24. Above that, we round towards zero
611 * as the fractional bits will not fit in a float. (It would be better to
612 * round towards even as the fpu does, but that is slower.)
613 */
614#define I2F_FRAC_BITS 23
615#define I2F_MASK ((1 << I2F_FRAC_BITS) - 1)
616static u32 msi3101_convert_sample_252(struct msi3101_state *s, u16 x)
617{
618 u32 msb, exponent, fraction, sign;
619
620 /* Zero is special */
621 if (!x)
622 return 0;
623
624 /* Negative / positive value */
625 if (x & (1 << 13)) {
626 x = -x;
627 x &= 0x1fff; /* result is 13 bit ... + sign */
628 sign = 1 << 31;
629 } else {
630 sign = 0 << 31;
631 }
632
633 /* Get location of the most significant bit */
634 msb = __fls(x);
635
636 /*
637 * Use a rotate instead of a shift because that works both leftwards
638 * and rightwards due to the mod(32) behaviour. This means we don't
639 * need to check to see if we are above 2^24 or not.
640 */
641 fraction = ror32(x, (msb - I2F_FRAC_BITS) & 0x1f) & I2F_MASK;
642 exponent = (127 + msb) << I2F_FRAC_BITS;
643
644 return (fraction + exponent) | sign;
645}
646
647static int msi3101_convert_stream_252(struct msi3101_state *s, u32 *dst,
648 u8 *src, unsigned int src_len)
649{
650 int i, j, i_max, dst_len = 0;
651 u16 sample[2];
652 u32 sample_num[3];
653
654 /* There could be 1-3 1024 bytes URB frames */
655 i_max = src_len / 1024;
656
657 for (i = 0; i < i_max; i++) {
658 sample_num[i] = src[3] << 24 | src[2] << 16 | src[1] << 8 | src[0] << 0;
659 if (i == 0 && s->next_sample != sample_num[0]) {
660 dev_dbg_ratelimited(&s->udev->dev,
661 "%d samples lost, %d %08x:%08x\n",
662 sample_num[0] - s->next_sample,
663 src_len, s->next_sample, sample_num[0]);
664 }
665
666 /*
667 * Dump all unknown 'garbage' data - maybe we will discover
668 * someday if there is something rational...
669 */
670 dev_dbg_ratelimited(&s->udev->dev, "%*ph\n", 12, &src[4]);
671
672 src += 16;
673 for (j = 0; j < 1008; j += 4) {
674 sample[0] = src[j + 0] >> 0 | src[j + 1] << 8;
675 sample[1] = src[j + 2] >> 0 | src[j + 3] << 8;
676
677 *dst++ = msi3101_convert_sample_252(s, sample[0]);
678 *dst++ = msi3101_convert_sample_252(s, sample[1]);
679 }
680 /* 252 x I+Q 32bit float samples */
681 dst_len += 252 * 2 * 4;
682 src += 1008;
683 }
684
685 /* calculate samping rate and output it in 10 seconds intervals */
686 if ((s->jiffies + msecs_to_jiffies(10000)) <= jiffies) {
687 unsigned long jiffies_now = jiffies;
688 unsigned long msecs = jiffies_to_msecs(jiffies_now) - jiffies_to_msecs(s->jiffies);
689 unsigned int samples = sample_num[i_max - 1] - s->sample;
690 s->jiffies = jiffies_now;
691 s->sample = sample_num[i_max - 1];
692 dev_dbg(&s->udev->dev,
693 "slen=%d samples=%u msecs=%lu sampling rate=%lu\n",
694 src_len, samples, msecs,
695 samples * 1000UL / msecs);
696 }
697
698 /* next sample (sample = sample + i * 252) */
699 s->next_sample = sample_num[i_max - 1] + 252;
700
701 return dst_len;
702}
703
704/*
606 * This gets called for the Isochronous pipe (stream). This is done in interrupt 705 * This gets called for the Isochronous pipe (stream). This is done in interrupt
607 * time, so it has to be fast, not crash, and not stall. Neat. 706 * time, so it has to be fast, not crash, and not stall. Neat.
608 */ 707 */
@@ -636,6 +735,8 @@ static void msi3101_isoc_handler(struct urb *urb)
636 735
637 /* Compact data */ 736 /* Compact data */
638 for (i = 0; i < urb->number_of_packets; i++) { 737 for (i = 0; i < urb->number_of_packets; i++) {
738 void *ptr;
739
639 /* Check frame error */ 740 /* Check frame error */
640 fstatus = urb->iso_frame_desc[i].status; 741 fstatus = urb->iso_frame_desc[i].status;
641 if (fstatus) { 742 if (fstatus) {
@@ -664,9 +765,9 @@ static void msi3101_isoc_handler(struct urb *urb)
664 765
665 /* fill framebuffer */ 766 /* fill framebuffer */
666#ifdef MSI3101_CONVERT_IN_URB_HANDLER 767#ifdef MSI3101_CONVERT_IN_URB_HANDLER
667 vb2_set_plane_payload(&fbuf->vb, 0, 768 ptr = vb2_plane_vaddr(&fbuf->vb, 0);
668 msi3101_convert_stream(s, 769 flen = s->convert_stream(s, ptr, iso_buf, flen);
669 vb2_plane_vaddr(&fbuf->vb, 0), iso_buf, flen)); 770 vb2_set_plane_payload(&fbuf->vb, 0, flen);
670#else 771#else
671 memcpy(fbuf->data, iso_buf, flen); 772 memcpy(fbuf->data, iso_buf, flen);
672 fbuf->filled = flen; 773 fbuf->filled = flen;
@@ -908,7 +1009,7 @@ static int msi3101_buf_finish(struct vb2_buffer *vb)
908 container_of(vb, struct msi3101_frame_buf, vb); 1009 container_of(vb, struct msi3101_frame_buf, vb);
909 int ret; 1010 int ret;
910 u32 *dst = vb2_plane_vaddr(&fbuf->vb, 0); 1011 u32 *dst = vb2_plane_vaddr(&fbuf->vb, 0);
911 ret = msi3101_convert_stream(s, dst, fbuf->data, fbuf->filled); 1012 ret = msi3101_convert_stream_384(s, dst, fbuf->data, fbuf->filled);
912 vb2_set_plane_payload(&fbuf->vb, 0, ret); 1013 vb2_set_plane_payload(&fbuf->vb, 0, ret);
913 return 0; 1014 return 0;
914} 1015}
@@ -988,7 +1089,19 @@ static int msi3101_tuner_write(struct msi3101_state *s, u32 data)
988static int msi3101_set_usb_adc(struct msi3101_state *s) 1089static int msi3101_set_usb_adc(struct msi3101_state *s)
989{ 1090{
990 int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract; 1091 int ret, div_n, div_m, div_r_out, f_sr, f_vco, fract;
991 u32 reg4, reg3; 1092 u32 reg3, reg4, reg7;
1093
1094 f_sr = s->ctrl_sampling_rate->val64;
1095
1096 /* select stream format */
1097 if (f_sr < 6000000) {
1098 s->convert_stream = msi3101_convert_stream_252;
1099 reg7 = 0x00009407;
1100 } else {
1101 s->convert_stream = msi3101_convert_stream_384;
1102 reg7 = 0x0000a507;
1103 }
1104
992 /* 1105 /*
993 * Synthesizer config is just a educated guess... 1106 * Synthesizer config is just a educated guess...
994 * 1107 *
@@ -1016,8 +1129,6 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
1016 * 1129 *
1017 * VCO 202000000 - 720000000++ 1130 * VCO 202000000 - 720000000++
1018 */ 1131 */
1019
1020 f_sr = s->ctrl_sampling_rate->val64;
1021 reg3 = 0x01c00303; 1132 reg3 = 0x01c00303;
1022 reg4 = 0x00000004; 1133 reg4 = 0x00000004;
1023 1134
@@ -1062,7 +1173,7 @@ static int msi3101_set_usb_adc(struct msi3101_state *s)
1062 if (ret) 1173 if (ret)
1063 goto err; 1174 goto err;
1064 1175
1065 ret = msi3101_ctrl_msg(s, CMD_WREG, 0x0000a507); 1176 ret = msi3101_ctrl_msg(s, CMD_WREG, reg7);
1066 if (ret) 1177 if (ret)
1067 goto err; 1178 goto err;
1068 1179