The patch number 7892 was added via Mauro Carvalho Chehab <[EMAIL PROTECTED]>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        [EMAIL PROTECTED]

------

From: Mauro Carvalho Chehab  <[EMAIL PROTECTED]>
merge: http://www.linuxtv.org/hg/~hverkuil/v4l-dvb




Signed-off-by: Mauro Carvalho Chehab <[EMAIL PROTECTED]>


---

 linux/drivers/media/video/cx18/cx18-cards.c   |   26 +++--
 linux/drivers/media/video/cx18/cx18-cards.h   |    5 -
 linux/drivers/media/video/cx18/cx18-driver.c  |   11 +-
 linux/drivers/media/video/cx18/cx18-fileops.c |    2 
 linux/drivers/media/video/cx18/cx18-gpio.c    |   53 +++++++----
 linux/drivers/media/video/cx18/cx18-streams.c |   15 +--
 linux/drivers/media/video/ivtv/ivtv-fileops.c |    2 
 linux/drivers/media/video/ivtv/ivtv-streams.c |   34 ++++---
 linux/drivers/media/video/ivtv/ivtvfb.c       |   82 ++++++++++++++++++
 9 files changed, 169 insertions(+), 61 deletions(-)

diff -r 57324b20f2d8 -r 1ef54d1daa8e linux/drivers/media/video/cx18/cx18-cards.c
--- a/linux/drivers/media/video/cx18/cx18-cards.c       Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/cx18/cx18-cards.c       Tue May 13 00:01:54 
2008 -0300
@@ -47,12 +47,12 @@ static const struct cx18_card cx18_card_
 static const struct cx18_card cx18_card_hvr1600_esmt = {
        .type = CX18_CARD_HVR_1600_ESMT,
        .name = "Hauppauge HVR-1600",
-       .comment = "DVB & VBI are not yet supported\n",
+       .comment = "VBI is not yet supported\n",
        .v4l2_capabilities = CX18_CAP_ENCODER,
        .hw_audio_ctrl = CX18_HW_CX23418,
        .hw_muxer = CX18_HW_CS5345,
-       .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345
-               | CX18_HW_DVB,
+       .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+                 CX18_HW_CS5345 | CX18_HW_DVB,
        .video_inputs = {
                { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
                { CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
@@ -87,11 +87,12 @@ static const struct cx18_card cx18_card_
 static const struct cx18_card cx18_card_hvr1600_samsung = {
        .type = CX18_CARD_HVR_1600_SAMSUNG,
        .name = "Hauppauge HVR-1600 (Preproduction)",
-       .comment = "DVB & VBI are not yet supported\n",
+       .comment = "VBI is not yet supported\n",
        .v4l2_capabilities = CX18_CAP_ENCODER,
        .hw_audio_ctrl = CX18_HW_CX23418,
        .hw_muxer = CX18_HW_CS5345,
-       .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | CX18_HW_CS5345,
+       .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
+                 CX18_HW_CS5345 | CX18_HW_DVB,
        .video_inputs = {
                { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
                { CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
@@ -135,14 +136,15 @@ static const struct cx18_card cx18_card_
 static const struct cx18_card cx18_card_h900 = {
        .type = CX18_CARD_COMPRO_H900,
        .name = "Compro VideoMate H900",
-       .comment = "Not yet supported!\n",
-       .v4l2_capabilities = 0,
+       .comment = "DVB & VBI are not yet supported\n",
+       .v4l2_capabilities = CX18_CAP_ENCODER,
        .hw_audio_ctrl = CX18_HW_CX23418,
        .hw_all = CX18_HW_TUNER,
        .video_inputs = {
-               { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE7 },
-               { CX18_CARD_INPUT_SVIDEO1,    1, CX23418_SVIDEO1    },
-               { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE3 },
+               { CX18_CARD_INPUT_VID_TUNER,  0, CX23418_COMPOSITE2 },
+               { CX18_CARD_INPUT_SVIDEO1,    1,
+                       CX23418_SVIDEO_LUMA3 | CX23418_SVIDEO_CHROMA4 },
+               { CX18_CARD_INPUT_COMPOSITE1, 1, CX23418_COMPOSITE1 },
        },
        .audio_inputs = {
                { CX18_CARD_INPUT_AUD_TUNER,
@@ -164,6 +166,7 @@ static const struct cx18_card cx18_card_
                .tune_lane = 0,
                .initial_emrs = 0,
        },
+       .xceive_pin = 15,
        .pci_list = cx18_pci_h900,
        .i2c = &cx18_i2c_std,
 };
@@ -201,8 +204,6 @@ static const struct cx18_card cx18_card_
                /* XC3028 tuner */
                { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
        },
-       /* tuner reset */
-       .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 },
        .ddr = {
                /* Probably Samsung K4D263238G-VC33 memory */
                .chip_config = 0x003,
@@ -212,6 +213,7 @@ static const struct cx18_card cx18_card_
                .tune_lane = 0,
                .initial_emrs = 2,
        },
+       .xceive_pin = 15,
        .pci_list = cx18_pci_mpc718,
        .i2c = &cx18_i2c_std,
 };
diff -r 57324b20f2d8 -r 1ef54d1daa8e linux/drivers/media/video/cx18/cx18-cards.h
--- a/linux/drivers/media/video/cx18/cx18-cards.h       Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/cx18/cx18-cards.h       Tue May 13 00:01:54 
2008 -0300
@@ -114,8 +114,8 @@ struct cx18_card_pci_info {
 /* The mask is the set of bits used by the operation */
 
 struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */
-       u16 direction;  /* DIR setting. Leave to 0 if no init is needed */
-       u16 initial_value;
+       u32 direction;  /* DIR setting. Leave to 0 if no init is needed */
+       u32 initial_value;
 };
 
 struct cx18_card_tuner {
@@ -153,6 +153,7 @@ struct cx18_card {
        struct cx18_card_audio_input radio_input;
 
        /* GPIO card-specific settings */
+       u8 xceive_pin;          /* XCeive tuner GPIO reset pin */
        struct cx18_gpio_init           gpio_init;
 
        struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS];
diff -r 57324b20f2d8 -r 1ef54d1daa8e 
linux/drivers/media/video/cx18/cx18-driver.c
--- a/linux/drivers/media/video/cx18/cx18-driver.c      Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/cx18/cx18-driver.c      Tue May 13 00:01:54 
2008 -0300
@@ -210,12 +210,12 @@ static void cx18_process_eeprom(struct c
 
        /* Many thanks to Steven Toth from Hauppauge for providing the
           model numbers */
+       /* Note: the Samsung memory models cannot be reliably determined
+          from the model number. Use the cardtype module option if you
+          have one of these preproduction models. */
        switch (tv.model) {
-       case 74000 ... 74099:
+       case 74000 ... 74999:
                cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
-               break;
-       case 74700 ... 74799:
-               cx->card = cx18_get_card(CX18_CARD_HVR_1600_SAMSUNG);
                break;
        case 0:
                CX18_ERR("Invalid EEPROM\n");
@@ -904,8 +904,7 @@ static void cx18_remove(struct pci_dev *
 
        free_irq(cx->dev->irq, (void *)cx);
 
-       if (cx->dev)
-               cx18_iounmap(cx);
+       cx18_iounmap(cx);
 
        release_mem_region(cx->base_addr, CX18_MEM_SIZE);
 
diff -r 57324b20f2d8 -r 1ef54d1daa8e 
linux/drivers/media/video/cx18/cx18-fileops.c
--- a/linux/drivers/media/video/cx18/cx18-fileops.c     Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/cx18/cx18-fileops.c     Tue May 13 00:01:54 
2008 -0300
@@ -697,6 +697,8 @@ int cx18_v4l2_open(struct inode *inode, 
        for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
                /* find out which stream this open was on */
                for (y = 0; y < CX18_MAX_STREAMS; y++) {
+                       if (cx18_cards[x] == NULL)
+                               continue;
                        s = &cx18_cards[x]->streams[y];
                        if (s->v4l2dev && s->v4l2dev->minor == minor) {
                                cx = cx18_cards[x];
diff -r 57324b20f2d8 -r 1ef54d1daa8e linux/drivers/media/video/cx18/cx18-gpio.c
--- a/linux/drivers/media/video/cx18/cx18-gpio.c        Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/cx18/cx18-gpio.c        Tue May 13 00:01:54 
2008 -0300
@@ -35,6 +35,9 @@
 #define CX18_REG_GPIO_OUT2   0xc78104
 #define CX18_REG_GPIO_DIR2   0xc7810c
 
+static u32 gpio_dir;
+static u32 gpio_val;
+
 /*
  * HVR-1600 GPIO pins, courtesy of Hauppauge:
  *
@@ -44,45 +47,53 @@
  * gpio13: cs5345 reset pin
 */
 
+static void gpio_write(struct cx18 *cx)
+{
+       write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1);
+       write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff),
+                       CX18_REG_GPIO_OUT1);
+       write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2);
+       write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16),
+                       CX18_REG_GPIO_OUT2);
+}
+
 void cx18_gpio_init(struct cx18 *cx)
 {
-       if (cx->card->gpio_init.direction == 0)
+       gpio_dir = cx->card->gpio_init.direction;
+       gpio_val = cx->card->gpio_init.initial_value;
+
+       if (gpio_dir == 0)
                return;
 
-       CX18_DEBUG_INFO("GPIO initial dir: %08x out: %08x\n",
-                  read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_OUT1));
+       gpio_dir |= 1 << cx->card->xceive_pin;
+       gpio_val |= 1 << cx->card->xceive_pin;
 
-       /* init output data then direction */
-       write_reg(cx->card->gpio_init.direction << 16, CX18_REG_GPIO_DIR1);
-       write_reg(0, CX18_REG_GPIO_DIR2);
-       write_reg((cx->card->gpio_init.direction << 16) |
-                       cx->card->gpio_init.initial_value, CX18_REG_GPIO_OUT1);
-       write_reg(0, CX18_REG_GPIO_OUT2);
+       CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n",
+                  read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2),
+                  read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2));
+
+       gpio_write(cx);
 }
 
 /* Xceive tuner reset function */
 int cx18_reset_tuner_gpio(void *dev, int cmd, int value)
 {
        struct i2c_algo_bit_data *algo = dev;
-       struct cx18 *cx = algo->data;
-/*     int curdir, curout;*/
+       struct cx18_i2c_algo_callback_data *cb_data = algo->data;
+       struct cx18 *cx = cb_data->cx;
 
        if (cmd != XC2028_TUNER_RESET)
                return 0;
        CX18_DEBUG_INFO("Resetting tuner\n");
-#if 0
-       /* TODO */
-       curout = read_reg(IVTV_REG_GPIO_OUT);
-       curdir = read_reg(IVTV_REG_GPIO_DIR);
-       curdir |= (1 << 12);  /* GPIO bit 12 */
 
-       curout &= ~(1 << 12);
-       write_reg(curout, IVTV_REG_GPIO_OUT);
+       gpio_dir |= 1 << cx->card->xceive_pin;
+       gpio_val &= ~(1 << cx->card->xceive_pin);
+
+       gpio_write(cx);
        schedule_timeout_interruptible(msecs_to_jiffies(1));
 
-       curout |= (1 << 12);
-       write_reg(curout, IVTV_REG_GPIO_OUT);
+       gpio_val |= 1 << cx->card->xceive_pin;
+       gpio_write(cx);
        schedule_timeout_interruptible(msecs_to_jiffies(1));
-#endif
        return 0;
 }
diff -r 57324b20f2d8 -r 1ef54d1daa8e 
linux/drivers/media/video/cx18/cx18-streams.c
--- a/linux/drivers/media/video/cx18/cx18-streams.c     Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/cx18/cx18-streams.c     Tue May 13 00:01:54 
2008 -0300
@@ -36,12 +36,15 @@
 #define CX18_DSP0_INTERRUPT_MASK       0xd0004C
 
 static struct file_operations cx18_v4l2_enc_fops = {
-      .owner = THIS_MODULE,
-      .read = cx18_v4l2_read,
-      .open = cx18_v4l2_open,
-      .ioctl = cx18_v4l2_ioctl,
-      .release = cx18_v4l2_close,
-      .poll = cx18_v4l2_enc_poll,
+       .owner = THIS_MODULE,
+       .read = cx18_v4l2_read,
+       .open = cx18_v4l2_open,
+       .ioctl = cx18_v4l2_ioctl,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+       .compat_ioctl = v4l_compat_ioctl32,
+#endif
+       .release = cx18_v4l2_close,
+       .poll = cx18_v4l2_enc_poll,
 };
 
 /* offset from 0 to register ts v4l2 minors on */
diff -r 57324b20f2d8 -r 1ef54d1daa8e 
linux/drivers/media/video/ivtv/ivtv-fileops.c
--- a/linux/drivers/media/video/ivtv/ivtv-fileops.c     Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/ivtv/ivtv-fileops.c     Tue May 13 00:01:54 
2008 -0300
@@ -987,6 +987,8 @@ int ivtv_v4l2_open(struct inode *inode, 
        /* Find which card this open was on */
        spin_lock(&ivtv_cards_lock);
        for (x = 0; itv == NULL && x < ivtv_cards_active; x++) {
+               if (ivtv_cards[x] == NULL)
+                       continue;
                /* find out which stream this open was on */
                for (y = 0; y < IVTV_MAX_STREAMS; y++) {
                        s = &ivtv_cards[x]->streams[y];
diff -r 57324b20f2d8 -r 1ef54d1daa8e 
linux/drivers/media/video/ivtv/ivtv-streams.c
--- a/linux/drivers/media/video/ivtv/ivtv-streams.c     Mon May 12 23:44:32 
2008 -0300
+++ b/linux/drivers/media/video/ivtv/ivtv-streams.c     Tue May 13 00:01:54 
2008 -0300
@@ -44,23 +44,29 @@
 #include "ivtv-streams.h"
 
 static const struct file_operations ivtv_v4l2_enc_fops = {
-      .owner = THIS_MODULE,
-      .read = ivtv_v4l2_read,
-      .write = ivtv_v4l2_write,
-      .open = ivtv_v4l2_open,
-      .ioctl = ivtv_v4l2_ioctl,
-      .release = ivtv_v4l2_close,
-      .poll = ivtv_v4l2_enc_poll,
+       .owner = THIS_MODULE,
+       .read = ivtv_v4l2_read,
+       .write = ivtv_v4l2_write,
+       .open = ivtv_v4l2_open,
+       .ioctl = ivtv_v4l2_ioctl,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+       .compat_ioctl = v4l_compat_ioctl32,
+#endif
+       .release = ivtv_v4l2_close,
+       .poll = ivtv_v4l2_enc_poll,
 };
 
 static const struct file_operations ivtv_v4l2_dec_fops = {
-      .owner = THIS_MODULE,
-      .read = ivtv_v4l2_read,
-      .write = ivtv_v4l2_write,
-      .open = ivtv_v4l2_open,
-      .ioctl = ivtv_v4l2_ioctl,
-      .release = ivtv_v4l2_close,
-      .poll = ivtv_v4l2_dec_poll,
+       .owner = THIS_MODULE,
+       .read = ivtv_v4l2_read,
+       .write = ivtv_v4l2_write,
+       .open = ivtv_v4l2_open,
+       .ioctl = ivtv_v4l2_ioctl,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11)
+       .compat_ioctl = v4l_compat_ioctl32,
+#endif
+       .release = ivtv_v4l2_close,
+       .poll = ivtv_v4l2_dec_poll,
 };
 
 #define IVTV_V4L2_DEC_MPG_OFFSET  16   /* offset from 0 to register decoder 
mpg v4l2 minors on */
diff -r 57324b20f2d8 -r 1ef54d1daa8e linux/drivers/media/video/ivtv/ivtvfb.c
--- a/linux/drivers/media/video/ivtv/ivtvfb.c   Mon May 12 23:44:32 2008 -0300
+++ b/linux/drivers/media/video/ivtv/ivtvfb.c   Tue May 13 00:01:54 2008 -0300
@@ -365,6 +365,87 @@ static int ivtvfb_prep_frame(struct ivtv
 
        /* Fill Buffers */
        return ivtvfb_prep_dec_dma_to_device(itv, dest_offset, source, count);
+}
+
+static ssize_t ivtvfb_write(struct fb_info *info, const char __user *buf,
+                    size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       void *dst;
+       int err = 0;
+       unsigned long total_size;
+       struct ivtv *itv = (struct ivtv *) info->par;
+       unsigned long dma_offset =
+                       IVTV_DECODER_OFFSET + itv->osd_info->video_rbase;
+       unsigned long dma_size;
+       u16 lead = 0, tail = 0;
+
+       if (info->state != FBINFO_STATE_RUNNING)
+               return -EPERM;
+
+       total_size = info->screen_size;
+
+       if (total_size == 0)
+               total_size = info->fix.smem_len;
+
+       if (p > total_size)
+               return -EFBIG;
+
+       if (count > total_size) {
+               err = -EFBIG;
+               count = total_size;
+       }
+
+       if (count + p > total_size) {
+               if (!err)
+                       err = -ENOSPC;
+
+               count = total_size - p;
+       }
+
+       dst = (void __force *) (info->screen_base + p);
+
+       if (info->fbops->fb_sync)
+               info->fbops->fb_sync(info);
+
+       if (!access_ok(VERIFY_READ, buf, count)) {
+               IVTVFB_WARN("Invalid userspace pointer 0x%08lx\n",
+                       (unsigned long)buf);
+               err = -EFAULT;
+       }
+
+       if (!err) {
+               /* If transfer size > threshold and both src/dst
+               addresses are aligned, use DMA */
+               if (count >= 4096 && ((u32)buf & 3) == ((u32)dst & 3)) {
+                       /* Odd address = can't DMA. Align */
+                       if ((u32)dst & 3) {
+                               lead = 4 - ((u32)dst & 3);
+                               memcpy(dst, buf, lead);
+                               buf += lead;
+                               dst += lead;
+                       }
+                       /* DMA resolution is 32 bits */
+                       if ((count - lead) & 3)
+                               tail = (count - lead) & 3;
+                       /* DMA the data */
+                       dma_size = count - lead - tail;
+                       err = ivtvfb_prep_dec_dma_to_device(itv,
+                              p + lead + dma_offset, (void *)buf, dma_size);
+                       dst += dma_size;
+                       buf += dma_size;
+                       /* Copy any leftover data */
+                       if (tail)
+                               memcpy(dst, buf, tail);
+               } else {
+                       memcpy(dst, buf, count);
+               }
+       }
+
+       if  (!err)
+               *ppos += count;
+
+       return (err) ? err : count;
 }
 
 static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long 
arg)
@@ -824,6 +905,7 @@ static int ivtvfb_blank(int blank_mode, 
 
 static struct fb_ops ivtvfb_ops = {
        .owner = THIS_MODULE,
+       .fb_write       = ivtvfb_write,
        .fb_check_var   = ivtvfb_check_var,
        .fb_set_par     = ivtvfb_set_par,
        .fb_setcolreg   = ivtvfb_setcolreg,


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/1ef54d1daa8e557c1a4944d7ff41366d4f75b7e0

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to