diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-01 04:58:39 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-06-01 04:58:39 -0300 |
commit | d7709cc1d93ee6c75fc6e421ae5e8646aff438a7 (patch) | |
tree | 811e21a51110680888635f01fedf0b85f219304e | |
parent | 18f456ba66ff7f265cebbc7c0fa00c6ea2d6ae21 (diff) | |
parent | 355e218336f85e723e8061e62c292436b0654104 (diff) | |
download | mediapointer-dvb-s2-d7709cc1d93ee6c75fc6e421ae5e8646aff438a7.tar.gz mediapointer-dvb-s2-d7709cc1d93ee6c75fc6e421ae5e8646aff438a7.tar.bz2 |
merge: http://linuxtv.org/hg/~dougsland/v4l-dvb
From: Mauro Carvalho Chehab <mchehab@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
21 files changed, 728 insertions, 126 deletions
diff --git a/linux/Documentation/video4linux/CARDLIST.cx23885 b/linux/Documentation/video4linux/CARDLIST.cx23885 index 948e43610..450b8f8c3 100644 --- a/linux/Documentation/video4linux/CARDLIST.cx23885 +++ b/linux/Documentation/video4linux/CARDLIST.cx23885 @@ -20,3 +20,4 @@ 19 -> Hauppauge WinTV-HVR1275 [0070:2215] 20 -> Hauppauge WinTV-HVR1255 [0070:2251] 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295] + 22 -> Mygica X8506 DMB-TH [14f1:8651] diff --git a/linux/Documentation/video4linux/CARDLIST.cx88 b/linux/Documentation/video4linux/CARDLIST.cx88 index 80527b292..89093f531 100644 --- a/linux/Documentation/video4linux/CARDLIST.cx88 +++ b/linux/Documentation/video4linux/CARDLIST.cx88 @@ -79,3 +79,4 @@ 78 -> Prof 6200 DVB-S [b022:3022] 79 -> Terratec Cinergy HT PCI MKII [153b:1177] 80 -> Hauppauge WinTV-IR Only [0070:9290] + 81 -> Leadtek WinFast DTV1800 Hybrid [107d:6654] diff --git a/linux/drivers/media/Kconfig b/linux/drivers/media/Kconfig index 223c36ede..ba69beeb0 100644 --- a/linux/drivers/media/Kconfig +++ b/linux/drivers/media/Kconfig @@ -2,8 +2,14 @@ # Multimedia device configuration # -menu "Multimedia devices" +menuconfig MEDIA_SUPPORT + tristate "Multimedia support" depends on HAS_IOMEM + help + If you want to use Video for Linux, DVB for Linux, or DAB adapters, + enable this option and other options below. + +if MEDIA_SUPPORT comment "Multimedia core support" @@ -136,4 +142,4 @@ config USB_DABUSB module will be called dabusb. endif # DAB -endmenu +endif # MEDIA_SUPPORT diff --git a/linux/drivers/media/dvb/b2c2/flexcop-misc.c b/linux/drivers/media/dvb/b2c2/flexcop-misc.c index e56627d2f..f06f3a907 100644 --- a/linux/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/linux/drivers/media/dvb/b2c2/flexcop-misc.c @@ -46,16 +46,16 @@ static const char *flexcop_revision_names[] = { }; static const char *flexcop_device_names[] = { - "Unknown device", - "Air2PC/AirStar 2 DVB-T", - "Air2PC/AirStar 2 ATSC 1st generation", - "Air2PC/AirStar 2 ATSC 2nd generation", - "Sky2PC/SkyStar 2 DVB-S", - "Sky2PC/SkyStar 2 DVB-S (old version)", - "Cable2PC/CableStar 2 DVB-C", - "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", - "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", - "Sky2PC/SkyStar 2 DVB-S rev 2.8", + [FC_UNK] = "Unknown device", + [FC_CABLE] = "Cable2PC/CableStar 2 DVB-C", + [FC_AIR_DVBT] = "Air2PC/AirStar 2 DVB-T", + [FC_AIR_ATSC1] = "Air2PC/AirStar 2 ATSC 1st generation", + [FC_AIR_ATSC2] = "Air2PC/AirStar 2 ATSC 2nd generation", + [FC_AIR_ATSC3] = "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", + [FC_SKY_REV23] = "Sky2PC/SkyStar 2 DVB-S rev 2.3 (old version)", + [FC_SKY_REV26] = "Sky2PC/SkyStar 2 DVB-S rev 2.6", + [FC_SKY_REV27] = "Sky2PC/SkyStar 2 DVB-S rev 2.7a/u", + [FC_SKY_REV28] = "Sky2PC/SkyStar 2 DVB-S rev 2.8", }; static const char *flexcop_bus_names[] = { diff --git a/linux/drivers/media/dvb/frontends/lgdt3305.c b/linux/drivers/media/dvb/frontends/lgdt3305.c index f0c0c8199..b16410c64 100644 --- a/linux/drivers/media/dvb/frontends/lgdt3305.c +++ b/linux/drivers/media/dvb/frontends/lgdt3305.c @@ -19,6 +19,7 @@ * */ +#include <asm/div64.h> #include "compat.h" #include <linux/dvb/frontend.h> #include "dvb_math.h" @@ -497,27 +498,15 @@ static int lgdt3305_set_if(struct lgdt3305_state *state, nco = if_freq_khz / 10; -#define LGDT3305_64BIT_DIVISION_ENABLED 0 - /* FIXME: 64bit division disabled to avoid linking error: - * WARNING: "__udivdi3" [lgdt3305.ko] undefined! - */ switch (param->u.vsb.modulation) { case VSB_8: -#if LGDT3305_64BIT_DIVISION_ENABLED nco <<= 24; - nco /= 625; -#else - nco *= ((1 << 24) / 625); -#endif + do_div(nco, 625); break; case QAM_64: case QAM_256: -#if LGDT3305_64BIT_DIVISION_ENABLED nco <<= 28; - nco /= 625; -#else - nco *= ((1 << 28) / 625); -#endif + do_div(nco, 625); break; default: return -EINVAL; diff --git a/linux/drivers/media/dvb/siano/sms-cards.c b/linux/drivers/media/dvb/siano/sms-cards.c index fda483f07..d8b15d583 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.c +++ b/linux/drivers/media/dvb/siano/sms-cards.c @@ -85,6 +85,16 @@ static struct sms_board sms_boards[] = { .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", .lna_ctrl = -1, }, + [SMS1XXX_BOARD_SIANO_NICE] = { + /* 11 */ + .name = "Siano Nice Digital Receiver", + .type = SMS_NOVA_B0, + }, + [SMS1XXX_BOARD_SIANO_VENICE] = { + /* 12 */ + .name = "Siano Venice Digital Receiver", + .type = SMS_VEGA, + }, }; struct sms_board *sms_get_board(int id) @@ -94,12 +104,179 @@ struct sms_board *sms_get_board(int id) return &sms_boards[id]; } EXPORT_SYMBOL_GPL(sms_get_board); +static inline void sms_gpio_assign_11xx_default_led_config( + struct smscore_gpio_config *pGpioConfig) { + pGpioConfig->Direction = SMS_GPIO_DIRECTION_OUTPUT; + pGpioConfig->InputCharacteristics = + SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL; + pGpioConfig->OutputDriving = SMS_GPIO_OUTPUT_DRIVING_4mA; + pGpioConfig->OutputSlewRate = SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS; + pGpioConfig->PullUpDown = SMS_GPIO_PULL_UP_DOWN_NONE; +} + +int sms_board_event(struct smscore_device_t *coredev, + enum SMS_BOARD_EVENTS gevent) { + int board_id = smscore_get_board_id(coredev); + struct sms_board *board = sms_get_board(board_id); + struct smscore_gpio_config MyGpioConfig; + + sms_gpio_assign_11xx_default_led_config(&MyGpioConfig); + + switch (gevent) { + case BOARD_EVENT_POWER_INIT: /* including hotplug */ + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + /* set I/O and turn off all LEDs */ + smscore_gpio_configure(coredev, + board->board_cfg.leds_power, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 0); + smscore_gpio_configure(coredev, board->board_cfg.led0, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 0); + smscore_gpio_configure(coredev, board->board_cfg.led1, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + /* set I/O and turn off LNA */ + smscore_gpio_configure(coredev, + board->board_cfg.foreign_lna0_ctrl, + &MyGpioConfig); + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 0); + break; + } + break; /* BOARD_EVENT_BIND */ + + case BOARD_EVENT_POWER_SUSPEND: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 0); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 0); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 0); + break; + } + break; /* BOARD_EVENT_POWER_SUSPEND */ + + case BOARD_EVENT_POWER_RESUME: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 1); + break; + } + break; /* BOARD_EVENT_POWER_RESUME */ + + case BOARD_EVENT_BIND: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.leds_power, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led0, 1); + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2: + case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD: + smscore_gpio_set_level(coredev, + board->board_cfg.foreign_lna0_ctrl, + 1); + break; + } + break; /* BOARD_EVENT_BIND */ + + case BOARD_EVENT_SCAN_PROG: + break; /* BOARD_EVENT_SCAN_PROG */ + case BOARD_EVENT_SCAN_COMP: + break; /* BOARD_EVENT_SCAN_COMP */ + case BOARD_EVENT_EMERGENCY_WARNING_SIGNAL: + break; /* BOARD_EVENT_EMERGENCY_WARNING_SIGNAL */ + case BOARD_EVENT_FE_LOCK: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 1); + break; + } + break; /* BOARD_EVENT_FE_LOCK */ + case BOARD_EVENT_FE_UNLOCK: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + } + break; /* BOARD_EVENT_FE_UNLOCK */ + case BOARD_EVENT_DEMOD_LOCK: + break; /* BOARD_EVENT_DEMOD_LOCK */ + case BOARD_EVENT_DEMOD_UNLOCK: + break; /* BOARD_EVENT_DEMOD_UNLOCK */ + case BOARD_EVENT_RECEPTION_MAX_4: + break; /* BOARD_EVENT_RECEPTION_MAX_4 */ + case BOARD_EVENT_RECEPTION_3: + break; /* BOARD_EVENT_RECEPTION_3 */ + case BOARD_EVENT_RECEPTION_2: + break; /* BOARD_EVENT_RECEPTION_2 */ + case BOARD_EVENT_RECEPTION_1: + break; /* BOARD_EVENT_RECEPTION_1 */ + case BOARD_EVENT_RECEPTION_LOST_0: + break; /* BOARD_EVENT_RECEPTION_LOST_0 */ + case BOARD_EVENT_MULTIPLEX_OK: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 1); + break; + } + break; /* BOARD_EVENT_MULTIPLEX_OK */ + case BOARD_EVENT_MULTIPLEX_ERRORS: + switch (board_id) { + case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM: + smscore_gpio_set_level(coredev, + board->board_cfg.led1, 0); + break; + } + break; /* BOARD_EVENT_MULTIPLEX_ERRORS */ + + default: + sms_err("Unknown SMS board event"); + break; + } + return 0; +} +EXPORT_SYMBOL_GPL(sms_board_event); static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable) { int lvl, ret; u32 gpio; - struct smscore_gpio_config gpioconfig = { + struct smscore_config_gpio gpioconfig = { .direction = SMS_GPIO_DIRECTION_OUTPUT, .pullupdown = SMS_GPIO_PULLUPDOWN_NONE, .inputcharacteristics = SMS_GPIO_INPUTCHARACTERISTICS_NORMAL, diff --git a/linux/drivers/media/dvb/siano/sms-cards.h b/linux/drivers/media/dvb/siano/sms-cards.h index 447481ab5..38f062f6a 100644 --- a/linux/drivers/media/dvb/siano/sms-cards.h +++ b/linux/drivers/media/dvb/siano/sms-cards.h @@ -35,6 +35,8 @@ #define SMS1XXX_BOARD_HAUPPAUGE_WINDHAM 8 #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD 9 #define SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 10 +#define SMS1XXX_BOARD_SIANO_NICE 11 +#define SMS1XXX_BOARD_SIANO_VENICE 12 struct sms_board_gpio_cfg { int lna_vhf_exist; @@ -83,6 +85,30 @@ struct sms_board *sms_get_board(int id); extern struct smscore_device_t *coredev; +enum SMS_BOARD_EVENTS { + BOARD_EVENT_POWER_INIT, + BOARD_EVENT_POWER_SUSPEND, + BOARD_EVENT_POWER_RESUME, + BOARD_EVENT_BIND, + BOARD_EVENT_SCAN_PROG, + BOARD_EVENT_SCAN_COMP, + BOARD_EVENT_EMERGENCY_WARNING_SIGNAL, + BOARD_EVENT_FE_LOCK, + BOARD_EVENT_FE_UNLOCK, + BOARD_EVENT_DEMOD_LOCK, + BOARD_EVENT_DEMOD_UNLOCK, + BOARD_EVENT_RECEPTION_MAX_4, + BOARD_EVENT_RECEPTION_3, + BOARD_EVENT_RECEPTION_2, + BOARD_EVENT_RECEPTION_1, + BOARD_EVENT_RECEPTION_LOST_0, + BOARD_EVENT_MULTIPLEX_OK, + BOARD_EVENT_MULTIPLEX_ERRORS +}; + +int sms_board_event(struct smscore_device_t *coredev, + enum SMS_BOARD_EVENTS gevent); + int sms_board_setup(struct smscore_device_t *coredev); #define SMS_LED_OFF 0 diff --git a/linux/drivers/media/dvb/siano/smscoreapi.c b/linux/drivers/media/dvb/siano/smscoreapi.c index 16917016c..e513408fc 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.c +++ b/linux/drivers/media/dvb/siano/smscoreapi.c @@ -352,6 +352,9 @@ int smscore_register_device(struct smsdevice_params_t *params, init_completion(&dev->init_device_done); init_completion(&dev->reload_start_done); init_completion(&dev->resume_done); + init_completion(&dev->gpio_configuration_done); + init_completion(&dev->gpio_set_level_done); + init_completion(&dev->gpio_get_level_done); init_completion(&dev->ir_init_done); /* Buffer management */ @@ -1051,6 +1054,23 @@ void smscore_onresponse(struct smscore_device_t *coredev, case MSG_SMS_SLEEP_RESUME_COMP_IND: complete(&coredev->resume_done); break; + case MSG_SMS_GPIO_CONFIG_EX_RES: + sms_debug("MSG_SMS_GPIO_CONFIG_EX_RES"); + complete(&coredev->gpio_configuration_done); + break; + case MSG_SMS_GPIO_SET_LEVEL_RES: + sms_debug("MSG_SMS_GPIO_SET_LEVEL_RES"); + complete(&coredev->gpio_set_level_done); + break; + case MSG_SMS_GPIO_GET_LEVEL_RES: + { + u32 *msgdata = (u32 *) phdr; + coredev->gpio_get_res = msgdata[1]; + sms_debug("MSG_SMS_GPIO_GET_LEVEL_RES gpio level %d", + coredev->gpio_get_res); + complete(&coredev->gpio_get_level_done); + break; + } case MSG_SMS_START_IR_RES: complete(&coredev->ir_init_done); break; @@ -1331,8 +1351,9 @@ static int smscore_map_common_buffer(struct smscore_device_t *coredev, } #endif +/* old GPIO managments implementation */ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_gpio_config *pinconfig) + struct smscore_config_gpio *pinconfig) { struct { struct SmsMsgHdr_ST hdr; @@ -1401,110 +1422,254 @@ int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level) &msg, sizeof(msg)); } -static int __init smscore_module_init(void) -{ - int rc = 0; +/* new GPIO managment implementation */ +static int GetGpioPinParams(u32 PinNum, u32 *pTranslatedPinNum, + u32 *pGroupNum, u32 *pGroupCfg) { + + *pGroupCfg = 1; + + if (PinNum >= 0 && PinNum <= 1) { + *pTranslatedPinNum = 0; + *pGroupNum = 9; + *pGroupCfg = 2; + } else if (PinNum >= 2 && PinNum <= 6) { + *pTranslatedPinNum = 2; + *pGroupNum = 0; + *pGroupCfg = 2; + } else if (PinNum >= 7 && PinNum <= 11) { + *pTranslatedPinNum = 7; + *pGroupNum = 1; + } else if (PinNum >= 12 && PinNum <= 15) { + *pTranslatedPinNum = 12; + *pGroupNum = 2; + *pGroupCfg = 3; + } else if (PinNum == 16) { + *pTranslatedPinNum = 16; + *pGroupNum = 23; + } else if (PinNum >= 17 && PinNum <= 24) { + *pTranslatedPinNum = 17; + *pGroupNum = 3; + } else if (PinNum == 25) { + *pTranslatedPinNum = 25; + *pGroupNum = 6; + } else if (PinNum >= 26 && PinNum <= 28) { + *pTranslatedPinNum = 26; + *pGroupNum = 4; + } else if (PinNum == 29) { + *pTranslatedPinNum = 29; + *pGroupNum = 5; + *pGroupCfg = 2; + } else if (PinNum == 30) { + *pTranslatedPinNum = 30; + *pGroupNum = 8; + } else if (PinNum == 31) { + *pTranslatedPinNum = 31; + *pGroupNum = 17; + } else + return -1; - INIT_LIST_HEAD(&g_smscore_notifyees); - INIT_LIST_HEAD(&g_smscore_devices); - kmutex_init(&g_smscore_deviceslock); + *pGroupCfg <<= 24; - INIT_LIST_HEAD(&g_smscore_registry); - kmutex_init(&g_smscore_registrylock); + return 0; +} -#if 0 /* def SMS_CHAR_CLIENT */ - /* Char interface Register */ - rc = smschar_register(); - if (rc) { - sms_err("Error registering char device client.\n"); - goto smschar_error; - } -#endif +int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, + struct smscore_gpio_config *pGpioConfig) { + + u32 totalLen; + u32 TranslatedPinNum; + u32 GroupNum; + u32 ElectricChar; + u32 groupCfg; + void *buffer; + int rc; + + struct SetGpioMsg { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[6]; + } *pMsg; -#if 0 /* def SMS_DVB_CLIENT */ - /* DVB Register */ - rc = smsdvb_register(); - if (rc) { - sms_err("Error registering DVB client.\n"); - goto smsdvb_error; - } -#endif -#if 0 /* def SMS_NET_CLIENT */ - /* DVB Register */ - rc = smsnet_register(); - if (rc) { - sms_err("Error registering Network client.\n"); - goto smsnet_error; + if (PinNum > MAX_GPIO_PIN_NUMBER) + return -EINVAL; + + if (pGpioConfig == NULL) + return -EINVAL; + + totalLen = sizeof(struct SmsMsgHdr_ST) + (sizeof(u32) * 6); + + buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (!buffer) + return -ENOMEM; + + pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); + + pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + pMsg->xMsgHeader.msgDstId = HIF_TASK; + pMsg->xMsgHeader.msgFlags = 0; + pMsg->xMsgHeader.msgLength = (u16) totalLen; + pMsg->msgData[0] = PinNum; + + if (!(coredev->device_flags & SMS_DEVICE_FAMILY2)) { + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_REQ; + if (GetGpioPinParams(PinNum, &TranslatedPinNum, &GroupNum, + &groupCfg) != 0) + return -EINVAL; + + pMsg->msgData[1] = TranslatedPinNum; + pMsg->msgData[2] = GroupNum; + ElectricChar = (pGpioConfig->PullUpDown) + | (pGpioConfig->InputCharacteristics << 2) + | (pGpioConfig->OutputSlewRate << 3) + | (pGpioConfig->OutputDriving << 4); + pMsg->msgData[3] = ElectricChar; + pMsg->msgData[4] = pGpioConfig->Direction; + pMsg->msgData[5] = groupCfg; + } else { + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_CONFIG_EX_REQ; + pMsg->msgData[1] = pGpioConfig->PullUpDown; + pMsg->msgData[2] = pGpioConfig->OutputSlewRate; + pMsg->msgData[3] = pGpioConfig->OutputDriving; + pMsg->msgData[4] = pGpioConfig->Direction; + pMsg->msgData[5] = 0; } -#endif -#if 0 /* def SMS_USB_BUS_DRV */ - /* USB Register */ - rc = smsusb_register(); - if (rc) { - sms_err("Error registering USB bus driver.\n"); - goto sms_bus_drv_error; + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); + rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, + &coredev->gpio_configuration_done); + + if (rc != 0) { + if (rc == -ETIME) + sms_err("smscore_gpio_configure timeout"); + else + sms_err("smscore_gpio_configure error"); } -#endif + kfree(buffer); + + return rc; +} + +int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, + u8 NewLevel) { + + u32 totalLen; + int rc; + void *buffer; + + struct SetGpioMsg { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[3]; /* keep it 3 ! */ + } *pMsg; + + if ((NewLevel > 1) || (PinNum > MAX_GPIO_PIN_NUMBER) || + (PinNum > MAX_GPIO_PIN_NUMBER)) + return -EINVAL; + + totalLen = sizeof(struct SmsMsgHdr_ST) + + (3 * sizeof(u32)); /* keep it 3 ! */ -#if 0 /* def SMS_SPI_BUS_DRV */ - /* USB Register */ - rc = smsspi_register(); - if (rc) { - sms_err("Error registering spi bus driver.\n"); - goto sms_bus_drv_error; + buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (!buffer) + return -ENOMEM; + + pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); + + pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + pMsg->xMsgHeader.msgDstId = HIF_TASK; + pMsg->xMsgHeader.msgFlags = 0; + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_SET_LEVEL_REQ; + pMsg->xMsgHeader.msgLength = (u16) totalLen; + pMsg->msgData[0] = PinNum; + pMsg->msgData[1] = NewLevel; + + /* Send message to SMS */ + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); + rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, + &coredev->gpio_set_level_done); + + if (rc != 0) { + if (rc == -ETIME) + sms_err("smscore_gpio_set_level timeout"); + else + sms_err("smscore_gpio_set_level error"); } -#endif + kfree(buffer); return rc; -#if 0 -sms_bus_drv_error: -#endif /* 0 */ -#if 0 /* def SMS_NET_CLIENT */ - smsnet_unregister(); -smsnet_error: -#endif -#if 0 /* def SMS_DVB_CLIENT */ - smsdvb_unregister(); -smsdvb_error: -#endif -#if 0 /* def SMS_CHAR_CLIENT */ - smschar_unregister(); -smschar_error: -#endif - sms_debug("rc %d", rc); +} + +int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, + u8 *level) { + + u32 totalLen; + int rc; + void *buffer; + + struct SetGpioMsg { + struct SmsMsgHdr_ST xMsgHeader; + u32 msgData[2]; + } *pMsg; + + + if (PinNum > MAX_GPIO_PIN_NUMBER) + return -EINVAL; + + totalLen = sizeof(struct SmsMsgHdr_ST) + (2 * sizeof(u32)); + + buffer = kmalloc(totalLen + SMS_DMA_ALIGNMENT, + GFP_KERNEL | GFP_DMA); + if (!buffer) + return -ENOMEM; + + pMsg = (struct SetGpioMsg *) SMS_ALIGN_ADDRESS(buffer); + + pMsg->xMsgHeader.msgSrcId = DVBT_BDA_CONTROL_MSG_ID; + pMsg->xMsgHeader.msgDstId = HIF_TASK; + pMsg->xMsgHeader.msgFlags = 0; + pMsg->xMsgHeader.msgType = MSG_SMS_GPIO_GET_LEVEL_REQ; + pMsg->xMsgHeader.msgLength = (u16) totalLen; + pMsg->msgData[0] = PinNum; + pMsg->msgData[1] = 0; + + /* Send message to SMS */ + smsendian_handle_tx_message((struct SmsMsgHdr_ST *)pMsg); + rc = smscore_sendrequest_and_wait(coredev, pMsg, totalLen, + &coredev->gpio_get_level_done); + + if (rc != 0) { + if (rc == -ETIME) + sms_err("smscore_gpio_get_level timeout"); + else + sms_err("smscore_gpio_get_level error"); + } + kfree(buffer); + + /* Its a race between other gpio_get_level() and the copy of the single + * global 'coredev->gpio_get_res' to the function's variable 'level' + */ + *level = coredev->gpio_get_res; return rc; } -static void __exit smscore_module_exit(void) +static int __init smscore_module_init(void) { -#if 0 /* def SMS_CHAR_CLIENT */ - /* Char interface UnRegister */ - smschar_unregister(); -#endif - -#if 0 /* def SMS_DVB_CLIENT */ - /* DVB UnRegister */ - smsdvb_unregister(); -#endif + int rc = 0; -#if 0 /* def SMS_NET_CLIENT */ - /* NET UnRegister */ - smsnet_unregister(); -#endif + INIT_LIST_HEAD(&g_smscore_notifyees); + INIT_LIST_HEAD(&g_smscore_devices); + kmutex_init(&g_smscore_deviceslock); -#if 0 /* def SMS_USB_BUS_DRV */ - /* Unregister USB */ - smsusb_unregister(); -#endif + INIT_LIST_HEAD(&g_smscore_registry); + kmutex_init(&g_smscore_registrylock); -#if 0 /* def SMS_SPI_BUS_DRV */ - /* Unregister SPI */ - smsspi_unregister(); -#endif + return rc; +} +static void __exit smscore_module_exit(void) +{ kmutex_lock(&g_smscore_deviceslock); while (!list_empty(&g_smscore_notifyees)) { struct smscore_device_notifyee_t *notifyee = diff --git a/linux/drivers/media/dvb/siano/smscoreapi.h b/linux/drivers/media/dvb/siano/smscoreapi.h index f4aa406ef..bc4572de6 100644 --- a/linux/drivers/media/dvb/siano/smscoreapi.h +++ b/linux/drivers/media/dvb/siano/smscoreapi.h @@ -550,7 +550,7 @@ struct SMSHOSTLIB_I2C_RES_ST { }; -struct smscore_gpio_config { +struct smscore_config_gpio { #define SMS_GPIO_DIRECTION_INPUT 0 #define SMS_GPIO_DIRECTION_OUTPUT 1 u8 direction; @@ -576,6 +576,47 @@ struct smscore_gpio_config { u8 outputdriving; }; +struct smscore_gpio_config { +#define SMS_GPIO_DIRECTION_INPUT 0 +#define SMS_GPIO_DIRECTION_OUTPUT 1 + u8 Direction; + +#define SMS_GPIO_PULL_UP_DOWN_NONE 0 +#define SMS_GPIO_PULL_UP_DOWN_PULLDOWN 1 +#define SMS_GPIO_PULL_UP_DOWN_PULLUP 2 +#define SMS_GPIO_PULL_UP_DOWN_KEEPER 3 + u8 PullUpDown; + +#define SMS_GPIO_INPUT_CHARACTERISTICS_NORMAL 0 +#define SMS_GPIO_INPUT_CHARACTERISTICS_SCHMITT 1 + u8 InputCharacteristics; + +#define SMS_GPIO_OUTPUT_SLEW_RATE_SLOW 1 /* 10xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_FAST 0 /* 10xx */ + + +#define SMS_GPIO_OUTPUT_SLEW_RATE_0_45_V_NS 0 /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_0_9_V_NS 1 /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_1_7_V_NS 2 /* 11xx */ +#define SMS_GPIO_OUTPUT_SLEW_RATE_3_3_V_NS 3 /* 11xx */ + u8 OutputSlewRate; + +#define SMS_GPIO_OUTPUT_DRIVING_S_4mA 0 /* 10xx */ +#define SMS_GPIO_OUTPUT_DRIVING_S_8mA 1 /* 10xx */ +#define SMS_GPIO_OUTPUT_DRIVING_S_12mA 2 /* 10xx */ +#define SMS_GPIO_OUTPUT_DRIVING_S_16mA 3 /* 10xx */ + +#define SMS_GPIO_OUTPUT_DRIVING_1_5mA 0 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_2_8mA 1 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_4mA 2 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_7mA 3 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_10mA 4 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_11mA 5 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_14mA 6 /* 11xx */ +#define SMS_GPIO_OUTPUT_DRIVING_16mA 7 /* 11xx */ + u8 OutputDriving; +}; + extern void smscore_registry_setmode(char *devpath, int mode); extern int smscore_registry_getmode(char *devpath); @@ -604,7 +645,6 @@ extern int smsclient_sendrequest(struct smscore_client_t *client, extern void smscore_onresponse(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); -#if 1 extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev); extern int smscore_map_common_buffer(struct smscore_device_t *coredev, struct vm_area_struct *vma); @@ -612,17 +652,25 @@ extern int smscore_get_fw_filename(struct smscore_device_t *coredev, int mode, char *filename); extern int smscore_send_fw_file(struct smscore_device_t *coredev, u8 *ufwbuf, int size); -#endif extern struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev); extern void smscore_putbuffer(struct smscore_device_t *coredev, struct smscore_buffer_t *cb); +/* old GPIO managment */ int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin, - struct smscore_gpio_config *pinconfig); + struct smscore_config_gpio *pinconfig); int smscore_set_gpio(struct smscore_device_t *coredev, u32 pin, int level); +/* new GPIO managment */ +extern int smscore_gpio_configure(struct smscore_device_t *coredev, u8 PinNum, + struct smscore_gpio_config *pGpioConfig); +extern int smscore_gpio_set_level(struct smscore_device_t *coredev, u8 PinNum, + u8 NewLevel); +extern int smscore_gpio_get_level(struct smscore_device_t *coredev, u8 PinNum, + u8 *level); + void smscore_set_board_id(struct smscore_device_t *core, int id); int smscore_get_board_id(struct smscore_device_t *core); diff --git a/linux/drivers/media/dvb/siano/smsdvb.c b/linux/drivers/media/dvb/siano/smsdvb.c index 39421ee6f..f8856d9c8 100644 --- a/linux/drivers/media/dvb/siano/smsdvb.c +++ b/linux/drivers/media/dvb/siano/smsdvb.c @@ -66,6 +66,54 @@ MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))"); /* Events that may come from DVB v3 adapter */ static void sms_board_dvb3_event(struct smsdvb_client_t *client, enum SMS_DVB3_EVENTS event) { + + struct smscore_device_t *coredev = client->coredev; + switch (event) { + case DVB3_EVENT_INIT: + sms_debug("DVB3_EVENT_INIT"); + sms_board_event(coredev, BOARD_EVENT_BIND); + break; + case DVB3_EVENT_SLEEP: + sms_debug("DVB3_EVENT_SLEEP"); + sms_board_event(coredev, BOARD_EVENT_POWER_SUSPEND); + break; + case DVB3_EVENT_HOTPLUG: + sms_debug("DVB3_EVENT_HOTPLUG"); + sms_board_event(coredev, BOARD_EVENT_POWER_INIT); + break; + case DVB3_EVENT_FE_LOCK: + if (client->event_fe_state != DVB3_EVENT_FE_LOCK) { + client->event_fe_state = DVB3_EVENT_FE_LOCK; + sms_debug("DVB3_EVENT_FE_LOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_LOCK); + } + break; + case DVB3_EVENT_FE_UNLOCK: + if (client->event_fe_state != DVB3_EVENT_FE_UNLOCK) { + client->event_fe_state = DVB3_EVENT_FE_UNLOCK; + sms_debug("DVB3_EVENT_FE_UNLOCK"); + sms_board_event(coredev, BOARD_EVENT_FE_UNLOCK); + } + break; + case DVB3_EVENT_UNC_OK: + if (client->event_unc_state != DVB3_EVENT_UNC_OK) { + client->event_unc_state = DVB3_EVENT_UNC_OK; + sms_debug("DVB3_EVENT_UNC_OK"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_OK); + } + break; + case DVB3_EVENT_UNC_ERR: + if (client->event_unc_state != DVB3_EVENT_UNC_ERR) { + client->event_unc_state = DVB3_EVENT_UNC_ERR; + sms_debug("DVB3_EVENT_UNC_ERR"); + sms_board_event(coredev, BOARD_EVENT_MULTIPLEX_ERRORS); + } + break; + + default: + sms_err("Unknown dvb3 api event"); + break; + } } static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) diff --git a/linux/drivers/media/dvb/siano/smsendian.h b/linux/drivers/media/dvb/siano/smsendian.h index 7fbedc6a6..1624d6fd3 100644 --- a/linux/drivers/media/dvb/siano/smsendian.h +++ b/linux/drivers/media/dvb/siano/smsendian.h @@ -24,9 +24,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <asm/byteorder.h> -void smsendian_handle_tx_message(void *buffer); -void smsendian_handle_rx_message(void *buffer); -void smsendian_handle_message_header(void *msg); +extern void smsendian_handle_tx_message(void *buffer); +extern void smsendian_handle_rx_message(void *buffer); +extern void smsendian_handle_message_header(void *msg); #endif /* __SMS_ENDIAN_H__ */ diff --git a/linux/drivers/media/dvb/siano/smssdio.c b/linux/drivers/media/dvb/siano/smssdio.c index 4f8fa59a9..dfaa49a53 100644 --- a/linux/drivers/media/dvb/siano/smssdio.c +++ b/linux/drivers/media/dvb/siano/smssdio.c @@ -332,7 +332,7 @@ static struct sdio_driver smssdio_driver = { /* Module functions */ /*******************************************************************/ -int smssdio_register(void) +int smssdio_module_init(void) { int ret = 0; @@ -344,11 +344,14 @@ int smssdio_register(void) return ret; } -void smssdio_unregister(void) +void smssdio_module_exit(void) { sdio_unregister_driver(&smssdio_driver); } +module_init(smssdio_module_init); +module_exit(smssdio_module_exit); + MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver"); MODULE_AUTHOR("Pierre Ossman"); MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/siano/smsusb.c b/linux/drivers/media/dvb/siano/smsusb.c index 3bbbdb197..c31a52d3a 100644 --- a/linux/drivers/media/dvb/siano/smsusb.c +++ b/linux/drivers/media/dvb/siano/smsusb.c @@ -489,7 +489,6 @@ static int smsusb_resume(struct usb_interface *intf) } struct usb_device_id smsusb_id_table[] = { -#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS { USB_DEVICE(0x187f, 0x0010), .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, { USB_DEVICE(0x187f, 0x0100), @@ -500,7 +499,6 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B }, { USB_DEVICE(0x187f, 0x0300), .driver_info = SMS1XXX_BOARD_SIANO_VEGA }, -#endif { USB_DEVICE(0x2040, 0x1700), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT }, { USB_DEVICE(0x2040, 0x1800), @@ -531,8 +529,13 @@ struct usb_device_id smsusb_id_table[] = { .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, { USB_DEVICE(0x2040, 0x5590), .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM }, - { } /* Terminating entry */ -}; + { USB_DEVICE(0x187f, 0x0202), + .driver_info = SMS1XXX_BOARD_SIANO_NICE }, + { USB_DEVICE(0x187f, 0x0301), + .driver_info = SMS1XXX_BOARD_SIANO_VENICE }, + { } /* Terminating entry */ + }; + MODULE_DEVICE_TABLE(usb, smsusb_id_table); static struct usb_driver smsusb_driver = { diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c index 93176fe4b..35b2abd6a 100644 --- a/linux/drivers/media/video/cx23885/cx23885-cards.c +++ b/linux/drivers/media/video/cx23885/cx23885-cards.c @@ -198,6 +198,10 @@ struct cx23885_board cx23885_boards[] = { .name = "Hauppauge WinTV-HVR1210", .portc = CX23885_MPEG_DVB, }, + [CX23885_BOARD_MYGICA_X8506] = { + .name = "Mygica X8506 DMB-TH", + .portb = CX23885_MPEG_DVB, + }, }; const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); @@ -317,6 +321,10 @@ struct cx23885_subid cx23885_subids[] = { .subvendor = 0x0070, .subdevice = 0x2295, .card = CX23885_BOARD_HAUPPAUGE_HVR1210, + }, { + .subvendor = 0x14f1, + .subdevice = 0x8651, + .card = CX23885_BOARD_MYGICA_X8506, }, }; const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); @@ -707,6 +715,15 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) mdelay(20); cx23885_gpio_set(dev, GPIO_9); break; + case CX23885_BOARD_MYGICA_X8506: + /* GPIO-1 reset XC5000 */ + /* GPIO-2 reset LGS8GL5 */ + cx_set(GP0_IO, 0x00060000); + cx_clear(GP0_IO, 0x00000006); + mdelay(100); + cx_set(GP0_IO, 0x00060006); + mdelay(100); + break; } } @@ -810,6 +827,11 @@ void cx23885_card_setup(struct cx23885_dev *dev) ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; break; + case CX23885_BOARD_MYGICA_X8506: + ts1->gen_ctrl_val = 0x5; /* Parallel */ + ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ + ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; + break; case CX23885_BOARD_HAUPPAUGE_HVR1250: case CX23885_BOARD_HAUPPAUGE_HVR1500: case CX23885_BOARD_HAUPPAUGE_HVR1500Q: diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c index 4efc7dee1..9c3259b22 100644 --- a/linux/drivers/media/video/cx23885/cx23885-dvb.c +++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c @@ -50,6 +50,7 @@ #include "lnbh24.h" #include "cx24116.h" #include "cimax2.h" +#include "lgs8gxx.h" #include "netup-eeprom.h" #include "netup-init.h" #include "lgdt3305.h" @@ -421,10 +422,29 @@ static struct cx24116_config dvbworld_cx24116_config = { .demod_address = 0x05, }; +static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = { + .prod = LGS8GXX_PROD_LGS8GL5, + .demod_address = 0x19, + .serial_ts = 0, + .ts_clk_pol = 1, + .ts_clk_gated = 1, + .if_clk_freq = 30400, /* 30.4 MHz */ + .if_freq = 5380, /* 5.38 MHz */ + .if_neg_center = 1, + .ext_adc = 0, + .adc_signed = 0, + .if_neg_edge = 0, +}; + +static struct xc5000_config mygica_x8506_xc5000_config = { + .i2c_address = 0x61, + .if_khz = 5380, +}; + static int dvb_register(struct cx23885_tsport *port) { struct cx23885_dev *dev = port->dev; - struct cx23885_i2c *i2c_bus = NULL; + struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; struct videobuf_dvb_frontend *fe0; int ret; @@ -746,6 +766,19 @@ static int dvb_register(struct cx23885_tsport *port) break; } break; + case CX23885_BOARD_MYGICA_X8506: + i2c_bus = &dev->i2c_bus[0]; + i2c_bus2 = &dev->i2c_bus[1]; + fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, + &mygica_x8506_lgs8gl5_config, + &i2c_bus->i2c_adap); + if (fe0->dvb.frontend != NULL) { + dvb_attach(xc5000_attach, + fe0->dvb.frontend, + &i2c_bus2->i2c_adap, + &mygica_x8506_xc5000_config); + } + break; default: printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " " isn't supported yet\n", diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h index 8dba2fdd6..2022ed7de 100644 --- a/linux/drivers/media/video/cx23885/cx23885.h +++ b/linux/drivers/media/video/cx23885/cx23885.h @@ -76,6 +76,7 @@ #define CX23885_BOARD_HAUPPAUGE_HVR1275 19 #define CX23885_BOARD_HAUPPAUGE_HVR1255 20 #define CX23885_BOARD_HAUPPAUGE_HVR1210 21 +#define CX23885_BOARD_MYGICA_X8506 22 #define GPIO_0 0x00000001 #define GPIO_1 0x00000002 diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c index 546793c02..825b1f25d 100644 --- a/linux/drivers/media/video/cx88/cx88-cards.c +++ b/linux/drivers/media/video/cx88/cx88-cards.c @@ -2009,6 +2009,47 @@ 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, + }, }; /* ------------------------------------------------------------------ */ @@ -2426,6 +2467,10 @@ 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, }, }; @@ -2624,6 +2669,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, @@ -2696,6 +2758,8 @@ 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_DTV1800H: + return cx88_xc3028_winfast1800h_callback(core, command, arg); } switch (command) { @@ -2882,6 +2946,16 @@ 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_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; } } @@ -2902,6 +2976,7 @@ 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: diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index f32cece95..36f35f0b5 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -1021,6 +1021,7 @@ static int dvb_register(struct cx8802_dev *dev) } break; case CX88_BOARD_PINNACLE_HYBRID_PCTV: + case CX88_BOARD_WINFAST_DTV1800H: fe0->dvb.frontend = dvb_attach(zl10353_attach, &cx88_pinnacle_hybrid_pctv, &core->i2c_adap); diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c index dad809335..7c5e94916 100644 --- a/linux/drivers/media/video/cx88/cx88-input.c +++ b/linux/drivers/media/video/cx88/cx88-input.c @@ -92,6 +92,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) gpio=(gpio & 0x7fd) + (auxgpio & 0xef); break; case CX88_BOARD_WINFAST_DTV1000: + case CX88_BOARD_WINFAST_DTV1800H: case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL: gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900); auxgpio = gpio; @@ -237,6 +238,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) ir->sampling = 1; break; case CX88_BOARD_WINFAST_DTV2000H: + case CX88_BOARD_WINFAST_DTV1800H: ir_codes = ir_codes_winfast; ir->gpio_addr = MO_GP0_IO; ir->mask_keycode = 0x8f8; diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h index 0c00c34bc..59fc01a53 100644 --- a/linux/drivers/media/video/cx88/cx88.h +++ b/linux/drivers/media/video/cx88/cx88.h @@ -237,6 +237,7 @@ extern struct sram_channel cx88_sram_channels[]; #define CX88_BOARD_PROF_6200 78 #define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79 #define CX88_BOARD_HAUPPAUGE_IRONLY 80 +#define CX88_BOARD_WINFAST_DTV1800H 81 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 26f1727e6..20b66cb8d 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -1448,7 +1448,7 @@ video_poll(struct file *file, struct poll_table_struct *wait) } if (!buf) - rc = POLLERR; + goto err; poll_wait(file, &buf->done, wait); if (buf->state == VIDEOBUF_DONE || |