aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHenrik Kurelid <henke@kurelid.se>2008-08-01 04:00:45 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-02-24 08:51:26 -0500
commitdf4846c35247a0d038c5359d502cddd59d04bc40 (patch)
tree40c58c28c389f238e3d26230f264782e8f4bcb1e /drivers
parent2c22861459f094e899c034515a9bb92ac307ceae (diff)
firesat: update isochronous interface, add CI support
I have finally managed to get the CI support for the card working. The implementation is a bare minimum to get encrypted channels to work in kaffeine. It works fine with my T/CI card. Now and then I get an AVC timeout and have to retune a channel in order to get it to work. Once the CAM seemed to hang so I needed to remove and insert it again. I.e. there are a number of glitches. The latest version contains the following changes: - Implemented the new hpsb iso interface so that data can be received from the card - Reduced some timers for demux setup which caused scanning to timeout - Added possibility to unload driver - Added support for getting C/N ratio - Added two debug parameters to the driver; ca_debug and avc_comm_debug. - Added CI support that works for me in kaffeine - Started working on CI MMI support. It now supports: o Enter menu o Receiving MMI objects - Added support for 64-bit platforms - Corrected DVB-C modulations problems Signed-off-by: Henrik Kurelid <henrik@kurelid.se> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (rebased, whitespace)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/dvb/firesat/Makefile1
-rw-r--r--drivers/media/dvb/firesat/avc_api.c770
-rw-r--r--drivers/media/dvb/firesat/avc_api.h296
-rw-r--r--drivers/media/dvb/firesat/cmp.c40
-rw-r--r--drivers/media/dvb/firesat/firesat-ci.c342
-rw-r--r--drivers/media/dvb/firesat/firesat.h174
-rw-r--r--drivers/media/dvb/firesat/firesat_1394.c123
-rw-r--r--drivers/media/dvb/firesat/firesat_dvb.c49
-rw-r--r--drivers/media/dvb/firesat/firesat_fe.c80
-rw-r--r--drivers/media/dvb/firesat/firesat_iso.c106
10 files changed, 1487 insertions, 494 deletions
diff --git a/drivers/media/dvb/firesat/Makefile b/drivers/media/dvb/firesat/Makefile
index fdf86870f1fd..be7701b817c9 100644
--- a/drivers/media/dvb/firesat/Makefile
+++ b/drivers/media/dvb/firesat/Makefile
@@ -1,6 +1,7 @@
1firesat-objs := firesat_1394.o \ 1firesat-objs := firesat_1394.o \
2 firesat_dvb.o \ 2 firesat_dvb.o \
3 firesat_fe.o \ 3 firesat_fe.o \
4 firesat_iso.o \
4 avc_api.o \ 5 avc_api.o \
5 cmp.o \ 6 cmp.o \
6 firesat-rc.o \ 7 firesat-rc.o \
diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c
index cd79c806ecc7..273c7235dd90 100644
--- a/drivers/media/dvb/firesat/avc_api.c
+++ b/drivers/media/dvb/firesat/avc_api.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com> 4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (c) 2008 Ben Backx <ben@bbackx.com> 5 * Copyright (c) 2008 Ben Backx <ben@bbackx.com>
6 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 * 7 *
7 * This program is free software; you can redistribute it and/or 8 * 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 * modify it under the terms of the GNU General Public License as
@@ -15,6 +16,7 @@
15#include <nodemgr.h> 16#include <nodemgr.h>
16#include <asm/byteorder.h> 17#include <asm/byteorder.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/crc32.h>
18#include "avc_api.h" 20#include "avc_api.h"
19#include "firesat-rc.h" 21#include "firesat-rc.h"
20 22
@@ -22,6 +24,10 @@
22#define COMMAND_REGISTER 0xFFFFF0000B00ULL 24#define COMMAND_REGISTER 0xFFFFF0000B00ULL
23#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL 25#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
24 26
27static unsigned int avc_comm_debug = 0;
28module_param(avc_comm_debug, int, 0644);
29MODULE_PARM_DESC(avc_comm_debug, "debug logging of AV/C communication, default is 0 (no)");
30
25static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); 31static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
26 32
27/* Frees an allocated packet */ 33/* Frees an allocated packet */
@@ -47,7 +53,124 @@ static int avc_down_timeout(atomic_t *done, int timeout)
47 return ((i > 0) ? 0:1); 53 return ((i > 0) ? 0:1);
48} 54}
49 55
50static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { 56static const char* get_ctype_string(__u8 ctype)
57{
58 switch(ctype)
59 {
60 case 0:
61 return "CONTROL";
62 case 1:
63 return "STATUS";
64 case 2:
65 return "SPECIFIC_INQUIRY";
66 case 3:
67 return "NOTIFY";
68 case 4:
69 return "GENERAL_INQUIRY";
70 }
71 return "UNKNOWN";
72}
73
74static const char* get_resp_string(__u8 ctype)
75{
76 switch(ctype)
77 {
78 case 8:
79 return "NOT_IMPLEMENTED";
80 case 9:
81 return "ACCEPTED";
82 case 10:
83 return "REJECTED";
84 case 11:
85 return "IN_TRANSITION";
86 case 12:
87 return "IMPLEMENTED_STABLE";
88 case 13:
89 return "CHANGED";
90 case 15:
91 return "INTERIM";
92 }
93 return "UNKNOWN";
94}
95
96static const char* get_subunit_address(__u8 subunit_id, __u8 subunit_type)
97{
98 if (subunit_id == 7 && subunit_type == 0x1F)
99 return "Unit";
100 if (subunit_id == 0 && subunit_type == 0x05)
101 return "Tuner(0)";
102 return "Unsupported";
103}
104
105static const char* get_opcode_string(__u8 opcode)
106{
107 switch(opcode)
108 {
109 case 0x02:
110 return "PlugInfo";
111 case 0x08:
112 return "OpenDescriptor";
113 case 0x09:
114 return "ReadDescriptor";
115 case 0x18:
116 return "OutputPlugSignalFormat";
117 case 0x31:
118 return "SubunitInfo";
119 case 0x30:
120 return "UnitInfo";
121 case 0xB2:
122 return "Power";
123 case 0xC8:
124 return "DirectSelectInformationType";
125 case 0xCB:
126 return "DirectSelectData";
127 case 0x00:
128 return "Vendor";
129
130 }
131 return "Unknown";
132}
133
134static void log_command_frame(const AVCCmdFrm *CmdFrm)
135{
136 int k;
137 printk(KERN_INFO "AV/C Command Frame:\n");
138 printk("CommandType=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), "
139 "length=%d\n", get_ctype_string(CmdFrm->ctype),
140 get_subunit_address(CmdFrm->suid, CmdFrm->sutyp),
141 CmdFrm->suid, CmdFrm->sutyp, get_opcode_string(CmdFrm->opcode),
142 CmdFrm->opcode, CmdFrm->length);
143 for(k = 0; k < CmdFrm->length - 3; k++) {
144 if (k % 5 != 0)
145 printk(", ");
146 else if (k != 0)
147 printk("\n");
148 printk("operand[%d] = %02X", k, CmdFrm->operand[k]);
149 }
150 printk("\n");
151}
152
153static void log_response_frame(const AVCRspFrm *RspFrm)
154{
155 int k;
156 printk(KERN_INFO "AV/C Response Frame:\n");
157 printk("Response=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), "
158 "length=%d\n", get_resp_string(RspFrm->resp),
159 get_subunit_address(RspFrm->suid, RspFrm->sutyp),
160 RspFrm->suid, RspFrm->sutyp, get_opcode_string(RspFrm->opcode),
161 RspFrm->opcode, RspFrm->length);
162 for(k = 0; k < RspFrm->length - 3; k++) {
163 if (k % 5 != 0)
164 printk(", ");
165 else if (k != 0)
166 printk("\n");
167 printk("operand[%d] = %02X", k, RspFrm->operand[k]);
168 }
169 printk("\n");
170}
171
172static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm,
173 AVCRspFrm *RspFrm) {
51 struct hpsb_packet *packet; 174 struct hpsb_packet *packet;
52 struct node_entry *ne; 175 struct node_entry *ne;
53 176
@@ -58,39 +181,50 @@ static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFr
58 } 181 }
59 182
60 /* need all input data */ 183 /* need all input data */
61 if(!firesat || !ne || !CmdFrm) 184 if(!firesat || !ne || !CmdFrm) {
185 printk("%s: missing input data!\n",__func__);
62 return -EINVAL; 186 return -EINVAL;
187 }
63 188
64// printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode); 189 if (avc_comm_debug == 1) {
65 190 log_command_frame(CmdFrm);
66// for(k=0;k<CmdFrm->length;k++) 191 }
67// printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]);
68
69 packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER,
70 (quadlet_t*)CmdFrm, CmdFrm->length);
71
72 hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet,
73 packet);
74
75 hpsb_node_fill_packet(ne, packet);
76 192
77 if(RspFrm) 193 if(RspFrm)
78 atomic_set(&firesat->avc_reply_received, 0); 194 atomic_set(&firesat->avc_reply_received, 0);
79 195
196 packet=hpsb_make_writepacket(ne->host, ne->nodeid,
197 COMMAND_REGISTER,
198 (quadlet_t*)CmdFrm,
199 CmdFrm->length);
200 hpsb_set_packet_complete_task(packet,
201 (void (*)(void*))avc_free_packet,
202 packet);
203 hpsb_node_fill_packet(ne, packet);
204
80 if (hpsb_send_packet(packet) < 0) { 205 if (hpsb_send_packet(packet) < 0) {
81 avc_free_packet(packet); 206 avc_free_packet(packet);
82 atomic_set(&firesat->avc_reply_received, 1); 207 atomic_set(&firesat->avc_reply_received, 1);
208 printk("%s: send failed!\n",__func__);
83 return -EIO; 209 return -EIO;
84 } 210 }
85 211
86 if(RspFrm) { 212 if(RspFrm) {
87 if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) { 213 // AV/C specs say that answers should be send within
88 printk("%s: timeout waiting for avc response\n",__func__); 214 // 150 ms so let's time out after 200 ms
215 if(avc_down_timeout(&firesat->avc_reply_received,
216 HZ / 5)) {
217 printk("%s: timeout waiting for avc response\n",
218 __func__);
89 atomic_set(&firesat->avc_reply_received, 1); 219 atomic_set(&firesat->avc_reply_received, 1);
90 return -ETIMEDOUT; 220 return -ETIMEDOUT;
91 } 221 }
92 222 memcpy(RspFrm, firesat->respfrm,
93 memcpy(RspFrm,firesat->respfrm,firesat->resp_length); 223 firesat->resp_length);
224 RspFrm->length = firesat->resp_length;
225 if (avc_comm_debug == 1) {
226 log_response_frame(RspFrm);
227 }
94 } 228 }
95 229
96 return 0; 230 return 0;
@@ -137,6 +271,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
137 271
138 // remote control handling 272 // remote control handling
139 273
274#if 0
140 AVCRspFrm *RspFrm = (AVCRspFrm*)data; 275 AVCRspFrm *RspFrm = (AVCRspFrm*)data;
141 276
142 if(/*RspFrm->length >= 8 && ###*/ 277 if(/*RspFrm->length >= 8 && ###*/
@@ -155,21 +290,21 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
155 printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp); 290 printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp);
156 return 0; 291 return 0;
157 } 292 }
158 293#endif
159 if(atomic_read(&firesat->avc_reply_received) == 1) { 294 if(atomic_read(&firesat->avc_reply_received) == 1) {
160 printk("%s: received out-of-order AVC response, ignored\n",__func__); 295 printk("%s: received out-of-order AVC response, ignored\n",__func__);
161 return -EINVAL; 296 return -EINVAL;
162 } 297 }
163// AVCRspFrm *resp=(AVCRspFrm *)data; 298// AVCRspFrm *resp=(AVCRspFrm *)data;
164// int k; 299// int k;
165/* 300
166 printk(KERN_INFO "resp=0x%x\n",resp->resp); 301// printk(KERN_INFO "resp=0x%x\n",resp->resp);
167 printk(KERN_INFO "cts=0x%x\n",resp->cts); 302// printk(KERN_INFO "cts=0x%x\n",resp->cts);
168 printk(KERN_INFO "suid=0x%x\n",resp->suid); 303// printk(KERN_INFO "suid=0x%x\n",resp->suid);
169 printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp); 304// printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
170 printk(KERN_INFO "opcode=0x%x\n",resp->opcode); 305// printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
171 printk(KERN_INFO "length=%d\n",resp->length); 306// printk(KERN_INFO "length=%d\n",resp->length);
172*/ 307
173// for(k=0;k<2;k++) 308// for(k=0;k<2;k++)
174// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]); 309// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
175 310
@@ -183,6 +318,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
183 318
184// tuning command for setting the relative LNB frequency (not supported by the AVC standard) 319// tuning command for setting the relative LNB frequency (not supported by the AVC standard)
185static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) { 320static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) {
321
186 memset(CmdFrm, 0, sizeof(AVCCmdFrm)); 322 memset(CmdFrm, 0, sizeof(AVCCmdFrm));
187 323
188 CmdFrm->cts = AVC; 324 CmdFrm->cts = AVC;
@@ -249,7 +385,7 @@ static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_param
249 CmdFrm->length = 16; 385 CmdFrm->length = 16;
250} 386}
251 387
252int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) { 388int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status) {
253 AVCCmdFrm CmdFrm; 389 AVCCmdFrm CmdFrm;
254 AVCRspFrm RspFrm; 390 AVCRspFrm RspFrm;
255 M_VALID_FLAGS flags; 391 M_VALID_FLAGS flags;
@@ -274,21 +410,15 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
274 flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO); 410 flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
275 flags.Bits_T.NetworkId = 0; 411 flags.Bits_T.NetworkId = 0;
276 } else { 412 } else {
277 flags.Bits.Modulation = 0; 413 flags.Bits.Modulation =
278 if(firesat->type == FireSAT_DVB_S) { 414 (params->u.qam.modulation != QAM_AUTO);
279 flags.Bits.FEC_inner = 1; 415 flags.Bits.FEC_inner =
280 } else if(firesat->type == FireSAT_DVB_C) { 416 (params->u.qam.fec_inner != FEC_AUTO);
281 flags.Bits.FEC_inner = 0;
282 }
283 flags.Bits.FEC_outer = 0; 417 flags.Bits.FEC_outer = 0;
284 flags.Bits.Symbol_Rate = 1; 418 flags.Bits.Symbol_Rate = 1;
285 flags.Bits.Frequency = 1; 419 flags.Bits.Frequency = 1;
286 flags.Bits.Orbital_Pos = 0; 420 flags.Bits.Orbital_Pos = 0;
287 if(firesat->type == FireSAT_DVB_S) { 421 flags.Bits.Polarisation = 0;
288 flags.Bits.Polarisation = 1;
289 } else if(firesat->type == FireSAT_DVB_C) {
290 flags.Bits.Polarisation = 0;
291 }
292 flags.Bits.reserved_fields = 0; 422 flags.Bits.reserved_fields = 0;
293 flags.Bits.reserved1 = 0; 423 flags.Bits.reserved1 = 0;
294 flags.Bits.Network_ID = 0; 424 flags.Bits.Network_ID = 0;
@@ -306,15 +436,18 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
306 CmdFrm.operand[1] = 0xD2; // subfunction replace 436 CmdFrm.operand[1] = 0xD2; // subfunction replace
307 CmdFrm.operand[2] = 0x20; // system id = DVB 437 CmdFrm.operand[2] = 0x20; // system id = DVB
308 CmdFrm.operand[3] = 0x00; // antenna number 438 CmdFrm.operand[3] = 0x00; // antenna number
309 CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length 439 // system_specific_multiplex selection_length
440 CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11;
310 CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0] 441 CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
311 CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1] 442 CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
312 443
313 if(firesat->type == FireSAT_DVB_T) { 444 if(firesat->type == FireSAT_DVB_T) {
314 CmdFrm.operand[7] = 0x0; 445 CmdFrm.operand[7] = 0x0;
315 CmdFrm.operand[8] = (params->frequency/10) >> 24; 446 CmdFrm.operand[8] = (params->frequency/10) >> 24;
316 CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF; 447 CmdFrm.operand[9] =
317 CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF; 448 ((params->frequency/10) >> 16) & 0xFF;
449 CmdFrm.operand[10] =
450 ((params->frequency/10) >> 8) & 0xFF;
318 CmdFrm.operand[11] = (params->frequency/10) & 0xFF; 451 CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
319 switch(params->u.ofdm.bandwidth) { 452 switch(params->u.ofdm.bandwidth) {
320 case BANDWIDTH_7_MHZ: 453 case BANDWIDTH_7_MHZ:
@@ -416,28 +549,24 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
416 CmdFrm.operand[16] = 0x00; // network_ID[1] 549 CmdFrm.operand[16] = 0x00; // network_ID[1]
417 CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted 550 CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
418 551
419 CmdFrm.length = 20; 552 CmdFrm.length = 24;
420 } else { 553 } else {
421 CmdFrm.operand[7] = 0x00; 554 CmdFrm.operand[7] = 0x00;
422 CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */ 555 CmdFrm.operand[8] = 0x00;
423 CmdFrm.operand[9] = 0x00; 556 CmdFrm.operand[9] = 0x00;
424 CmdFrm.operand[10] = 0x00; 557 CmdFrm.operand[10] = 0x00;
425 558
426 if(firesat->type == FireSAT_DVB_S) { 559 CmdFrm.operand[11] =
427 /* ### relative frequency -> absolute frequency */ 560 (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
428 CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6); 561 CmdFrm.operand[12] =
429 CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF; 562 ((params->frequency/4000) >> 8) & 0xFF;
430 CmdFrm.operand[13] = (params->frequency/4) & 0xFF; 563 CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
431 } else if(firesat->type == FireSAT_DVB_C) { 564 CmdFrm.operand[14] =
432 CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6); 565 ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
433 CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF; 566 CmdFrm.operand[15] =
434 CmdFrm.operand[13] = (params->frequency/4000) & 0xFF; 567 ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
435 } 568 CmdFrm.operand[16] =
436 569 ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
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;
440
441 CmdFrm.operand[17] = 0x00; 570 CmdFrm.operand[17] = 0x00;
442 switch(params->u.qpsk.fec_inner) { 571 switch(params->u.qpsk.fec_inner) {
443 case FEC_1_2: 572 case FEC_1_2:
@@ -455,35 +584,35 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
455 case FEC_7_8: 584 case FEC_7_8:
456 CmdFrm.operand[18] = 0x5; 585 CmdFrm.operand[18] = 0x5;
457 break; 586 break;
458 case FEC_4_5:
459 case FEC_8_9: 587 case FEC_8_9:
588 CmdFrm.operand[18] = 0x6;
589 break;
590 case FEC_4_5:
591 CmdFrm.operand[18] = 0x8;
592 break;
460 case FEC_AUTO: 593 case FEC_AUTO:
461 default: 594 default:
462 CmdFrm.operand[18] = 0x0; 595 CmdFrm.operand[18] = 0x0;
463 } 596 }
464 if(firesat->type == FireSAT_DVB_S) { 597 switch(params->u.qam.modulation) {
598 case QAM_16:
465 CmdFrm.operand[19] = 0x08; // modulation 599 CmdFrm.operand[19] = 0x08; // modulation
466 } else if(firesat->type == FireSAT_DVB_C) { 600 break;
467 switch(params->u.qam.modulation) { 601 case QAM_32:
468 case QAM_16: 602 CmdFrm.operand[19] = 0x10; // modulation
469 CmdFrm.operand[19] = 0x08; // modulation 603 break;
470 break; 604 case QAM_64:
471 case QAM_32: 605 CmdFrm.operand[19] = 0x18; // modulation
472 CmdFrm.operand[19] = 0x10; // modulation 606 break;
473 break; 607 case QAM_128:
474 case QAM_64: 608 CmdFrm.operand[19] = 0x20; // modulation
475 CmdFrm.operand[19] = 0x18; // modulation 609 break;
476 break; 610 case QAM_256:
477 case QAM_128: 611 CmdFrm.operand[19] = 0x28; // modulation
478 CmdFrm.operand[19] = 0x20; // modulation 612 break;
479 break; 613 case QAM_AUTO:
480 case QAM_256: 614 default:
481 CmdFrm.operand[19] = 0x28; // modulation 615 CmdFrm.operand[19] = 0x00; // modulation
482 break;
483 case QAM_AUTO:
484 default:
485 CmdFrm.operand[19] = 0x00; // modulation
486 }
487 } 616 }
488 CmdFrm.operand[20] = 0x00; 617 CmdFrm.operand[20] = 0x00;
489 CmdFrm.operand[21] = 0x00; 618 CmdFrm.operand[21] = 0x00;
@@ -496,7 +625,6 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
496 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) 625 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
497 return k; 626 return k;
498 627
499// msleep(250);
500 mdelay(500); 628 mdelay(500);
501 629
502 if(status) 630 if(status)
@@ -504,13 +632,12 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
504 return 0; 632 return 0;
505} 633}
506 634
507int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) { 635int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[])
636{
508 AVCCmdFrm CmdFrm; 637 AVCCmdFrm CmdFrm;
509 AVCRspFrm RspFrm; 638 AVCRspFrm RspFrm;
510 int pos,k; 639 int pos,k;
511 640
512 printk(KERN_INFO "%s\n", __func__);
513
514 if(pidc > 16 && pidc != 0xFF) 641 if(pidc > 16 && pidc != 0xFF)
515 return -EINVAL; 642 return -EINVAL;
516 643
@@ -526,49 +653,11 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
526 CmdFrm.operand[1] = 0xD2; // subfunction replace 653 CmdFrm.operand[1] = 0xD2; // subfunction replace
527 CmdFrm.operand[2] = 0x20; // system id = DVB 654 CmdFrm.operand[2] = 0x20; // system id = DVB
528 CmdFrm.operand[3] = 0x00; // antenna number 655 CmdFrm.operand[3] = 0x00; // antenna number
529 CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length 656 CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length
530 CmdFrm.operand[5] = 0x00; // valid_flags [0] 657 CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs
531 CmdFrm.operand[6] = 0x00; // valid_flags [1] 658
532 659 pos=6;
533 if(firesat->type == FireSAT_DVB_T) { 660 if(pidc != 0xFF) {
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;
542
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
546
547 pos=18;
548 } else {
549/* CmdFrm.operand[7] = 0x00;
550 CmdFrm.operand[8] = 0x00;
551 CmdFrm.operand[9] = 0x00;
552 CmdFrm.operand[10] = 0x00;
553
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;
557
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;
561
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
568
569 pos=23;
570 }
571 if(pidc != 0xFF)
572 for(k=0;k<pidc;k++) { 661 for(k=0;k<pidc;k++) {
573 CmdFrm.operand[pos++] = 0x13; // flowfunction relay 662 CmdFrm.operand[pos++] = 0x13; // flowfunction relay
574 CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID 663 CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
@@ -577,17 +666,16 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
577 CmdFrm.operand[pos++] = 0x00; // tableID 666 CmdFrm.operand[pos++] = 0x00; // tableID
578 CmdFrm.operand[pos++] = 0x00; // filter_length 667 CmdFrm.operand[pos++] = 0x00; // filter_length
579 } 668 }
669 }
580 670
581 CmdFrm.length = pos+3; 671 CmdFrm.length = pos+3;
582
583 if((pos+3)%4) 672 if((pos+3)%4)
584 CmdFrm.length += 4 - ((pos+3)%4); 673 CmdFrm.length += 4 - ((pos+3)%4);
585 674
586 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) 675 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
587 return k; 676 return k;
588 677
589 mdelay(250); 678 mdelay(50);
590
591 return 0; 679 return 0;
592} 680}
593 681
@@ -596,7 +684,7 @@ int AVCTuner_GetTS(struct firesat *firesat){
596 AVCRspFrm RspFrm; 684 AVCRspFrm RspFrm;
597 int k; 685 int k;
598 686
599 printk(KERN_INFO "%s\n", __func__); 687 //printk(KERN_INFO "%s\n", __func__);
600 688
601 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 689 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
602 690
@@ -612,20 +700,21 @@ int AVCTuner_GetTS(struct firesat *firesat){
612 CmdFrm.operand[3] = 0x20; // system id = DVB 700 CmdFrm.operand[3] = 0x20; // system id = DVB
613 CmdFrm.operand[4] = 0x00; // antenna number 701 CmdFrm.operand[4] = 0x00; // antenna number
614 CmdFrm.operand[5] = 0x0; // system_specific_search_flags 702 CmdFrm.operand[5] = 0x0; // system_specific_search_flags
615 CmdFrm.operand[6] = 0x11; // system_specific_multiplex selection_length 703 CmdFrm.operand[6] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
616 CmdFrm.operand[7] = 0x00; // valid_flags [0] 704 CmdFrm.operand[7] = 0x00; // valid_flags [0]
617 CmdFrm.operand[8] = 0x00; // valid_flags [1] 705 CmdFrm.operand[8] = 0x00; // valid_flags [1]
618 CmdFrm.operand[24] = 0x00; // nr_of_dsit_sel_specs (always 0) 706 CmdFrm.operand[7 + (firesat->type == FireSAT_DVB_T)?0x0c:0x11] = 0x00; // nr_of_dsit_sel_specs (always 0)
619 707
620 CmdFrm.length = 28; 708 CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28;
621 709
622 if((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) return k; 710 if ((k=AVCWrite(firesat, &CmdFrm, &RspFrm)))
711 return k;
623 712
624 mdelay(250); 713 mdelay(250);
625 return 0; 714 return 0;
626} 715}
627 716
628int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) { 717int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport) {
629 AVCCmdFrm CmdFrm; 718 AVCCmdFrm CmdFrm;
630 AVCRspFrm RspFrm; 719 AVCRspFrm RspFrm;
631 720
@@ -660,8 +749,6 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr
660 } 749 }
661 if(systemId) 750 if(systemId)
662 *systemId = RspFrm.operand[7]; 751 *systemId = RspFrm.operand[7];
663 if(has_ci)
664 *has_ci = (RspFrm.operand[14] >> 4) & 0x1;
665 return 0; 752 return 0;
666} 753}
667 754
@@ -679,14 +766,13 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in
679 CmdFrm.opcode=READ_DESCRIPTOR; 766 CmdFrm.opcode=READ_DESCRIPTOR;
680 767
681 CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS; 768 CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
682 CmdFrm.operand[1]=0xff; 769 CmdFrm.operand[1]=0xff; //read_result_status
683 CmdFrm.operand[2]=0x00; 770 CmdFrm.operand[2]=0x00; // reserver
684 CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8; 771 CmdFrm.operand[3]=0;//sizeof(ANTENNA_INPUT_INFO) >> 8;
685 CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF; 772 CmdFrm.operand[4]=0;//sizeof(ANTENNA_INPUT_INFO) & 0xFF;
686 CmdFrm.operand[5]=0x00; 773 CmdFrm.operand[5]=0x00;
687 CmdFrm.operand[6]=0x03; 774 CmdFrm.operand[6]=0x00;
688 CmdFrm.length=12; 775 CmdFrm.length=12;
689 //Absenden des AVC request und warten auf response
690 if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 776 if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
691 return -EIO; 777 return -EIO;
692 778
@@ -695,10 +781,11 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in
695 return -EINVAL; 781 return -EINVAL;
696 } 782 }
697 783
698 length = (RspFrm.operand[3] << 8) + RspFrm.operand[4]; 784 length = RspFrm.operand[9];
699 if(length == sizeof(ANTENNA_INPUT_INFO)) 785 if(RspFrm.operand[1] == 0x10 && length == sizeof(ANTENNA_INPUT_INFO))
700 { 786 {
701 memcpy(antenna_input_info,&RspFrm.operand[7],length); 787 memcpy(antenna_input_info, &RspFrm.operand[10],
788 sizeof(ANTENNA_INPUT_INFO));
702 return 0; 789 return 0;
703 } 790 }
704 printk("%s: invalid info returned from AVC\n",__func__); 791 printk("%s: invalid info returned from AVC\n",__func__);
@@ -837,3 +924,384 @@ int AVCRegisterRemoteControl(struct firesat*firesat)
837{ 924{
838 return __AVCRegisterRemoteControl(firesat, 0); 925 return __AVCRegisterRemoteControl(firesat, 0);
839} 926}
927
928int AVCTuner_Host2Ca(struct firesat *firesat)
929{
930
931 AVCCmdFrm CmdFrm;
932 AVCRspFrm RspFrm;
933
934 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
935 CmdFrm.cts = AVC;
936 CmdFrm.ctype = CONTROL;
937 CmdFrm.sutyp = 0x5;
938 CmdFrm.suid = firesat->subunit;
939 CmdFrm.opcode = VENDOR;
940
941 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
942 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
943 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
944 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
945 CmdFrm.operand[4] = 0; // slot
946 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
947 CmdFrm.operand[6] = 0; // more/last
948 CmdFrm.operand[7] = 0; // length
949 CmdFrm.length = 12;
950
951 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
952 return -EIO;
953
954 return 0;
955}
956
957static int get_ca_object_pos(AVCRspFrm *RspFrm)
958{
959 int length = 1;
960
961 // Check length of length field
962 if (RspFrm->operand[7] & 0x80)
963 length = (RspFrm->operand[7] & 0x7F) + 1;
964 return length + 7;
965}
966
967static int get_ca_object_length(AVCRspFrm *RspFrm)
968{
969 int size = 0;
970 int i;
971
972 if (RspFrm->operand[7] & 0x80) {
973 for (i = 0; i < (RspFrm->operand[7] & 0x7F); i++) {
974 size <<= 8;
975 size += RspFrm->operand[8 + i];
976 }
977 }
978 return RspFrm->operand[7];
979}
980
981int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length)
982{
983 AVCCmdFrm CmdFrm;
984 AVCRspFrm RspFrm;
985 int pos;
986
987 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
988 CmdFrm.cts = AVC;
989 CmdFrm.ctype = STATUS;
990 CmdFrm.sutyp = 0x5;
991 CmdFrm.suid = firesat->subunit;
992 CmdFrm.opcode = VENDOR;
993
994 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
995 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
996 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
997 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
998 CmdFrm.operand[4] = 0; // slot
999 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
1000 CmdFrm.length = 12;
1001
1002 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1003 return -EIO;
1004
1005
1006 pos = get_ca_object_pos(&RspFrm);
1007 app_info[0] = (TAG_APP_INFO >> 16) & 0xFF;
1008 app_info[1] = (TAG_APP_INFO >> 8) & 0xFF;
1009 app_info[2] = (TAG_APP_INFO >> 0) & 0xFF;
1010 app_info[3] = 6 + RspFrm.operand[pos + 4];
1011 app_info[4] = 0x01;
1012 memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]);
1013 *length = app_info[3] + 4;
1014
1015 return 0;
1016}
1017
1018int avc_ca_info(struct firesat *firesat, char *app_info, int *length)
1019{
1020 AVCCmdFrm CmdFrm;
1021 AVCRspFrm RspFrm;
1022 int pos;
1023
1024 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1025 CmdFrm.cts = AVC;
1026 CmdFrm.ctype = STATUS;
1027 CmdFrm.sutyp = 0x5;
1028 CmdFrm.suid = firesat->subunit;
1029 CmdFrm.opcode = VENDOR;
1030
1031 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
1032 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
1033 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
1034 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
1035 CmdFrm.operand[4] = 0; // slot
1036 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
1037 CmdFrm.length = 12;
1038
1039 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1040 return -EIO;
1041
1042 pos = get_ca_object_pos(&RspFrm);
1043 app_info[0] = (TAG_CA_INFO >> 16) & 0xFF;
1044 app_info[1] = (TAG_CA_INFO >> 8) & 0xFF;
1045 app_info[2] = (TAG_CA_INFO >> 0) & 0xFF;
1046 app_info[3] = 2;
1047 app_info[4] = app_info[5];
1048 app_info[5] = app_info[6];
1049 *length = app_info[3] + 4;
1050
1051 return 0;
1052}
1053
1054int avc_ca_reset(struct firesat *firesat)
1055{
1056 AVCCmdFrm CmdFrm;
1057 AVCRspFrm RspFrm;
1058
1059 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1060 CmdFrm.cts = AVC;
1061 CmdFrm.ctype = CONTROL;
1062 CmdFrm.sutyp = 0x5;
1063 CmdFrm.suid = firesat->subunit;
1064 CmdFrm.opcode = VENDOR;
1065
1066 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
1067 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
1068 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
1069 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
1070 CmdFrm.operand[4] = 0; // slot
1071 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_RESET; // ca tag
1072 CmdFrm.operand[6] = 0; // more/last
1073 CmdFrm.operand[7] = 1; // length
1074 CmdFrm.operand[8] = 0; // force hardware reset
1075 CmdFrm.length = 12;
1076
1077 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1078 return -EIO;
1079
1080 return 0;
1081}
1082
1083int avc_ca_pmt(struct firesat *firesat, char *msg, int length)
1084{
1085 AVCCmdFrm CmdFrm;
1086 AVCRspFrm RspFrm;
1087 int list_management;
1088 int program_info_length;
1089 int pmt_cmd_id;
1090 int read_pos;
1091 int write_pos;
1092 int es_info_length;
1093 int crc32_csum;
1094
1095 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1096 CmdFrm.cts = AVC;
1097 CmdFrm.ctype = CONTROL;
1098 CmdFrm.sutyp = 0x5;
1099 CmdFrm.suid = firesat->subunit;
1100 CmdFrm.opcode = VENDOR;
1101
1102 if (msg[0] != LIST_MANAGEMENT_ONLY) {
1103 printk(KERN_ERR "The only list_manasgement parameter that is "
1104 "supported by the firesat driver is \"only\" (3).");
1105 return -EFAULT;
1106 }
1107 // We take the cmd_id from the programme level only!
1108 list_management = msg[0];
1109 program_info_length = ((msg[4] & 0x0F) << 8) + msg[5];
1110 if (program_info_length > 0)
1111 program_info_length--; // Remove pmt_cmd_id
1112 pmt_cmd_id = msg[6];
1113
1114 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
1115 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
1116 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
1117 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
1118 CmdFrm.operand[4] = 0; // slot
1119 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_PMT; // ca tag
1120 CmdFrm.operand[6] = 0; // more/last
1121 //CmdFrm.operand[7] = XXXprogram_info_length + 17; // length
1122 CmdFrm.operand[8] = list_management;
1123 CmdFrm.operand[9] = 0x01; // pmt_cmd=OK_descramble
1124
1125 // TS program map table
1126
1127 // Table id=2
1128 CmdFrm.operand[10] = 0x02;
1129 // Section syntax + length
1130 CmdFrm.operand[11] = 0x80;
1131 //CmdFrm.operand[12] = XXXprogram_info_length + 12;
1132 // Program number
1133 CmdFrm.operand[13] = msg[1];
1134 CmdFrm.operand[14] = msg[2];
1135 // Version number=0 + current/next=1
1136 CmdFrm.operand[15] = 0x01;
1137 // Section number=0
1138 CmdFrm.operand[16] = 0x00;
1139 // Last section number=0
1140 CmdFrm.operand[17] = 0x00;
1141 // PCR_PID=1FFF
1142 CmdFrm.operand[18] = 0x1F;
1143 CmdFrm.operand[19] = 0xFF;
1144 // Program info length
1145 CmdFrm.operand[20] = (program_info_length >> 8);
1146 CmdFrm.operand[21] = (program_info_length & 0xFF);
1147 // CA descriptors at programme level
1148 read_pos = 6;
1149 write_pos = 22;
1150 if (program_info_length > 0) {
1151/* printk(KERN_INFO "Copying descriptors at programme level.\n"); */
1152 pmt_cmd_id = msg[read_pos++];
1153 if (pmt_cmd_id != 1 && pmt_cmd_id !=4) {
1154 printk(KERN_ERR "Invalid pmt_cmd_id=%d.\n",
1155 pmt_cmd_id);
1156 }
1157 memcpy(&CmdFrm.operand[write_pos], &msg[read_pos],
1158 program_info_length);
1159 read_pos += program_info_length;
1160 write_pos += program_info_length;
1161 }
1162 while (read_pos < length) {
1163/* printk(KERN_INFO "Copying descriptors at stream level for " */
1164/* "stream type %d.\n", msg[read_pos]); */
1165 CmdFrm.operand[write_pos++] = msg[read_pos++];
1166 CmdFrm.operand[write_pos++] = msg[read_pos++];
1167 CmdFrm.operand[write_pos++] = msg[read_pos++];
1168 es_info_length =
1169 ((msg[read_pos] & 0x0F) << 8) + msg[read_pos + 1];
1170 read_pos += 2;
1171 if (es_info_length > 0)
1172 es_info_length--; // Remove pmt_cmd_id
1173 CmdFrm.operand[write_pos++] = es_info_length >> 8;
1174 CmdFrm.operand[write_pos++] = es_info_length & 0xFF;
1175 if (es_info_length > 0) {
1176 pmt_cmd_id = msg[read_pos++];
1177 if (pmt_cmd_id != 1 && pmt_cmd_id !=4) {
1178 printk(KERN_ERR "Invalid pmt_cmd_id=%d at "
1179 "stream level.\n", pmt_cmd_id);
1180 }
1181 memcpy(&CmdFrm.operand[write_pos], &msg[read_pos],
1182 es_info_length);
1183 read_pos += es_info_length;
1184 write_pos += es_info_length;
1185 }
1186 }
1187
1188 // CRC
1189 CmdFrm.operand[write_pos++] = 0x00;
1190 CmdFrm.operand[write_pos++] = 0x00;
1191 CmdFrm.operand[write_pos++] = 0x00;
1192 CmdFrm.operand[write_pos++] = 0x00;
1193
1194 CmdFrm.operand[7] = write_pos - 8;
1195 CmdFrm.operand[12] = write_pos - 13;
1196
1197 crc32_csum = crc32_be(0, &CmdFrm.operand[10],
1198 CmdFrm.operand[12] - 1);
1199 CmdFrm.operand[write_pos - 4] = (crc32_csum >> 24) & 0xFF;
1200 CmdFrm.operand[write_pos - 3] = (crc32_csum >> 16) & 0xFF;
1201 CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF;
1202 CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF;
1203
1204 CmdFrm.length = write_pos + 3;
1205 if ((write_pos + 3) % 4)
1206 CmdFrm.length += 4 - ((write_pos + 3) % 4);
1207
1208 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1209 return -EIO;
1210
1211 if (RspFrm.resp != ACCEPTED) {
1212 printk(KERN_ERR "Answer to CA PMT was %d\n", RspFrm.resp);
1213 return -EFAULT;
1214 }
1215
1216 return 0;
1217
1218}
1219
1220int avc_ca_get_time_date(struct firesat *firesat, int *interval)
1221{
1222 AVCCmdFrm CmdFrm;
1223 AVCRspFrm RspFrm;
1224
1225 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1226 CmdFrm.cts = AVC;
1227 CmdFrm.ctype = STATUS;
1228 CmdFrm.sutyp = 0x5;
1229 CmdFrm.suid = firesat->subunit;
1230 CmdFrm.opcode = VENDOR;
1231
1232 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
1233 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
1234 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
1235 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
1236 CmdFrm.operand[4] = 0; // slot
1237 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; // ca tag
1238 CmdFrm.operand[6] = 0; // more/last
1239 CmdFrm.operand[7] = 0; // length
1240 CmdFrm.length = 12;
1241
1242 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1243 return -EIO;
1244
1245 *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)];
1246
1247 return 0;
1248}
1249
1250int avc_ca_enter_menu(struct firesat *firesat)
1251{
1252 AVCCmdFrm CmdFrm;
1253 AVCRspFrm RspFrm;
1254
1255 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1256 CmdFrm.cts = AVC;
1257 CmdFrm.ctype = STATUS;
1258 CmdFrm.sutyp = 0x5;
1259 CmdFrm.suid = firesat->subunit;
1260 CmdFrm.opcode = VENDOR;
1261
1262 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
1263 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
1264 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
1265 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
1266 CmdFrm.operand[4] = 0; // slot
1267 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
1268 CmdFrm.operand[6] = 0; // more/last
1269 CmdFrm.operand[7] = 0; // length
1270 CmdFrm.length = 12;
1271
1272 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1273 return -EIO;
1274
1275 return 0;
1276}
1277
1278int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length)
1279{
1280 AVCCmdFrm CmdFrm;
1281 AVCRspFrm RspFrm;
1282
1283 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1284 CmdFrm.cts = AVC;
1285 CmdFrm.ctype = STATUS;
1286 CmdFrm.sutyp = 0x5;
1287 CmdFrm.suid = firesat->subunit;
1288 CmdFrm.opcode = VENDOR;
1289
1290 CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
1291 CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
1292 CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
1293 CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
1294 CmdFrm.operand[4] = 0; // slot
1295 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_MMI;
1296 CmdFrm.operand[6] = 0; // more/last
1297 CmdFrm.operand[7] = 0; // length
1298 CmdFrm.length = 12;
1299
1300 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
1301 return -EIO;
1302
1303 *length = get_ca_object_length(&RspFrm);
1304 memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *length);
1305
1306 return 0;
1307}
diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h
index f9a190adcd37..041665685903 100644
--- a/drivers/media/dvb/firesat/avc_api.h
+++ b/drivers/media/dvb/firesat/avc_api.h
@@ -4,6 +4,7 @@
4 begin : Wed May 1 2000 4 begin : Wed May 1 2000
5 copyright : (C) 2000 by Manfred Weihs 5 copyright : (C) 2000 by Manfred Weihs
6 copyright : (C) 2003 by Philipp Gutgsell 6 copyright : (C) 2003 by Philipp Gutgsell
7 copyright : (C) 2008 by Henrik Kurelid (henrik@kurelid.se)
7 email : 0014guph@edu.fh-kaernten.ac.at 8 email : 0014guph@edu.fh-kaernten.ac.at
8 ***************************************************************************/ 9 ***************************************************************************/
9 10
@@ -27,12 +28,10 @@
27 28
28#include <linux/dvb/frontend.h> 29#include <linux/dvb/frontend.h>
29 30
30#define BYTE unsigned char 31/*************************************************************
31#define WORD unsigned short 32 Constants from EN510221
32#define DWORD unsigned long 33**************************************************************/
33#define ULONG unsigned long 34#define LIST_MANAGEMENT_ONLY 0x03
34#define LONG long
35
36 35
37/************************************************************* 36/*************************************************************
38 FCP Address range 37 FCP Address range
@@ -68,12 +67,12 @@ typedef struct {
68typedef struct _AVCCmdFrm 67typedef struct _AVCCmdFrm
69{ 68{
70 // AV/C command frame 69 // AV/C command frame
71 BYTE ctype : 4 ; // command type 70 __u8 ctype : 4 ; // command type
72 BYTE cts : 4 ; // always 0x0 for AVC 71 __u8 cts : 4 ; // always 0x0 for AVC
73 BYTE suid : 3 ; // subunit ID 72 __u8 suid : 3 ; // subunit ID
74 BYTE sutyp : 5 ; // subunit_typ 73 __u8 sutyp : 5 ; // subunit_typ
75 BYTE opcode : 8 ; // opcode 74 __u8 opcode : 8 ; // opcode
76 BYTE operand[509] ; // array of operands [1-507] 75 __u8 operand[509] ; // array of operands [1-507]
77 int length; //length of the command frame 76 int length; //length of the command frame
78} AVCCmdFrm ; 77} AVCCmdFrm ;
79 78
@@ -81,12 +80,12 @@ typedef struct _AVCCmdFrm
81typedef struct _AVCRspFrm 80typedef struct _AVCRspFrm
82{ 81{
83 // AV/C response frame 82 // AV/C response frame
84 BYTE resp : 4 ; // response type 83 __u8 resp : 4 ; // response type
85 BYTE cts : 4 ; // always 0x0 for AVC 84 __u8 cts : 4 ; // always 0x0 for AVC
86 BYTE suid : 3 ; // subunit ID 85 __u8 suid : 3 ; // subunit ID
87 BYTE sutyp : 5 ; // subunit_typ 86 __u8 sutyp : 5 ; // subunit_typ
88 BYTE opcode : 8 ; // opcode 87 __u8 opcode : 8 ; // opcode
89 BYTE operand[509] ; // array of operands [1-507] 88 __u8 operand[509] ; // array of operands [1-507]
90 int length; //length of the response frame 89 int length; //length of the response frame
91} AVCRspFrm ; 90} AVCRspFrm ;
92 91
@@ -94,23 +93,23 @@ typedef struct _AVCRspFrm
94 93
95typedef struct _AVCCmdFrm 94typedef struct _AVCCmdFrm
96{ 95{
97 BYTE cts:4; 96 __u8 cts:4;
98 BYTE ctype:4; 97 __u8 ctype:4;
99 BYTE sutyp:5; 98 __u8 sutyp:5;
100 BYTE suid:3; 99 __u8 suid:3;
101 BYTE opcode; 100 __u8 opcode;
102 BYTE operand[509]; 101 __u8 operand[509];
103 int length; 102 int length;
104} AVCCmdFrm; 103} AVCCmdFrm;
105 104
106typedef struct _AVCRspFrm 105typedef struct _AVCRspFrm
107{ 106{
108 BYTE cts:4; 107 __u8 cts:4;
109 BYTE resp:4; 108 __u8 resp:4;
110 BYTE sutyp:5; 109 __u8 sutyp:5;
111 BYTE suid:3; 110 __u8 suid:3;
112 BYTE opcode; 111 __u8 opcode;
113 BYTE operand[509]; 112 __u8 operand[509];
114 int length; 113 int length;
115} AVCRspFrm; 114} AVCRspFrm;
116 115
@@ -197,6 +196,14 @@ typedef struct _AVCRspFrm
197#define SFE_VENDOR_OPCODE_CISTATUS 0x59 196#define SFE_VENDOR_OPCODE_CISTATUS 0x59
198#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices 197#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices
199 198
199// CA Tags
200#define SFE_VENDOR_TAG_CA_RESET 0x00
201#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
202#define SFE_VENDOR_TAG_CA_PMT 0x02
203#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
204#define SFE_VENDOR_TAG_CA_MMI 0x05
205#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
206
200 207
201//AVCTuner DVB identifier service_ID 208//AVCTuner DVB identifier service_ID
202#define DVB 0x20 209#define DVB 0x20
@@ -209,8 +216,8 @@ typedef struct _AVCRspFrm
209#define Tuner_Status_Descriptor 0x80 216#define Tuner_Status_Descriptor 0x80
210 217
211typedef struct { 218typedef struct {
212 BYTE Subunit_Type; 219 __u8 Subunit_Type;
213 BYTE Max_Subunit_ID; 220 __u8 Max_Subunit_ID;
214} SUBUNIT_INFO; 221} SUBUNIT_INFO;
215 222
216/************************************************************* 223/*************************************************************
@@ -220,12 +227,12 @@ typedef struct {
220**************************************************************/ 227**************************************************************/
221 228
222typedef struct { 229typedef struct {
223 BYTE Byte0; 230 __u8 Byte0;
224 BYTE Byte1; 231 __u8 Byte1;
225 BYTE Byte2; 232 __u8 Byte2;
226 BYTE Byte3; 233 __u8 Byte3;
227 BYTE Byte4; 234 __u8 Byte4;
228 BYTE Byte5; 235 __u8 Byte5;
229}OBJECT_ID; 236}OBJECT_ID;
230 237
231/************************************************************* 238/*************************************************************
@@ -234,14 +241,14 @@ typedef struct {
234typedef struct 241typedef struct
235{ 242{
236#ifdef __LITTLE_ENDIAN 243#ifdef __LITTLE_ENDIAN
237 BYTE RF_frequency_hByte:6; 244 __u8 RF_frequency_hByte:6;
238 BYTE raster_Frequency:2;//Bit7,6 raster frequency 245 __u8 raster_Frequency:2;//Bit7,6 raster frequency
239#else 246#else
240 BYTE raster_Frequency:2; 247 __u8 raster_Frequency:2;
241 BYTE RF_frequency_hByte:6; 248 __u8 RF_frequency_hByte:6;
242#endif 249#endif
243 BYTE RF_frequency_mByte; 250 __u8 RF_frequency_mByte;
244 BYTE RF_frequency_lByte; 251 __u8 RF_frequency_lByte;
245 252
246}FREQUENCY; 253}FREQUENCY;
247 254
@@ -249,63 +256,63 @@ typedef struct
249 256
250typedef struct 257typedef struct
251{ 258{
252 BYTE Modulation :1; 259 __u8 Modulation :1;
253 BYTE FEC_inner :1; 260 __u8 FEC_inner :1;
254 BYTE FEC_outer :1; 261 __u8 FEC_outer :1;
255 BYTE Symbol_Rate :1; 262 __u8 Symbol_Rate :1;
256 BYTE Frequency :1; 263 __u8 Frequency :1;
257 BYTE Orbital_Pos :1; 264 __u8 Orbital_Pos :1;
258 BYTE Polarisation :1; 265 __u8 Polarisation :1;
259 BYTE reserved_fields :1; 266 __u8 reserved_fields :1;
260 BYTE reserved1 :7; 267 __u8 reserved1 :7;
261 BYTE Network_ID :1; 268 __u8 Network_ID :1;
262 269
263}MULTIPLEX_VALID_FLAGS; 270}MULTIPLEX_VALID_FLAGS;
264 271
265typedef struct 272typedef struct
266{ 273{
267 BYTE GuardInterval:1; 274 __u8 GuardInterval:1;
268 BYTE CodeRateLPStream:1; 275 __u8 CodeRateLPStream:1;
269 BYTE CodeRateHPStream:1; 276 __u8 CodeRateHPStream:1;
270 BYTE HierarchyInfo:1; 277 __u8 HierarchyInfo:1;
271 BYTE Constellation:1; 278 __u8 Constellation:1;
272 BYTE Bandwidth:1; 279 __u8 Bandwidth:1;
273 BYTE CenterFrequency:1; 280 __u8 CenterFrequency:1;
274 BYTE reserved1:1; 281 __u8 reserved1:1;
275 BYTE reserved2:5; 282 __u8 reserved2:5;
276 BYTE OtherFrequencyFlag:1; 283 __u8 OtherFrequencyFlag:1;
277 BYTE TransmissionMode:1; 284 __u8 TransmissionMode:1;
278 BYTE NetworkId:1; 285 __u8 NetworkId:1;
279}MULTIPLEX_VALID_FLAGS_DVBT; 286}MULTIPLEX_VALID_FLAGS_DVBT;
280 287
281#else 288#else
282 289
283typedef struct { 290typedef struct {
284 BYTE reserved_fields:1; 291 __u8 reserved_fields:1;
285 BYTE Polarisation:1; 292 __u8 Polarisation:1;
286 BYTE Orbital_Pos:1; 293 __u8 Orbital_Pos:1;
287 BYTE Frequency:1; 294 __u8 Frequency:1;
288 BYTE Symbol_Rate:1; 295 __u8 Symbol_Rate:1;
289 BYTE FEC_outer:1; 296 __u8 FEC_outer:1;
290 BYTE FEC_inner:1; 297 __u8 FEC_inner:1;
291 BYTE Modulation:1; 298 __u8 Modulation:1;
292 BYTE Network_ID:1; 299 __u8 Network_ID:1;
293 BYTE reserved1:7; 300 __u8 reserved1:7;
294}MULTIPLEX_VALID_FLAGS; 301}MULTIPLEX_VALID_FLAGS;
295 302
296typedef struct { 303typedef struct {
297 BYTE reserved1:1; 304 __u8 reserved1:1;
298 BYTE CenterFrequency:1; 305 __u8 CenterFrequency:1;
299 BYTE Bandwidth:1; 306 __u8 Bandwidth:1;
300 BYTE Constellation:1; 307 __u8 Constellation:1;
301 BYTE HierarchyInfo:1; 308 __u8 HierarchyInfo:1;
302 BYTE CodeRateHPStream:1; 309 __u8 CodeRateHPStream:1;
303 BYTE CodeRateLPStream:1; 310 __u8 CodeRateLPStream:1;
304 BYTE GuardInterval:1; 311 __u8 GuardInterval:1;
305 BYTE NetworkId:1; 312 __u8 NetworkId:1;
306 BYTE TransmissionMode:1; 313 __u8 TransmissionMode:1;
307 BYTE OtherFrequencyFlag:1; 314 __u8 OtherFrequencyFlag:1;
308 BYTE reserved2:5; 315 __u8 reserved2:5;
309}MULTIPLEX_VALID_FLAGS_DVBT; 316}MULTIPLEX_VALID_FLAGS_DVBT;
310 317
311#endif 318#endif
@@ -314,47 +321,98 @@ typedef union {
314 MULTIPLEX_VALID_FLAGS Bits; 321 MULTIPLEX_VALID_FLAGS Bits;
315 MULTIPLEX_VALID_FLAGS_DVBT Bits_T; 322 MULTIPLEX_VALID_FLAGS_DVBT Bits_T;
316 struct { 323 struct {
317 BYTE ByteHi; 324 __u8 ByteHi;
318 BYTE ByteLo; 325 __u8 ByteLo;
319 } Valid_Word; 326 } Valid_Word;
320} M_VALID_FLAGS; 327} M_VALID_FLAGS;
321 328
322typedef struct 329typedef struct
323{ 330{
324#ifdef __LITTLE_ENDIAN 331#ifdef __LITTLE_ENDIAN
325 BYTE ActiveSystem; 332 __u8 ActiveSystem;
326 BYTE reserved:5; 333 __u8 reserved:5;
327 BYTE NoRF:1; 334 __u8 NoRF:1;
328 BYTE Moving:1; 335 __u8 Moving:1;
329 BYTE Searching:1; 336 __u8 Searching:1;
330 337
331 BYTE SelectedAntenna:7; 338 __u8 SelectedAntenna:7;
332 BYTE Input:1; 339 __u8 Input:1;
333 340
334 BYTE BER[4]; 341 __u8 BER[4];
335 342
336 BYTE SignalStrength; 343 __u8 SignalStrength;
337 FREQUENCY Frequency; 344 FREQUENCY Frequency;
338 345
339 BYTE ManDepInfoLength; 346 __u8 ManDepInfoLength;
347
348 __u8 PowerSupply:1;
349 __u8 FrontEndPowerStatus:1;
350 __u8 reserved3:1;
351 __u8 AntennaError:1;
352 __u8 FrontEndError:1;
353 __u8 reserved2:3;
354
355 __u8 CarrierNoiseRatio[2];
356 __u8 reserved4[2];
357 __u8 PowerSupplyVoltage;
358 __u8 AntennaVoltage;
359 __u8 FirewireBusVoltage;
360
361 __u8 CaMmi:1;
362 __u8 reserved5:7;
363
364 __u8 reserved6:1;
365 __u8 CaInitializationStatus:1;
366 __u8 CaErrorFlag:1;
367 __u8 CaDvbFlag:1;
368 __u8 CaModulePresentStatus:1;
369 __u8 CaApplicationInfo:1;
370 __u8 CaDateTimeRequest:1;
371 __u8 CaPmtReply:1;
372
340#else 373#else
341 BYTE ActiveSystem; 374 __u8 ActiveSystem;
342 BYTE Searching:1; 375 __u8 Searching:1;
343 BYTE Moving:1; 376 __u8 Moving:1;
344 BYTE NoRF:1; 377 __u8 NoRF:1;
345 BYTE reserved:5; 378 __u8 reserved:5;
346 379
347 BYTE Input:1; 380 __u8 Input:1;
348 BYTE SelectedAntenna:7; 381 __u8 SelectedAntenna:7;
349 382
350 BYTE BER[4]; 383 __u8 BER[4];
351 384
352 BYTE SignalStrength; 385 __u8 SignalStrength;
353 FREQUENCY Frequency; 386 FREQUENCY Frequency;
354 387
355 BYTE ManDepInfoLength; 388 __u8 ManDepInfoLength;
389
390 __u8 reserved2:3;
391 __u8 FrontEndError:1;
392 __u8 AntennaError:1;
393 __u8 reserved3:1;
394 __u8 FrontEndPowerStatus:1;
395 __u8 PowerSupply:1;
396
397 __u8 CarrierNoiseRatio[2];
398 __u8 reserved4[2];
399 __u8 PowerSupplyVoltage;
400 __u8 AntennaVoltage;
401 __u8 FirewireBusVoltage;
402
403 __u8 reserved5:7;
404 __u8 CaMmi:1;
405 __u8 CaPmtReply:1;
406 __u8 CaDateTimeRequest:1;
407 __u8 CaApplicationInfo:1;
408 __u8 CaModulePresentStatus:1;
409 __u8 CaDvbFlag:1;
410 __u8 CaErrorFlag:1;
411 __u8 CaInitializationStatus:1;
412 __u8 reserved6:1;
413
356#endif 414#endif
357} ANTENNA_INPUT_INFO; // 11 Byte 415} ANTENNA_INPUT_INFO; // 22 Byte
358 416
359#define LNBCONTROL_DONTCARE 0xff 417#define LNBCONTROL_DONTCARE 0xff
360 418
@@ -365,17 +423,27 @@ extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
365extern int AVCTuner_DSIT(struct firesat *firesat, 423extern int AVCTuner_DSIT(struct firesat *firesat,
366 int Source_Plug, 424 int Source_Plug,
367 struct dvb_frontend_parameters *params, 425 struct dvb_frontend_parameters *params,
368 BYTE *status); 426 __u8 *status);
369 427
370extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); 428extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info);
371extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status); 429extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status);
372extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); 430extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
373extern int AVCTuner_GetTS(struct firesat *firesat); 431extern int AVCTuner_GetTS(struct firesat *firesat);
374 432
375extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci); 433extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport);
376extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); 434extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd);
377extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); 435extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
378extern int AVCRegisterRemoteControl(struct firesat *firesat); 436extern int AVCRegisterRemoteControl(struct firesat *firesat);
437extern int AVCTuner_Host2Ca(struct firesat *firesat);
438extern int avc_ca_app_info(struct firesat *firesat, char *app_info,
439 int *length);
440extern int avc_ca_info(struct firesat *firesat, char *app_info, int *length);
441extern int avc_ca_reset(struct firesat *firesat);
442extern int avc_ca_pmt(struct firesat *firesat, char *app_info, int length);
443extern int avc_ca_get_time_date(struct firesat *firesat, int *interval);
444extern int avc_ca_enter_menu(struct firesat *firesat);
445extern int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object,
446 int *length);
379 447
380#endif 448#endif
381 449
diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c
index 37b91f3f7ff1..a1291caa0674 100644
--- a/drivers/media/dvb/firesat/cmp.c
+++ b/drivers/media/dvb/firesat/cmp.c
@@ -1,3 +1,15 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (c) ?
5 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 *
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.
11 */
12
1#include "cmp.h" 13#include "cmp.h"
2#include <ieee1394.h> 14#include <ieee1394.h>
3#include <nodemgr.h> 15#include <nodemgr.h>
@@ -10,18 +22,18 @@
10 22
11typedef struct _OPCR 23typedef struct _OPCR
12{ 24{
13 BYTE PTPConnCount : 6 ; // Point to point connect. counter 25 __u8 PTPConnCount : 6 ; // Point to point connect. counter
14 BYTE BrConnCount : 1 ; // Broadcast connection counter 26 __u8 BrConnCount : 1 ; // Broadcast connection counter
15 BYTE OnLine : 1 ; // On Line 27 __u8 OnLine : 1 ; // On Line
16 28
17 BYTE ChNr : 6 ; // Channel number 29 __u8 ChNr : 6 ; // Channel number
18 BYTE Res : 2 ; // Reserved 30 __u8 Res : 2 ; // Reserved
19 31
20 BYTE PayloadHi : 2 ; // Payoad high bits 32 __u8 PayloadHi : 2 ; // Payoad high bits
21 BYTE OvhdID : 4 ; // Overhead ID 33 __u8 OvhdID : 4 ; // Overhead ID
22 BYTE DataRate : 2 ; // Data Rate 34 __u8 DataRate : 2 ; // Data Rate
23 35
24 BYTE PayloadLo ; // Payoad low byte 36 __u8 PayloadLo ; // Payoad low byte
25} OPCR ; 37} OPCR ;
26 38
27#define FIRESAT_SPEED IEEE1394_SPEED_400 39#define FIRESAT_SPEED IEEE1394_SPEED_400
@@ -94,13 +106,13 @@ int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int i
94 u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); 106 u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
95 int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); 107 int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
96 108
97 printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); 109/* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */
98 110
99 if (result < 0) { 111 if (result < 0) {
100 printk("%s: cannot read oPCR\n", __func__); 112 printk("%s: cannot read oPCR\n", __func__);
101 return result; 113 return result;
102 } else { 114 } else {
103 printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); 115/* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */
104 do { 116 do {
105 OPCR *hilf= (OPCR*) &test_oPCR; 117 OPCR *hilf= (OPCR*) &test_oPCR;
106 118
@@ -134,8 +146,8 @@ int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int i
134 146
135 hilf->PTPConnCount++; 147 hilf->PTPConnCount++;
136 new_oPCR=test_oPCR; 148 new_oPCR=test_oPCR;
137 printk(KERN_INFO "%s: trying compare_swap...\n",__func__); 149/* printk(KERN_INFO "%s: trying compare_swap...\n",__func__); */
138 printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); 150/* printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); */
139 result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); 151 result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
140 152
141 if (result < 0) { 153 if (result < 0) {
@@ -169,7 +181,7 @@ int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_ch
169 u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); 181 u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
170 int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); 182 int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
171 183
172 printk(KERN_INFO "%s\n",__func__); 184/* printk(KERN_INFO "%s\n",__func__); */
173 185
174 if (result < 0) { 186 if (result < 0) {
175 printk("%s: cannot read oPCR\n", __func__); 187 printk("%s: cannot read oPCR\n", __func__);
diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c
index 862d9553c5bc..821048db283b 100644
--- a/drivers/media/dvb/firesat/firesat-ci.c
+++ b/drivers/media/dvb/firesat/firesat-ci.c
@@ -1,66 +1,303 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 */
11
1#include "firesat-ci.h" 12#include "firesat-ci.h"
2#include "firesat.h" 13#include "firesat.h"
3#include "avc_api.h" 14#include "avc_api.h"
4 15
5#include <linux/dvb/ca.h> 16#include <linux/dvb/ca.h>
6#include <dvbdev.h> 17#include <dvbdev.h>
7/*
8static int firesat_ca_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) {
9 //struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
10 int err;
11 18
12// printk(KERN_INFO "%s: ioctl %d\n",__func__,cmd); 19static unsigned int ca_debug = 0;
20module_param(ca_debug, int, 0644);
21MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)");
13 22
14 switch(cmd) { 23static int firesat_ca_ready(ANTENNA_INPUT_INFO *info)
15 case CA_RESET: 24{
16 // TODO: Needs to be implemented with new AVC Vendor commands 25 if (ca_debug != 0)
26 printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, "
27 "CaModule=%d, CaAppInfo=%d, CaDateTime=%d, "
28 "CaPmt=%d\n", __func__, info->CaMmi,
29 info->CaInitializationStatus, info->CaErrorFlag,
30 info->CaDvbFlag, info->CaModulePresentStatus,
31 info->CaApplicationInfo,
32 info->CaDateTimeRequest, info->CaPmtReply);
33 return info->CaInitializationStatus == 1 &&
34 info->CaErrorFlag == 0 &&
35 info->CaDvbFlag == 1 &&
36 info->CaModulePresentStatus == 1;
37}
38
39static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info)
40{
41 int flags = 0;
42 if (info->CaModulePresentStatus == 1)
43 flags |= CA_CI_MODULE_PRESENT;
44 if (info->CaInitializationStatus == 1 &&
45 info->CaErrorFlag == 0 &&
46 info->CaDvbFlag == 1)
47 flags |= CA_CI_MODULE_READY;
48 return flags;
49}
50
51static int firesat_ca_reset(struct firesat *firesat)
52{
53 if (ca_debug)
54 printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__);
55 if (avc_ca_reset(firesat))
56 return -EFAULT;
57 return 0;
58}
59
60static int firesat_ca_get_caps(struct firesat *firesat, void *arg)
61{
62 struct ca_caps *cap_p = (struct ca_caps*)arg;
63 int err = 0;
64
65 cap_p->slot_num = 1;
66 cap_p->slot_type = CA_CI;
67 cap_p->descr_num = 1;
68 cap_p->descr_type = CA_ECD;
69 if (ca_debug)
70 printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__);
71 return err;
72}
73
74static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg)
75{
76 ANTENNA_INPUT_INFO info;
77 struct ca_slot_info *slot_p = (struct ca_slot_info*)arg;
78
79 if (ca_debug)
80 printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n",
81 __func__, slot_p->num);
82 if (AVCTunerStatus(firesat, &info))
83 return -EFAULT;
84
85 if (slot_p->num == 0) {
86 slot_p->type = CA_CI;
87 slot_p->flags = firesat_get_ca_flags(&info);
88 }
89 else {
90 return -EFAULT;
91 }
92 return 0;
93}
94
95static int firesat_ca_app_info(struct firesat *firesat, void *arg)
96{
97 struct ca_msg *reply_p = (struct ca_msg*)arg;
98 int i;
99
100 if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length))
101 return -EFAULT;
102 if (ca_debug) {
103 printk(KERN_INFO "%s: Creating TAG_APP_INFO message:",
104 __func__);
105 for (i = 0; i < reply_p->length; i++)
106 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
107 printk("\n");
108 }
109 return 0;
110}
111
112static int firesat_ca_info(struct firesat *firesat, void *arg)
113{
114 struct ca_msg *reply_p = (struct ca_msg*)arg;
115 int i;
116
117 if (avc_ca_info(firesat, reply_p->msg, &reply_p->length))
118 return -EFAULT;
119 if (ca_debug) {
120 printk(KERN_INFO "%s: Creating TAG_CA_INFO message:",
121 __func__);
122 for (i = 0; i < reply_p->length; i++)
123 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
124 printk("\n");
125 }
126 return 0;
127}
128
129static int firesat_ca_get_mmi(struct firesat *firesat, void *arg)
130{
131 struct ca_msg *reply_p = (struct ca_msg*)arg;
132 int i;
133
134 if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length))
135 return -EFAULT;
136 if (ca_debug) {
137 printk(KERN_INFO "%s: Creating MMI reply INFO message:",
138 __func__);
139 for (i = 0; i < reply_p->length; i++)
140 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
141 printk("\n");
142 }
143 return 0;
144}
145
146static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
147{
148 int err;
149 ANTENNA_INPUT_INFO info;
150
151 switch (firesat->ca_last_command) {
152 case TAG_APP_INFO_ENQUIRY:
153 err = firesat_ca_app_info(firesat, arg);
154 break;
155 case TAG_CA_INFO_ENQUIRY:
156 err = firesat_ca_info(firesat, arg);
17 break; 157 break;
18 case CA_GET_CAP: { 158 default:
19 ca_caps_t *cap=(ca_caps_t*)parg; 159 if (AVCTunerStatus(firesat, &info))
20 cap->slot_num = 1; 160 err = -EFAULT;
21 cap->slot_type = CA_CI_LINK; 161 else if (info.CaMmi == 1) {
22 cap->descr_num = 1; 162 err = firesat_ca_get_mmi(firesat, arg);
23 cap->descr_type = CA_DSS; 163 }
164 else {
165 printk(KERN_INFO "%s: Unhandled message 0x%08X\n",
166 __func__, firesat->ca_last_command);
167 err = -EFAULT;
168 }
169 }
170 firesat->ca_last_command = 0;
171 return err;
172}
24 173
174static int firesat_ca_pmt(struct firesat *firesat, void *arg)
175{
176 struct ca_msg *msg_p = (struct ca_msg*)arg;
177 int data_pos;
178
179 if (msg_p->msg[3] & 0x80)
180 data_pos = (msg_p->msg[4] && 0x7F) + 4;
181 else
182 data_pos = 4;
183 if (avc_ca_pmt(firesat, &msg_p->msg[data_pos],
184 msg_p->length - data_pos))
185 return -EFAULT;
186 return 0;
187}
188
189static int firesat_ca_send_msg(struct firesat *firesat, void *arg)
190{
191 int err;
192 struct ca_msg *msg_p = (struct ca_msg*)arg;
193
194 // Do we need a semaphore for this?
195 firesat->ca_last_command =
196 (msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2];
197 switch (firesat->ca_last_command) {
198 case TAG_CA_PMT:
199 if (ca_debug != 0)
200 printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n",
201 __func__);
202 err = firesat_ca_pmt(firesat, arg);
203 break;
204 case TAG_APP_INFO_ENQUIRY:
205 // This is all handled in ca_get_msg
206 if (ca_debug != 0)
207 printk(KERN_INFO "%s: Message received: "
208 "TAG_APP_INFO_ENQUIRY\n", __func__);
25 err = 0; 209 err = 0;
26 break; 210 break;
27 } 211 case TAG_CA_INFO_ENQUIRY:
28 case CA_GET_SLOT_INFO: { 212 // This is all handled in ca_get_msg
29 ca_slot_info_t *slot=(ca_slot_info_t*)parg; 213 if (ca_debug != 0)
30 if(slot->num == 0) { 214 printk(KERN_INFO "%s: Message received: "
31 slot->type = CA_CI | CA_CI_LINK | CA_DESCR; 215 "TAG_CA_APP_INFO_ENQUIRY\n", __func__);
32 slot->flags = CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY;
33 } else {
34 slot->type = 0;
35 slot->flags = 0;
36 }
37 err = 0; 216 err = 0;
38 break; 217 break;
218 case TAG_ENTER_MENU:
219 if (ca_debug != 0)
220 printk(KERN_INFO "%s: Entering CA menu.\n", __func__);
221 err = avc_ca_enter_menu(firesat);
222 break;
223 default:
224 printk(KERN_ERR "%s: Unhandled unknown message 0x%08X\n",
225 __func__, firesat->ca_last_command);
226 err = -EFAULT;
39 } 227 }
228 return err;
229}
230
231static int firesat_ca_ioctl(struct inode *inode, struct file *file,
232 unsigned int cmd, void *arg)
233{
234 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
235 struct firesat *firesat = dvbdev->priv;
236 int err;
237 ANTENNA_INPUT_INFO info;
238
239 switch(cmd) {
240 case CA_RESET:
241 err = firesat_ca_reset(firesat);
242 break;
243 case CA_GET_CAP:
244 err = firesat_ca_get_caps(firesat, arg);
245 break;
246 case CA_GET_SLOT_INFO:
247 err = firesat_ca_get_slot_info(firesat, arg);
248 break;
249 case CA_GET_MSG:
250 err = firesat_ca_get_msg(firesat, arg);
251 break;
252 case CA_SEND_MSG:
253 err = firesat_ca_send_msg(firesat, arg);
254 break;
40 default: 255 default:
41 err=-EINVAL; 256 printk(KERN_INFO "%s: Unhandled ioctl, command: %u\n",__func__,
257 cmd);
258 err = -EOPNOTSUPP;
42 } 259 }
260
261 if (AVCTunerStatus(firesat, &info))
262 return err;
263
264 firesat_ca_ready(&info);
265
43 return err; 266 return err;
44} 267}
45*/
46 268
47static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { 269static int firesat_get_date_time_request(struct firesat *firesat)
48 //return dvb_usercopy(inode, file, cmd, arg, firesat_ca_do_ioctl); 270{
49 return dvb_generic_ioctl(inode, file, cmd, arg); 271 if (ca_debug)
272 printk(KERN_INFO "%s: Retrieving Time/Date request\n",
273 __func__);
274 if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval))
275 return -EFAULT;
276 if (ca_debug)
277 printk(KERN_INFO "%s: Time/Date interval is %d\n",
278 __func__, firesat->ca_time_interval);
279
280 return 0;
50} 281}
51 282
52static int firesat_ca_io_open(struct inode *inode, struct file *file) { 283static int firesat_ca_io_open(struct inode *inode, struct file *file)
53 printk(KERN_INFO "%s!\n",__func__); 284{
285 if (ca_debug != 0)
286 printk(KERN_INFO "%s\n",__func__);
54 return dvb_generic_open(inode, file); 287 return dvb_generic_open(inode, file);
55} 288}
56 289
57static int firesat_ca_io_release(struct inode *inode, struct file *file) { 290static int firesat_ca_io_release(struct inode *inode, struct file *file)
58 printk(KERN_INFO "%s!\n",__func__); 291{
292 if (ca_debug != 0)
293 printk(KERN_INFO "%s\n",__func__);
59 return dvb_generic_release(inode, file); 294 return dvb_generic_release(inode, file);
60} 295}
61 296
62static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) { 297static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait)
63// printk(KERN_INFO "%s!\n",__func__); 298{
299 if (ca_debug != 0)
300 printk(KERN_INFO "%s\n",__func__);
64 return POLLIN; 301 return POLLIN;
65} 302}
66 303
@@ -68,7 +305,7 @@ static struct file_operations firesat_ca_fops = {
68 .owner = THIS_MODULE, 305 .owner = THIS_MODULE,
69 .read = NULL, // There is no low level read anymore 306 .read = NULL, // There is no low level read anymore
70 .write = NULL, // There is no low level write anymore 307 .write = NULL, // There is no low level write anymore
71 .ioctl = firesat_ca_ioctl, 308 .ioctl = dvb_generic_ioctl,
72 .open = firesat_ca_io_open, 309 .open = firesat_ca_io_open,
73 .release = firesat_ca_io_release, 310 .release = firesat_ca_io_release,
74 .poll = firesat_ca_io_poll, 311 .poll = firesat_ca_io_poll,
@@ -80,16 +317,37 @@ static struct dvb_device firesat_ca = {
80 .readers = 1, 317 .readers = 1,
81 .writers = 1, 318 .writers = 1,
82 .fops = &firesat_ca_fops, 319 .fops = &firesat_ca_fops,
320 .kernel_ioctl = firesat_ca_ioctl,
83}; 321};
84 322
85int firesat_ca_init(struct firesat *firesat) { 323int firesat_ca_init(struct firesat *firesat)
86 int ret = dvb_register_device(firesat->adapter, &firesat->cadev, &firesat_ca, firesat, DVB_DEVICE_CA); 324{
87 if(ret) return ret; 325 int err;
326 ANTENNA_INPUT_INFO info;
88 327
89 // avoid unnecessary delays, we're not talking to the CI yet anyways 328 if (AVCTunerStatus(firesat, &info))
90 return 0; 329 return -EINVAL;
330
331 if (firesat_ca_ready(&info)) {
332 err = dvb_register_device(firesat->adapter,
333 &firesat->cadev,
334 &firesat_ca, firesat,
335 DVB_DEVICE_CA);
336
337 if (info.CaApplicationInfo == 0)
338 printk(KERN_ERR "%s: CaApplicationInfo is not set.\n",
339 __func__);
340 if (info.CaDateTimeRequest == 1)
341 firesat_get_date_time_request(firesat);
342 }
343 else
344 err = -EFAULT;
345
346 return err;
91} 347}
92 348
93void firesat_ca_release(struct firesat *firesat) { 349void firesat_ca_release(struct firesat *firesat)
350{
351 if (firesat->cadev)
94 dvb_unregister_device(firesat->cadev); 352 dvb_unregister_device(firesat->cadev);
95} 353}
diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h
index d1e2ce37063e..1beed177d98b 100644
--- a/drivers/media/dvb/firesat/firesat.h
+++ b/drivers/media/dvb/firesat/firesat.h
@@ -1,3 +1,15 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (c) ?
5 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 *
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.
11 */
12
1#ifndef __FIRESAT_H 13#ifndef __FIRESAT_H
2#define __FIRESAT_H 14#define __FIRESAT_H
3 15
@@ -6,15 +18,108 @@
6#include "dvb_demux.h" 18#include "dvb_demux.h"
7#include "dvb_net.h" 19#include "dvb_net.h"
8 20
21#include <linux/version.h>
22#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
9#include <linux/semaphore.h> 23#include <linux/semaphore.h>
24#endif
10#include <linux/dvb/frontend.h> 25#include <linux/dvb/frontend.h>
11#include <linux/dvb/dmx.h> 26#include <linux/dvb/dmx.h>
27#include <iso.h>
28
29#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
30#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v)
31#else
32#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w)
33#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(x)
34#endif
35
36/*****************************************************************
37 * CA message command constants from en50221_app_tags.h of libdvb
38 *****************************************************************/
39/* Resource Manager */
40#define TAG_PROFILE_ENQUIRY 0x9f8010
41#define TAG_PROFILE 0x9f8011
42#define TAG_PROFILE_CHANGE 0x9f8012
43
44/* Application Info */
45#define TAG_APP_INFO_ENQUIRY 0x9f8020
46#define TAG_APP_INFO 0x9f8021
47#define TAG_ENTER_MENU 0x9f8022
48
49/* CA Support */
50#define TAG_CA_INFO_ENQUIRY 0x9f8030
51#define TAG_CA_INFO 0x9f8031
52#define TAG_CA_PMT 0x9f8032
53#define TAG_CA_PMT_REPLY 0x9f8033
54
55/* Host Control */
56#define TAG_TUNE 0x9f8400
57#define TAG_REPLACE 0x9f8401
58#define TAG_CLEAR_REPLACE 0x9f8402
59#define TAG_ASK_RELEASE 0x9f8403
60
61/* Date and Time */
62#define TAG_DATE_TIME_ENQUIRY 0x9f8440
63#define TAG_DATE_TIME 0x9f8441
64
65/* Man Machine Interface (MMI) */
66#define TAG_CLOSE_MMI 0x9f8800
67#define TAG_DISPLAY_CONTROL 0x9f8801
68#define TAG_DISPLAY_REPLY 0x9f8802
69#define TAG_TEXT_LAST 0x9f8803
70#define TAG_TEXT_MORE 0x9f8804
71#define TAG_KEYPAD_CONTROL 0x9f8805
72#define TAG_KEYPRESS 0x9f8806
73#define TAG_ENQUIRY 0x9f8807
74#define TAG_ANSWER 0x9f8808
75#define TAG_MENU_LAST 0x9f8809
76#define TAG_MENU_MORE 0x9f880a
77#define TAG_MENU_ANSWER 0x9f880b
78#define TAG_LIST_LAST 0x9f880c
79#define TAG_LIST_MORE 0x9f880d
80#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e
81#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f
82#define TAG_DISPLAY_MESSAGE 0x9f8810
83#define TAG_SCENE_END_MARK 0x9f8811
84#define TAG_SCENE_DONE 0x9f8812
85#define TAG_SCENE_CONTROL 0x9f8813
86#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814
87#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815
88#define TAG_FLUSH_DOWNLOAD 0x9f8816
89#define TAG_DOWNLOAD_REPLY 0x9f8817
90
91/* Low Speed Communications */
92#define TAG_COMMS_COMMAND 0x9f8c00
93#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01
94#define TAG_COMMS_REPLY 0x9f8c02
95#define TAG_COMMS_SEND_LAST 0x9f8c03
96#define TAG_COMMS_SEND_MORE 0x9f8c04
97#define TAG_COMMS_RECV_LAST 0x9f8c05
98#define TAG_COMMS_RECV_MORE 0x9f8c06
99
100/* Authentication */
101#define TAG_AUTH_REQ 0x9f8200
102#define TAG_AUTH_RESP 0x9f8201
103
104/* Teletext */
105#define TAG_TELETEXT_EBU 0x9f9000
106
107/* Smartcard */
108#define TAG_SMARTCARD_COMMAND 0x9f8e00
109#define TAG_SMARTCARD_REPLY 0x9f8e01
110#define TAG_SMARTCARD_SEND 0x9f8e02
111#define TAG_SMARTCARD_RCV 0x9f8e03
112
113/* EPG */
114#define TAG_EPG_ENQUIRY 0x9f8f00
115#define TAG_EPG_REPLY 0x9f8f01
116
12 117
13enum model_type { 118enum model_type {
14 FireSAT_DVB_S = 1, 119 FireSAT_DVB_S = 1,
15 FireSAT_DVB_C = 2, 120 FireSAT_DVB_C = 2,
16 FireSAT_DVB_T = 3, 121 FireSAT_DVB_T = 3,
17 FireSAT_DVB_S2 = 4 122 FireSAT_DVB_S2 = 4
18}; 123};
19 124
20struct firesat { 125struct firesat {
@@ -31,12 +136,13 @@ struct firesat {
31 struct dvb_frontend *fe; 136 struct dvb_frontend *fe;
32 137
33 struct dvb_device *cadev; 138 struct dvb_device *cadev;
34 int has_ci; 139 int ca_last_command;
140 int ca_time_interval;
35 141
36 struct semaphore avc_sem; 142 struct semaphore avc_sem;
37 atomic_t avc_reply_received; 143 atomic_t avc_reply_received;
38 144
39 atomic_t reschedule_remotecontrol; 145 atomic_t reschedule_remotecontrol;
40 146
41 struct firesat_channel { 147 struct firesat_channel {
42 struct firesat *firesat; 148 struct firesat *firesat;
@@ -53,20 +159,54 @@ struct firesat {
53 void *respfrm; 159 void *respfrm;
54 int resp_length; 160 int resp_length;
55 161
56// nodeid_t nodeid; 162 struct hpsb_host *host;
57 struct hpsb_host *host;
58 u64 guid; /* GUID of this node */ 163 u64 guid; /* GUID of this node */
59 u32 guid_vendor_id; /* Top 24bits of guid */ 164 u32 guid_vendor_id; /* Top 24bits of guid */
60 struct node_entry *nodeentry; 165 struct node_entry *nodeentry;
61 166
62 enum model_type type; 167 enum model_type type;
63 char subunit; 168 char subunit;
64 fe_sec_voltage_t voltage; 169 fe_sec_voltage_t voltage;
65 fe_sec_tone_mode_t tone; 170 fe_sec_tone_mode_t tone;
66 171
67 int isochannel; 172 int isochannel;
173 struct hpsb_iso *iso_handle;
174
175 struct list_head list;
176};
177
178struct firewireheader {
179 union {
180 struct {
181 __u8 tcode:4;
182 __u8 sy:4;
183 __u8 tag:2;
184 __u8 channel:6;
185
186 __u8 length_l;
187 __u8 length_h;
188 } hdr;
189 __u32 val;
190 };
191};
68 192
69 struct list_head list; 193struct CIPHeader {
194 union {
195 struct {
196 __u8 syncbits:2;
197 __u8 sid:6;
198 __u8 dbs;
199 __u8 fn:2;
200 __u8 qpc:3;
201 __u8 sph:1;
202 __u8 rsv:2;
203 __u8 dbc;
204 __u8 syncbits2:2;
205 __u8 fmt:6;
206 __u32 fdf:24;
207 } cip;
208 __u64 val;
209 };
70}; 210};
71 211
72extern struct list_head firesat_list; 212extern struct list_head firesat_list;
@@ -76,11 +216,15 @@ extern spinlock_t firesat_list_lock;
76extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); 216extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
77extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); 217extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
78extern int firesat_dvbdev_init(struct firesat *firesat, 218extern int firesat_dvbdev_init(struct firesat *firesat,
79 struct device *dev, 219 struct device *dev,
80 struct dvb_frontend *fe); 220 struct dvb_frontend *fe);
81 221
82/* firesat_fe.c */ 222/* firesat_fe.c */
83extern int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); 223extern int firesat_frontend_attach(struct firesat *firesat,
224 struct dvb_frontend *fe);
84 225
226/* firesat_iso.c */
227extern int setup_iso_channel(struct firesat *firesat);
228extern void tear_down_iso_channel(struct firesat *firesat);
85 229
86#endif 230#endif
diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c
index dcac70a2991e..04ad31666fb9 100644
--- a/drivers/media/dvb/firesat/firesat_1394.c
+++ b/drivers/media/dvb/firesat/firesat_1394.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com> 4 * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com> 5 * Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com>
6 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 * 7 *
7 * This program is free software; you can redistribute it and/or 8 * 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 * modify it under the terms of the GNU General Public License as
@@ -18,7 +19,6 @@
18#include <linux/time.h> 19#include <linux/time.h>
19#include <linux/errno.h> 20#include <linux/errno.h>
20#include <linux/interrupt.h> 21#include <linux/interrupt.h>
21#include <linux/semaphore.h>
22#include <ieee1394_hotplug.h> 22#include <ieee1394_hotplug.h>
23#include <nodemgr.h> 23#include <nodemgr.h>
24#include <highlevel.h> 24#include <highlevel.h>
@@ -79,11 +79,6 @@ static void firesat_add_host(struct hpsb_host *host);
79static void firesat_remove_host(struct hpsb_host *host); 79static void firesat_remove_host(struct hpsb_host *host);
80static void firesat_host_reset(struct hpsb_host *host); 80static void firesat_host_reset(struct hpsb_host *host);
81 81
82/*
83static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
84 size_t length);
85*/
86
87static void fcp_request(struct hpsb_host *host, 82static void fcp_request(struct hpsb_host *host,
88 int nodeid, 83 int nodeid,
89 int direction, 84 int direction,
@@ -96,7 +91,6 @@ static struct hpsb_highlevel firesat_highlevel = {
96 .add_host = firesat_add_host, 91 .add_host = firesat_add_host,
97 .remove_host = firesat_remove_host, 92 .remove_host = firesat_remove_host,
98 .host_reset = firesat_host_reset, 93 .host_reset = firesat_host_reset,
99// FIXME .iso_receive = iso_receive,
100 .fcp_request = fcp_request, 94 .fcp_request = fcp_request,
101}; 95};
102 96
@@ -127,100 +121,6 @@ static void firesat_host_reset(struct hpsb_host *host)
127 printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active); 121 printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
128} 122}
129 123
130struct firewireheader {
131 union {
132 struct {
133 unsigned char tcode:4;
134 unsigned char sy:4;
135 unsigned char tag:2;
136 unsigned char channel:6;
137
138 unsigned char length_l;
139 unsigned char length_h;
140 } hdr;
141 unsigned long val;
142 };
143};
144
145struct CIPHeader {
146 union {
147 struct {
148 unsigned char syncbits:2;
149 unsigned char sid:6;
150 unsigned char dbs;
151 unsigned char fn:2;
152 unsigned char qpc:3;
153 unsigned char sph:1;
154 unsigned char rsv:2;
155 unsigned char dbc;
156 unsigned char syncbits2:2;
157 unsigned char fmt:6;
158 unsigned long fdf:24;
159 } cip;
160 unsigned long long val;
161 };
162};
163
164struct MPEG2Header {
165 union {
166 struct {
167 unsigned char sync; // must be 0x47
168 unsigned char transport_error_indicator:1;
169 unsigned char payload_unit_start_indicator:1;
170 unsigned char transport_priority:1;
171 unsigned short pid:13;
172 unsigned char transport_scrambling_control:2;
173 unsigned char adaption_field_control:2;
174 unsigned char continuity_counter:4;
175 } hdr;
176 unsigned long val;
177 };
178};
179
180#if 0
181static void iso_receive(struct hpsb_host *host,
182 int channel,
183 quadlet_t *data,
184 size_t length)
185{
186 struct firesat *firesat = NULL;
187 struct firesat *firesat_entry;
188 unsigned long flags;
189
190// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length);
191
192 if (length <= 12)
193 return; // ignore empty packets
194 else {
195
196 spin_lock_irqsave(&firesat_list_lock, flags);
197 list_for_each_entry(firesat_entry,&firesat_list,list) {
198 if(firesat_entry->host == host && firesat_entry->isochannel == channel) {
199 firesat=firesat_entry;
200 break;
201 }
202 }
203 spin_unlock_irqrestore(&firesat_list_lock, flags);
204
205 if (firesat) {
206 char *buf= ((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader);
207 int count = (length-sizeof(struct CIPHeader)) / 192;
208
209// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__func__, length, data[0],data[1],data[2],data[3],data[4]);
210
211 while (count--) {
212
213 if (buf[sizeof(quadlet_t) /*timestamp*/] == 0x47)
214 dvb_dmx_swfilter_packets(&firesat->demux, &buf[sizeof(quadlet_t)], 1);
215 else
216 printk("%s: invalid packet, skipping\n", __func__);
217 buf += 188 + sizeof (quadlet_t) /* timestamp */;
218 }
219 }
220 }
221}
222#endif
223
224static void fcp_request(struct hpsb_host *host, 124static void fcp_request(struct hpsb_host *host,
225 int nodeid, 125 int nodeid,
226 int direction, 126 int direction,
@@ -251,7 +151,9 @@ static void fcp_request(struct hpsb_host *host,
251 AVCRecv(firesat,data,length); 151 AVCRecv(firesat,data,length);
252 else 152 else
253 printk("%s: received fcp request from unknown source, ignored\n", __func__); 153 printk("%s: received fcp request from unknown source, ignored\n", __func__);
254 } // else ignore 154 }
155 else
156 printk("%s: received invalid fcp request, ignored\n", __func__);
255} 157}
256 158
257static int firesat_probe(struct device *dev) 159static int firesat_probe(struct device *dev)
@@ -260,7 +162,6 @@ static int firesat_probe(struct device *dev)
260 struct firesat *firesat; 162 struct firesat *firesat;
261 struct dvb_frontend *fe; 163 struct dvb_frontend *fe;
262 unsigned long flags; 164 unsigned long flags;
263 int result;
264 unsigned char subunitcount = 0xff, subunit; 165 unsigned char subunitcount = 0xff, subunit;
265 struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); 166 struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL);
266 int kv_len; 167 int kv_len;
@@ -298,6 +199,7 @@ static int firesat_probe(struct device *dev)
298 firesat->isochannel = -1; 199 firesat->isochannel = -1;
299 firesat->tone = 0xff; 200 firesat->tone = 0xff;
300 firesat->voltage = 0xff; 201 firesat->voltage = 0xff;
202 firesat->fe = fe;
301 203
302 if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) { 204 if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) {
303 printk("%s: couldn't allocate memory.\n", __func__); 205 printk("%s: couldn't allocate memory.\n", __func__);
@@ -357,7 +259,7 @@ static int firesat_probe(struct device *dev)
357 } 259 }
358 kfree(kv_buf); 260 kfree(kv_buf);
359 261
360 if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type, &firesat->has_ci)) { 262 if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) {
361 printk("%s: cannot identify subunit %d\n", __func__, subunit); 263 printk("%s: cannot identify subunit %d\n", __func__, subunit);
362 spin_lock_irqsave(&firesat_list_lock, flags); 264 spin_lock_irqsave(&firesat_list_lock, flags);
363 list_del(&firesat->list); 265 list_del(&firesat->list);
@@ -382,7 +284,6 @@ static int firesat_probe(struct device *dev)
382static int firesat_remove(struct device *dev) 284static int firesat_remove(struct device *dev)
383{ 285{
384 struct unit_directory *ud = container_of(dev, struct unit_directory, device); 286 struct unit_directory *ud = container_of(dev, struct unit_directory, device);
385 struct dvb_frontend* fe;
386 struct firesat **firesats = ud->device.driver_data; 287 struct firesat **firesats = ud->device.driver_data;
387 int k; 288 int k;
388 unsigned long flags; 289 unsigned long flags;
@@ -390,18 +291,9 @@ static int firesat_remove(struct device *dev)
390 if (firesats) { 291 if (firesats) {
391 for (k = 0; k < 2; k++) 292 for (k = 0; k < 2; k++)
392 if (firesats[k]) { 293 if (firesats[k]) {
393 if (firesats[k]->has_ci)
394 firesat_ca_release(firesats[k]); 294 firesat_ca_release(firesats[k]);
395 295
396#if 0 296 dvb_unregister_frontend(firesats[k]->fe);
397 if (!(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) {
398 fe->ops = firesat_ops;
399 fe->dvb = firesats[k]->adapter;
400
401 dvb_unregister_frontend(fe);
402 kfree(fe);
403 }
404#endif
405 dvb_net_release(&firesats[k]->dvbnet); 297 dvb_net_release(&firesats[k]->dvbnet);
406 firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); 298 firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx);
407 firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); 299 firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend);
@@ -413,6 +305,7 @@ static int firesat_remove(struct device *dev)
413 list_del(&firesats[k]->list); 305 list_del(&firesats[k]->list);
414 spin_unlock_irqrestore(&firesat_list_lock, flags); 306 spin_unlock_irqrestore(&firesat_list_lock, flags);
415 307
308 kfree(firesats[k]->fe);
416 kfree(firesats[k]->adapter); 309 kfree(firesats[k]->adapter);
417 kfree(firesats[k]->respfrm); 310 kfree(firesats[k]->respfrm);
418 kfree(firesats[k]); 311 kfree(firesats[k]);
diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c
index 38aad0812881..9e87402289a6 100644
--- a/drivers/media/dvb/firesat/firesat_dvb.c
+++ b/drivers/media/dvb/firesat/firesat_dvb.c
@@ -1,3 +1,15 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (c) ?
5 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 *
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.
11 */
12
1#include <linux/init.h> 13#include <linux/init.h>
2#include <linux/slab.h> 14#include <linux/slab.h>
3#include <linux/wait.h> 15#include <linux/wait.h>
@@ -6,7 +18,6 @@
6#include <linux/time.h> 18#include <linux/time.h>
7#include <linux/errno.h> 19#include <linux/errno.h>
8#include <linux/interrupt.h> 20#include <linux/interrupt.h>
9#include <linux/semaphore.h>
10#include <ieee1394_hotplug.h> 21#include <ieee1394_hotplug.h>
11#include <nodemgr.h> 22#include <nodemgr.h>
12#include <highlevel.h> 23#include <highlevel.h>
@@ -26,13 +37,13 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat)
26{ 37{
27 int k; 38 int k;
28 39
29 printk(KERN_INFO "%s\n", __func__); 40 //printk(KERN_INFO "%s\n", __func__);
30 41
31 if (down_interruptible(&firesat->demux_sem)) 42 if (down_interruptible(&firesat->demux_sem))
32 return NULL; 43 return NULL;
33 44
34 for (k = 0; k < 16; k++) { 45 for (k = 0; k < 16; k++) {
35 printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid); 46 //printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid);
36 47
37 if (firesat->channel[k].active == 0) { 48 if (firesat->channel[k].active == 0) {
38 firesat->channel[k].active = 1; 49 firesat->channel[k].active = 1;
@@ -82,14 +93,15 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
82 int pidc,k; 93 int pidc,k;
83 u16 pids[16]; 94 u16 pids[16];
84 95
85 printk(KERN_INFO "%s (pid %u)\n",__func__,dvbdmxfeed->pid); 96// printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
86 97
87 switch (dvbdmxfeed->type) { 98 switch (dvbdmxfeed->type) {
88 case DMX_TYPE_TS: 99 case DMX_TYPE_TS:
89 case DMX_TYPE_SEC: 100 case DMX_TYPE_SEC:
90 break; 101 break;
91 default: 102 default:
92 printk("%s: invalid type %u\n",__func__,dvbdmxfeed->type); 103 printk(KERN_ERR "%s: invalid type %u\n",
104 __func__, dvbdmxfeed->type);
93 return -EINVAL; 105 return -EINVAL;
94 } 106 }
95 107
@@ -110,7 +122,8 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
110 channel = firesat_channel_allocate(firesat); 122 channel = firesat_channel_allocate(firesat);
111 break; 123 break;
112 default: 124 default:
113 printk("%s: invalid pes type %u\n",__func__, dvbdmxfeed->pes_type); 125 printk(KERN_ERR "%s: invalid pes type %u\n",
126 __func__, dvbdmxfeed->pes_type);
114 return -EINVAL; 127 return -EINVAL;
115 } 128 }
116 } else { 129 } else {
@@ -118,7 +131,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
118 } 131 }
119 132
120 if (!channel) { 133 if (!channel) {
121 printk("%s: busy!\n", __func__); 134 printk(KERN_ERR "%s: busy!\n", __func__);
122 return -EBUSY; 135 return -EBUSY;
123 } 136 }
124 137
@@ -131,22 +144,23 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
131 144
132 if (firesat_channel_collect(firesat, &pidc, pids)) { 145 if (firesat_channel_collect(firesat, &pidc, pids)) {
133 firesat_channel_release(firesat, channel); 146 firesat_channel_release(firesat, channel);
147 printk(KERN_ERR "%s: could not collect pids!\n", __func__);
134 return -EINTR; 148 return -EINTR;
135 } 149 }
136 150
137 if(dvbdmxfeed->pid == 8192) { 151 if(dvbdmxfeed->pid == 8192) {
138 if((k=AVCTuner_GetTS(firesat))) { 152 if((k = AVCTuner_GetTS(firesat))) {
139 firesat_channel_release(firesat, channel); 153 firesat_channel_release(firesat, channel);
140 printk("%s: AVCTuner_GetTS failed with error %d\n", 154 printk("%s: AVCTuner_GetTS failed with error %d\n",
141 __func__,k); 155 __func__, k);
142 return k; 156 return k;
143 } 157 }
144 } 158 }
145 else { 159 else {
146 if((k=AVCTuner_SetPIDs(firesat, pidc, pids))) { 160 if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) {
147 firesat_channel_release(firesat, channel); 161 firesat_channel_release(firesat, channel);
148 printk("%s: AVCTuner_SetPIDs failed with error %d\n", 162 printk("%s: AVCTuner_SetPIDs failed with error %d\n",
149 __func__,k); 163 __func__, k);
150 return k; 164 return k;
151 } 165 }
152 } 166 }
@@ -161,7 +175,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
161 int k, l = 0; 175 int k, l = 0;
162 u16 pids[16]; 176 u16 pids[16];
163 177
164 printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); 178 //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
165 179
166 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && 180 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
167 (demux->dmx.frontend->source != DMX_MEMORY_FE))) { 181 (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
@@ -189,12 +203,13 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
189 203
190 // list except channel to be removed 204 // list except channel to be removed
191 for (k = 0; k < 16; k++) 205 for (k = 0; k < 16; k++)
192 if (firesat->channel[k].active == 1) 206 if (firesat->channel[k].active == 1) {
193 if (&firesat->channel[k] != 207 if (&firesat->channel[k] !=
194 (struct firesat_channel *)dvbdmxfeed->priv) 208 (struct firesat_channel *)dvbdmxfeed->priv)
195 pids[l++] = firesat->channel[k].pid; 209 pids[l++] = firesat->channel[k].pid;
196 else 210 else
197 firesat->channel[k].active = 0; 211 firesat->channel[k].active = 0;
212 }
198 213
199 if ((k = AVCTuner_SetPIDs(firesat, l, pids))) { 214 if ((k = AVCTuner_SetPIDs(firesat, l, pids))) {
200 up(&firesat->demux_sem); 215 up(&firesat->demux_sem);
@@ -214,8 +229,6 @@ int firesat_dvbdev_init(struct firesat *firesat,
214{ 229{
215 int result; 230 int result;
216 231
217 firesat->has_ci = 1; // TEMP workaround
218
219#if 0 232#if 0
220 switch (firesat->type) { 233 switch (firesat->type) {
221 case FireSAT_DVB_S: 234 case FireSAT_DVB_S:
@@ -254,7 +267,7 @@ int firesat_dvbdev_init(struct firesat *firesat,
254 return -ENOMEM; 267 return -ENOMEM;
255 } 268 }
256 269
257 if ((result = dvb_register_adapter(firesat->adapter, 270 if ((result = DVB_REGISTER_ADAPTER(firesat->adapter,
258 firesat->model_name, 271 firesat->model_name,
259 THIS_MODULE, 272 THIS_MODULE,
260 dev, adapter_nr)) < 0) { 273 dev, adapter_nr)) < 0) {
@@ -271,6 +284,7 @@ int firesat_dvbdev_init(struct firesat *firesat,
271 return result; 284 return result;
272 } 285 }
273 286
287 memset(&firesat->demux, 0, sizeof(struct dvb_demux));
274 firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/; 288 firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
275 289
276 firesat->demux.priv = (void *)firesat; 290 firesat->demux.priv = (void *)firesat;
@@ -343,8 +357,9 @@ int firesat_dvbdev_init(struct firesat *firesat,
343 return result; 357 return result;
344 } 358 }
345 359
346 if (firesat->has_ci)
347 firesat_ca_init(firesat); 360 firesat_ca_init(firesat);
348 361
349 return 0; 362 return 0;
350} 363}
364
365
diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c
index f7abd38f0014..1c86c3e61373 100644
--- a/drivers/media/dvb/firesat/firesat_fe.c
+++ b/drivers/media/dvb/firesat/firesat_fe.c
@@ -1,3 +1,15 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (c) ?
5 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
6 *
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.
11 */
12
1#include <linux/init.h> 13#include <linux/init.h>
2#include <linux/slab.h> 14#include <linux/slab.h>
3#include <linux/wait.h> 15#include <linux/wait.h>
@@ -6,7 +18,6 @@
6#include <linux/time.h> 18#include <linux/time.h>
7#include <linux/errno.h> 19#include <linux/errno.h>
8#include <linux/interrupt.h> 20#include <linux/interrupt.h>
9#include <linux/semaphore.h>
10#include <ieee1394_hotplug.h> 21#include <ieee1394_hotplug.h>
11#include <nodemgr.h> 22#include <nodemgr.h>
12#include <highlevel.h> 23#include <highlevel.h>
@@ -22,22 +33,29 @@
22 33
23static int firesat_dvb_init(struct dvb_frontend *fe) 34static int firesat_dvb_init(struct dvb_frontend *fe)
24{ 35{
36 int result;
25 struct firesat *firesat = fe->sec_priv; 37 struct firesat *firesat = fe->sec_priv;
26 printk("fdi: 1\n"); 38// printk("fdi: 1\n");
27 firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM 39 firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM
28 printk("fdi: 2\n"); 40// printk("fdi: 2\n");
29 try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); 41 result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel);
30 printk("fdi: 3\n"); 42 if (result != 0) {
31//FIXME hpsb_listen_channel(&firesat_highlevel, firesat->host, firesat->isochannel); 43 printk(KERN_ERR "Could not establish point to point "
32 printk("fdi: 4\n"); 44 "connection.\n");
33 return 0; 45 return -1;
46 }
47// printk("fdi: 3\n");
48
49 result = setup_iso_channel(firesat);
50// printk("fdi: 4. Result was %d\n", result);
51 return result;
34} 52}
35 53
36static int firesat_sleep(struct dvb_frontend *fe) 54static int firesat_sleep(struct dvb_frontend *fe)
37{ 55{
38 struct firesat *firesat = fe->sec_priv; 56 struct firesat *firesat = fe->sec_priv;
39 57
40//FIXME hpsb_unlisten_channel(&firesat_highlevel, firesat->host, firesat->isochannel); 58 tear_down_iso_channel(firesat);
41 try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); 59 try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel);
42 firesat->isochannel = -1; 60 firesat->isochannel = -1;
43 return 0; 61 return 0;
@@ -83,19 +101,20 @@ static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status)
83 if (AVCTunerStatus(firesat, &info)) 101 if (AVCTunerStatus(firesat, &info))
84 return -EINVAL; 102 return -EINVAL;
85 103
86 if (info.NoRF) 104 if (info.NoRF) {
87 *status = 0; 105 *status = 0;
88 else 106 } else {
89 *status = *status = FE_HAS_SIGNAL | 107 *status = FE_HAS_SIGNAL |
90 FE_HAS_VITERBI | 108 FE_HAS_VITERBI |
91 FE_HAS_SYNC | 109 FE_HAS_SYNC |
92 FE_HAS_CARRIER | 110 FE_HAS_CARRIER |
93 FE_HAS_LOCK; 111 FE_HAS_LOCK;
112 }
94 113
95 return 0; 114 return 0;
96} 115}
97 116
98static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber) 117static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber)
99{ 118{
100 struct firesat *firesat = fe->sec_priv; 119 struct firesat *firesat = fe->sec_priv;
101 ANTENNA_INPUT_INFO info; 120 ANTENNA_INPUT_INFO info;
@@ -103,10 +122,10 @@ static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber)
103 if (AVCTunerStatus(firesat, &info)) 122 if (AVCTunerStatus(firesat, &info))
104 return -EINVAL; 123 return -EINVAL;
105 124
106 *ber = ((info.BER[0] << 24) & 0xff) | 125 *ber = (info.BER[0] << 24) |
107 ((info.BER[1] << 16) & 0xff) | 126 (info.BER[1] << 16) |
108 ((info.BER[2] << 8) & 0xff) | 127 (info.BER[2] << 8) |
109 (info.BER[3] & 0xff); 128 info.BER[3];
110 129
111 return 0; 130 return 0;
112} 131}
@@ -115,19 +134,29 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength)
115{ 134{
116 struct firesat *firesat = fe->sec_priv; 135 struct firesat *firesat = fe->sec_priv;
117 ANTENNA_INPUT_INFO info; 136 ANTENNA_INPUT_INFO info;
118 u16 *signal = strength;
119 137
120 if (AVCTunerStatus(firesat, &info)) 138 if (AVCTunerStatus(firesat, &info))
121 return -EINVAL; 139 return -EINVAL;
122 140
123 *signal = info.SignalStrength; 141 *strength = info.SignalStrength << 8;
124 142
125 return 0; 143 return 0;
126} 144}
127 145
128static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) 146static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr)
129{ 147{
130 return -EOPNOTSUPP; 148 struct firesat *firesat = fe->sec_priv;
149 ANTENNA_INPUT_INFO info;
150
151 if (AVCTunerStatus(firesat, &info))
152 return -EINVAL;
153
154 *snr = (info.CarrierNoiseRatio[0] << 8) +
155 info.CarrierNoiseRatio[1];
156 *snr *= 257;
157 // C/N[dB] = -10 * log10(snr / 65535)
158
159 return 0;
131} 160}
132 161
133static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) 162static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
@@ -192,14 +221,13 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe)
192 firesat->frontend_info = &firesat_T_frontend_info; 221 firesat->frontend_info = &firesat_T_frontend_info;
193 break; 222 break;
194 default: 223 default:
195// printk("%s: unknown model type 0x%x on subunit %d!\n",
196// __func__, firesat->type,subunit);
197 printk("%s: unknown model type 0x%x !\n", 224 printk("%s: unknown model type 0x%x !\n",
198 __func__, firesat->type); 225 __func__, firesat->type);
199 firesat->model_name = "Unknown"; 226 firesat->model_name = "Unknown";
200 firesat->frontend_info = NULL; 227 firesat->frontend_info = NULL;
201 } 228 }
202 fe->ops = firesat_ops; 229 fe->ops = firesat_ops;
230 fe->ops.info = *(firesat->frontend_info);
203 fe->dvb = firesat->adapter; 231 fe->dvb = firesat->adapter;
204 232
205 return 0; 233 return 0;
diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c
new file mode 100644
index 000000000000..15e23cf7d503
--- /dev/null
+++ b/drivers/media/dvb/firesat/firesat_iso.c
@@ -0,0 +1,106 @@
1/*
2 * FireSAT DVB driver
3 *
4 * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 */
11
12#include "firesat.h"
13
14static void rawiso_activity_cb(struct hpsb_iso *iso);
15
16void tear_down_iso_channel(struct firesat *firesat)
17{
18 if (firesat->iso_handle != NULL) {
19 hpsb_iso_stop(firesat->iso_handle);
20 hpsb_iso_shutdown(firesat->iso_handle);
21 }
22 firesat->iso_handle = NULL;
23}
24
25int setup_iso_channel(struct firesat *firesat)
26{
27 int result;
28 firesat->iso_handle =
29 hpsb_iso_recv_init(firesat->host,
30 256 * 200, //data_buf_size,
31 256, //buf_packets,
32 firesat->isochannel,
33 HPSB_ISO_DMA_DEFAULT, //dma_mode,
34 -1, //stat.config.irq_interval,
35 rawiso_activity_cb);
36 if (firesat->iso_handle == NULL) {
37 printk(KERN_ERR "Cannot initialize iso receive.\n");
38 return -EINVAL;
39 }
40 result = hpsb_iso_recv_start(firesat->iso_handle, -1, -1, 0);
41 if (result != 0) {
42 printk(KERN_ERR "Cannot start iso receive.\n");
43 return -EINVAL;
44 }
45 return 0;
46}
47
48static void rawiso_activity_cb(struct hpsb_iso *iso)
49{
50 unsigned int num;
51 unsigned int i;
52/* unsigned int j; */
53 unsigned int packet;
54 unsigned long flags;
55 struct firesat *firesat = NULL;
56 struct firesat *firesat_iterator;
57
58 spin_lock_irqsave(&firesat_list_lock, flags);
59 list_for_each_entry(firesat_iterator, &firesat_list, list) {
60 if(firesat_iterator->iso_handle == iso) {
61 firesat = firesat_iterator;
62 break;
63 }
64 }
65 spin_unlock_irqrestore(&firesat_list_lock, flags);
66
67 if (firesat) {
68 packet = iso->first_packet;
69 num = hpsb_iso_n_ready(iso);
70 for (i = 0; i < num; i++,
71 packet = (packet + 1) % iso->buf_packets) {
72 unsigned char *buf =
73 dma_region_i(&iso->data_buf, unsigned char,
74 iso->infos[packet].offset +
75 sizeof(struct CIPHeader));
76 int count = (iso->infos[packet].len -
77 sizeof(struct CIPHeader)) /
78 (188 + sizeof(struct firewireheader));
79 if (iso->infos[packet].len <= sizeof(struct CIPHeader))
80 continue; // ignore empty packet
81/* printk("%s: Handling packets (%d): ", __func__, */
82/* iso->infos[packet].len); */
83/* for (j = 0; j < iso->infos[packet].len - */
84/* sizeof(struct CIPHeader); j++) */
85/* printk("%02X,", buf[j]); */
86/* printk("\n"); */
87 while (count --) {
88 if (buf[sizeof(struct firewireheader)] == 0x47)
89 dvb_dmx_swfilter_packets(&firesat->demux,
90 &buf[sizeof(struct firewireheader)], 1);
91 else
92 printk("%s: invalid packet, skipping\n", __func__);
93 buf += 188 + sizeof(struct firewireheader);
94
95 }
96
97 }
98 hpsb_iso_recv_release_packets(iso, num);
99 }
100 else {
101 printk("%s: packets for unknown iso channel, skipping\n",
102 __func__);
103 hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso));
104 }
105}
106