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
243 if (firesat->type == FireSAT_DVB_S2) {
244 CmdFrm->operand[13] = 0x1;
245 CmdFrm->operand[14] = 0xFF;
246 CmdFrm->operand[15] = 0xFF;
252 int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) {
258 // printk(KERN_INFO "%s\n", __func__);
260 if (firesat->type == FireSAT_DVB_S || firesat->type == FireSAT_DVB_S2)
261 AVCTuner_tuneQPSK(firesat, params, &CmdFrm);
263 if(firesat->type == FireSAT_DVB_T) {
264 flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO);
265 flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO);
266 flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO);
267 flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO);
268 flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO);
269 flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO);
270 flags.Bits_T.CenterFrequency = 1;
271 flags.Bits_T.reserved1 = 0;
272 flags.Bits_T.reserved2 = 0;
273 flags.Bits_T.OtherFrequencyFlag = 0;
274 flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
275 flags.Bits_T.NetworkId = 0;
277 flags.Bits.Modulation = 0;
278 if(firesat->type == FireSAT_DVB_S) {
279 flags.Bits.FEC_inner = 1;
280 } else if(firesat->type == FireSAT_DVB_C) {
281 flags.Bits.FEC_inner = 0;
283 flags.Bits.FEC_outer = 0;
284 flags.Bits.Symbol_Rate = 1;
285 flags.Bits.Frequency = 1;
286 flags.Bits.Orbital_Pos = 0;
287 if(firesat->type == FireSAT_DVB_S) {
288 flags.Bits.Polarisation = 1;
289 } else if(firesat->type == FireSAT_DVB_C) {
290 flags.Bits.Polarisation = 0;
292 flags.Bits.reserved_fields = 0;
293 flags.Bits.reserved1 = 0;
294 flags.Bits.Network_ID = 0;
297 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
300 CmdFrm.ctype = CONTROL;
302 CmdFrm.suid = firesat->subunit;
305 CmdFrm.operand[0] = 0; // source plug
306 CmdFrm.operand[1] = 0xD2; // subfunction replace
307 CmdFrm.operand[2] = 0x20; // system id = DVB
308 CmdFrm.operand[3] = 0x00; // antenna number
309 CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
310 CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
311 CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
313 if(firesat->type == FireSAT_DVB_T) {
314 CmdFrm.operand[7] = 0x0;
315 CmdFrm.operand[8] = (params->frequency/10) >> 24;
316 CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF;
317 CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF;
318 CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
319 switch(params->u.ofdm.bandwidth) {
320 case BANDWIDTH_7_MHZ:
321 CmdFrm.operand[12] = 0x20;
323 case BANDWIDTH_8_MHZ:
324 case BANDWIDTH_6_MHZ: // not defined by AVC spec
327 CmdFrm.operand[12] = 0x00;
329 switch(params->u.ofdm.constellation) {
331 CmdFrm.operand[13] = 1 << 6;
334 CmdFrm.operand[13] = 2 << 6;
338 CmdFrm.operand[13] = 0x00;
340 switch(params->u.ofdm.hierarchy_information) {
342 CmdFrm.operand[13] |= 1 << 3;
345 CmdFrm.operand[13] |= 2 << 3;
348 CmdFrm.operand[13] |= 3 << 3;
355 switch(params->u.ofdm.code_rate_HP) {
357 CmdFrm.operand[13] |= 1;
360 CmdFrm.operand[13] |= 2;
363 CmdFrm.operand[13] |= 3;
366 CmdFrm.operand[13] |= 4;
372 switch(params->u.ofdm.code_rate_LP) {
374 CmdFrm.operand[14] = 1 << 5;
377 CmdFrm.operand[14] = 2 << 5;
380 CmdFrm.operand[14] = 3 << 5;
383 CmdFrm.operand[14] = 4 << 5;
387 CmdFrm.operand[14] = 0x00;
390 switch(params->u.ofdm.guard_interval) {
391 case GUARD_INTERVAL_1_16:
392 CmdFrm.operand[14] |= 1 << 3;
394 case GUARD_INTERVAL_1_8:
395 CmdFrm.operand[14] |= 2 << 3;
397 case GUARD_INTERVAL_1_4:
398 CmdFrm.operand[14] |= 3 << 3;
400 case GUARD_INTERVAL_1_32:
401 case GUARD_INTERVAL_AUTO:
405 switch(params->u.ofdm.transmission_mode) {
406 case TRANSMISSION_MODE_8K:
407 CmdFrm.operand[14] |= 1 << 1;
409 case TRANSMISSION_MODE_2K:
410 case TRANSMISSION_MODE_AUTO:
415 CmdFrm.operand[15] = 0x00; // network_ID[0]
416 CmdFrm.operand[16] = 0x00; // network_ID[1]
417 CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
421 CmdFrm.operand[7] = 0x00;
422 CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */
423 CmdFrm.operand[9] = 0x00;
424 CmdFrm.operand[10] = 0x00;
426 if(firesat->type == FireSAT_DVB_S) {
427 /* ### relative frequency -> absolute frequency */
428 CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
429 CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF;
430 CmdFrm.operand[13] = (params->frequency/4) & 0xFF;
431 } else if(firesat->type == FireSAT_DVB_C) {
432 CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
433 CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF;
434 CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
437 CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
438 CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
439 CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
441 CmdFrm.operand[17] = 0x00;
442 switch(params->u.qpsk.fec_inner) {
444 CmdFrm.operand[18] = 0x1;
447 CmdFrm.operand[18] = 0x2;
450 CmdFrm.operand[18] = 0x3;
453 CmdFrm.operand[18] = 0x4;
456 CmdFrm.operand[18] = 0x5;
462 CmdFrm.operand[18] = 0x0;
464 if(firesat->type == FireSAT_DVB_S) {
465 CmdFrm.operand[19] = 0x08; // modulation
466 } else if(firesat->type == FireSAT_DVB_C) {
467 switch(params->u.qam.modulation) {
469 CmdFrm.operand[19] = 0x08; // modulation
472 CmdFrm.operand[19] = 0x10; // modulation
475 CmdFrm.operand[19] = 0x18; // modulation
478 CmdFrm.operand[19] = 0x20; // modulation
481 CmdFrm.operand[19] = 0x28; // modulation
485 CmdFrm.operand[19] = 0x00; // modulation
488 CmdFrm.operand[20] = 0x00;
489 CmdFrm.operand[21] = 0x00;
490 CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
494 } // AVCTuner_DSD_direct
496 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
503 *status=RspFrm.operand[2];
507 int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
512 printk(KERN_INFO "%s\n", __func__);
514 if(pidc > 16 && pidc != 0xFF)
517 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
520 CmdFrm.ctype = CONTROL;
522 CmdFrm.suid = firesat->subunit;
525 CmdFrm.operand[0] = 0; // source plug
526 CmdFrm.operand[1] = 0xD2; // subfunction replace
527 CmdFrm.operand[2] = 0x20; // system id = DVB
528 CmdFrm.operand[3] = 0x00; // antenna number
529 CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length
530 CmdFrm.operand[5] = 0x00; // valid_flags [0]
531 CmdFrm.operand[6] = 0x00; // valid_flags [1]
533 if(firesat->type == FireSAT_DVB_T) {
534 /* CmdFrm.operand[7] = 0x00;
535 CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24;
536 CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF;
537 CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF;
538 CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF;
539 CmdFrm.operand[12] = 0x00;
540 CmdFrm.operand[13] = 0x00;
541 CmdFrm.operand[14] = 0x00;
543 CmdFrm.operand[15] = 0x00; // network_ID[0]
544 CmdFrm.operand[16] = 0x00; // network_ID[1]
545 */ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs
549 /* CmdFrm.operand[7] = 0x00;
550 CmdFrm.operand[8] = 0x00;
551 CmdFrm.operand[9] = 0x00;
552 CmdFrm.operand[10] = 0x00;
554 CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
555 CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF;
556 CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF;
558 CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
559 CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
560 CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
562 CmdFrm.operand[17] = 0x00;
563 CmdFrm.operand[18] = 0x00;
564 CmdFrm.operand[19] = 0x00; // modulation
565 CmdFrm.operand[20] = 0x00;
566 CmdFrm.operand[21] = 0x00;*/
567 CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs
572 for(k=0;k<pidc;k++) {
573 CmdFrm.operand[pos++] = 0x13; // flowfunction relay
574 CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
575 CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F;
576 CmdFrm.operand[pos++] = pid[k] & 0xFF;
577 CmdFrm.operand[pos++] = 0x00; // tableID
578 CmdFrm.operand[pos++] = 0x00; // filter_length
581 CmdFrm.length = pos+3;
584 CmdFrm.length += 4 - ((pos+3)%4);
586 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
594 int AVCTuner_GetTS(struct firesat *firesat){
599 printk(KERN_INFO "%s\n", __func__);
601 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
604 CmdFrm.ctype = CONTROL;
606 CmdFrm.suid = firesat->subunit;
607 CmdFrm.opcode = DSIT;
609 CmdFrm.operand[0] = 0; // source plug
610 CmdFrm.operand[1] = 0xD2; // subfunction replace
611 CmdFrm.operand[2] = 0xFF; //status
612 CmdFrm.operand[3] = 0x20; // system id = DVB
613 CmdFrm.operand[4] = 0x00; // antenna number
614 CmdFrm.operand[5] = 0x0; // system_specific_search_flags
615 CmdFrm.operand[6] = 0x11; // system_specific_multiplex selection_length
616 CmdFrm.operand[7] = 0x00; // valid_flags [0]
617 CmdFrm.operand[8] = 0x00; // valid_flags [1]
618 CmdFrm.operand[24] = 0x00; // nr_of_dsit_sel_specs (always 0)
622 if((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) return k;
628 int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) {
632 memset(&CmdFrm,0,sizeof(AVCCmdFrm));
635 CmdFrm.ctype = CONTROL;
636 CmdFrm.sutyp = 0x5; // tuner
637 CmdFrm.suid = firesat->subunit;
638 CmdFrm.opcode = READ_DESCRIPTOR;
640 CmdFrm.operand[0]=DESCRIPTOR_SUBUNIT_IDENTIFIER;
641 CmdFrm.operand[1]=0xff;
642 CmdFrm.operand[2]=0x00;
643 CmdFrm.operand[3]=0x00; // length highbyte
644 CmdFrm.operand[4]=0x08; // length lowbyte
645 CmdFrm.operand[5]=0x00; // offset highbyte
646 CmdFrm.operand[6]=0x0d; // offset lowbyte
650 if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0)
653 if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
654 printk("%s: AVCWrite returned error code %d\n",__func__,RspFrm.resp);
657 if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) {
658 printk("%s: Invalid response length\n",__func__);
662 *systemId = RspFrm.operand[7];
664 *has_ci = (RspFrm.operand[14] >> 4) & 0x1;
668 int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) {
673 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
676 CmdFrm.ctype=CONTROL;
677 CmdFrm.sutyp=0x05; // tuner
678 CmdFrm.suid=firesat->subunit;
679 CmdFrm.opcode=READ_DESCRIPTOR;
681 CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
682 CmdFrm.operand[1]=0xff;
683 CmdFrm.operand[2]=0x00;
684 CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8;
685 CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF;
686 CmdFrm.operand[5]=0x00;
687 CmdFrm.operand[6]=0x03;
689 //Absenden des AVC request und warten auf response
690 if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
693 if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
694 printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp);
698 length = (RspFrm.operand[3] << 8) + RspFrm.operand[4];
699 if(length == sizeof(ANTENNA_INPUT_INFO))
701 memcpy(antenna_input_info,&RspFrm.operand[7],length);
704 printk("%s: invalid info returned from AVC\n",__func__);
708 int AVCLNBControl(struct firesat *firesat, char voltage, char burst,
709 char conttone, char nrdiseq,
710 struct dvb_diseqc_master_cmd *diseqcmd)
716 printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",__func__,voltage,burst,conttone);
718 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
721 CmdFrm.ctype=CONTROL;
723 CmdFrm.suid=firesat->subunit;
724 CmdFrm.opcode=VENDOR;
726 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
727 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
728 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
729 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_LNB_CONTROL;
731 CmdFrm.operand[4]=voltage;
732 CmdFrm.operand[5]=nrdiseq;
736 for(j=0;j<nrdiseq;j++) {
738 printk(KERN_INFO "%s: diseq %d len %x\n",__func__,j,diseqcmd[j].msg_len);
739 CmdFrm.operand[i++]=diseqcmd[j].msg_len;
741 for(k=0;k<diseqcmd[j].msg_len;k++) {
742 printk(KERN_INFO "%s: diseq %d msg[%d] = %x\n",__func__,j,k,diseqcmd[j].msg[k]);
743 CmdFrm.operand[i++]=diseqcmd[j].msg[k];
747 CmdFrm.operand[i++]=burst;
748 CmdFrm.operand[i++]=conttone;
752 CmdFrm.length += 4 - ((i+3)%4);
754 /* for(j=0;j<CmdFrm.length;j++)
755 printk(KERN_INFO "%s: CmdFrm.operand[%d]=0x%x\n",__func__,j,CmdFrm.operand[j]);
757 printk(KERN_INFO "%s: cmdfrm.length = %u\n",__func__,CmdFrm.length);
759 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
762 if(RspFrm.resp != ACCEPTED) {
763 printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp);
770 int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount)
775 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
778 CmdFrm.ctype = STATUS;
781 CmdFrm.opcode = SUBUNIT_Info;
783 CmdFrm.operand[0] = 0x07;
784 CmdFrm.operand[1] = 0xff;
785 CmdFrm.operand[2] = 0xff;
786 CmdFrm.operand[3] = 0xff;
787 CmdFrm.operand[4] = 0xff;
791 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
794 if(RspFrm.resp != STABLE) {
795 printk("%s: AVCWrite returned code %d\n",__func__,RspFrm.resp);
800 *subunitcount = (RspFrm.operand[1] & 0x7) + 1;
805 static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal)
809 // printk(KERN_INFO "%s\n",__func__);
811 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
814 CmdFrm.ctype = NOTIFY;
817 CmdFrm.opcode = VENDOR;
819 CmdFrm.operand[0] = SFE_VENDOR_DE_COMPANYID_0;
820 CmdFrm.operand[1] = SFE_VENDOR_DE_COMPANYID_1;
821 CmdFrm.operand[2] = SFE_VENDOR_DE_COMPANYID_2;
822 CmdFrm.operand[3] = SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL;
827 if(__AVCWrite(firesat,&CmdFrm,NULL) < 0)
830 if(AVCWrite(firesat,&CmdFrm,NULL) < 0)
836 int AVCRegisterRemoteControl(struct firesat*firesat)
838 return __AVCRegisterRemoteControl(firesat, 0);