V4L/DVB (6896): ivtv: add XC2028 support for Club3D cards
authorHans Verkuil <hverkuil@xs4all.nl>
Sat, 22 Dec 2007 00:33:36 +0000 (21:33 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Fri, 25 Jan 2008 21:04:15 +0000 (19:04 -0200)
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/video/ivtv/ivtv-cards.c
drivers/media/video/ivtv/ivtv-driver.c
drivers/media/video/ivtv/ivtv-driver.h
drivers/media/video/ivtv/ivtv-gpio.c
drivers/media/video/ivtv/ivtv-i2c.c

index 26322e9..f23c6b8 100644 (file)
@@ -880,7 +880,7 @@ static const struct ivtv_card ivtv_card_pg600v2 = {
        .hw_video = IVTV_HW_CX25840,
        .hw_audio = IVTV_HW_CX25840,
        .hw_audio_ctrl = IVTV_HW_CX25840,
-       .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
+       .hw_all = IVTV_HW_CX25840,
        .video_inputs = {
                { IVTV_CARD_INPUT_SVIDEO1,    0,
                  CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
@@ -889,9 +889,6 @@ static const struct ivtv_card ivtv_card_pg600v2 = {
        .audio_inputs = {
                { IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL },
        },
-       .tuners = {
-               { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
-       },
        .pci_list = ivtv_pci_pg600v2,
        .i2c = &ivtv_i2c_std,
 };
@@ -914,13 +911,17 @@ static const struct ivtv_card ivtv_card_club3d = {
        .hw_audio_ctrl = IVTV_HW_CX25840,
        .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
        .video_inputs = {
-               { IVTV_CARD_INPUT_SVIDEO1,    0,
+               { IVTV_CARD_INPUT_VID_TUNER,  0, CX25840_COMPOSITE2 },
+               { IVTV_CARD_INPUT_SVIDEO1,    1,
                  CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
-               { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE3 },
+               { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE3 },
        },
        .audio_inputs = {
+               { IVTV_CARD_INPUT_AUD_TUNER,  CX25840_AUDIO5       },
                { IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL },
        },
+       .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5 },
+       .gpio_init = { .direction = 0x1000, .initial_value = 0x1000 }, /* tuner reset */
        .tuners = {
                { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
        },
@@ -944,7 +945,7 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
        .hw_video = IVTV_HW_CX25840,
        .hw_audio = IVTV_HW_CX25840,
        .hw_audio_ctrl = IVTV_HW_CX25840,
-       .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER | IVTV_HW_WM8739,
+       .hw_all = IVTV_HW_CX25840 | IVTV_HW_WM8739,
        .video_inputs = {
                { IVTV_CARD_INPUT_SVIDEO1,    0, CX25840_SVIDEO3    },
                { IVTV_CARD_INPUT_COMPOSITE1, 0, CX25840_COMPOSITE1 },
@@ -953,9 +954,6 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
                { IVTV_CARD_INPUT_LINE_IN1,   CX25840_AUDIO_SERIAL, 1 },
        },
        .gpio_init = { .direction = 0xe000, .initial_value = 0x4000 }, /* enable line-in */
-       .tuners = {
-               { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
-       },
        .pci_list = ivtv_pci_avertv_mce116,
        .i2c = &ivtv_i2c_std,
 };
index 2765624..0cb832a 100644 (file)
@@ -59,6 +59,7 @@
 #include <media/tveeprom.h>
 #include <media/saa7115.h>
 #include <media/v4l2-chip-ident.h>
+#include "tuner-xc2028.h"
 
 /* var to keep track of the number of array elements in use */
 int ivtv_cards_active = 0;
@@ -844,11 +845,6 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
        unsigned i;
 
        /* load modules */
-       if ((hw & IVTV_HW_TUNER) && itv->options.tuner == TUNER_XC2028) {
-               IVTV_INFO("Xceive tuner not yet supported, only composite\n");
-               IVTV_INFO("and S-Video inputs will be available\n");
-               hw &= ~IVTV_HW_TUNER;
-       }
 #ifndef CONFIG_VIDEO_TUNER
        hw = ivtv_request_module(itv, hw, "tuner", IVTV_HW_TUNER);
 #endif
@@ -1150,7 +1146,20 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
                setup.addr = ADDR_UNSET;
                setup.type = itv->options.tuner;
                setup.mode_mask = T_ANALOG_TV;  /* matches TV tuners */
+               setup.tuner_callback = (setup.type == TUNER_XC2028) ?
+                       ivtv_reset_tuner_gpio : NULL;
                ivtv_call_i2c_clients(itv, TUNER_SET_TYPE_ADDR, &setup);
+               if (setup.type == TUNER_XC2028) {
+                       static struct xc2028_ctrl ctrl = {
+                               .fname = XC2028_DEFAULT_FIRMWARE,
+                               .max_len = 64,
+                       };
+                       struct v4l2_priv_tun_config cfg = {
+                               .tuner = itv->options.tuner,
+                               .priv = &ctrl,
+                       };
+                       ivtv_call_i2c_clients(itv, TUNER_SET_CONFIG, &cfg);
+               }
        }
 
        /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
index 8eeea3a..536140f 100644 (file)
@@ -65,7 +65,6 @@
 
 #include <linux/ivtv.h>
 
-
 /* Memory layout */
 #define IVTV_ENCODER_OFFSET    0x00000000
 #define IVTV_ENCODER_SIZE      0x00800000      /* Total size is 0x01000000, but only first half is used */
index 132fb5f..688cd38 100644 (file)
@@ -22,6 +22,7 @@
 #include "ivtv-driver.h"
 #include "ivtv-cards.h"
 #include "ivtv-gpio.h"
+#include "tuner-xc2028.h"
 #include <media/tuner.h>
 
 /*
@@ -122,6 +123,29 @@ void ivtv_reset_ir_gpio(struct ivtv *itv)
        write_reg(curdir, IVTV_REG_GPIO_DIR);
 }
 
+/* Xceive tuner reset function */
+int ivtv_reset_tuner_gpio(void *dev, int cmd, int value)
+{
+       struct i2c_algo_bit_data *algo = dev;
+       struct ivtv *itv = algo->data;
+       int curdir, curout;
+
+       if (cmd != XC2028_TUNER_RESET)
+               return 0;
+       IVTV_DEBUG_INFO("Resetting tuner\n");
+       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);
+       schedule_timeout_interruptible(msecs_to_jiffies(1));
+
+       curout |= (1 << 12);
+       write_reg(curout, IVTV_REG_GPIO_OUT);
+       schedule_timeout_interruptible(msecs_to_jiffies(1));
+       return 0;
+}
 
 void ivtv_gpio_init(struct ivtv *itv)
 {
index 9acfde6..efd4a13 100644 (file)
@@ -777,9 +777,9 @@ int init_ivtv_i2c(struct ivtv *itv)
                       sizeof(struct i2c_adapter));
                memcpy(&itv->i2c_algo, &ivtv_i2c_algo_template,
                       sizeof(struct i2c_algo_bit_data));
-               itv->i2c_algo.data = itv;
-               itv->i2c_adap.algo_data = &itv->i2c_algo;
        }
+       itv->i2c_algo.data = itv;
+       itv->i2c_adap.algo_data = &itv->i2c_algo;
 
        sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
                itv->num);