include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[safe/jmp/linux-2.6] / drivers / media / video / cx88 / cx88-cards.c
index d2aa27e..2918a6e 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/slab.h>
 
 #include "cx88.h"
 #include "tea5767.h"
@@ -1283,6 +1284,51 @@ static const struct cx88_board cx88_boards[] = {
                },
                .mpeg           = CX88_MPEG_DVB,
        },
+       [CX88_BOARD_WINFAST_DTV2000H_J] = {
+               .name           = "WinFast DTV2000 H rev. J",
+               .tuner_type     = TUNER_PHILIPS_FMD1216ME_MK3,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .tda9887_conf   = TDA9887_PRESENT,
+               .input          = {{
+                       .type   = CX88_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0x00017300,
+                       .gpio1  = 0x00008207,
+                       .gpio2  = 0x00000000,
+                       .gpio3  = 0x02000000,
+               },{
+                       .type   = CX88_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0x00018300,
+                       .gpio1  = 0x0000f207,
+                       .gpio2  = 0x00017304,
+                       .gpio3  = 0x02000000,
+               },{
+                       .type   = CX88_VMUX_COMPOSITE1,
+                       .vmux   = 1,
+                       .gpio0  = 0x00018301,
+                       .gpio1  = 0x0000f207,
+                       .gpio2  = 0x00017304,
+                       .gpio3  = 0x02000000,
+               },{
+                       .type   = CX88_VMUX_SVIDEO,
+                       .vmux   = 2,
+                       .gpio0  = 0x00018301,
+                       .gpio1  = 0x0000f207,
+                       .gpio2  = 0x00017304,
+                       .gpio3  = 0x02000000,
+               }},
+               .radio = {
+                        .type  = CX88_RADIO,
+                        .gpio0 = 0x00015702,
+                        .gpio1 = 0x0000f207,
+                        .gpio2 = 0x00015702,
+                        .gpio3 = 0x02000000,
+               },
+               .mpeg           = CX88_MPEG_DVB,
+       },
        [CX88_BOARD_GENIATECH_DVBS] = {
                .name          = "Geniatech DVB-S",
                .tuner_type    = TUNER_ABSENT,
@@ -1421,6 +1467,18 @@ static const struct cx88_board cx88_boards[] = {
                        .audioroute = 8,
                },
        },
+       [CX88_BOARD_SAMSUNG_SMT_7020] = {
+               .name           = "Samsung SMT 7020 DVB-S",
+               .tuner_type     = TUNER_ABSENT,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .input          = { {
+                       .type   = CX88_VMUX_DVB,
+                       .vmux   = 0,
+               } },
+               .mpeg           = CX88_MPEG_DVB,
+       },
        [CX88_BOARD_ADSTECH_PTV_390] = {
                .name           = "ADS Tech Instant Video PCI",
                .tuner_type     = TUNER_ABSENT,
@@ -1524,33 +1582,45 @@ static const struct cx88_board cx88_boards[] = {
                },
                .mpeg           = CX88_MPEG_DVB,
        },
+       /* Terry Wu <terrywu2009@gmail.com> */
+       /* TV Audio :      set GPIO 2, 18, 19 value to 0, 1, 0 */
+       /* FM Audio :      set GPIO 2, 18, 19 value to 0, 0, 0 */
+       /* Line-in Audio : set GPIO 2, 18, 19 value to 0, 1, 1 */
+       /* Mute Audio :    set GPIO 2 value to 1               */
        [CX88_BOARD_WINFAST_TV2000_XP_GLOBAL] = {
-               .name           = "Winfast TV2000 XP Global",
+               .name           = "Leadtek TV2000 XP Global",
                .tuner_type     = TUNER_XC2028,
                .tuner_addr     = 0x61,
+               .radio_type     = TUNER_XC2028,
+               .radio_addr     = 0x61,
                .input          = { {
                        .type   = CX88_VMUX_TELEVISION,
                        .vmux   = 0,
-                       .gpio0  = 0x0400, /* pin 2:mute = 0 (off?) */
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
                        .gpio1  = 0x0000,
-                       .gpio2  = 0x0800, /* pin 19:audio = 0 (tv) */
-
+                       .gpio2  = 0x0C04,       /* pin 18 = 1, pin 19 = 0 */
+                       .gpio3  = 0x0000,
                }, {
                        .type   = CX88_VMUX_COMPOSITE1,
                        .vmux   = 1,
-                       .gpio0  = 0x0400, /* probably?  or 0x0404 to turn mute on */
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
                        .gpio1  = 0x0000,
-                       .gpio2  = 0x0808, /* pin 19:audio = 1 (line) */
-
+                       .gpio2  = 0x0C0C,       /* pin 18 = 1, pin 19 = 1 */
+                       .gpio3  = 0x0000,
                }, {
                        .type   = CX88_VMUX_SVIDEO,
                        .vmux   = 2,
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
+                       .gpio1  = 0x0000,
+                       .gpio2  = 0x0C0C,       /* pin 18 = 1, pin 19 = 1 */
+                       .gpio3  = 0x0000,
                } },
                .radio = {
                        .type   = CX88_RADIO,
-                       .gpio0  = 0x004ff,
-                       .gpio1  = 0x010ff,
-                       .gpio2  = 0x0ff,
+                       .gpio0  = 0x0400,        /* pin 2 = 0 */
+                       .gpio1  = 0x0000,
+                       .gpio2  = 0x0C00,       /* pin 18 = 0, pin 19 = 0 */
+                       .gpio3  = 0x0000,
                },
        },
        [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = {
@@ -1896,7 +1966,8 @@ static const struct cx88_board cx88_boards[] = {
                .radio_addr     = ADDR_UNSET,
                .input          = {{
                        .type   = CX88_VMUX_DVB,
-                       .vmux   = 1,
+                       .vmux   = 0,
+                       .gpio0  = 0x8080,
                } },
                .mpeg           = CX88_MPEG_DVB,
        },
@@ -1976,6 +2047,59 @@ static const struct cx88_board cx88_boards[] = {
                .tuner_addr     = ADDR_UNSET,
                .radio_addr     = ADDR_UNSET,
        },
+       [CX88_BOARD_WINFAST_DTV1800H] = {
+               .name           = "Leadtek WinFast DTV1800 Hybrid",
+               .tuner_type     = TUNER_XC2028,
+               .radio_type     = TUNER_XC2028,
+               .tuner_addr     = 0x61,
+               .radio_addr     = 0x61,
+               /*
+                * GPIO setting
+                *
+                *  2: mute (0=off,1=on)
+                * 12: tuner reset pin
+                * 13: audio source (0=tuner audio,1=line in)
+                * 14: FM (0=on,1=off ???)
+                */
+               .input          = {{
+                       .type   = CX88_VMUX_TELEVISION,
+                       .vmux   = 0,
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
+                       .gpio1  = 0x6040,       /* pin 13 = 0, pin 14 = 1 */
+                       .gpio2  = 0x0000,
+               }, {
+                       .type   = CX88_VMUX_COMPOSITE1,
+                       .vmux   = 1,
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
+                       .gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
+                       .gpio2  = 0x0000,
+               }, {
+                       .type   = CX88_VMUX_SVIDEO,
+                       .vmux   = 2,
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
+                       .gpio1  = 0x6060,       /* pin 13 = 1, pin 14 = 1 */
+                       .gpio2  = 0x0000,
+               } },
+               .radio = {
+                       .type   = CX88_RADIO,
+                       .gpio0  = 0x0400,       /* pin 2 = 0 */
+                       .gpio1  = 0x6000,       /* pin 13 = 0, pin 14 = 0 */
+                       .gpio2  = 0x0000,
+               },
+               .mpeg           = CX88_MPEG_DVB,
+       },
+       [CX88_BOARD_PROF_7301] = {
+               .name           = "Prof 7301 DVB-S/S2",
+               .tuner_type     = UNSET,
+               .radio_type     = UNSET,
+               .tuner_addr     = ADDR_UNSET,
+               .radio_addr     = ADDR_UNSET,
+               .input          = { {
+                       .type   = CX88_VMUX_DVB,
+                       .vmux   = 0,
+               } },
+               .mpeg           = CX88_MPEG_DVB,
+       },
 };
 
 /* ------------------------------------------------------------------ */
@@ -2229,6 +2353,10 @@ static const struct cx88_subid cx88_subids[] = {
                .subdevice = 0x665e,
                .card      = CX88_BOARD_WINFAST_DTV2000H,
        },{
+               .subvendor = 0x107d,
+               .subdevice = 0x6f2b,
+               .card      = CX88_BOARD_WINFAST_DTV2000H_J,
+       },{
                .subvendor = 0x18ac,
                .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */
                .card      = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q,
@@ -2240,6 +2368,14 @@ static const struct cx88_subid cx88_subids[] = {
                .subvendor = 0x0070,
                .subdevice = 0x1404,
                .card      = CX88_BOARD_HAUPPAUGE_HVR3000,
+       }, {
+               .subvendor = 0x18ac,
+               .subdevice = 0xdc00,
+               .card      = CX88_BOARD_SAMSUNG_SMT_7020,
+       }, {
+               .subvendor = 0x18ac,
+               .subdevice = 0xdccd,
+               .card      = CX88_BOARD_SAMSUNG_SMT_7020,
        },{
                .subvendor = 0x1461,
                .subdevice = 0xc111, /* AverMedia M150-D */
@@ -2393,6 +2529,49 @@ static const struct cx88_subid cx88_subids[] = {
                .subvendor = 0x0070,
                .subdevice = 0x9290,
                .card      = CX88_BOARD_HAUPPAUGE_IRONLY,
+       }, {
+               .subvendor = 0x107d,
+               .subdevice = 0x6654,
+               .card      = CX88_BOARD_WINFAST_DTV1800H,
+       }, {
+               /* PVR2000 PAL Model [107d:6630] */
+               .subvendor = 0x107d,
+               .subdevice = 0x6630,
+               .card      = CX88_BOARD_LEADTEK_PVR2000,
+       }, {
+               /* PVR2000 PAL Model [107d:6638] */
+               .subvendor = 0x107d,
+               .subdevice = 0x6638,
+               .card      = CX88_BOARD_LEADTEK_PVR2000,
+       }, {
+               /* PVR2000 NTSC Model [107d:6631] */
+               .subvendor = 0x107d,
+               .subdevice = 0x6631,
+               .card      = CX88_BOARD_LEADTEK_PVR2000,
+       }, {
+               /* PVR2000 NTSC Model [107d:6637] */
+               .subvendor = 0x107d,
+               .subdevice = 0x6637,
+               .card      = CX88_BOARD_LEADTEK_PVR2000,
+       }, {
+               /* PVR2000 NTSC Model [107d:663d] */
+               .subvendor = 0x107d,
+               .subdevice = 0x663d,
+               .card      = CX88_BOARD_LEADTEK_PVR2000,
+       }, {
+               /* DV2000 NTSC Model [107d:6621] */
+               .subvendor = 0x107d,
+               .subdevice = 0x6621,
+               .card      = CX88_BOARD_WINFAST_DV2000,
+       }, {
+               /* TV2000 XP Global [107d:6618]  */
+               .subvendor = 0x107d,
+               .subdevice = 0x6618,
+               .card      = CX88_BOARD_WINFAST_TV2000_XP_GLOBAL,
+       }, {
+               .subvendor = 0xb034,
+               .subdevice = 0x3034,
+               .card      = CX88_BOARD_PROF_7301,
        },
 };
 
@@ -2401,12 +2580,6 @@ static const struct cx88_subid cx88_subids[] = {
 
 static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
 {
-       /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on
-        * any others.
-        *
-        * Byte 0 is 1 on the NTSC board.
-        */
-
        if (eeprom_data[4] != 0x7d ||
            eeprom_data[5] != 0x10 ||
            eeprom_data[7] != 0x66) {
@@ -2414,8 +2587,19 @@ static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
                return;
        }
 
-       core->board.tuner_type = (eeprom_data[6] == 0x13) ?
-               TUNER_PHILIPS_FM1236_MK3 : TUNER_PHILIPS_FM1216ME_MK3;
+       /* Terry Wu <terrywu2009@gmail.com> */
+       switch (eeprom_data[6]) {
+       case 0x13: /* SSID 6613 for TV2000 XP Expert NTSC Model */
+       case 0x21: /* SSID 6621 for DV2000 NTSC Model */
+       case 0x31: /* SSID 6631 for PVR2000 NTSC Model */
+       case 0x37: /* SSID 6637 for PVR2000 NTSC Model */
+       case 0x3d: /* SSID 6637 for PVR2000 NTSC Model */
+               core->board.tuner_type = TUNER_PHILIPS_FM1236_MK3;
+               break;
+       default:
+               core->board.tuner_type = TUNER_PHILIPS_FM1216ME_MK3;
+               break;
+       }
 
        info_printk(core, "Leadtek Winfast 2000XP Expert config: "
                    "tuner=%d, eeprom[0]=0x%02x\n",
@@ -2470,6 +2654,9 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data)
        case 98559: /* WinTV-HVR1100LP (Video no IR, Retail - Low Profile) */
                /* known */
                break;
+       case CX88_BOARD_SAMSUNG_SMT_7020:
+               cx_set(MO_GP0_IO, 0x008989FF);
+               break;
        default:
                warn_printk(core, "warning: unknown hauppauge model #%d\n",
                            tv.model);
@@ -2591,6 +2778,23 @@ static int cx88_xc3028_geniatech_tuner_callback(struct cx88_core *core,
        return -EINVAL;
 }
 
+static int cx88_xc3028_winfast1800h_callback(struct cx88_core *core,
+                                            int command, int arg)
+{
+       switch (command) {
+       case XC2028_TUNER_RESET:
+               /* GPIO 12 (xc3028 tuner reset) */
+               cx_set(MO_GP1_IO, 0x1010);
+               mdelay(50);
+               cx_clear(MO_GP1_IO, 0x10);
+               mdelay(50);
+               cx_set(MO_GP1_IO, 0x10);
+               mdelay(50);
+               return 0;
+       }
+       return -EINVAL;
+}
+
 /* ------------------------------------------------------------------- */
 /* some Divco specific stuff                                           */
 static int cx88_pv_8000gt_callback(struct cx88_core *core,
@@ -2651,7 +2855,6 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
 {
        /* Board-specific callbacks */
        switch (core->boardnr) {
-       case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
        case CX88_BOARD_POWERCOLOR_REAL_ANGEL:
        case CX88_BOARD_GENIATECH_X8000_MT:
        case CX88_BOARD_KWORLD_ATSC_120:
@@ -2663,6 +2866,9 @@ static int cx88_xc2028_tuner_callback(struct cx88_core *core,
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
                return cx88_dvico_xc2028_callback(core, command, arg);
+       case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
+       case CX88_BOARD_WINFAST_DTV1800H:
+               return cx88_xc3028_winfast1800h_callback(core, command, arg);
        }
 
        switch (command) {
@@ -2849,6 +3055,17 @@ static void cx88_card_setup_pre_i2c(struct cx88_core *core)
                cx_set(MO_GP0_IO, 0x00000080); /* 702 out of reset */
                udelay(1000);
                break;
+
+       case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
+       case CX88_BOARD_WINFAST_DTV1800H:
+               /* GPIO 12 (xc3028 tuner reset) */
+               cx_set(MO_GP1_IO, 0x1010);
+               mdelay(50);
+               cx_clear(MO_GP1_IO, 0x10);
+               mdelay(50);
+               cx_set(MO_GP1_IO, 0x10);
+               mdelay(50);
+               break;
        }
 }
 
@@ -2869,12 +3086,22 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
                        core->i2c_algo.udelay = 16;
                break;
        case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO:
+       case CX88_BOARD_WINFAST_DTV1800H:
                ctl->demod = XC3028_FE_ZARLINK456;
                break;
        case CX88_BOARD_KWORLD_ATSC_120:
        case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
                ctl->demod = XC3028_FE_OREN538;
                break;
+       case CX88_BOARD_GENIATECH_X8000_MT:
+               /* FIXME: For this board, the xc3028 never recovers after being
+                  powered down (the reset GPIO probably is not set properly).
+                  We don't have access to the hardware so we cannot determine
+                  which GPIO is used for xc3028, so just disable power xc3028
+                  power management for now */
+               ctl->disable_power_mgmt = 1;
+               break;
+       case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
        case CX88_BOARD_PROLINK_PV_GLOBAL_XTREME:
        case CX88_BOARD_PROLINK_PV_8000GT:
                /*
@@ -2918,6 +3145,8 @@ static void cx88_card_setup(struct cx88_core *core)
                if (0 == core->i2c_rc)
                        gdi_eeprom(core, eeprom);
                break;
+       case CX88_BOARD_LEADTEK_PVR2000:
+       case CX88_BOARD_WINFAST_DV2000:
        case CX88_BOARD_WINFAST2000XP_EXPERT:
                if (0 == core->i2c_rc)
                        leadtek_eeprom(core, eeprom);
@@ -3022,8 +3251,13 @@ static void cx88_card_setup(struct cx88_core *core)
        case  CX88_BOARD_TBS_8920:
        case  CX88_BOARD_PROF_6200:
        case  CX88_BOARD_PROF_7300:
+       case  CX88_BOARD_PROF_7301:
        case  CX88_BOARD_SATTRADE_ST4200:
+               cx_write(MO_GP0_IO, 0x8000);
+               msleep(100);
                cx_write(MO_SRST_IO, 0);
+               msleep(10);
+               cx_write(MO_GP0_IO, 0x8080);
                msleep(100);
                cx_write(MO_SRST_IO, 1);
                msleep(100);
@@ -3074,7 +3308,7 @@ static void cx88_card_setup(struct cx88_core *core)
                            ctl.fname);
                call_all(core, tuner, s_config, &xc2028_cfg);
        }
-       call_all(core, tuner, s_standby);
+       call_all(core, core, s_power, 0);
 }
 
 /* ------------------------------------------------------------------ */
@@ -3246,20 +3480,20 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
                   The radio_type is sometimes missing, or set to UNSET but
                   later code configures a tea5767.
                 */
-               v4l2_i2c_new_probed_subdev(&core->v4l2_dev, &core->i2c_adap,
+               v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
                                "tuner", "tuner",
-                               v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+                               0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
                if (has_demod)
-                       v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+                       v4l2_i2c_new_subdev(&core->v4l2_dev,
                                &core->i2c_adap, "tuner", "tuner",
-                               v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+                               0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
                if (core->board.tuner_addr == ADDR_UNSET) {
-                       v4l2_i2c_new_probed_subdev(&core->v4l2_dev,
+                       v4l2_i2c_new_subdev(&core->v4l2_dev,
                                &core->i2c_adap, "tuner", "tuner",
-                               has_demod ? tv_addrs + 4 : tv_addrs);
+                               0, has_demod ? tv_addrs + 4 : tv_addrs);
                } else {
                        v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
-                               "tuner", "tuner", core->board.tuner_addr);
+                               "tuner", "tuner", core->board.tuner_addr, NULL);
                }
        }