17 #include <linux/device.h>
19 #include <linux/kernel.h>
22 #include <linux/string.h>
24 #include <linux/wait.h>
31 #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
33 #define AVC_CTYPE_CONTROL 0x0
34 #define AVC_CTYPE_STATUS 0x1
35 #define AVC_CTYPE_NOTIFY 0x3
37 #define AVC_RESPONSE_ACCEPTED 0x9
38 #define AVC_RESPONSE_STABLE 0xc
39 #define AVC_RESPONSE_CHANGED 0xd
40 #define AVC_RESPONSE_INTERIM 0xf
42 #define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3)
43 #define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3)
45 #define AVC_OPCODE_VENDOR 0x00
46 #define AVC_OPCODE_READ_DESCRIPTOR 0x09
47 #define AVC_OPCODE_DSIT 0xc8
48 #define AVC_OPCODE_DSD 0xcb
50 #define DESCRIPTOR_TUNER_STATUS 0x80
51 #define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
53 #define SFE_VENDOR_DE_COMPANYID_0 0x00
54 #define SFE_VENDOR_DE_COMPANYID_1 0x12
55 #define SFE_VENDOR_DE_COMPANYID_2 0x87
57 #define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
58 #define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
59 #define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58
61 #define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00
62 #define SFE_VENDOR_OPCODE_HOST2CA 0x56
63 #define SFE_VENDOR_OPCODE_CA2HOST 0x57
64 #define SFE_VENDOR_OPCODE_CISTATUS 0x59
65 #define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60
67 #define SFE_VENDOR_TAG_CA_RESET 0x00
68 #define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
69 #define SFE_VENDOR_TAG_CA_PMT 0x02
70 #define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
71 #define SFE_VENDOR_TAG_CA_MMI 0x05
72 #define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
74 #define EN50221_LIST_MANAGEMENT_ONLY 0x03
75 #define EN50221_TAG_APP_INFO 0x9f8021
76 #define EN50221_TAG_CA_INFO 0x9f8031
92 #define LAST_OPERAND (509 - 1)
101 int to =
ALIGN(from, 4);
104 clear_operands(c, from, to);
107 #define AVC_DEBUG_READ_DESCRIPTOR 0x0001
108 #define AVC_DEBUG_DSIT 0x0002
109 #define AVC_DEBUG_DSD 0x0004
110 #define AVC_DEBUG_REGISTER_REMOTE_CONTROL 0x0008
111 #define AVC_DEBUG_LNB_CONTROL 0x0010
112 #define AVC_DEBUG_TUNE_QPSK 0x0020
113 #define AVC_DEBUG_TUNE_QPSK2 0x0040
114 #define AVC_DEBUG_HOST2CA 0x0080
115 #define AVC_DEBUG_CA2HOST 0x0100
116 #define AVC_DEBUG_APPLICATION_PMT 0x4000
117 #define AVC_DEBUG_FCP_PAYLOADS 0x8000
119 static int avc_debug;
133 ", or a combination, or all = -1)");
141 static unsigned int num_fake_ca_system_ids;
142 static int fake_ca_system_ids[4] = { -1, -1, -1, -1 };
144 MODULE_PARM_DESC(fake_ca_system_ids,
"If your CAM application manufacturer "
145 "does not have the same ca_system_id as your CAS, you can "
146 "override what ca_system_ids are presented to the "
147 "application by setting this field to an array of ids.");
149 static const char *debug_fcp_ctype(
unsigned int ctype)
151 static const char *ctypes[] = {
152 [0x0] =
"CONTROL", [0x1] =
"STATUS",
153 [0x2] =
"SPECIFIC INQUIRY", [0x3] =
"NOTIFY",
154 [0x4] =
"GENERAL INQUIRY", [0x8] =
"NOT IMPLEMENTED",
155 [0x9] =
"ACCEPTED", [0xa] =
"REJECTED",
156 [0xb] =
"IN TRANSITION", [0xc] =
"IMPLEMENTED/STABLE",
157 [0xd] =
"CHANGED", [0xf] =
"INTERIM",
161 return ret ? ret :
"?";
164 static const char *debug_fcp_opcode(
unsigned int opcode,
172 "ReadDescriptor" :
NULL;
175 "DirectSelectInfo.Type" :
NULL;
186 return "Vendor/Unknown";
203 return "Vendor/Unknown";
206 static void debug_fcp(
const u8 *data,
int length)
208 unsigned int subunit_type, subunit_id,
opcode;
211 prefix = data[0] > 7 ?
"FCP <- " :
"FCP -> ";
212 subunit_type = data[1] >> 3;
213 subunit_id = data[1] & 7;
214 opcode = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
215 op = debug_fcp_opcode(opcode, data, length);
219 prefix, subunit_type, subunit_id, length,
220 debug_fcp_ctype(data[0]), op);
223 16, 1, data, length,
false);
227 static void debug_pmt(
char *
msg,
int length)
231 16, 1, msg, length,
false);
234 static int avc_write(
struct firedtv *fdtv)
240 for (retry = 0; retry < 6; retry++) {
280 debug_fcp(data, length);
282 if (length >= 8 && is_register_rc(r)) {
289 if (is_register_rc((
void *)fdtv->
avc_data))
294 "remote control result = %d\n", r->
response);
300 dev_err(fdtv->
device,
"out-of-order AVC response, ignored\n");
317 for (i = 0, n = 0; i < 16; i++) {
319 operand[pos++] = 0x13;
320 operand[pos++] = 0x80;
323 operand[pos++] = 0x00;
324 operand[pos++] = 0x00;
337 static int avc_tuner_tuneqpsk(
struct firedtv *fdtv,
379 if (fdtv->
tone == 0xff)
387 if (fdtv->
fe.dtv_property_cache.delivery_system ==
SYS_DVBS2) {
388 switch (fdtv->
fe.dtv_property_cache.modulation) {
392 default: c->
operand[13] = 0x2;
break;
394 switch (fdtv->
fe.dtv_property_cache.rolloff) {
399 default: c->
operand[14] = 0x2;
break;
402 switch (fdtv->
fe.dtv_property_cache.pilot) {
418 static int avc_tuner_dsd_dvb_c(
struct firedtv *fdtv,
477 default: c->
operand[19] = 0x00;
483 return 22 + add_pid_filter(fdtv, &c->
operand[22]);
486 static int avc_tuner_dsd_dvb_t(
struct firedtv *fdtv,
524 case 7000000: c->
operand[12] = 0x20;
break;
528 default: c->
operand[12] = 0x00;
535 default: c->
operand[13] = 0x00;
562 default: c->
operand[14] = 0x00;
break;
584 return 17 + add_pid_filter(fdtv, &c->
operand[17]);
598 switch (fdtv->
type) {
601 case FIREDTV_DVB_C: pos = avc_tuner_dsd_dvb_c(fdtv, p);
break;
602 case FIREDTV_DVB_T: pos = avc_tuner_dsd_dvb_t(fdtv, p);
break;
606 pad_operands(c, pos);
609 ret = avc_write(fdtv);
632 if (pidc > 16 && pidc != 0xff)
650 for (
k = 0;
k < pidc;
k++) {
653 c->
operand[pos++] = (pid[
k] >> 8) & 0x1f;
658 pad_operands(c, pos);
661 ret = avc_write(fdtv);
698 clear_operands(c, 7, 24);
701 ret = avc_write(fdtv);
732 clear_operands(c, 7, 8);
735 ret = avc_write(fdtv);
741 (
r->operand[3] << 8) +
r->operand[4] != 8) {
751 #define SIZEOF_ANTENNA_INPUT_INFO 22
772 clear_operands(c, 2, 31);
775 ret = avc_write(fdtv);
786 length =
r->operand[9];
795 stat->
moving =
r->operand[11] >> 6 & 1;
796 stat->
no_rf =
r->operand[11] >> 5 & 1;
797 stat->
input =
r->operand[12] >> 7 & 1;
799 stat->
ber =
r->operand[13] << 24 |
800 r->operand[14] << 16 |
801 r->operand[15] << 8 |
806 r->operand[19] << 8 |
818 stat->
ca_mmi =
r->operand[30] & 1;
833 char conttone,
char nrdiseq,
854 for (j = 0; j < nrdiseq; j++) {
857 for (k = 0; k < diseqcmd[
j].
msg_len; k++)
862 pad_operands(c, pos);
865 ret = avc_write(fdtv);
897 ret = avc_write(fdtv);
916 int avc_tuner_host2ca(
struct firedtv *fdtv)
933 clear_operands(c, 6, 8);
936 ret = avc_write(fdtv);
952 length = (r->
operand[7] & 0x7f) + 1;
963 for (i = 0; i < (r->
operand[7] & 0x7f); i++) {
992 ret = avc_write(fdtv);
998 pos = get_ca_object_pos(r);
1002 app_info[3] = 6 + r->
operand[pos + 4];
1005 *len = app_info[3] + 4;
1033 ret = avc_write(fdtv);
1039 pos = get_ca_object_pos(r);
1043 if (num_fake_ca_system_ids == 0) {
1045 app_info[4] = r->
operand[pos + 0];
1046 app_info[5] = r->
operand[pos + 1];
1048 app_info[3] = num_fake_ca_system_ids * 2;
1049 for (i = 0; i < num_fake_ca_system_ids; i++) {
1050 app_info[4 + i * 2] =
1051 (fake_ca_system_ids[
i] >> 8) & 0xff;
1052 app_info[5 + i * 2] = fake_ca_system_ids[
i] & 0xff;
1055 *len = app_info[3] + 4;
1084 ret = avc_write(fdtv);
1097 int list_management;
1098 int program_info_length;
1107 debug_pmt(msg, length);
1120 list_management = msg[0];
1121 program_info_length = ((msg[4] & 0x0f) << 8) + msg[5];
1122 if (program_info_length > 0)
1123 program_info_length--;
1124 pmt_cmd_id = msg[6];
1134 c->
operand[10] = list_management;
1149 c->
operand[22] = (program_info_length >> 8);
1150 c->
operand[23] = (program_info_length & 0xff);
1155 if (program_info_length > 0) {
1156 pmt_cmd_id = msg[read_pos++];
1157 if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
1159 "invalid pmt_cmd_id %d\n", pmt_cmd_id);
1162 program_info_length);
1163 read_pos += program_info_length;
1164 write_pos += program_info_length;
1166 while (read_pos < length) {
1167 c->
operand[write_pos++] = msg[read_pos++];
1168 c->
operand[write_pos++] = msg[read_pos++];
1169 c->
operand[write_pos++] = msg[read_pos++];
1171 ((msg[read_pos] & 0x0f) << 8) + msg[read_pos + 1];
1173 if (es_info_length > 0)
1175 c->
operand[write_pos++] = es_info_length >> 8;
1176 c->
operand[write_pos++] = es_info_length & 0xff;
1177 if (es_info_length > 0) {
1178 pmt_cmd_id = msg[read_pos++];
1179 if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
1181 "at stream level\n", pmt_cmd_id);
1185 read_pos += es_info_length;
1186 write_pos += es_info_length;
1192 c->
operand[8] = (write_pos - 10) >> 8;
1193 c->
operand[9] = (write_pos - 10) & 0xff;
1194 c->
operand[14] = write_pos - 15;
1197 c->
operand[write_pos - 4] = (crc32_csum >> 24) & 0xff;
1198 c->
operand[write_pos - 3] = (crc32_csum >> 16) & 0xff;
1199 c->
operand[write_pos - 2] = (crc32_csum >> 8) & 0xff;
1200 c->
operand[write_pos - 1] = (crc32_csum >> 0) & 0xff;
1201 pad_operands(c, write_pos);
1204 ret = avc_write(fdtv);
1210 "CA PMT failed with response 0x%x\n", r->
response);
1240 ret = avc_write(fdtv);
1246 *interval = r->
operand[get_ca_object_pos(r)];
1270 clear_operands(c, 6, 8);
1273 ret = avc_write(fdtv);
1303 ret = avc_write(fdtv);
1309 *len = get_ca_object_length(r);
1310 memcpy(mmi_object, &r->
operand[get_ca_object_pos(r)], *len);
1317 #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
1352 #define get_opcr_online(v) get_opcr((v), 0x1, 31)
1353 #define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
1354 #define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
1356 #define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
1357 #define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
1358 #define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
1359 #define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
1363 __be32 old_opcr, opcr[2];
1368 ret = cmp_read(fdtv, opcr_address, opcr);
1403 ret = cmp_lock(fdtv, opcr_address, opcr);
1407 if (old_opcr != *opcr) {
1423 __be32 old_opcr, opcr[2];
1427 if (cmp_read(fdtv, opcr_address, opcr) < 0)
1443 if (cmp_lock(fdtv, opcr_address, opcr) < 0)
1446 if (old_opcr != *opcr) {