V4L/DVB: tm6000+audio
authorDmitri Belimov <d.belimov@gmail.com>
Mon, 20 Sep 2010 20:07:15 +0000 (17:07 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 21 Oct 2010 03:06:20 +0000 (01:06 -0200)
I rework my last patch for audio and now audio works well. This patch
can be submited to GIT tree Quality of audio now is good for SECAM-DK.
For other standard I set some value from datasheet need some tests.

1. Fix pcm buffer overflow
2. Rework pcm buffer fill method
3. Swap bytes in audio stream
4. Change some registers value for TM6010
5. Change pcm buffer size

Signed-off-by: Beholder Intl. Ltd. Dmitry Belimov <d.belimov@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/staging/tm6000/tm6000-alsa.c
drivers/staging/tm6000/tm6000-core.c
drivers/staging/tm6000/tm6000-stds.c
drivers/staging/tm6000/tm6000-video.c

index 087137d9164deb1dbf17ba110a0686e7669c6926..a99101fef1a39ee3991a3db7752b396b5a18860d 100644 (file)
@@ -160,15 +160,15 @@ static struct snd_pcm_hardware snd_tm6000_digital_hw = {
                SNDRV_PCM_INFO_MMAP_VALID,
        .formats = SNDRV_PCM_FMTBIT_S16_LE,
 
-       .rates =                SNDRV_PCM_RATE_48000,
+       .rates =                SNDRV_PCM_RATE_CONTINUOUS,
        .rate_min =             48000,
        .rate_max =             48000,
        .channels_min = 2,
        .channels_max = 2,
-       .period_bytes_min = 62720,
-       .period_bytes_max = 62720,
+       .period_bytes_min = 64,
+       .period_bytes_max = 12544,
        .periods_min = 1,
-       .periods_max = 1024,
+       .periods_max = 98,
        .buffer_bytes_max = 62720 * 8,
 };
 
@@ -211,38 +211,64 @@ static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size)
        struct snd_pcm_runtime *runtime;
        int period_elapsed = 0;
        unsigned int stride, buf_pos;
+       int length;
 
-       if (!size || !substream)
+       if (!size || !substream) {
+               dprintk(1, "substream was NULL\n");
                return -EINVAL;
+       }
 
        runtime = substream->runtime;
-       if (!runtime || !runtime->dma_area)
+       if (!runtime || !runtime->dma_area) {
+               dprintk(1, "runtime was NULL\n");
                return -EINVAL;
+       }
 
        buf_pos = chip->buf_pos;
        stride = runtime->frame_bits >> 3;
 
+       if (stride == 0) {
+               dprintk(1, "stride is zero\n");
+               return -EINVAL;
+       }
+
+       length = size / stride;
+       if (length == 0) {
+               dprintk(1, "%s: length was zero\n", __func__);
+               return -EINVAL;
+       }
+
        dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size,
                runtime->dma_area, buf_pos,
                (unsigned int)runtime->buffer_size, stride);
 
-       if (buf_pos + size >= runtime->buffer_size * stride) {
-               unsigned int cnt = runtime->buffer_size * stride - buf_pos;
-               memcpy(runtime->dma_area + buf_pos, buf, cnt);
-               memcpy(runtime->dma_area, buf + cnt, size - cnt);
+       if (buf_pos + length >= runtime->buffer_size) {
+               unsigned int cnt = runtime->buffer_size - buf_pos;
+               memcpy(runtime->dma_area + buf_pos * stride, buf, cnt * stride);
+               memcpy(runtime->dma_area, buf + cnt * stride,
+                       length * stride - cnt * stride);
        } else
-               memcpy(runtime->dma_area + buf_pos, buf, size);
+               memcpy(runtime->dma_area + buf_pos * stride, buf,
+                       length * stride);
 
-       chip->buf_pos += size;
-       if (chip->buf_pos >= runtime->buffer_size * stride)
-               chip->buf_pos -= runtime->buffer_size * stride;
+#ifndef NO_PCM_LOCK
+       snd_pcm_stream_lock(substream);
+#endif
 
-       chip->period_pos += size;
+       chip->buf_pos += length;
+       if (chip->buf_pos >= runtime->buffer_size)
+               chip->buf_pos -= runtime->buffer_size;
+
+       chip->period_pos += length;
        if (chip->period_pos >= runtime->period_size) {
                chip->period_pos -= runtime->period_size;
                period_elapsed = 1;
        }
 
+#ifndef NO_PCM_LOCK
+       snd_pcm_stream_unlock(substream);
+#endif
+
        if (period_elapsed)
                snd_pcm_period_elapsed(substream);
 
index cded411d8bba552eff047f068eefbf9adb3720d4..57cb69e1fce9ad9d95fa3fa04fde399e62172fd9 100644 (file)
@@ -256,7 +256,6 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
                tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
                tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
                tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0);
-               tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x05);
                tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x06);
                tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00);
                tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00);
index 6bf4a73b320d82327d9fd7a64487a7212f853e7a..f6aa75334d0dff39e9317b8608e30c1a41d9c613 100644 (file)
@@ -96,6 +96,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
 
                        {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
                        {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
+                       {TM6010_REQ08_R05_A_STANDARD_MOD, 0x21}, /* FIXME */
                        {TM6010_REQ07_R3F_RESET, 0x00},
                        {0, 0, 0},
                },
@@ -154,6 +155,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
 
                        {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
                        {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
+                       {TM6010_REQ08_R05_A_STANDARD_MOD, 0x21}, /* FIXME */
                        {TM6010_REQ07_R3F_RESET, 0x00},
                        {0, 0, 0},
                },
@@ -212,6 +214,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
 
                        {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
                        {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
+                       {TM6010_REQ08_R05_A_STANDARD_MOD, 0x76}, /* FIXME */
                        {TM6010_REQ07_R3F_RESET, 0x00},
                        {0, 0, 0},
                },
@@ -269,6 +272,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
                        {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
 
                        {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
+                       {TM6010_REQ08_R05_A_STANDARD_MOD, 0x79},
                        {TM6010_REQ07_R3F_RESET, 0x00},
                        {0, 0, 0},
                },
@@ -327,6 +331,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
 
                        {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
                        {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
+                       {TM6010_REQ08_R05_A_STANDARD_MOD, 0x22}, /* FIXME */
                        {TM6010_REQ07_R3F_RESET, 0x00},
                        {0, 0, 0},
                },
index 4c22c658494009ed197d4ca5891fd8e3078e5346..a45b012c340e9bab18c672a9fa7ebca3274a8c42 100644 (file)
@@ -304,6 +304,14 @@ static int copy_streams(u8 *data, unsigned long len,
                                        memcpy (&voutp[pos], ptr, cpysize);
                                break;
                        case TM6000_URB_MSG_AUDIO:
+                               /* Need some code to copy audio buffer */
+                               if (dev->fourcc == V4L2_PIX_FMT_YUYV) {
+                                       /* Swap word bytes */
+                                       int i;
+
+                                       for (i = 0; i < cpysize; i += 2)
+                                               swab16s((u16 *)(ptr + i));
+                               }
                                tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
                                break;
                        case TM6000_URB_MSG_VBI: