16 #define DVB_USB_LOG_PREFIX "pctv452e"
38 #define ISOC_INTERFACE_ALTERNATIVE 3
40 #define SYNC_BYTE_OUT 0xaa
41 #define SYNC_BYTE_IN 0x55
44 #define PCTV_CMD_RESET 0x15
46 #define PCTV_CMD_IR 0x1b
48 #define PCTV_CMD_I2C 0x31
50 #define I2C_ADDR_STB0899 (0xd0 >> 1)
51 #define I2C_ADDR_STB6100 (0xc0 >> 1)
52 #define I2C_ADDR_LNBP22 (0x10 >> 1)
53 #define I2C_ADDR_24C16 (0xa0 >> 1)
54 #define I2C_ADDR_24C64 (0xa2 >> 1)
58 #define PCTV_ANSWER_LEN 64
60 #define PCTV_TIMEOUT 1000
63 #define PCTV_LED_GPIO STB0899_GPIO01
64 #define PCTV_LED_GREEN 0x82
65 #define PCTV_LED_ORANGE 0x02
67 #define ci_dbg(format, arg...) \
70 printk(KERN_DEBUG DVB_USB_LOG_PREFIX \
71 ": " format "\n" , ## arg); \
103 unsigned int write_len,
unsigned int read_len)
111 BUG_ON(
NULL == data && 0 != (write_len | read_len));
112 BUG_ON(write_len > 64 - 4);
113 BUG_ON(read_len > 64 - 4);
124 rlen = (read_len > 0) ? 64 : 0;
139 err(
"CI error %d; %02X %02X %02X -> %*ph.",
147 unsigned int read_len)
154 ret = tt3650_ci_msg(d, cmd, data, write_len, read_len);
169 buf[0] = (address >> 8) & 0x0F;
174 ci_dbg(
"%s %04x -> %d 0x%02x",
175 __func__, address, ret, buf[2]);
183 static int tt3650_ci_write_attribute_mem(
struct dvb_ca_en50221 *ca,
184 int slot,
int address,
u8 value)
188 ci_dbg(
"%s %d 0x%04x 0x%02x",
189 __func__, slot, address, value);
194 buf[0] = (address >> 8) & 0x0F;
211 buf[0] = address & 3;
215 ci_dbg(
"%s 0x%02x -> %d 0x%02x",
216 __func__, address, ret, buf[1]);
231 ci_dbg(
"%s %d 0x%02x 0x%02x",
232 __func__, slot, address, value);
250 ci_dbg(
"%s %d %d", __func__, slot, enable);
262 if (enable != buf[0]) {
263 err(
"CI not %sabled.", enable ?
"en" :
"dis");
270 static int tt3650_ci_slot_shutdown(
struct dvb_ca_en50221 *ca,
int slot)
272 return tt3650_ci_set_video_port(ca, slot, 0);
275 static int tt3650_ci_slot_ts_enable(
struct dvb_ca_en50221 *ca,
int slot)
277 return tt3650_ci_set_video_port(ca, slot, 1);
280 static int tt3650_ci_slot_reset(
struct dvb_ca_en50221 *ca,
int slot)
287 ci_dbg(
"%s %d", __func__, slot);
355 if (
NULL == state->
ca.data)
359 tt3650_ci_set_video_port(&state->
ca, 0, 0);
377 state->
ca.read_attribute_mem = tt3650_ci_read_attribute_mem;
378 state->
ca.write_attribute_mem = tt3650_ci_write_attribute_mem;
379 state->
ca.read_cam_control = tt3650_ci_read_cam_control;
380 state->
ca.write_cam_control = tt3650_ci_write_cam_control;
381 state->
ca.slot_reset = tt3650_ci_slot_reset;
382 state->
ca.slot_shutdown = tt3650_ci_slot_shutdown;
383 state->
ca.slot_ts_enable = tt3650_ci_slot_ts_enable;
384 state->
ca.poll_slot_status = tt3650_ci_poll_slot_status;
392 err(
"Cannot initialize CI: Error %d.", ret);
397 info(
"CI initialized.");
402 #define CMD_BUFFER_SIZE 0x28
404 const u8 *snd_buf,
u8 snd_len,
405 u8 *rcv_buf,
u8 rcv_len)
415 if (snd_len > 64 - 7 || rcv_len > 64 - 7)
421 buf[3] = snd_len + 3;
426 memcpy(buf + 7, snd_buf, snd_len);
441 if (buf[5] < snd_len || buf[6] < rcv_len)
444 memcpy(rcv_buf, buf + 7, rcv_len);
449 err(
"I2C error %d; %02X %02X %02X %02X %02X -> "
450 "%02X %02X %02X %02X %02X.",
452 buf[0], buf[1], buf[4], buf[5], buf[6]);
466 for (i = 0; i < num; i++) {
467 u8 addr, snd_len, rcv_len, *snd_buf, *rcv_buf;
474 rcv_buf = msg[
i].
buf;
475 rcv_len = msg[
i].
len;
478 snd_buf = msg[
i].
buf;
479 snd_len = msg[
i].
len;
484 ret = pctv452e_i2c_msg(d, addr, snd_buf, snd_len, rcv_buf,
506 info(
"%s: %d\n", __func__, i);
517 info(
"%s: Warning set interface returned: %d\n",
559 info(
"%s: read: %2d: %*ph: ", __func__, ret, 3, rx);
561 info(
" %02x", rx[i+3]);
566 if ((rx[3] == 9) && (rx[12] & 0x01)) {
570 info(
"%s: cmd=0x%02x sys=0x%02x\n",
571 __func__, rx[6], rx[7]);
584 const u8 mem_addr[] = { 0x1f, 0xcc };
822 .init_s2_demod = stb0899_s2_init_2,
823 .init_s1_demod = pctv452e_init_s1_demod,
824 .init_s2_fec = stb0899_s2_init_4,
825 .init_tst = stb0899_s1_init_5,
830 .xtal_freq = 27000000,
838 .data_clk_parity = 0,
856 .tuner_get_frequency = stb6100_get_frequency,
857 .tuner_set_frequency = stb6100_set_frequency,
858 .tuner_set_bandwidth = stb6100_set_bandwidth,
859 .tuner_get_bandwidth = stb6100_get_bandwidth,
860 .tuner_set_rfsiggain =
NULL,
863 .postproc = pctv45e_postproc
873 .master_xfer = pctv452e_i2c_xfer,
874 .functionality = pctv452e_i2c_func
886 &a->
dev->i2c_adap)) == 0)
887 err(
"Cannot attach lnbp22\n");
889 id = a->
dev->desc->warm_ids[0];
903 &a->
dev->i2c_adap) == 0) {
904 err(
"%s failed\n", __func__);
926 .power_ctrl = pctv452e_power_ctrl,
931 .rc_query = pctv452e_rc_query,
939 .frontend_attach = pctv452e_frontend_attach,
940 .tuner_attach = pctv452e_tuner_attach,
958 .i2c_algo = &pctv452e_i2c_algo,
960 .generic_bulk_ctrl_endpoint = 1,
962 .num_device_descs = 1,
964 { .name =
"PCTV HDTV USB",
966 .warm_ids = { &pctv452e_usb_table[0],
NULL }
978 .power_ctrl = pctv452e_power_ctrl,
979 .read_mac_address = pctv452e_read_mac_address,
984 .rc_query = pctv452e_rc_query,
992 .frontend_attach = pctv452e_frontend_attach,
993 .tuner_attach = pctv452e_tuner_attach,
1012 .i2c_algo = &pctv452e_i2c_algo,
1014 .generic_bulk_ctrl_endpoint = 1,
1016 .num_device_descs = 2,
1018 { .name =
"Technotrend TT Connect S2-3600",
1020 .warm_ids = { &pctv452e_usb_table[1],
NULL }
1022 { .name =
"Technotrend TT Connect S2-3650-CI",
1024 .warm_ids = { &pctv452e_usb_table[2],
NULL }
1034 tt3650_ci_uninit(d);
1050 static struct usb_driver pctv452e_usb_driver = {
1052 .probe = pctv452e_usb_probe,
1053 .disconnect = pctv452e_usb_disconnect,
1054 .id_table = pctv452e_usb_table,