X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Fttusb-dec%2Fttusb_dec.c;h=f85069f8b21997aa95bee1d81dc3928ddd14e549;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=cc48a65e8b143dd37ce8893708d91f487fbcf0f9;hpb=87fc8d1bb10cd459024a742c6a10961fefcef18f;p=linux-2.6.git diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index cc48a65e8..f85069f8b 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -22,28 +22,31 @@ #include #include #include +#include #include #include #include #include +#include #include #include -#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE) #include -#else -#warning "CRC checking of firmware not available" -#endif #include #include "dmxdev.h" #include "dvb_demux.h" -#include "dvb_i2c.h" #include "dvb_filter.h" #include "dvb_frontend.h" #include "dvb_net.h" +#include "ttusbdecfe.h" -static int debug = 0; -static int output_pva = 0; +static int debug; +static int output_pva; + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); +module_param(output_pva, int, 0444); +MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)"); #define dprintk if (debug) printk @@ -63,9 +66,6 @@ static int output_pva = 0; #define MAX_PVA_LENGTH 6144 -#define LOF_HI 10600000 -#define LOF_LO 9750000 - enum ttusb_dec_model { TTUSB_DEC2000T, TTUSB_DEC2540T, @@ -95,14 +95,10 @@ struct ttusb_dec { struct dmxdev dmxdev; struct dvb_demux demux; struct dmx_frontend frontend; - struct dvb_i2c_bus i2c_bus; struct dvb_net dvb_net; - struct dvb_frontend_info *frontend_info; - int (*frontend_ioctl) (struct dvb_frontend *, unsigned int, void *); + struct dvb_frontend* fe; u16 pid[DMX_PES_OTHER]; - int hi_band; - int voltage; /* USB bits */ struct usb_device *udev; @@ -161,32 +157,6 @@ struct filter_info { struct list_head filter_info_list; }; -static struct dvb_frontend_info dec2000t_frontend_info = { - .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", - .type = FE_OFDM, - .frequency_min = 51000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .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_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, -}; - -static struct dvb_frontend_info dec3000s_frontend_info = { - .name = "TechnoTrend/Hauppauge DEC3000-s Frontend", - .type = FE_QPSK, - .frequency_min = 950000, - .frequency_max = 2150000, - .frequency_stepsize = 125, - .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_AUTO | - FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO, -}; - static void ttusb_dec_set_model(struct ttusb_dec *dec, enum ttusb_dec_model model); @@ -786,7 +756,7 @@ static void ttusb_dec_stop_iso_xfer(struct ttusb_dec *dec) if (!dec->iso_stream_count) { for (i = 0; i < ISO_BUF_COUNT; i++) - usb_unlink_urb(dec->iso_urb[i]); + usb_kill_urb(dec->iso_urb[i]); } up(&dec->iso_sem); @@ -851,7 +821,7 @@ static int ttusb_dec_start_iso_xfer(struct ttusb_dec *dec) "error %d\n", __FUNCTION__, i, result); while (i) { - usb_unlink_urb(dec->iso_urb[i - 1]); + usb_kill_urb(dec->iso_urb[i - 1]); i--; } @@ -1100,7 +1070,7 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) &dec->iso_dma_handle); memset(dec->iso_buffer, 0, - sizeof(ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT))); + ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT)); for (i = 0; i < ISO_BUF_COUNT; i++) { struct urb *urb; @@ -1120,7 +1090,7 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) static void ttusb_dec_init_tasklet(struct ttusb_dec *dec) { - dec->urb_frame_list_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&dec->urb_frame_list_lock); INIT_LIST_HEAD(&dec->urb_frame_list); tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list, (unsigned long)dec); @@ -1165,10 +1135,9 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) u16 firmware_csum = 0; u16 firmware_csum_ns; u32 firmware_size_nl; -#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE) u32 crc32_csum, crc32_check, tmp; -#endif const struct firmware *fw_entry = NULL; + dprintk("%s\n", __FUNCTION__); if (request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev)) { @@ -1189,7 +1158,6 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) /* a 32 bit checksum over the first 56 bytes of the DSP Code is stored at offset 56 of file, so use it to check if the firmware file is valid. */ -#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE) crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; memcpy(&tmp, &firmware[56], 4); crc32_check = htonl(tmp); @@ -1199,7 +1167,6 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) __FUNCTION__, crc32_csum, crc32_check); return -1; } -#endif memcpy(idstring, &firmware[36], 20); idstring[20] = '\0'; printk(KERN_INFO "ttusb_dec: found DSP code \"%s\".\n", idstring); @@ -1288,6 +1255,7 @@ static int ttusb_dec_init_stb(struct ttusb_dec *dec) ttusb_dec_set_model(dec, TTUSB_DEC3000S); break; case 0x00070009: + case 0x00070013: ttusb_dec_set_model(dec, TTUSB_DEC2000T); break; case 0x00070011: @@ -1398,6 +1366,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); dvb_dmxdev_release(&dec->dmxdev); dvb_dmx_release(&dec->demux); + if (dec->fe) dvb_unregister_frontend(dec->fe); dvb_unregister_adapter(dec->adapter); } @@ -1410,7 +1379,7 @@ static void ttusb_dec_exit_usb(struct ttusb_dec *dec) dec->iso_stream_count = 0; for (i = 0; i < ISO_BUF_COUNT; i++) - usb_unlink_urb(dec->iso_urb[i]); + usb_kill_urb(dec->iso_urb[i]); ttusb_dec_free_iso_urbs(dec); } @@ -1429,261 +1398,10 @@ static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec) } } -static int ttusb_dec_2000t_frontend_ioctl(struct dvb_frontend *fe, unsigned int cmd, - void *arg) -{ - struct ttusb_dec *dec = fe->data; - - dprintk("%s\n", __FUNCTION__); - - switch (cmd) { - - case FE_GET_INFO: - dprintk("%s: FE_GET_INFO\n", __FUNCTION__); - memcpy(arg, dec->frontend_info, - sizeof (struct dvb_frontend_info)); - break; - - case FE_READ_STATUS: { - fe_status_t *status = (fe_status_t *)arg; - dprintk("%s: FE_READ_STATUS\n", __FUNCTION__); - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - break; - } - - case FE_READ_BER: { - u32 *ber = (u32 *)arg; - dprintk("%s: FE_READ_BER\n", __FUNCTION__); - *ber = 0; - return -ENOSYS; - break; - } - - case FE_READ_SIGNAL_STRENGTH: { - dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__); - *(s32 *)arg = 0xFF; - return -ENOSYS; - break; - } - - case FE_READ_SNR: - dprintk("%s: FE_READ_SNR\n", __FUNCTION__); - *(s32 *)arg = 0; - return -ENOSYS; - break; - - case FE_READ_UNCORRECTED_BLOCKS: - dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__); - *(u32 *)arg = 0; - return -ENOSYS; - break; - - case FE_SET_FRONTEND: { - struct dvb_frontend_parameters *p = - (struct dvb_frontend_parameters *)arg; - u8 b[] = { 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0xff, - 0x00, 0x00, 0x00, 0xff }; - u32 freq; - - dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__); - - dprintk(" frequency->%d\n", p->frequency); - dprintk(" symbol_rate->%d\n", - p->u.qam.symbol_rate); - dprintk(" inversion->%d\n", p->inversion); - - freq = htonl(p->frequency / 1000); - memcpy(&b[4], &freq, sizeof (u32)); - ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL); - - break; - } - - case FE_GET_FRONTEND: - dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__); - break; - - case FE_SLEEP: - dprintk("%s: FE_SLEEP\n", __FUNCTION__); - return -ENOSYS; - break; - - case FE_INIT: - dprintk("%s: FE_INIT\n", __FUNCTION__); - break; - - default: - dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd); - return -EINVAL; - - } - - return 0; -} - -static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, - unsigned int cmd, void *arg) -{ - struct ttusb_dec *dec = fe->data; - - dprintk("%s\n", __FUNCTION__); - - switch (cmd) { - - case FE_GET_INFO: - dprintk("%s: FE_GET_INFO\n", __FUNCTION__); - memcpy(arg, dec->frontend_info, - sizeof (struct dvb_frontend_info)); - break; - - case FE_READ_STATUS: { - fe_status_t *status = (fe_status_t *)arg; - dprintk("%s: FE_READ_STATUS\n", __FUNCTION__); - *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | - FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; - break; - } - - case FE_READ_BER: { - u32 *ber = (u32 *)arg; - dprintk("%s: FE_READ_BER\n", __FUNCTION__); - *ber = 0; - return -ENOSYS; - break; - } - - case FE_READ_SIGNAL_STRENGTH: { - dprintk("%s: FE_READ_SIGNAL_STRENGTH\n", __FUNCTION__); - *(s32 *)arg = 0xFF; - return -ENOSYS; - break; - } - - case FE_READ_SNR: - dprintk("%s: FE_READ_SNR\n", __FUNCTION__); - *(s32 *)arg = 0; - return -ENOSYS; - break; - - case FE_READ_UNCORRECTED_BLOCKS: - dprintk("%s: FE_READ_UNCORRECTED_BLOCKS\n", __FUNCTION__); - *(u32 *)arg = 0; - return -ENOSYS; - break; - - case FE_SET_FRONTEND: { - struct dvb_frontend_parameters *p = - (struct dvb_frontend_parameters *)arg; - u8 b[] = { 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 }; - u32 freq; - u32 sym_rate; - u32 band; - u32 lnb_voltage; - - dprintk("%s: FE_SET_FRONTEND\n", __FUNCTION__); - - dprintk(" frequency->%d\n", p->frequency); - dprintk(" symbol_rate->%d\n", - p->u.qam.symbol_rate); - dprintk(" inversion->%d\n", p->inversion); - - freq = htonl(p->frequency * 1000 + - (dec->hi_band ? LOF_HI : LOF_LO)); - memcpy(&b[4], &freq, sizeof(u32)); - sym_rate = htonl(p->u.qam.symbol_rate); - memcpy(&b[12], &sym_rate, sizeof(u32)); - band = htonl(dec->hi_band ? LOF_HI : LOF_LO); - memcpy(&b[24], &band, sizeof(u32)); - lnb_voltage = htonl(dec->voltage); - memcpy(&b[28], &lnb_voltage, sizeof(u32)); - - ttusb_dec_send_command(dec, 0x71, sizeof(b), b, NULL, NULL); - - break; - } - - case FE_GET_FRONTEND: - dprintk("%s: FE_GET_FRONTEND\n", __FUNCTION__); - break; - - case FE_SLEEP: - dprintk("%s: FE_SLEEP\n", __FUNCTION__); - return -ENOSYS; - break; - - case FE_INIT: - dprintk("%s: FE_INIT\n", __FUNCTION__); - break; - - case FE_DISEQC_SEND_MASTER_CMD: - dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__); - break; - - case FE_DISEQC_SEND_BURST: - dprintk("%s: FE_DISEQC_SEND_BURST\n", __FUNCTION__); - break; - - case FE_SET_TONE: { - fe_sec_tone_mode_t tone = (fe_sec_tone_mode_t)arg; - dprintk("%s: FE_SET_TONE\n", __FUNCTION__); - dec->hi_band = (SEC_TONE_ON == tone); - break; - } - - case FE_SET_VOLTAGE: - dprintk("%s: FE_SET_VOLTAGE\n", __FUNCTION__); - switch ((fe_sec_voltage_t) arg) { - case SEC_VOLTAGE_13: - dec->voltage = 13; - break; - case SEC_VOLTAGE_18: - dec->voltage = 18; - break; - default: - return -EINVAL; - break; - } - break; - - default: - dprintk("%s: unknown IOCTL (0x%X)\n", __FUNCTION__, cmd); - return -EINVAL; - - } - - return 0; -} - -static void ttusb_dec_init_frontend(struct ttusb_dec *dec) -{ - dec->i2c_bus.adapter = dec->adapter; - - dvb_register_frontend(dec->frontend_ioctl, &dec->i2c_bus, (void *)dec, - dec->frontend_info); -} - -static void ttusb_dec_exit_frontend(struct ttusb_dec *dec) -{ - dvb_unregister_frontend(dec->frontend_ioctl, &dec->i2c_bus); -} - static void ttusb_dec_init_filters(struct ttusb_dec *dec) { INIT_LIST_HEAD(&dec->filter_info_list); - dec->filter_info_list_lock = SPIN_LOCK_UNLOCKED; + spin_lock_init(&dec->filter_info_list_lock); } static void ttusb_dec_exit_filters(struct ttusb_dec *dec) @@ -1698,6 +1416,18 @@ static void ttusb_dec_exit_filters(struct ttusb_dec *dec) } } +int fe_send_command(struct dvb_frontend* fe, const u8 command, + int param_length, const u8 params[], + int *result_length, u8 cmd_result[]) +{ + struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; + return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); +} + +struct ttusbdecfe_config fe_config = { + .send_command = fe_send_command +}; + static int ttusb_dec_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1717,7 +1447,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, memset(dec, 0, sizeof(struct ttusb_dec)); - switch (id->idProduct) { + switch (le16_to_cpu(id->idProduct)) { case 0x1006: ttusb_dec_set_model(dec, TTUSB_DEC3000S); break; @@ -1739,7 +1469,32 @@ static int ttusb_dec_probe(struct usb_interface *intf, return 0; } ttusb_dec_init_dvb(dec); - ttusb_dec_init_frontend(dec); + + dec->adapter->priv = dec; + switch (le16_to_cpu(id->idProduct)) { + case 0x1006: + dec->fe = ttusbdecfe_dvbs_attach(&fe_config); + break; + + case 0x1008: + case 0x1009: + dec->fe = ttusbdecfe_dvbt_attach(&fe_config); + break; + } + + if (dec->fe == NULL) { + printk("dvb-ttusb-dec: A frontend driver was not found for device %04x/%04x\n", + le16_to_cpu(dec->udev->descriptor.idVendor), + le16_to_cpu(dec->udev->descriptor.idProduct)); + } else { + if (dvb_register_frontend(dec->adapter, dec->fe)) { + printk("budget-ci: Frontend registration failed!\n"); + if (dec->fe->ops->release) + dec->fe->ops->release(dec->fe); + dec->fe = NULL; + } + } + ttusb_dec_init_v_pes(dec); ttusb_dec_init_filters(dec); ttusb_dec_init_tasklet(dec); @@ -1763,7 +1518,6 @@ static void ttusb_dec_disconnect(struct usb_interface *intf) ttusb_dec_exit_tasklet(dec); ttusb_dec_exit_filters(dec); ttusb_dec_exit_usb(dec); - ttusb_dec_exit_frontend(dec); ttusb_dec_exit_dvb(dec); } @@ -1779,22 +1533,16 @@ static void ttusb_dec_set_model(struct ttusb_dec *dec, case TTUSB_DEC2000T: dec->model_name = "DEC2000-t"; dec->firmware_name = "dvb-ttusb-dec-2000t.fw"; - dec->frontend_info = &dec2000t_frontend_info; - dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl; break; case TTUSB_DEC2540T: dec->model_name = "DEC2540-t"; dec->firmware_name = "dvb-ttusb-dec-2540t.fw"; - dec->frontend_info = &dec2000t_frontend_info; - dec->frontend_ioctl = ttusb_dec_2000t_frontend_ioctl; break; case TTUSB_DEC3000S: dec->model_name = "DEC3000-s"; dec->firmware_name = "dvb-ttusb-dec-3000s.fw"; - dec->frontend_info = &dec3000s_frontend_info; - dec->frontend_ioctl = ttusb_dec_3000s_frontend_ioctl; break; } } @@ -1840,7 +1588,3 @@ MODULE_DESCRIPTION(DRIVER_NAME); MODULE_LICENSE("GPL"); MODULE_DEVICE_TABLE(usb, ttusb_dec_table); -MODULE_PARM(debug, "i"); -MODULE_PARM_DESC(debug, "Debug level"); -MODULE_PARM(output_pva, "i"); -MODULE_PARM_DESC(output_pva, "Output PVA from dvr device");