2 * FireDTV driver (formerly known as FireSAT)
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2008 Ben Backx <ben@bbackx.com>
6 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
14 #include <linux/bug.h>
15 #include <linux/crc32.h>
16 #include <linux/delay.h>
17 #include <linux/device.h>
18 #include <linux/jiffies.h>
19 #include <linux/kernel.h>
20 #include <linux/moduleparam.h>
21 #include <linux/mutex.h>
22 #include <linux/string.h>
23 #include <linux/stringify.h>
24 #include <linux/wait.h>
25 #include <linux/workqueue.h>
29 #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
31 #define AVC_CTYPE_CONTROL 0x0
32 #define AVC_CTYPE_STATUS 0x1
33 #define AVC_CTYPE_NOTIFY 0x3
35 #define AVC_RESPONSE_ACCEPTED 0x9
36 #define AVC_RESPONSE_STABLE 0xc
37 #define AVC_RESPONSE_CHANGED 0xd
38 #define AVC_RESPONSE_INTERIM 0xf
40 #define AVC_SUBUNIT_TYPE_TUNER (0x05 << 3)
41 #define AVC_SUBUNIT_TYPE_UNIT (0x1f << 3)
43 #define AVC_OPCODE_VENDOR 0x00
44 #define AVC_OPCODE_READ_DESCRIPTOR 0x09
45 #define AVC_OPCODE_DSIT 0xc8
46 #define AVC_OPCODE_DSD 0xcb
48 #define DESCRIPTOR_TUNER_STATUS 0x80
49 #define DESCRIPTOR_SUBUNIT_IDENTIFIER 0x00
51 #define SFE_VENDOR_DE_COMPANYID_0 0x00 /* OUI of Digital Everywhere */
52 #define SFE_VENDOR_DE_COMPANYID_1 0x12
53 #define SFE_VENDOR_DE_COMPANYID_2 0x87
55 #define SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL 0x0a
56 #define SFE_VENDOR_OPCODE_LNB_CONTROL 0x52
57 #define SFE_VENDOR_OPCODE_TUNE_QPSK 0x58 /* for DVB-S */
59 #define SFE_VENDOR_OPCODE_GET_FIRMWARE_VERSION 0x00
60 #define SFE_VENDOR_OPCODE_HOST2CA 0x56
61 #define SFE_VENDOR_OPCODE_CA2HOST 0x57
62 #define SFE_VENDOR_OPCODE_CISTATUS 0x59
63 #define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 /* for DVB-S2 */
65 #define SFE_VENDOR_TAG_CA_RESET 0x00
66 #define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
67 #define SFE_VENDOR_TAG_CA_PMT 0x02
68 #define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
69 #define SFE_VENDOR_TAG_CA_MMI 0x05
70 #define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
72 #define EN50221_LIST_MANAGEMENT_ONLY 0x03
73 #define EN50221_TAG_APP_INFO 0x9f8021
74 #define EN50221_TAG_CA_INFO 0x9f8031
76 struct avc_command_frame
{
83 struct avc_response_frame
{
90 #define LAST_OPERAND (509 - 1)
92 static inline void clear_operands(struct avc_command_frame
*c
, int from
, int to
)
94 memset(&c
->operand
[from
], 0, to
- from
+ 1);
97 static void pad_operands(struct avc_command_frame
*c
, int from
)
99 int to
= ALIGN(from
, 4);
101 if (from
<= to
&& to
<= LAST_OPERAND
)
102 clear_operands(c
, from
, to
);
105 #define AVC_DEBUG_READ_DESCRIPTOR 0x0001
106 #define AVC_DEBUG_DSIT 0x0002
107 #define AVC_DEBUG_DSD 0x0004
108 #define AVC_DEBUG_REGISTER_REMOTE_CONTROL 0x0008
109 #define AVC_DEBUG_LNB_CONTROL 0x0010
110 #define AVC_DEBUG_TUNE_QPSK 0x0020
111 #define AVC_DEBUG_TUNE_QPSK2 0x0040
112 #define AVC_DEBUG_HOST2CA 0x0080
113 #define AVC_DEBUG_CA2HOST 0x0100
114 #define AVC_DEBUG_APPLICATION_PMT 0x4000
115 #define AVC_DEBUG_FCP_PAYLOADS 0x8000
117 static int avc_debug
;
118 module_param_named(debug
, avc_debug
, int, 0644);
119 MODULE_PARM_DESC(debug
, "Verbose logging (none = 0"
121 ": READ DESCRIPTOR = " __stringify(AVC_DEBUG_READ_DESCRIPTOR
)
122 ", DSIT = " __stringify(AVC_DEBUG_DSIT
)
123 ", REGISTER_REMOTE_CONTROL = " __stringify(AVC_DEBUG_REGISTER_REMOTE_CONTROL
)
124 ", LNB CONTROL = " __stringify(AVC_DEBUG_LNB_CONTROL
)
125 ", TUNE QPSK = " __stringify(AVC_DEBUG_TUNE_QPSK
)
126 ", TUNE QPSK2 = " __stringify(AVC_DEBUG_TUNE_QPSK2
)
127 ", HOST2CA = " __stringify(AVC_DEBUG_HOST2CA
)
128 ", CA2HOST = " __stringify(AVC_DEBUG_CA2HOST
)
129 "; Application sent PMT = " __stringify(AVC_DEBUG_APPLICATION_PMT
)
130 ", FCP payloads = " __stringify(AVC_DEBUG_FCP_PAYLOADS
)
131 ", or a combination, or all = -1)");
133 static const char *debug_fcp_ctype(unsigned int ctype
)
135 static const char *ctypes
[] = {
136 [0x0] = "CONTROL", [0x1] = "STATUS",
137 [0x2] = "SPECIFIC INQUIRY", [0x3] = "NOTIFY",
138 [0x4] = "GENERAL INQUIRY", [0x8] = "NOT IMPLEMENTED",
139 [0x9] = "ACCEPTED", [0xa] = "REJECTED",
140 [0xb] = "IN TRANSITION", [0xc] = "IMPLEMENTED/STABLE",
141 [0xd] = "CHANGED", [0xf] = "INTERIM",
143 const char *ret
= ctype
< ARRAY_SIZE(ctypes
) ? ctypes
[ctype
] : NULL
;
145 return ret
? ret
: "?";
148 static const char *debug_fcp_opcode(unsigned int opcode
,
149 const u8
*data
, int length
)
152 case AVC_OPCODE_VENDOR
:
154 case AVC_OPCODE_READ_DESCRIPTOR
:
155 return avc_debug
& AVC_DEBUG_READ_DESCRIPTOR
?
156 "ReadDescriptor" : NULL
;
157 case AVC_OPCODE_DSIT
:
158 return avc_debug
& AVC_DEBUG_DSIT
?
159 "DirectSelectInfo.Type" : NULL
;
161 return avc_debug
& AVC_DEBUG_DSD
? "DirectSelectData" : NULL
;
167 data
[3] != SFE_VENDOR_DE_COMPANYID_0
||
168 data
[4] != SFE_VENDOR_DE_COMPANYID_1
||
169 data
[5] != SFE_VENDOR_DE_COMPANYID_2
)
170 return "Vendor/Unknown";
173 case SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL
:
174 return avc_debug
& AVC_DEBUG_REGISTER_REMOTE_CONTROL
?
176 case SFE_VENDOR_OPCODE_LNB_CONTROL
:
177 return avc_debug
& AVC_DEBUG_LNB_CONTROL
? "LNBControl" : NULL
;
178 case SFE_VENDOR_OPCODE_TUNE_QPSK
:
179 return avc_debug
& AVC_DEBUG_TUNE_QPSK
? "TuneQPSK" : NULL
;
180 case SFE_VENDOR_OPCODE_TUNE_QPSK2
:
181 return avc_debug
& AVC_DEBUG_TUNE_QPSK2
? "TuneQPSK2" : NULL
;
182 case SFE_VENDOR_OPCODE_HOST2CA
:
183 return avc_debug
& AVC_DEBUG_HOST2CA
? "Host2CA" : NULL
;
184 case SFE_VENDOR_OPCODE_CA2HOST
:
185 return avc_debug
& AVC_DEBUG_CA2HOST
? "CA2Host" : NULL
;
187 return "Vendor/Unknown";
190 static void debug_fcp(const u8
*data
, int length
)
192 unsigned int subunit_type
, subunit_id
, opcode
;
193 const char *op
, *prefix
;
195 prefix
= data
[0] > 7 ? "FCP <- " : "FCP -> ";
196 subunit_type
= data
[1] >> 3;
197 subunit_id
= data
[1] & 7;
198 opcode
= subunit_type
== 0x1e || subunit_id
== 5 ? ~0 : data
[2];
199 op
= debug_fcp_opcode(opcode
, data
, length
);
202 printk(KERN_INFO
"%ssu=%x.%x l=%d: %-8s - %s\n",
203 prefix
, subunit_type
, subunit_id
, length
,
204 debug_fcp_ctype(data
[0]), op
);
205 if (avc_debug
& AVC_DEBUG_FCP_PAYLOADS
)
206 print_hex_dump(KERN_INFO
, prefix
, DUMP_PREFIX_NONE
,
207 16, 1, data
, length
, false);
211 static void debug_pmt(char *msg
, int length
)
213 printk(KERN_INFO
"APP PMT -> l=%d\n", length
);
214 print_hex_dump(KERN_INFO
, "APP PMT -> ", DUMP_PREFIX_NONE
,
215 16, 1, msg
, length
, false);
218 static int avc_write(struct firedtv
*fdtv
)
222 fdtv
->avc_reply_received
= false;
224 for (retry
= 0; retry
< 6; retry
++) {
225 if (unlikely(avc_debug
))
226 debug_fcp(fdtv
->avc_data
, fdtv
->avc_data_length
);
228 err
= fdtv
->backend
->write(fdtv
, FCP_COMMAND_REGISTER
,
229 fdtv
->avc_data
, fdtv
->avc_data_length
);
231 dev_err(fdtv
->device
, "FCP command write failed\n");
237 * AV/C specs say that answers should be sent within 150 ms.
238 * Time out after 200 ms.
240 if (wait_event_timeout(fdtv
->avc_wait
,
241 fdtv
->avc_reply_received
,
242 msecs_to_jiffies(200)) != 0)
245 dev_err(fdtv
->device
, "FCP response timed out\n");
250 static bool is_register_rc(struct avc_response_frame
*r
)
252 return r
->opcode
== AVC_OPCODE_VENDOR
&&
253 r
->operand
[0] == SFE_VENDOR_DE_COMPANYID_0
&&
254 r
->operand
[1] == SFE_VENDOR_DE_COMPANYID_1
&&
255 r
->operand
[2] == SFE_VENDOR_DE_COMPANYID_2
&&
256 r
->operand
[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL
;
259 int avc_recv(struct firedtv
*fdtv
, void *data
, size_t length
)
261 struct avc_response_frame
*r
= data
;
263 if (unlikely(avc_debug
))
264 debug_fcp(data
, length
);
266 if (length
>= 8 && is_register_rc(r
)) {
267 switch (r
->response
) {
268 case AVC_RESPONSE_CHANGED
:
269 fdtv_handle_rc(fdtv
, r
->operand
[4] << 8 | r
->operand
[5]);
270 schedule_work(&fdtv
->remote_ctrl_work
);
272 case AVC_RESPONSE_INTERIM
:
273 if (is_register_rc((void *)fdtv
->avc_data
))
277 dev_info(fdtv
->device
,
278 "remote control result = %d\n", r
->response
);
283 if (fdtv
->avc_reply_received
) {
284 dev_err(fdtv
->device
, "out-of-order AVC response, ignored\n");
288 memcpy(fdtv
->avc_data
, data
, length
);
289 fdtv
->avc_data_length
= length
;
291 fdtv
->avc_reply_received
= true;
292 wake_up(&fdtv
->avc_wait
);
297 static int add_pid_filter(struct firedtv
*fdtv
, u8
*operand
)
301 for (i
= 0, n
= 0; i
< 16; i
++) {
302 if (test_bit(i
, &fdtv
->channel_active
)) {
303 operand
[pos
++] = 0x13; /* flowfunction relay */
304 operand
[pos
++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
305 operand
[pos
++] = (fdtv
->channel_pid
[i
] >> 8) & 0x1f;
306 operand
[pos
++] = fdtv
->channel_pid
[i
] & 0xff;
307 operand
[pos
++] = 0x00; /* tableID */
308 operand
[pos
++] = 0x00; /* filter_length */
318 * tuning command for setting the relative LNB frequency
319 * (not supported by the AVC standard)
321 static int avc_tuner_tuneqpsk(struct firedtv
*fdtv
,
322 struct dvb_frontend_parameters
*params
)
324 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
326 c
->opcode
= AVC_OPCODE_VENDOR
;
328 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
329 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
330 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
331 if (fdtv
->type
== FIREDTV_DVB_S2
)
332 c
->operand
[3] = SFE_VENDOR_OPCODE_TUNE_QPSK2
;
334 c
->operand
[3] = SFE_VENDOR_OPCODE_TUNE_QPSK
;
336 c
->operand
[4] = (params
->frequency
>> 24) & 0xff;
337 c
->operand
[5] = (params
->frequency
>> 16) & 0xff;
338 c
->operand
[6] = (params
->frequency
>> 8) & 0xff;
339 c
->operand
[7] = params
->frequency
& 0xff;
341 c
->operand
[8] = ((params
->u
.qpsk
.symbol_rate
/ 1000) >> 8) & 0xff;
342 c
->operand
[9] = (params
->u
.qpsk
.symbol_rate
/ 1000) & 0xff;
344 switch (params
->u
.qpsk
.fec_inner
) {
345 case FEC_1_2
: c
->operand
[10] = 0x1; break;
346 case FEC_2_3
: c
->operand
[10] = 0x2; break;
347 case FEC_3_4
: c
->operand
[10] = 0x3; break;
348 case FEC_5_6
: c
->operand
[10] = 0x4; break;
349 case FEC_7_8
: c
->operand
[10] = 0x5; break;
353 default: c
->operand
[10] = 0x0;
356 if (fdtv
->voltage
== 0xff)
357 c
->operand
[11] = 0xff;
358 else if (fdtv
->voltage
== SEC_VOLTAGE_18
) /* polarisation */
363 if (fdtv
->tone
== 0xff)
364 c
->operand
[12] = 0xff;
365 else if (fdtv
->tone
== SEC_TONE_ON
) /* band */
370 if (fdtv
->type
== FIREDTV_DVB_S2
) {
371 c
->operand
[13] = 0x1;
372 c
->operand
[14] = 0xff;
373 c
->operand
[15] = 0xff;
381 static int avc_tuner_dsd_dvb_c(struct firedtv
*fdtv
,
382 struct dvb_frontend_parameters
*params
)
384 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
386 c
->opcode
= AVC_OPCODE_DSD
;
388 c
->operand
[0] = 0; /* source plug */
389 c
->operand
[1] = 0xd2; /* subfunction replace */
390 c
->operand
[2] = 0x20; /* system id = DVB */
391 c
->operand
[3] = 0x00; /* antenna number */
392 c
->operand
[4] = 0x11; /* system_specific_multiplex selection_length */
394 /* multiplex_valid_flags, high byte */
395 c
->operand
[5] = 0 << 7 /* reserved */
396 | 0 << 6 /* Polarisation */
397 | 0 << 5 /* Orbital_Pos */
398 | 1 << 4 /* Frequency */
399 | 1 << 3 /* Symbol_Rate */
400 | 0 << 2 /* FEC_outer */
401 | (params
->u
.qam
.fec_inner
!= FEC_AUTO
? 1 << 1 : 0)
402 | (params
->u
.qam
.modulation
!= QAM_AUTO
? 1 << 0 : 0);
404 /* multiplex_valid_flags, low byte */
405 c
->operand
[6] = 0 << 7 /* NetworkID */
406 | 0 << 0 /* reserved */ ;
408 c
->operand
[7] = 0x00;
409 c
->operand
[8] = 0x00;
410 c
->operand
[9] = 0x00;
411 c
->operand
[10] = 0x00;
413 c
->operand
[11] = (((params
->frequency
/ 4000) >> 16) & 0xff) | (2 << 6);
414 c
->operand
[12] = ((params
->frequency
/ 4000) >> 8) & 0xff;
415 c
->operand
[13] = (params
->frequency
/ 4000) & 0xff;
416 c
->operand
[14] = ((params
->u
.qpsk
.symbol_rate
/ 1000) >> 12) & 0xff;
417 c
->operand
[15] = ((params
->u
.qpsk
.symbol_rate
/ 1000) >> 4) & 0xff;
418 c
->operand
[16] = ((params
->u
.qpsk
.symbol_rate
/ 1000) << 4) & 0xf0;
419 c
->operand
[17] = 0x00;
421 switch (params
->u
.qpsk
.fec_inner
) {
422 case FEC_1_2
: c
->operand
[18] = 0x1; break;
423 case FEC_2_3
: c
->operand
[18] = 0x2; break;
424 case FEC_3_4
: c
->operand
[18] = 0x3; break;
425 case FEC_5_6
: c
->operand
[18] = 0x4; break;
426 case FEC_7_8
: c
->operand
[18] = 0x5; break;
427 case FEC_8_9
: c
->operand
[18] = 0x6; break;
428 case FEC_4_5
: c
->operand
[18] = 0x8; break;
430 default: c
->operand
[18] = 0x0;
433 switch (params
->u
.qam
.modulation
) {
434 case QAM_16
: c
->operand
[19] = 0x08; break;
435 case QAM_32
: c
->operand
[19] = 0x10; break;
436 case QAM_64
: c
->operand
[19] = 0x18; break;
437 case QAM_128
: c
->operand
[19] = 0x20; break;
438 case QAM_256
: c
->operand
[19] = 0x28; break;
440 default: c
->operand
[19] = 0x00;
443 c
->operand
[20] = 0x00;
444 c
->operand
[21] = 0x00;
446 return 22 + add_pid_filter(fdtv
, &c
->operand
[22]);
449 static int avc_tuner_dsd_dvb_t(struct firedtv
*fdtv
,
450 struct dvb_frontend_parameters
*params
)
452 struct dvb_ofdm_parameters
*ofdm
= ¶ms
->u
.ofdm
;
453 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
455 c
->opcode
= AVC_OPCODE_DSD
;
457 c
->operand
[0] = 0; /* source plug */
458 c
->operand
[1] = 0xd2; /* subfunction replace */
459 c
->operand
[2] = 0x20; /* system id = DVB */
460 c
->operand
[3] = 0x00; /* antenna number */
461 c
->operand
[4] = 0x0c; /* system_specific_multiplex selection_length */
463 /* multiplex_valid_flags, high byte */
465 0 << 7 /* reserved */
466 | 1 << 6 /* CenterFrequency */
467 | (ofdm
->bandwidth
!= BANDWIDTH_AUTO
? 1 << 5 : 0)
468 | (ofdm
->constellation
!= QAM_AUTO
? 1 << 4 : 0)
469 | (ofdm
->hierarchy_information
!= HIERARCHY_AUTO
? 1 << 3 : 0)
470 | (ofdm
->code_rate_HP
!= FEC_AUTO
? 1 << 2 : 0)
471 | (ofdm
->code_rate_LP
!= FEC_AUTO
? 1 << 1 : 0)
472 | (ofdm
->guard_interval
!= GUARD_INTERVAL_AUTO
? 1 << 0 : 0);
474 /* multiplex_valid_flags, low byte */
476 0 << 7 /* NetworkID */
477 | (ofdm
->transmission_mode
!= TRANSMISSION_MODE_AUTO
? 1 << 6 : 0)
478 | 0 << 5 /* OtherFrequencyFlag */
479 | 0 << 0 /* reserved */ ;
482 c
->operand
[8] = (params
->frequency
/ 10) >> 24;
483 c
->operand
[9] = ((params
->frequency
/ 10) >> 16) & 0xff;
484 c
->operand
[10] = ((params
->frequency
/ 10) >> 8) & 0xff;
485 c
->operand
[11] = (params
->frequency
/ 10) & 0xff;
487 switch (ofdm
->bandwidth
) {
488 case BANDWIDTH_7_MHZ
: c
->operand
[12] = 0x20; break;
489 case BANDWIDTH_8_MHZ
:
490 case BANDWIDTH_6_MHZ
: /* not defined by AVC spec */
492 default: c
->operand
[12] = 0x00;
495 switch (ofdm
->constellation
) {
496 case QAM_16
: c
->operand
[13] = 1 << 6; break;
497 case QAM_64
: c
->operand
[13] = 2 << 6; break;
499 default: c
->operand
[13] = 0x00;
502 switch (ofdm
->hierarchy_information
) {
503 case HIERARCHY_1
: c
->operand
[13] |= 1 << 3; break;
504 case HIERARCHY_2
: c
->operand
[13] |= 2 << 3; break;
505 case HIERARCHY_4
: c
->operand
[13] |= 3 << 3; break;
511 switch (ofdm
->code_rate_HP
) {
512 case FEC_2_3
: c
->operand
[13] |= 1; break;
513 case FEC_3_4
: c
->operand
[13] |= 2; break;
514 case FEC_5_6
: c
->operand
[13] |= 3; break;
515 case FEC_7_8
: c
->operand
[13] |= 4; break;
520 switch (ofdm
->code_rate_LP
) {
521 case FEC_2_3
: c
->operand
[14] = 1 << 5; break;
522 case FEC_3_4
: c
->operand
[14] = 2 << 5; break;
523 case FEC_5_6
: c
->operand
[14] = 3 << 5; break;
524 case FEC_7_8
: c
->operand
[14] = 4 << 5; break;
526 default: c
->operand
[14] = 0x00; break;
529 switch (ofdm
->guard_interval
) {
530 case GUARD_INTERVAL_1_16
: c
->operand
[14] |= 1 << 3; break;
531 case GUARD_INTERVAL_1_8
: c
->operand
[14] |= 2 << 3; break;
532 case GUARD_INTERVAL_1_4
: c
->operand
[14] |= 3 << 3; break;
533 case GUARD_INTERVAL_1_32
:
534 case GUARD_INTERVAL_AUTO
:
538 switch (ofdm
->transmission_mode
) {
539 case TRANSMISSION_MODE_8K
: c
->operand
[14] |= 1 << 1; break;
540 case TRANSMISSION_MODE_2K
:
541 case TRANSMISSION_MODE_AUTO
:
545 c
->operand
[15] = 0x00; /* network_ID[0] */
546 c
->operand
[16] = 0x00; /* network_ID[1] */
548 return 17 + add_pid_filter(fdtv
, &c
->operand
[17]);
551 int avc_tuner_dsd(struct firedtv
*fdtv
,
552 struct dvb_frontend_parameters
*params
)
554 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
557 mutex_lock(&fdtv
->avc_mutex
);
559 c
->ctype
= AVC_CTYPE_CONTROL
;
560 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
562 switch (fdtv
->type
) {
564 case FIREDTV_DVB_S2
: pos
= avc_tuner_tuneqpsk(fdtv
, params
); break;
565 case FIREDTV_DVB_C
: pos
= avc_tuner_dsd_dvb_c(fdtv
, params
); break;
566 case FIREDTV_DVB_T
: pos
= avc_tuner_dsd_dvb_t(fdtv
, params
); break;
570 pad_operands(c
, pos
);
572 fdtv
->avc_data_length
= ALIGN(3 + pos
, 4);
573 ret
= avc_write(fdtv
);
574 mutex_unlock(&fdtv
->avc_mutex
);
582 int avc_tuner_set_pids(struct firedtv
*fdtv
, unsigned char pidc
, u16 pid
[])
584 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
587 if (pidc
> 16 && pidc
!= 0xff)
590 mutex_lock(&fdtv
->avc_mutex
);
592 c
->ctype
= AVC_CTYPE_CONTROL
;
593 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
594 c
->opcode
= AVC_OPCODE_DSD
;
596 c
->operand
[0] = 0; /* source plug */
597 c
->operand
[1] = 0xd2; /* subfunction replace */
598 c
->operand
[2] = 0x20; /* system id = DVB */
599 c
->operand
[3] = 0x00; /* antenna number */
600 c
->operand
[4] = 0x00; /* system_specific_multiplex selection_length */
601 c
->operand
[5] = pidc
; /* Nr_of_dsd_sel_specs */
605 for (k
= 0; k
< pidc
; k
++) {
606 c
->operand
[pos
++] = 0x13; /* flowfunction relay */
607 c
->operand
[pos
++] = 0x80; /* dsd_sel_spec_valid_flags -> PID */
608 c
->operand
[pos
++] = (pid
[k
] >> 8) & 0x1f;
609 c
->operand
[pos
++] = pid
[k
] & 0xff;
610 c
->operand
[pos
++] = 0x00; /* tableID */
611 c
->operand
[pos
++] = 0x00; /* filter_length */
613 pad_operands(c
, pos
);
615 fdtv
->avc_data_length
= ALIGN(3 + pos
, 4);
616 ret
= avc_write(fdtv
);
619 mutex_unlock(&fdtv
->avc_mutex
);
627 int avc_tuner_get_ts(struct firedtv
*fdtv
)
629 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
632 mutex_lock(&fdtv
->avc_mutex
);
634 c
->ctype
= AVC_CTYPE_CONTROL
;
635 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
636 c
->opcode
= AVC_OPCODE_DSIT
;
638 sl
= fdtv
->type
== FIREDTV_DVB_T
? 0x0c : 0x11;
640 c
->operand
[0] = 0; /* source plug */
641 c
->operand
[1] = 0xd2; /* subfunction replace */
642 c
->operand
[2] = 0xff; /* status */
643 c
->operand
[3] = 0x20; /* system id = DVB */
644 c
->operand
[4] = 0x00; /* antenna number */
645 c
->operand
[5] = 0x0; /* system_specific_search_flags */
646 c
->operand
[6] = sl
; /* system_specific_multiplex selection_length */
648 * operand[7]: valid_flags[0]
649 * operand[8]: valid_flags[1]
650 * operand[7 + sl]: nr_of_dsit_sel_specs (always 0)
652 clear_operands(c
, 7, 24);
654 fdtv
->avc_data_length
= fdtv
->type
== FIREDTV_DVB_T
? 24 : 28;
655 ret
= avc_write(fdtv
);
658 mutex_unlock(&fdtv
->avc_mutex
);
666 int avc_identify_subunit(struct firedtv
*fdtv
)
668 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
669 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
672 mutex_lock(&fdtv
->avc_mutex
);
674 c
->ctype
= AVC_CTYPE_CONTROL
;
675 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
676 c
->opcode
= AVC_OPCODE_READ_DESCRIPTOR
;
678 c
->operand
[0] = DESCRIPTOR_SUBUNIT_IDENTIFIER
;
679 c
->operand
[1] = 0xff;
680 c
->operand
[2] = 0x00;
681 c
->operand
[3] = 0x00; /* length highbyte */
682 c
->operand
[4] = 0x08; /* length lowbyte */
683 c
->operand
[5] = 0x00; /* offset highbyte */
684 c
->operand
[6] = 0x0d; /* offset lowbyte */
685 clear_operands(c
, 7, 8); /* padding */
687 fdtv
->avc_data_length
= 12;
688 ret
= avc_write(fdtv
);
692 if ((r
->response
!= AVC_RESPONSE_STABLE
&&
693 r
->response
!= AVC_RESPONSE_ACCEPTED
) ||
694 (r
->operand
[3] << 8) + r
->operand
[4] != 8) {
695 dev_err(fdtv
->device
, "cannot read subunit identifier\n");
699 mutex_unlock(&fdtv
->avc_mutex
);
704 #define SIZEOF_ANTENNA_INPUT_INFO 22
706 int avc_tuner_status(struct firedtv
*fdtv
, struct firedtv_tuner_status
*stat
)
708 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
709 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
712 mutex_lock(&fdtv
->avc_mutex
);
714 c
->ctype
= AVC_CTYPE_CONTROL
;
715 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
716 c
->opcode
= AVC_OPCODE_READ_DESCRIPTOR
;
718 c
->operand
[0] = DESCRIPTOR_TUNER_STATUS
;
719 c
->operand
[1] = 0xff; /* read_result_status */
721 * operand[2]: reserved
722 * operand[3]: SIZEOF_ANTENNA_INPUT_INFO >> 8
723 * operand[4]: SIZEOF_ANTENNA_INPUT_INFO & 0xff
725 clear_operands(c
, 2, 31);
727 fdtv
->avc_data_length
= 12;
728 ret
= avc_write(fdtv
);
732 if (r
->response
!= AVC_RESPONSE_STABLE
&&
733 r
->response
!= AVC_RESPONSE_ACCEPTED
) {
734 dev_err(fdtv
->device
, "cannot read tuner status\n");
739 length
= r
->operand
[9];
740 if (r
->operand
[1] != 0x10 || length
!= SIZEOF_ANTENNA_INPUT_INFO
) {
741 dev_err(fdtv
->device
, "got invalid tuner status\n");
746 stat
->active_system
= r
->operand
[10];
747 stat
->searching
= r
->operand
[11] >> 7 & 1;
748 stat
->moving
= r
->operand
[11] >> 6 & 1;
749 stat
->no_rf
= r
->operand
[11] >> 5 & 1;
750 stat
->input
= r
->operand
[12] >> 7 & 1;
751 stat
->selected_antenna
= r
->operand
[12] & 0x7f;
752 stat
->ber
= r
->operand
[13] << 24 |
753 r
->operand
[14] << 16 |
754 r
->operand
[15] << 8 |
756 stat
->signal_strength
= r
->operand
[17];
757 stat
->raster_frequency
= r
->operand
[18] >> 6 & 2;
758 stat
->rf_frequency
= (r
->operand
[18] & 0x3f) << 16 |
759 r
->operand
[19] << 8 |
761 stat
->man_dep_info_length
= r
->operand
[21];
762 stat
->front_end_error
= r
->operand
[22] >> 4 & 1;
763 stat
->antenna_error
= r
->operand
[22] >> 3 & 1;
764 stat
->front_end_power_status
= r
->operand
[22] >> 1 & 1;
765 stat
->power_supply
= r
->operand
[22] & 1;
766 stat
->carrier_noise_ratio
= r
->operand
[23] << 8 |
768 stat
->power_supply_voltage
= r
->operand
[27];
769 stat
->antenna_voltage
= r
->operand
[28];
770 stat
->firewire_bus_voltage
= r
->operand
[29];
771 stat
->ca_mmi
= r
->operand
[30] & 1;
772 stat
->ca_pmt_reply
= r
->operand
[31] >> 7 & 1;
773 stat
->ca_date_time_request
= r
->operand
[31] >> 6 & 1;
774 stat
->ca_application_info
= r
->operand
[31] >> 5 & 1;
775 stat
->ca_module_present_status
= r
->operand
[31] >> 4 & 1;
776 stat
->ca_dvb_flag
= r
->operand
[31] >> 3 & 1;
777 stat
->ca_error_flag
= r
->operand
[31] >> 2 & 1;
778 stat
->ca_initialization_status
= r
->operand
[31] >> 1 & 1;
780 mutex_unlock(&fdtv
->avc_mutex
);
785 int avc_lnb_control(struct firedtv
*fdtv
, char voltage
, char burst
,
786 char conttone
, char nrdiseq
,
787 struct dvb_diseqc_master_cmd
*diseqcmd
)
789 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
790 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
793 mutex_lock(&fdtv
->avc_mutex
);
795 c
->ctype
= AVC_CTYPE_CONTROL
;
796 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
797 c
->opcode
= AVC_OPCODE_VENDOR
;
799 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
800 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
801 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
802 c
->operand
[3] = SFE_VENDOR_OPCODE_LNB_CONTROL
;
803 c
->operand
[4] = voltage
;
804 c
->operand
[5] = nrdiseq
;
807 for (j
= 0; j
< nrdiseq
; j
++) {
808 c
->operand
[pos
++] = diseqcmd
[j
].msg_len
;
810 for (k
= 0; k
< diseqcmd
[j
].msg_len
; k
++)
811 c
->operand
[pos
++] = diseqcmd
[j
].msg
[k
];
813 c
->operand
[pos
++] = burst
;
814 c
->operand
[pos
++] = conttone
;
815 pad_operands(c
, pos
);
817 fdtv
->avc_data_length
= ALIGN(3 + pos
, 4);
818 ret
= avc_write(fdtv
);
822 if (r
->response
!= AVC_RESPONSE_ACCEPTED
) {
823 dev_err(fdtv
->device
, "LNB control failed\n");
827 mutex_unlock(&fdtv
->avc_mutex
);
832 int avc_register_remote_control(struct firedtv
*fdtv
)
834 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
837 mutex_lock(&fdtv
->avc_mutex
);
839 c
->ctype
= AVC_CTYPE_NOTIFY
;
840 c
->subunit
= AVC_SUBUNIT_TYPE_UNIT
| 7;
841 c
->opcode
= AVC_OPCODE_VENDOR
;
843 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
844 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
845 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
846 c
->operand
[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL
;
847 c
->operand
[4] = 0; /* padding */
849 fdtv
->avc_data_length
= 8;
850 ret
= avc_write(fdtv
);
853 mutex_unlock(&fdtv
->avc_mutex
);
858 void avc_remote_ctrl_work(struct work_struct
*work
)
860 struct firedtv
*fdtv
=
861 container_of(work
, struct firedtv
, remote_ctrl_work
);
863 /* Should it be rescheduled in failure cases? */
864 avc_register_remote_control(fdtv
);
868 static int get_ca_object_pos(struct avc_response_frame
*r
)
872 /* Check length of length field */
873 if (r
->operand
[7] & 0x80)
874 length
= (r
->operand
[7] & 0x7f) + 1;
878 static int get_ca_object_length(struct avc_response_frame
*r
)
880 return r
->operand
[7];
883 int avc_ca_app_info(struct firedtv
*fdtv
, char *app_info
, unsigned int *len
)
885 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
886 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
889 mutex_lock(&fdtv
->avc_mutex
);
891 c
->ctype
= AVC_CTYPE_STATUS
;
892 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
893 c
->opcode
= AVC_OPCODE_VENDOR
;
895 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
896 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
897 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
898 c
->operand
[3] = SFE_VENDOR_OPCODE_CA2HOST
;
899 c
->operand
[4] = 0; /* slot */
900 c
->operand
[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO
; /* ca tag */
901 clear_operands(c
, 6, LAST_OPERAND
);
903 fdtv
->avc_data_length
= 12;
904 ret
= avc_write(fdtv
);
909 pos
= get_ca_object_pos(r
);
910 app_info
[0] = (EN50221_TAG_APP_INFO
>> 16) & 0xff;
911 app_info
[1] = (EN50221_TAG_APP_INFO
>> 8) & 0xff;
912 app_info
[2] = (EN50221_TAG_APP_INFO
>> 0) & 0xff;
913 app_info
[3] = 6 + r
->operand
[pos
+ 4];
915 memcpy(&app_info
[5], &r
->operand
[pos
], 5 + r
->operand
[pos
+ 4]);
916 *len
= app_info
[3] + 4;
918 mutex_unlock(&fdtv
->avc_mutex
);
923 int avc_ca_info(struct firedtv
*fdtv
, char *app_info
, unsigned int *len
)
925 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
926 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
929 mutex_lock(&fdtv
->avc_mutex
);
931 c
->ctype
= AVC_CTYPE_STATUS
;
932 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
933 c
->opcode
= AVC_OPCODE_VENDOR
;
935 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
936 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
937 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
938 c
->operand
[3] = SFE_VENDOR_OPCODE_CA2HOST
;
939 c
->operand
[4] = 0; /* slot */
940 c
->operand
[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO
; /* ca tag */
941 clear_operands(c
, 6, LAST_OPERAND
);
943 fdtv
->avc_data_length
= 12;
944 ret
= avc_write(fdtv
);
949 pos
= get_ca_object_pos(r
);
950 app_info
[0] = (EN50221_TAG_CA_INFO
>> 16) & 0xff;
951 app_info
[1] = (EN50221_TAG_CA_INFO
>> 8) & 0xff;
952 app_info
[2] = (EN50221_TAG_CA_INFO
>> 0) & 0xff;
954 app_info
[4] = r
->operand
[pos
+ 0];
955 app_info
[5] = r
->operand
[pos
+ 1];
956 *len
= app_info
[3] + 4;
958 mutex_unlock(&fdtv
->avc_mutex
);
963 int avc_ca_reset(struct firedtv
*fdtv
)
965 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
968 mutex_lock(&fdtv
->avc_mutex
);
970 c
->ctype
= AVC_CTYPE_CONTROL
;
971 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
972 c
->opcode
= AVC_OPCODE_VENDOR
;
974 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
975 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
976 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
977 c
->operand
[3] = SFE_VENDOR_OPCODE_HOST2CA
;
978 c
->operand
[4] = 0; /* slot */
979 c
->operand
[5] = SFE_VENDOR_TAG_CA_RESET
; /* ca tag */
980 c
->operand
[6] = 0; /* more/last */
981 c
->operand
[7] = 1; /* length */
982 c
->operand
[8] = 0; /* force hardware reset */
984 fdtv
->avc_data_length
= 12;
985 ret
= avc_write(fdtv
);
988 mutex_unlock(&fdtv
->avc_mutex
);
993 int avc_ca_pmt(struct firedtv
*fdtv
, char *msg
, int length
)
995 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
996 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
998 int program_info_length
;
1006 if (unlikely(avc_debug
& AVC_DEBUG_APPLICATION_PMT
))
1007 debug_pmt(msg
, length
);
1009 mutex_lock(&fdtv
->avc_mutex
);
1011 c
->ctype
= AVC_CTYPE_CONTROL
;
1012 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
1013 c
->opcode
= AVC_OPCODE_VENDOR
;
1015 if (msg
[0] != EN50221_LIST_MANAGEMENT_ONLY
) {
1016 dev_info(fdtv
->device
, "forcing list_management to ONLY\n");
1017 msg
[0] = EN50221_LIST_MANAGEMENT_ONLY
;
1019 /* We take the cmd_id from the programme level only! */
1020 list_management
= msg
[0];
1021 program_info_length
= ((msg
[4] & 0x0f) << 8) + msg
[5];
1022 if (program_info_length
> 0)
1023 program_info_length
--; /* Remove pmt_cmd_id */
1024 pmt_cmd_id
= msg
[6];
1026 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
1027 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
1028 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
1029 c
->operand
[3] = SFE_VENDOR_OPCODE_HOST2CA
;
1030 c
->operand
[4] = 0; /* slot */
1031 c
->operand
[5] = SFE_VENDOR_TAG_CA_PMT
; /* ca tag */
1032 c
->operand
[6] = 0; /* more/last */
1033 /* Use three bytes for length field in case length > 127 */
1034 c
->operand
[10] = list_management
;
1035 c
->operand
[11] = 0x01; /* pmt_cmd=OK_descramble */
1037 /* TS program map table */
1039 c
->operand
[12] = 0x02; /* Table id=2 */
1040 c
->operand
[13] = 0x80; /* Section syntax + length */
1042 c
->operand
[15] = msg
[1]; /* Program number */
1043 c
->operand
[16] = msg
[2];
1044 c
->operand
[17] = msg
[3]; /* Version number and current/next */
1045 c
->operand
[18] = 0x00; /* Section number=0 */
1046 c
->operand
[19] = 0x00; /* Last section number=0 */
1047 c
->operand
[20] = 0x1f; /* PCR_PID=1FFF */
1048 c
->operand
[21] = 0xff;
1049 c
->operand
[22] = (program_info_length
>> 8); /* Program info length */
1050 c
->operand
[23] = (program_info_length
& 0xff);
1052 /* CA descriptors at programme level */
1055 if (program_info_length
> 0) {
1056 pmt_cmd_id
= msg
[read_pos
++];
1057 if (pmt_cmd_id
!= 1 && pmt_cmd_id
!= 4)
1058 dev_err(fdtv
->device
,
1059 "invalid pmt_cmd_id %d\n", pmt_cmd_id
);
1061 memcpy(&c
->operand
[write_pos
], &msg
[read_pos
],
1062 program_info_length
);
1063 read_pos
+= program_info_length
;
1064 write_pos
+= program_info_length
;
1066 while (read_pos
< length
) {
1067 c
->operand
[write_pos
++] = msg
[read_pos
++];
1068 c
->operand
[write_pos
++] = msg
[read_pos
++];
1069 c
->operand
[write_pos
++] = msg
[read_pos
++];
1071 ((msg
[read_pos
] & 0x0f) << 8) + msg
[read_pos
+ 1];
1073 if (es_info_length
> 0)
1074 es_info_length
--; /* Remove pmt_cmd_id */
1075 c
->operand
[write_pos
++] = es_info_length
>> 8;
1076 c
->operand
[write_pos
++] = es_info_length
& 0xff;
1077 if (es_info_length
> 0) {
1078 pmt_cmd_id
= msg
[read_pos
++];
1079 if (pmt_cmd_id
!= 1 && pmt_cmd_id
!= 4)
1080 dev_err(fdtv
->device
, "invalid pmt_cmd_id %d "
1081 "at stream level\n", pmt_cmd_id
);
1083 memcpy(&c
->operand
[write_pos
], &msg
[read_pos
],
1085 read_pos
+= es_info_length
;
1086 write_pos
+= es_info_length
;
1089 write_pos
+= 4; /* CRC */
1091 c
->operand
[7] = 0x82;
1092 c
->operand
[8] = (write_pos
- 10) >> 8;
1093 c
->operand
[9] = (write_pos
- 10) & 0xff;
1094 c
->operand
[14] = write_pos
- 15;
1096 crc32_csum
= crc32_be(0, &c
->operand
[10], c
->operand
[12] - 1);
1097 c
->operand
[write_pos
- 4] = (crc32_csum
>> 24) & 0xff;
1098 c
->operand
[write_pos
- 3] = (crc32_csum
>> 16) & 0xff;
1099 c
->operand
[write_pos
- 2] = (crc32_csum
>> 8) & 0xff;
1100 c
->operand
[write_pos
- 1] = (crc32_csum
>> 0) & 0xff;
1101 pad_operands(c
, write_pos
);
1103 fdtv
->avc_data_length
= ALIGN(3 + write_pos
, 4);
1104 ret
= avc_write(fdtv
);
1108 if (r
->response
!= AVC_RESPONSE_ACCEPTED
) {
1109 dev_err(fdtv
->device
,
1110 "CA PMT failed with response 0x%x\n", r
->response
);
1114 mutex_unlock(&fdtv
->avc_mutex
);
1119 int avc_ca_get_time_date(struct firedtv
*fdtv
, int *interval
)
1121 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
1122 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
1125 mutex_lock(&fdtv
->avc_mutex
);
1127 c
->ctype
= AVC_CTYPE_STATUS
;
1128 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
1129 c
->opcode
= AVC_OPCODE_VENDOR
;
1131 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
1132 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
1133 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
1134 c
->operand
[3] = SFE_VENDOR_OPCODE_CA2HOST
;
1135 c
->operand
[4] = 0; /* slot */
1136 c
->operand
[5] = SFE_VENDOR_TAG_CA_DATE_TIME
; /* ca tag */
1137 clear_operands(c
, 6, LAST_OPERAND
);
1139 fdtv
->avc_data_length
= 12;
1140 ret
= avc_write(fdtv
);
1145 *interval
= r
->operand
[get_ca_object_pos(r
)];
1147 mutex_unlock(&fdtv
->avc_mutex
);
1152 int avc_ca_enter_menu(struct firedtv
*fdtv
)
1154 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
1157 mutex_lock(&fdtv
->avc_mutex
);
1159 c
->ctype
= AVC_CTYPE_STATUS
;
1160 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
1161 c
->opcode
= AVC_OPCODE_VENDOR
;
1163 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
1164 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
1165 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
1166 c
->operand
[3] = SFE_VENDOR_OPCODE_HOST2CA
;
1167 c
->operand
[4] = 0; /* slot */
1168 c
->operand
[5] = SFE_VENDOR_TAG_CA_ENTER_MENU
;
1169 clear_operands(c
, 6, 8);
1171 fdtv
->avc_data_length
= 12;
1172 ret
= avc_write(fdtv
);
1175 mutex_unlock(&fdtv
->avc_mutex
);
1180 int avc_ca_get_mmi(struct firedtv
*fdtv
, char *mmi_object
, unsigned int *len
)
1182 struct avc_command_frame
*c
= (void *)fdtv
->avc_data
;
1183 struct avc_response_frame
*r
= (void *)fdtv
->avc_data
;
1186 mutex_lock(&fdtv
->avc_mutex
);
1188 c
->ctype
= AVC_CTYPE_STATUS
;
1189 c
->subunit
= AVC_SUBUNIT_TYPE_TUNER
| fdtv
->subunit
;
1190 c
->opcode
= AVC_OPCODE_VENDOR
;
1192 c
->operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
1193 c
->operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
1194 c
->operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
1195 c
->operand
[3] = SFE_VENDOR_OPCODE_CA2HOST
;
1196 c
->operand
[4] = 0; /* slot */
1197 c
->operand
[5] = SFE_VENDOR_TAG_CA_MMI
;
1198 clear_operands(c
, 6, LAST_OPERAND
);
1200 fdtv
->avc_data_length
= 12;
1201 ret
= avc_write(fdtv
);
1206 *len
= get_ca_object_length(r
);
1207 memcpy(mmi_object
, &r
->operand
[get_ca_object_pos(r
)], *len
);
1209 mutex_unlock(&fdtv
->avc_mutex
);
1214 #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
1216 static int cmp_read(struct firedtv
*fdtv
, u64 addr
, __be32
*data
)
1220 mutex_lock(&fdtv
->avc_mutex
);
1222 ret
= fdtv
->backend
->read(fdtv
, addr
, data
);
1224 dev_err(fdtv
->device
, "CMP: read I/O error\n");
1226 mutex_unlock(&fdtv
->avc_mutex
);
1231 static int cmp_lock(struct firedtv
*fdtv
, u64 addr
, __be32 data
[])
1235 mutex_lock(&fdtv
->avc_mutex
);
1237 /* data[] is stack-allocated and should not be DMA-mapped. */
1238 memcpy(fdtv
->avc_data
, data
, 8);
1240 ret
= fdtv
->backend
->lock(fdtv
, addr
, fdtv
->avc_data
);
1242 dev_err(fdtv
->device
, "CMP: lock I/O error\n");
1244 memcpy(data
, fdtv
->avc_data
, 8);
1246 mutex_unlock(&fdtv
->avc_mutex
);
1251 static inline u32
get_opcr(__be32 opcr
, u32 mask
, u32 shift
)
1253 return (be32_to_cpu(opcr
) >> shift
) & mask
;
1256 static inline void set_opcr(__be32
*opcr
, u32 value
, u32 mask
, u32 shift
)
1258 *opcr
&= ~cpu_to_be32(mask
<< shift
);
1259 *opcr
|= cpu_to_be32((value
& mask
) << shift
);
1262 #define get_opcr_online(v) get_opcr((v), 0x1, 31)
1263 #define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
1264 #define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
1266 #define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
1267 #define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
1268 #define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
1269 #define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
1271 int cmp_establish_pp_connection(struct firedtv
*fdtv
, int plug
, int channel
)
1273 __be32 old_opcr
, opcr
[2];
1274 u64 opcr_address
= CMP_OUTPUT_PLUG_CONTROL_REG_0
+ (plug
<< 2);
1278 ret
= cmp_read(fdtv
, opcr_address
, opcr
);
1283 if (!get_opcr_online(*opcr
)) {
1284 dev_err(fdtv
->device
, "CMP: output offline\n");
1290 if (get_opcr_p2p_connections(*opcr
)) {
1291 if (get_opcr_channel(*opcr
) != channel
) {
1292 dev_err(fdtv
->device
, "CMP: cannot change channel\n");
1295 dev_info(fdtv
->device
, "CMP: overlaying connection\n");
1297 /* We don't allocate isochronous resources. */
1299 set_opcr_channel(opcr
, channel
);
1300 set_opcr_data_rate(opcr
, 2); /* S400 */
1302 set_opcr_overhead_id(opcr
, 0);
1306 set_opcr_p2p_connections(opcr
, get_opcr_p2p_connections(*opcr
) + 1);
1311 ret
= cmp_lock(fdtv
, opcr_address
, opcr
);
1315 if (old_opcr
!= *opcr
) {
1317 if (++attempts
< 6) /* arbitrary limit */
1325 void cmp_break_pp_connection(struct firedtv
*fdtv
, int plug
, int channel
)
1327 __be32 old_opcr
, opcr
[2];
1328 u64 opcr_address
= CMP_OUTPUT_PLUG_CONTROL_REG_0
+ (plug
<< 2);
1331 if (cmp_read(fdtv
, opcr_address
, opcr
) < 0)
1335 if (!get_opcr_online(*opcr
) || !get_opcr_p2p_connections(*opcr
) ||
1336 get_opcr_channel(*opcr
) != channel
) {
1337 dev_err(fdtv
->device
, "CMP: no connection to break\n");
1342 set_opcr_p2p_connections(opcr
, get_opcr_p2p_connections(*opcr
) - 1);
1347 if (cmp_lock(fdtv
, opcr_address
, opcr
) < 0)
1350 if (old_opcr
!= *opcr
) {
1352 if (++attempts
< 6) /* arbitrary limit */