4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (c) 2008 Ben Backx <ben@bbackx.com>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
14 #include <ieee1394_transactions.h>
16 #include <asm/byteorder.h>
17 #include <linux/delay.h>
19 #include "firesat-rc.h"
21 #define RESPONSE_REGISTER 0xFFFFF0000D00ULL
22 #define COMMAND_REGISTER 0xFFFFF0000B00ULL
23 #define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
25 static int __AVCRegisterRemoteControl(struct firesat
*firesat
, int internal
);
27 /* Frees an allocated packet */
28 static void avc_free_packet(struct hpsb_packet
*packet
)
30 hpsb_free_tlabel(packet
);
31 hpsb_free_packet(packet
);
35 * Goofy routine that basically does a down_timeout function.
38 static int avc_down_timeout(atomic_t
*done
, int timeout
)
42 for (i
= timeout
; (i
> 0 && atomic_read(done
) == 0); i
-= HZ
/10) {
43 set_current_state(TASK_INTERRUPTIBLE
);
44 if (schedule_timeout(HZ
/10)) /* 100ms */
47 return ((i
> 0) ? 0:1);
50 static int __AVCWrite(struct firesat
*firesat
, const AVCCmdFrm
*CmdFrm
, AVCRspFrm
*RspFrm
) {
51 struct hpsb_packet
*packet
;
52 struct node_entry
*ne
;
54 ne
= firesat
->nodeentry
;
56 printk("%s: lost node!\n",__func__
);
60 /* need all input data */
61 if(!firesat
|| !ne
|| !CmdFrm
)
64 // printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode);
66 // for(k=0;k<CmdFrm->length;k++)
67 // printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]);
69 packet
=hpsb_make_writepacket(ne
->host
, ne
->nodeid
, COMMAND_REGISTER
,
70 (quadlet_t
*)CmdFrm
, CmdFrm
->length
);
72 hpsb_set_packet_complete_task(packet
, (void (*)(void*))avc_free_packet
,
75 hpsb_node_fill_packet(ne
, packet
);
78 atomic_set(&firesat
->avc_reply_received
, 0);
80 if (hpsb_send_packet(packet
) < 0) {
81 avc_free_packet(packet
);
82 atomic_set(&firesat
->avc_reply_received
, 1);
87 if(avc_down_timeout(&firesat
->avc_reply_received
,HZ
/2)) {
88 printk("%s: timeout waiting for avc response\n",__func__
);
89 atomic_set(&firesat
->avc_reply_received
, 1);
93 memcpy(RspFrm
,firesat
->respfrm
,firesat
->resp_length
);
99 int AVCWrite(struct firesat
*firesat
, const AVCCmdFrm
*CmdFrm
, AVCRspFrm
*RspFrm
) {
101 if(down_interruptible(&firesat
->avc_sem
))
104 ret
= __AVCWrite(firesat
, CmdFrm
, RspFrm
);
106 up(&firesat
->avc_sem
);
110 static void do_schedule_remotecontrol(unsigned long ignored
);
111 DECLARE_TASKLET(schedule_remotecontrol
, do_schedule_remotecontrol
, 0);
113 static void do_schedule_remotecontrol(unsigned long ignored
) {
114 struct firesat
*firesat
;
117 spin_lock_irqsave(&firesat_list_lock
, flags
);
118 list_for_each_entry(firesat
,&firesat_list
,list
) {
119 if(atomic_read(&firesat
->reschedule_remotecontrol
) == 1) {
120 if(down_trylock(&firesat
->avc_sem
))
121 tasklet_schedule(&schedule_remotecontrol
);
123 if(__AVCRegisterRemoteControl(firesat
, 1) == 0)
124 atomic_set(&firesat
->reschedule_remotecontrol
, 0);
126 tasklet_schedule(&schedule_remotecontrol
);
128 up(&firesat
->avc_sem
);
132 spin_unlock_irqrestore(&firesat_list_lock
, flags
);
135 int AVCRecv(struct firesat
*firesat
, u8
*data
, size_t length
) {
136 // printk(KERN_INFO "%s\n",__func__);
138 // remote control handling
140 AVCRspFrm
*RspFrm
= (AVCRspFrm
*)data
;
142 if(/*RspFrm->length >= 8 && ###*/
143 ((RspFrm
->operand
[0] == SFE_VENDOR_DE_COMPANYID_0
&&
144 RspFrm
->operand
[1] == SFE_VENDOR_DE_COMPANYID_1
&&
145 RspFrm
->operand
[2] == SFE_VENDOR_DE_COMPANYID_2
)) &&
146 RspFrm
->operand
[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL
) {
147 if(RspFrm
->resp
== CHANGED
) {
148 // printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]);
149 firesat_got_remotecontrolcode((((u16
)RspFrm
->operand
[4]) << 8) | ((u16
)RspFrm
->operand
[5]));
152 atomic_set(&firesat
->reschedule_remotecontrol
, 1);
153 tasklet_schedule(&schedule_remotecontrol
);
154 } else if(RspFrm
->resp
!= INTERIM
)
155 printk(KERN_INFO
"%s: remote control result = %d\n",__func__
, RspFrm
->resp
);
159 if(atomic_read(&firesat
->avc_reply_received
) == 1) {
160 printk("%s: received out-of-order AVC response, ignored\n",__func__
);
163 // AVCRspFrm *resp=(AVCRspFrm *)data;
166 printk(KERN_INFO "resp=0x%x\n",resp->resp);
167 printk(KERN_INFO "cts=0x%x\n",resp->cts);
168 printk(KERN_INFO "suid=0x%x\n",resp->suid);
169 printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
170 printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
171 printk(KERN_INFO "length=%d\n",resp->length);
174 // printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
176 memcpy(firesat
->respfrm
,data
,length
);
177 firesat
->resp_length
=length
;
179 atomic_set(&firesat
->avc_reply_received
, 1);
184 // tuning command for setting the relative LNB frequency (not supported by the AVC standard)
185 static void AVCTuner_tuneQPSK(struct firesat
*firesat
, struct dvb_frontend_parameters
*params
, AVCCmdFrm
*CmdFrm
) {
186 memset(CmdFrm
, 0, sizeof(AVCCmdFrm
));
189 CmdFrm
->ctype
= CONTROL
;
191 CmdFrm
->suid
= firesat
->subunit
;
192 CmdFrm
->opcode
= VENDOR
;
194 CmdFrm
->operand
[0]=SFE_VENDOR_DE_COMPANYID_0
;
195 CmdFrm
->operand
[1]=SFE_VENDOR_DE_COMPANYID_1
;
196 CmdFrm
->operand
[2]=SFE_VENDOR_DE_COMPANYID_2
;
197 CmdFrm
->operand
[3]=SFE_VENDOR_OPCODE_TUNE_QPSK
;
199 printk(KERN_INFO
"%s: tuning to frequency %u\n",__func__
,params
->frequency
);
201 CmdFrm
->operand
[4] = (params
->frequency
>> 24) & 0xFF;
202 CmdFrm
->operand
[5] = (params
->frequency
>> 16) & 0xFF;
203 CmdFrm
->operand
[6] = (params
->frequency
>> 8) & 0xFF;
204 CmdFrm
->operand
[7] = params
->frequency
& 0xFF;
206 printk(KERN_INFO
"%s: symbol rate = %uBd\n",__func__
,params
->u
.qpsk
.symbol_rate
);
208 CmdFrm
->operand
[8] = ((params
->u
.qpsk
.symbol_rate
/1000) >> 8) & 0xFF;
209 CmdFrm
->operand
[9] = (params
->u
.qpsk
.symbol_rate
/1000) & 0xFF;
211 switch(params
->u
.qpsk
.fec_inner
) {
213 CmdFrm
->operand
[10] = 0x1;
216 CmdFrm
->operand
[10] = 0x2;
219 CmdFrm
->operand
[10] = 0x3;
222 CmdFrm
->operand
[10] = 0x4;
225 CmdFrm
->operand
[10] = 0x5;
231 CmdFrm
->operand
[10] = 0x0;
234 if(firesat
->voltage
== 0xff)
235 CmdFrm
->operand
[11] = 0xff;
237 CmdFrm
->operand
[11] = (firesat
->voltage
==SEC_VOLTAGE_18
)?0:1; // polarisation
238 if(firesat
->tone
== 0xff)
239 CmdFrm
->operand
[12] = 0xff;
241 CmdFrm
->operand
[12] = (firesat
->tone
==SEC_TONE_ON
)?1:0; // band
246 int AVCTuner_DSD(struct firesat
*firesat
, struct dvb_frontend_parameters
*params
, BYTE
*status
) {
252 // printk(KERN_INFO "%s\n", __func__);
254 if(firesat
->type
== FireSAT_DVB_S
)
255 AVCTuner_tuneQPSK(firesat
, params
, &CmdFrm
);
257 if(firesat
->type
== FireSAT_DVB_T
) {
258 flags
.Bits_T
.GuardInterval
= (params
->u
.ofdm
.guard_interval
!= GUARD_INTERVAL_AUTO
);
259 flags
.Bits_T
.CodeRateLPStream
= (params
->u
.ofdm
.code_rate_LP
!= FEC_AUTO
);
260 flags
.Bits_T
.CodeRateHPStream
= (params
->u
.ofdm
.code_rate_HP
!= FEC_AUTO
);
261 flags
.Bits_T
.HierarchyInfo
= (params
->u
.ofdm
.hierarchy_information
!= HIERARCHY_AUTO
);
262 flags
.Bits_T
.Constellation
= (params
->u
.ofdm
.constellation
!= QAM_AUTO
);
263 flags
.Bits_T
.Bandwidth
= (params
->u
.ofdm
.bandwidth
!= BANDWIDTH_AUTO
);
264 flags
.Bits_T
.CenterFrequency
= 1;
265 flags
.Bits_T
.reserved1
= 0;
266 flags
.Bits_T
.reserved2
= 0;
267 flags
.Bits_T
.OtherFrequencyFlag
= 0;
268 flags
.Bits_T
.TransmissionMode
= (params
->u
.ofdm
.transmission_mode
!= TRANSMISSION_MODE_AUTO
);
269 flags
.Bits_T
.NetworkId
= 0;
271 flags
.Bits
.Modulation
= 0;
272 if(firesat
->type
== FireSAT_DVB_S
) {
273 flags
.Bits
.FEC_inner
= 1;
274 } else if(firesat
->type
== FireSAT_DVB_C
) {
275 flags
.Bits
.FEC_inner
= 0;
277 flags
.Bits
.FEC_outer
= 0;
278 flags
.Bits
.Symbol_Rate
= 1;
279 flags
.Bits
.Frequency
= 1;
280 flags
.Bits
.Orbital_Pos
= 0;
281 if(firesat
->type
== FireSAT_DVB_S
) {
282 flags
.Bits
.Polarisation
= 1;
283 } else if(firesat
->type
== FireSAT_DVB_C
) {
284 flags
.Bits
.Polarisation
= 0;
286 flags
.Bits
.reserved_fields
= 0;
287 flags
.Bits
.reserved1
= 0;
288 flags
.Bits
.Network_ID
= 0;
291 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
294 CmdFrm
.ctype
= CONTROL
;
296 CmdFrm
.suid
= firesat
->subunit
;
299 CmdFrm
.operand
[0] = 0; // source plug
300 CmdFrm
.operand
[1] = 0xD2; // subfunction replace
301 CmdFrm
.operand
[2] = 0x20; // system id = DVB
302 CmdFrm
.operand
[3] = 0x00; // antenna number
303 CmdFrm
.operand
[4] = (firesat
->type
== FireSAT_DVB_T
)?0x0c:0x11; // system_specific_multiplex selection_length
304 CmdFrm
.operand
[5] = flags
.Valid_Word
.ByteHi
; // valid_flags [0]
305 CmdFrm
.operand
[6] = flags
.Valid_Word
.ByteLo
; // valid_flags [1]
307 if(firesat
->type
== FireSAT_DVB_T
) {
308 CmdFrm
.operand
[7] = 0x0;
309 CmdFrm
.operand
[8] = (params
->frequency
/10) >> 24;
310 CmdFrm
.operand
[9] = ((params
->frequency
/10) >> 16) & 0xFF;
311 CmdFrm
.operand
[10] = ((params
->frequency
/10) >> 8) & 0xFF;
312 CmdFrm
.operand
[11] = (params
->frequency
/10) & 0xFF;
313 switch(params
->u
.ofdm
.bandwidth
) {
314 case BANDWIDTH_7_MHZ
:
315 CmdFrm
.operand
[12] = 0x20;
317 case BANDWIDTH_8_MHZ
:
318 case BANDWIDTH_6_MHZ
: // not defined by AVC spec
321 CmdFrm
.operand
[12] = 0x00;
323 switch(params
->u
.ofdm
.constellation
) {
325 CmdFrm
.operand
[13] = 1 << 6;
328 CmdFrm
.operand
[13] = 2 << 6;
332 CmdFrm
.operand
[13] = 0x00;
334 switch(params
->u
.ofdm
.hierarchy_information
) {
336 CmdFrm
.operand
[13] |= 1 << 3;
339 CmdFrm
.operand
[13] |= 2 << 3;
342 CmdFrm
.operand
[13] |= 3 << 3;
349 switch(params
->u
.ofdm
.code_rate_HP
) {
351 CmdFrm
.operand
[13] |= 1;
354 CmdFrm
.operand
[13] |= 2;
357 CmdFrm
.operand
[13] |= 3;
360 CmdFrm
.operand
[13] |= 4;
366 switch(params
->u
.ofdm
.code_rate_LP
) {
368 CmdFrm
.operand
[14] = 1 << 5;
371 CmdFrm
.operand
[14] = 2 << 5;
374 CmdFrm
.operand
[14] = 3 << 5;
377 CmdFrm
.operand
[14] = 4 << 5;
381 CmdFrm
.operand
[14] = 0x00;
384 switch(params
->u
.ofdm
.guard_interval
) {
385 case GUARD_INTERVAL_1_16
:
386 CmdFrm
.operand
[14] |= 1 << 3;
388 case GUARD_INTERVAL_1_8
:
389 CmdFrm
.operand
[14] |= 2 << 3;
391 case GUARD_INTERVAL_1_4
:
392 CmdFrm
.operand
[14] |= 3 << 3;
394 case GUARD_INTERVAL_1_32
:
395 case GUARD_INTERVAL_AUTO
:
399 switch(params
->u
.ofdm
.transmission_mode
) {
400 case TRANSMISSION_MODE_8K
:
401 CmdFrm
.operand
[14] |= 1 << 1;
403 case TRANSMISSION_MODE_2K
:
404 case TRANSMISSION_MODE_AUTO
:
409 CmdFrm
.operand
[15] = 0x00; // network_ID[0]
410 CmdFrm
.operand
[16] = 0x00; // network_ID[1]
411 CmdFrm
.operand
[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
415 CmdFrm
.operand
[7] = 0x00;
416 CmdFrm
.operand
[8] = (((firesat
->voltage
==SEC_VOLTAGE_18
)?0:1)<<6); /* 0 = H, 1 = V */
417 CmdFrm
.operand
[9] = 0x00;
418 CmdFrm
.operand
[10] = 0x00;
420 if(firesat
->type
== FireSAT_DVB_S
) {
421 /* ### relative frequency -> absolute frequency */
422 CmdFrm
.operand
[11] = (((params
->frequency
/4) >> 16) & 0xFF) | (2 << 6);
423 CmdFrm
.operand
[12] = ((params
->frequency
/4) >> 8) & 0xFF;
424 CmdFrm
.operand
[13] = (params
->frequency
/4) & 0xFF;
425 } else if(firesat
->type
== FireSAT_DVB_C
) {
426 CmdFrm
.operand
[11] = (((params
->frequency
/4000) >> 16) & 0xFF) | (2 << 6);
427 CmdFrm
.operand
[12] = ((params
->frequency
/4000) >> 8) & 0xFF;
428 CmdFrm
.operand
[13] = (params
->frequency
/4000) & 0xFF;
431 CmdFrm
.operand
[14] = ((params
->u
.qpsk
.symbol_rate
/1000) >> 12) & 0xFF;
432 CmdFrm
.operand
[15] = ((params
->u
.qpsk
.symbol_rate
/1000) >> 4) & 0xFF;
433 CmdFrm
.operand
[16] = ((params
->u
.qpsk
.symbol_rate
/1000) << 4) & 0xF0;
435 CmdFrm
.operand
[17] = 0x00;
436 switch(params
->u
.qpsk
.fec_inner
) {
438 CmdFrm
.operand
[18] = 0x1;
441 CmdFrm
.operand
[18] = 0x2;
444 CmdFrm
.operand
[18] = 0x3;
447 CmdFrm
.operand
[18] = 0x4;
450 CmdFrm
.operand
[18] = 0x5;
456 CmdFrm
.operand
[18] = 0x0;
458 if(firesat
->type
== FireSAT_DVB_S
) {
459 CmdFrm
.operand
[19] = 0x08; // modulation
460 } else if(firesat
->type
== FireSAT_DVB_C
) {
461 switch(params
->u
.qam
.modulation
) {
463 CmdFrm
.operand
[19] = 0x08; // modulation
466 CmdFrm
.operand
[19] = 0x10; // modulation
469 CmdFrm
.operand
[19] = 0x18; // modulation
472 CmdFrm
.operand
[19] = 0x20; // modulation
475 CmdFrm
.operand
[19] = 0x28; // modulation
479 CmdFrm
.operand
[19] = 0x00; // modulation
482 CmdFrm
.operand
[20] = 0x00;
483 CmdFrm
.operand
[21] = 0x00;
484 CmdFrm
.operand
[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
488 } // AVCTuner_DSD_direct
490 if((k
=AVCWrite(firesat
,&CmdFrm
,&RspFrm
)))
497 *status
=RspFrm
.operand
[2];
501 int AVCTuner_SetPIDs(struct firesat
*firesat
, unsigned char pidc
, u16 pid
[]) {
506 printk(KERN_INFO
"%s\n", __func__
);
508 if(pidc
> 16 && pidc
!= 0xFF)
511 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
514 CmdFrm
.ctype
= CONTROL
;
516 CmdFrm
.suid
= firesat
->subunit
;
519 CmdFrm
.operand
[0] = 0; // source plug
520 CmdFrm
.operand
[1] = 0xD2; // subfunction replace
521 CmdFrm
.operand
[2] = 0x20; // system id = DVB
522 CmdFrm
.operand
[3] = 0x00; // antenna number
523 CmdFrm
.operand
[4] = 0x11; // system_specific_multiplex selection_length
524 CmdFrm
.operand
[5] = 0x00; // valid_flags [0]
525 CmdFrm
.operand
[6] = 0x00; // valid_flags [1]
527 if(firesat
->type
== FireSAT_DVB_T
) {
528 /* CmdFrm.operand[7] = 0x00;
529 CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24;
530 CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF;
531 CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF;
532 CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF;
533 CmdFrm.operand[12] = 0x00;
534 CmdFrm.operand[13] = 0x00;
535 CmdFrm.operand[14] = 0x00;
537 CmdFrm.operand[15] = 0x00; // network_ID[0]
538 CmdFrm.operand[16] = 0x00; // network_ID[1]
539 */ CmdFrm
.operand
[17] = pidc
; // Nr_of_dsd_sel_specs
543 /* CmdFrm.operand[7] = 0x00;
544 CmdFrm.operand[8] = 0x00;
545 CmdFrm.operand[9] = 0x00;
546 CmdFrm.operand[10] = 0x00;
548 CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
549 CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF;
550 CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF;
552 CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
553 CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
554 CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
556 CmdFrm.operand[17] = 0x00;
557 CmdFrm.operand[18] = 0x00;
558 CmdFrm.operand[19] = 0x00; // modulation
559 CmdFrm.operand[20] = 0x00;
560 CmdFrm.operand[21] = 0x00;*/
561 CmdFrm
.operand
[22] = pidc
; // Nr_of_dsd_sel_specs
566 for(k
=0;k
<pidc
;k
++) {
567 CmdFrm
.operand
[pos
++] = 0x13; // flowfunction relay
568 CmdFrm
.operand
[pos
++] = 0x80; // dsd_sel_spec_valid_flags -> PID
569 CmdFrm
.operand
[pos
++] = (pid
[k
] >> 8) & 0x1F;
570 CmdFrm
.operand
[pos
++] = pid
[k
] & 0xFF;
571 CmdFrm
.operand
[pos
++] = 0x00; // tableID
572 CmdFrm
.operand
[pos
++] = 0x00; // filter_length
575 CmdFrm
.length
= pos
+3;
578 CmdFrm
.length
+= 4 - ((pos
+3)%4);
580 if((k
=AVCWrite(firesat
,&CmdFrm
,&RspFrm
)))
588 int AVCTuner_GetTS(struct firesat
*firesat
){
593 printk(KERN_INFO
"%s\n", __func__
);
595 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
598 CmdFrm
.ctype
= CONTROL
;
600 CmdFrm
.suid
= firesat
->subunit
;
601 CmdFrm
.opcode
= DSIT
;
603 CmdFrm
.operand
[0] = 0; // source plug
604 CmdFrm
.operand
[1] = 0xD2; // subfunction replace
605 CmdFrm
.operand
[2] = 0xFF; //status
606 CmdFrm
.operand
[3] = 0x20; // system id = DVB
607 CmdFrm
.operand
[4] = 0x00; // antenna number
608 CmdFrm
.operand
[5] = 0x0; // system_specific_search_flags
609 CmdFrm
.operand
[6] = 0x11; // system_specific_multiplex selection_length
610 CmdFrm
.operand
[7] = 0x00; // valid_flags [0]
611 CmdFrm
.operand
[8] = 0x00; // valid_flags [1]
612 CmdFrm
.operand
[24] = 0x00; // nr_of_dsit_sel_specs (always 0)
616 if((k
=AVCWrite(firesat
, &CmdFrm
, &RspFrm
))) return k
;
622 int AVCIdentifySubunit(struct firesat
*firesat
, unsigned char *systemId
, int *transport
, int *has_ci
) {
626 memset(&CmdFrm
,0,sizeof(AVCCmdFrm
));
629 CmdFrm
.ctype
= CONTROL
;
630 CmdFrm
.sutyp
= 0x5; // tuner
631 CmdFrm
.suid
= firesat
->subunit
;
632 CmdFrm
.opcode
= READ_DESCRIPTOR
;
634 CmdFrm
.operand
[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER
;
635 CmdFrm
.operand
[1]=0xff;
636 CmdFrm
.operand
[2]=0x00;
637 CmdFrm
.operand
[3]=0x00; // length highbyte
638 CmdFrm
.operand
[4]=0x08; // length lowbyte
639 CmdFrm
.operand
[5]=0x00; // offset highbyte
640 CmdFrm
.operand
[6]=0x0d; // offset lowbyte
644 if(AVCWrite(firesat
,&CmdFrm
,&RspFrm
)<0)
647 if(RspFrm
.resp
!= STABLE
&& RspFrm
.resp
!= ACCEPTED
) {
648 printk("%s: AVCWrite returned error code %d\n",__func__
,RspFrm
.resp
);
651 if(((RspFrm
.operand
[3] << 8) + RspFrm
.operand
[4]) != 8) {
652 printk("%s: Invalid response length\n",__func__
);
656 *systemId
= RspFrm
.operand
[7];
658 *transport
= RspFrm
.operand
[14] & 0x7;
659 switch(RspFrm
.operand
[14] & 0x7) {
661 printk(KERN_INFO
"%s: found DVB/S\n",__func__
);
664 printk(KERN_INFO
"%s: found DVB/C\n",__func__
);
667 printk(KERN_INFO
"%s: found DVB/T\n",__func__
);
670 printk(KERN_INFO
"%s: found unknown tuner id %u\n",__func__
,RspFrm
.operand
[14] & 0x7);
673 *has_ci
= (RspFrm
.operand
[14] >> 4) & 0x1;
677 int AVCTunerStatus(struct firesat
*firesat
, ANTENNA_INPUT_INFO
*antenna_input_info
) {
682 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
685 CmdFrm
.ctype
=CONTROL
;
686 CmdFrm
.sutyp
=0x05; // tuner
687 CmdFrm
.suid
=firesat
->subunit
;
688 CmdFrm
.opcode
=READ_DESCRIPTOR
;
690 CmdFrm
.operand
[0]=DESCRIPTOR_TUNER_STATUS
;
691 CmdFrm
.operand
[1]=0xff;
692 CmdFrm
.operand
[2]=0x00;
693 CmdFrm
.operand
[3]=sizeof(ANTENNA_INPUT_INFO
) >> 8;
694 CmdFrm
.operand
[4]=sizeof(ANTENNA_INPUT_INFO
) & 0xFF;
695 CmdFrm
.operand
[5]=0x00;
696 CmdFrm
.operand
[6]=0x03;
698 //Absenden des AVC request und warten auf response
699 if (AVCWrite(firesat
,&CmdFrm
,&RspFrm
) < 0)
702 if(RspFrm
.resp
!= STABLE
&& RspFrm
.resp
!= ACCEPTED
) {
703 printk("%s: AVCWrite returned code %d\n",__func__
,RspFrm
.resp
);
707 length
= (RspFrm
.operand
[3] << 8) + RspFrm
.operand
[4];
708 if(length
== sizeof(ANTENNA_INPUT_INFO
))
710 memcpy(antenna_input_info
,&RspFrm
.operand
[7],length
);
713 printk("%s: invalid info returned from AVC\n",__func__
);
717 int AVCLNBControl(struct firesat
*firesat
, char voltage
, char burst
,
718 char conttone
, char nrdiseq
,
719 struct dvb_diseqc_master_cmd
*diseqcmd
)
725 printk(KERN_INFO
"%s: voltage = %x, burst = %x, conttone = %x\n",__func__
,voltage
,burst
,conttone
);
727 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
730 CmdFrm
.ctype
=CONTROL
;
732 CmdFrm
.suid
=firesat
->subunit
;
733 CmdFrm
.opcode
=VENDOR
;
735 CmdFrm
.operand
[0]=SFE_VENDOR_DE_COMPANYID_0
;
736 CmdFrm
.operand
[1]=SFE_VENDOR_DE_COMPANYID_1
;
737 CmdFrm
.operand
[2]=SFE_VENDOR_DE_COMPANYID_2
;
738 CmdFrm
.operand
[3]=SFE_VENDOR_OPCODE_LNB_CONTROL
;
740 CmdFrm
.operand
[4]=voltage
;
741 CmdFrm
.operand
[5]=nrdiseq
;
745 for(j
=0;j
<nrdiseq
;j
++) {
747 printk(KERN_INFO
"%s: diseq %d len %x\n",__func__
,j
,diseqcmd
[j
].msg_len
);
748 CmdFrm
.operand
[i
++]=diseqcmd
[j
].msg_len
;
750 for(k
=0;k
<diseqcmd
[j
].msg_len
;k
++) {
751 printk(KERN_INFO
"%s: diseq %d msg[%d] = %x\n",__func__
,j
,k
,diseqcmd
[j
].msg
[k
]);
752 CmdFrm
.operand
[i
++]=diseqcmd
[j
].msg
[k
];
756 CmdFrm
.operand
[i
++]=burst
;
757 CmdFrm
.operand
[i
++]=conttone
;
761 CmdFrm
.length
+= 4 - ((i
+3)%4);
763 /* for(j=0;j<CmdFrm.length;j++)
764 printk(KERN_INFO "%s: CmdFrm.operand[%d]=0x%x\n",__func__,j,CmdFrm.operand[j]);
766 printk(KERN_INFO "%s: cmdfrm.length = %u\n",__func__,CmdFrm.length);
768 if(AVCWrite(firesat
,&CmdFrm
,&RspFrm
) < 0)
771 if(RspFrm
.resp
!= ACCEPTED
) {
772 printk("%s: AVCWrite returned code %d\n",__func__
,RspFrm
.resp
);
779 int AVCSubUnitInfo(struct firesat
*firesat
, char *subunitcount
)
784 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
787 CmdFrm
.ctype
= STATUS
;
790 CmdFrm
.opcode
= SUBUNIT_Info
;
792 CmdFrm
.operand
[0] = 0x07;
793 CmdFrm
.operand
[1] = 0xff;
794 CmdFrm
.operand
[2] = 0xff;
795 CmdFrm
.operand
[3] = 0xff;
796 CmdFrm
.operand
[4] = 0xff;
800 if(AVCWrite(firesat
,&CmdFrm
,&RspFrm
) < 0)
803 if(RspFrm
.resp
!= STABLE
) {
804 printk("%s: AVCWrite returned code %d\n",__func__
,RspFrm
.resp
);
809 *subunitcount
= (RspFrm
.operand
[1] & 0x7) + 1;
814 static int __AVCRegisterRemoteControl(struct firesat
*firesat
, int internal
)
818 // printk(KERN_INFO "%s\n",__func__);
820 memset(&CmdFrm
, 0, sizeof(AVCCmdFrm
));
823 CmdFrm
.ctype
= NOTIFY
;
826 CmdFrm
.opcode
= VENDOR
;
828 CmdFrm
.operand
[0] = SFE_VENDOR_DE_COMPANYID_0
;
829 CmdFrm
.operand
[1] = SFE_VENDOR_DE_COMPANYID_1
;
830 CmdFrm
.operand
[2] = SFE_VENDOR_DE_COMPANYID_2
;
831 CmdFrm
.operand
[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL
;
836 if(__AVCWrite(firesat
,&CmdFrm
,NULL
) < 0)
839 if(AVCWrite(firesat
,&CmdFrm
,NULL
) < 0)
845 int AVCRegisterRemoteControl(struct firesat
*firesat
)
847 return __AVCRegisterRemoteControl(firesat
, 0);