diff -Nur linux-2.6.24.5-2mnb-orig/drivers/media/dvb/dvb-usb/vp702x.c linux-2.6.24.5-2mnb-ZsoltTech.Com/drivers/media/dvb/dvb-usb/vp702x.c --- linux-2.6.24.5-2mnb-orig/drivers/media/dvb/dvb-usb/vp702x.c 2008-01-24 23:58:37.000000000 +0100 +++ linux-2.6.24.5-2mnb-ZsoltTech.Com/drivers/media/dvb/dvb-usb/vp702x.c 2008-06-22 13:40:28.000000000 +0200 @@ -25,6 +25,8 @@ int pid_filter_count; int pid_filter_can_bypass; u8 pid_filter_state; + u8 pid_state; + u8 pid_table[17]; }; struct vp702x_device_state { @@ -35,13 +37,21 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret = -1; + u8 req_t; + + switch (req) { + case RESET_TUNER: + req_t = USB_TYPE_VENDOR; + break; + default: + req_t = USB_TYPE_VENDOR | USB_DIR_IN; + } ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_IN, + req,req_t, value,index,b,blen, - 2000); + USB_CTRL_GET_TIMEOUT); if (ret < 0) { warn("usb in operation failed. (%d)", ret); @@ -49,9 +59,13 @@ } else ret = 0; - - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); + if (req == READ_REMOTE_REQ) { + deb_rc("in: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x wLength=%04x \ndata: ",req,req_t,value,index,blen); // take blen not ret + debug_dump(b,blen,deb_rc); + } else { + deb_xfer("in: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x wLength=%04x \ndata: ",req,req_t,value,index,blen); // take blen not ret + debug_dump(b,blen,deb_xfer); + } return ret; } @@ -60,15 +74,24 @@ u16 index, u8 *b, int blen) { int ret; - deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + u8 req_t; + + switch (req) { + case RESET_TUNER: + req_t = USB_TYPE_VENDOR; + break; + default: + req_t = USB_TYPE_VENDOR | USB_DIR_OUT; + } + + deb_xfer("out: bRequest=%02x bRrequestType=%02x wValue=%04x wIndex=%04x wLength=%04x \ndata: ",req,req_t,value,index,blen); // take blen not ret debug_dump(b,blen,deb_xfer); if ((ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, + req,req_t, value,index,b,blen, - 2000)) != blen) { + USB_CTRL_SET_TIMEOUT)) != blen) { warn("usb out operation failed. (%d)",ret); return -EIO; } else @@ -110,93 +133,71 @@ return ret; } -static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass) -{ - u8 buf[16] = { 0 }; - return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16); -} - -static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state) -{ - u8 buf[16] = { 0 }; - return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16); -} - -static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff) -{ - struct vp702x_state *st = adap->priv; - u8 buf[16] = { 0 }; - - if (onoff) - st->pid_filter_state |= (1 << id); - else { - st->pid_filter_state &= ~(1 << id); - pid = 0xffff; - } - - id = 0x10 + id*2; - - vp702x_set_pld_state(adap, st->pid_filter_state); - vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16); - vp702x_usb_in_op(adap->dev, 0xe0, (((pid ) & 0xff) << 8) | (id+1), 0, buf, 16); - return 0; -} - - -static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap) -{ - struct vp702x_state *st = adap->priv; - int i; - u8 b[10] = { 0 }; - - st->pid_filter_count = 8; - st->pid_filter_can_bypass = 1; - st->pid_filter_state = 0x00; - - vp702x_set_pld_mode(adap, 1); // bypass - - for (i = 0; i < st->pid_filter_count; i++) - vp702x_set_pid(adap, 0xffff, i, 1); - - vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10); - vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10); - vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10); - - //vp702x_set_pld_mode(d, 0); // filter - return 0; -} - -static int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) -{ - return 0; -} /* keys for the enclosed remote control */ static struct dvb_usb_rc_key vp702x_rc_keys[] = { - { 0x00, 0x01, KEY_1 }, - { 0x00, 0x02, KEY_2 }, + { 0x4d, 0xb2, KEY_ZOOM }, + { 0x16, 0xe9, KEY_POWER2 }, + { 0x03, 0xfc, KEY_1 }, + { 0x01, 0xfe, KEY_2 }, + { 0x06, 0xf9, KEY_3 }, + { 0x09, 0xf6, KEY_4 }, + { 0x1d, 0xe2, KEY_5 }, + { 0x1f, 0xe0, KEY_6 }, + { 0x0d, 0xf2, KEY_7 }, + { 0x19, 0xe6, KEY_8 }, + { 0x1b, 0xe4, KEY_9 }, + { 0x15, 0xea, KEY_0 }, + { 0x11, 0xee, KEY_RECORD }, + { 0x17, 0xe8, KEY_FAVORITES }, + { 0x40, 0xbf, KEY_PREVIOUS }, + { 0x12, 0xed, KEY_NEXT }, + { 0x05, 0xfa, KEY_CHANNELUP }, + { 0x02, 0xfd, KEY_CHANNELDOWN }, + { 0x0a, 0xf5, KEY_VOLUMEDOWN }, + { 0x1e, 0xe1, KEY_VOLUMEUP }, + { 0x14, 0xeb, KEY_PLAY }, + { 0x0e, 0xf1, KEY_RESERVED }, // KEY_RECALL + { 0x1a, 0xe5, KEY_STOP }, + { 0x4c, 0xb3, KEY_PAUSE }, + { 0x10, 0xef, KEY_MUTE }, + { 0x0c, 0xf3, KEY_CANCEL }, + { 0x54, 0xab, KEY_SHUFFLE }, // KEY_CAPTURE + { 0x48, 0xb7, KEY_RESERVED }, // KEY_PREVIEW + { 0x1c, 0xe3, KEY_EPG }, + { 0x04, 0xfb, KEY_RESERVED }, // KEY_RECORD_LIST + { 0x00, 0xff, KEY_TAB }, + { 0x0f, 0xf0, KEY_TEXT }, }; -/* remote control stuff (does not work with my box) */ static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) { - u8 key[10]; + u8 key[10] = { 0 }; int i; -/* remove the following return to enabled remote querying */ - return 0; +/* + * disable it with "options dvb-usb disable_rc_polling=1" + * in /etc/modprobe.conf + * + */ vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); - deb_rc("remote query key: %x %d\n",key[1],key[1]); - if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; return 0; } + if (key[2] != 0xff) { + *state = REMOTE_NO_KEY_PRESSED; + return 0; + } + + deb_rc("remote query summ: %02x keycode: %02x-%02x\n",key[2], key[3], key[4]); + for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++) - if (vp702x_rc_keys[i].custom == key[1]) { + if (vp702x_rc_keys[i].custom == key[3] && + vp702x_rc_keys[i].data == key[4] ) { *state = REMOTE_KEY_PRESSED; *event = vp702x_rc_keys[i].event; break; @@ -204,13 +205,46 @@ return 0; } +int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + struct vp702x_device_state *st = adap->priv; + + deb_fe("%s onoff %d\n",__FUNCTION__, onoff); + + + return 0; +} + +static int vp702x_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) +{ + struct vp702x_state *st = adap->priv; + + u8 buf[9]; + deb_fe("%s: index=%d pid=%04x onoff %d\n",__FUNCTION__,index,pid,onoff); + + if (onoff) { + st->pid_table[16] |= 1 << index; + st->pid_table[index*2] = (pid >> 8) & 0xff; + st->pid_table[index*2+1] = pid & 0xff; + } else { + st->pid_table[16] &= ~(1 << index); + st->pid_table[index*2] = st->pid_table[index*2+1] = 0; + } + + vp702x_usb_inout_cmd(adap->dev,SET_PID_FILTER,st->pid_table,17,buf,9,10); + + return 0; +} + int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff) { struct vp702x_device_state *st = d->priv; - if (st->power_state == 0 && onoff) + deb_fe("%s onoff %d\n",__FUNCTION__, onoff); + + if (onoff) vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 1, 7, NULL, 0); - else if (st->power_state == 1 && onoff == 0) + else vp702x_usb_out_op(d, SET_TUNER_POWER_REQ, 0, 7, NULL, 0); st->power_state = onoff; @@ -238,7 +272,7 @@ buf[9] = '\0'; info("system string: %s",&buf[1]); - vp702x_init_pid_filter(adap); + // vp702x_init_pid_filter(adap); adap->fe = vp702x_fe_attach(adap->dev); vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0); @@ -264,7 +298,7 @@ static struct dvb_usb_device_properties vp702x_properties = { .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-vp702x-02.fw", + .firmware = "dvb-usb-vp7021N.fw", .no_reconnect = 1, .size_of_priv = sizeof(struct vp702x_device_state), @@ -272,16 +306,24 @@ .num_adapters = 1, .adapter = { { - .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, +// .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS | +// DVB_USB_ADAP_HAS_PID_FILTER, +// +// .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING | DVB_USB_ADAP_RECEIVES_204_BYTE_TS, + // .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING |DVB_USB_ADAP_RECEIVES_204_BYTE_TS, + .pid_filter_count = 8, + .pid_filter = vp702x_pid_filter, +// .pid_filter_ctrl = vp702x_pid_filter_ctrl, - .streaming_ctrl = vp702x_streaming_ctrl, +// .streaming_ctrl = vp702x_streaming_ctrl, .frontend_attach = vp702x_frontend_attach, /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, .count = 10, - .endpoint = 0x02, + .endpoint = 0x82, .u = { .bulk = { .buffersize = 4096, @@ -297,7 +339,7 @@ .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys), .rc_interval = 400, .rc_query = vp702x_rc_query, - + .power_ctrl = vp702x_power_ctrl, .num_device_descs = 1, .devices = { { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)", @@ -314,6 +356,9 @@ /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver vp702x_usb_driver = { +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + .owner = THIS_MODULE, +#endif .name = "dvb_usb_vp702x", .probe = vp702x_usb_probe, .disconnect = dvb_usb_device_exit, @@ -341,7 +386,7 @@ module_init(vp702x_usb_module_init); module_exit(vp702x_usb_module_exit); -MODULE_AUTHOR("Patrick Boettcher "); -MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones"); -MODULE_VERSION("1.0"); +MODULE_AUTHOR("Patrick Boettcher & Ser Lev Arris "); +MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones (Firmware loading and IR-Remote support)"); +MODULE_VERSION("1.1-ZsoltTech.Com"); MODULE_LICENSE("GPL"); diff -Nur linux-2.6.24.5-2mnb-orig/drivers/media/dvb/dvb-usb/vp702x-fe.c linux-2.6.24.5-2mnb-ZsoltTech.Com/drivers/media/dvb/dvb-usb/vp702x-fe.c --- linux-2.6.24.5-2mnb-orig/drivers/media/dvb/dvb-usb/vp702x-fe.c 2008-01-24 23:58:37.000000000 +0100 +++ linux-2.6.24.5-2mnb-ZsoltTech.Com/drivers/media/dvb/dvb-usb/vp702x-fe.c 2008-06-22 13:25:25.000000000 +0200 @@ -34,6 +34,8 @@ u8 lock; u8 sig; u8 snr; + u8 ber; + u8 unc; unsigned long next_status_check; unsigned long status_check_interval; @@ -48,7 +50,9 @@ st->lock = buf[4]; vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1); vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1); - + /* vp702x_usb_in_op(st->d,READ_PID_NUMBER_REQ,0x15,0,&st->ber,2); + vp702x_usb_in_op(st->d,READ_PID_NUMBER_REQ,0x15,0,&st->unc,2); +*/ st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; } return 0; @@ -84,8 +88,8 @@ /* not supported by this Frontend */ static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber) { - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); +// struct vp702x_fe_state *st = fe->demodulator_priv; +// vp702x_fe_refresh_state(st); *ber = 0; return 0; } @@ -93,8 +97,8 @@ /* not supported by this Frontend */ static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) { - struct vp702x_fe_state *st = fe->demodulator_priv; - vp702x_fe_refresh_state(st); +// struct vp702x_fe_state *st = fe->demodulator_priv; +// vp702x_fe_refresh_state(st); *unc = 0; return 0; } @@ -122,7 +126,7 @@ static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) { deb_fe("%s\n",__FUNCTION__); - tune->min_delay_ms = 2000; + tune->min_delay_ms = 1500; return 0; } @@ -171,6 +175,10 @@ st->next_status_check = jiffies; vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); + deb_fe("%s: command: ",__FUNCTION__); + debug_dump(cmd,8,deb_fe); + deb_fe("%s: answer: ",__FUNCTION__); + debug_dump(ibuf,10,deb_fe); if (ibuf[2] == 0 && ibuf[3] == 0) deb_fe("tuning failed.\n"); @@ -190,14 +198,16 @@ static int vp702x_fe_sleep(struct dvb_frontend *fe) { + struct vp702x_fe_state *st = fe->demodulator_priv; deb_fe("%s\n",__FUNCTION__); return 0; + // vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0); } static int vp702x_fe_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) { - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s: DUMMY!\n",__FUNCTION__); return 0; } @@ -219,6 +229,10 @@ cmd[7] = vp702x_chksum(cmd,0,7); vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); + deb_fe("%s: command: ",__FUNCTION__); + debug_dump(cmd,8,deb_fe); + deb_fe("%s: answer: ",__FUNCTION__); + debug_dump(ibuf,10,deb_fe); if (ibuf[2] == 0 && ibuf[3] == 0) deb_fe("diseqc cmd failed.\n"); @@ -230,7 +244,7 @@ static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) { - deb_fe("%s\n",__FUNCTION__); + deb_fe("%s: DUMMY!\n",__FUNCTION__); return 0; } @@ -250,11 +264,15 @@ st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); + deb_fe("%s: lnb buf: ",__FUNCTION__); + debug_dump(st->lnb_buf,8,deb_fe); + deb_fe("%s: answer: ",__FUNCTION__); + debug_dump(ibuf,10,deb_fe); if (ibuf[2] == 0 && ibuf[3] == 0) deb_fe("set_tone cmd failed.\n"); - else + else deb_fe("set_tone cmd succeeded.\n"); - + return 0; } @@ -262,7 +280,7 @@ voltage) { struct vp702x_fe_state *st = fe->demodulator_priv; - u8 ibuf[10]; + u8 ibuf[10] = { 0 }; deb_fe("%s\n",__FUNCTION__); st->voltage = voltage; @@ -275,12 +293,17 @@ st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); - if (ibuf[2] == 0 && ibuf[3] == 0) + deb_fe("%s: lnb buf: ",__FUNCTION__); + debug_dump(st->lnb_buf,8,deb_fe); + deb_fe("%s: answer: ",__FUNCTION__); + debug_dump(ibuf,10,deb_fe); + if (ibuf[2] == 0 && ibuf[3] == 0) { deb_fe("set_voltage cmd failed.\n"); - else + return -EREMOTEIO; + } else { deb_fe("set_voltage cmd succeeded.\n"); - - return 0; + return 0; + } } static void vp702x_fe_release(struct dvb_frontend* fe) @@ -322,10 +345,18 @@ .symbol_rate_min = 1000000, .symbol_rate_max = 45000000, .symbol_rate_tolerance = 500, /* ppm */ - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | - FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_QPSK | - FE_CAN_FEC_AUTO + /* .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | + FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_QAM_16 | + FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | + FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO | + FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | + FE_CAN_INVERSION_AUTO | FE_CAN_MUTE_TS */ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | + FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | + FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO | + FE_CAN_QPSK | FE_CAN_FEC_AUTO }, .release = vp702x_fe_release, diff -Nur linux-2.6.24.5-2mnb-orig/drivers/media/dvb/dvb-usb/vp702x.h linux-2.6.24.5-2mnb-ZsoltTech.Com/drivers/media/dvb/dvb-usb/vp702x.h --- linux-2.6.24.5-2mnb-orig/drivers/media/dvb/dvb-usb/vp702x.h 2008-01-24 23:58:37.000000000 +0100 +++ linux-2.6.24.5-2mnb-ZsoltTech.Com/drivers/media/dvb/dvb-usb/vp702x.h 2008-06-22 13:26:54.000000000 +0200 @@ -3,6 +3,7 @@ #define DVB_USB_LOG_PREFIX "vp702x" #include "dvb-usb.h" +#include extern int dvb_usb_vp702x_debug; #define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args) @@ -71,6 +72,8 @@ #define READ_PID_NUMBER_REQ 0xB5 /* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ +#define PID_CONTROL 0xE0 + #define WRITE_EEPROM_REQ 0xB6 /* OUT i: offset; v: value to write; no extra buffer */ @@ -104,5 +107,6 @@ extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); extern int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff); +extern int vp702x_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff); #endif