diff options
author | Henrik Kurelid <henke@kurelid.se> | 2008-08-01 04:00:45 -0400 |
---|---|---|
committer | Stefan Richter <stefanr@s5r6.in-berlin.de> | 2009-02-24 08:51:26 -0500 |
commit | df4846c35247a0d038c5359d502cddd59d04bc40 (patch) | |
tree | 40c58c28c389f238e3d26230f264782e8f4bcb1e /drivers | |
parent | 2c22861459f094e899c034515a9bb92ac307ceae (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/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/avc_api.c | 770 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/avc_api.h | 296 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/cmp.c | 40 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat-ci.c | 342 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat.h | 174 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_1394.c | 123 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_dvb.c | 49 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_fe.c | 80 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_iso.c | 106 |
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 @@ | |||
1 | firesat-objs := firesat_1394.o \ | 1 | firesat-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 | ||
27 | static unsigned int avc_comm_debug = 0; | ||
28 | module_param(avc_comm_debug, int, 0644); | ||
29 | MODULE_PARM_DESC(avc_comm_debug, "debug logging of AV/C communication, default is 0 (no)"); | ||
30 | |||
25 | static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); | 31 | static 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 | ||
50 | static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { | 56 | static 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 | |||
74 | static 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 | |||
96 | static 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 | |||
105 | static 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 | |||
134 | static 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 | |||
153 | static 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 | |||
172 | static 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) |
185 | static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) { | 320 | static 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 | ||
252 | int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) { | 388 | int 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 | ||
507 | int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) { | 635 | int 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 | ||
628 | int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) { | 717 | int 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 | |||
928 | int 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 | |||
957 | static 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 | |||
967 | static 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 | |||
981 | int 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 | |||
1018 | int 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 | |||
1054 | int 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 | |||
1083 | int 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 | |||
1220 | int 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 | |||
1250 | int 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 | |||
1278 | int 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 { | |||
68 | typedef struct _AVCCmdFrm | 67 | typedef 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 | |||
81 | typedef struct _AVCRspFrm | 80 | typedef 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 | ||
95 | typedef struct _AVCCmdFrm | 94 | typedef 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 | ||
106 | typedef struct _AVCRspFrm | 105 | typedef 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 | ||
211 | typedef struct { | 218 | typedef 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 | ||
222 | typedef struct { | 229 | typedef 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 { | |||
234 | typedef struct | 241 | typedef 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 | ||
250 | typedef struct | 257 | typedef 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 | ||
265 | typedef struct | 272 | typedef 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 | ||
283 | typedef struct { | 290 | typedef 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 | ||
296 | typedef struct { | 303 | typedef 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 | ||
322 | typedef struct | 329 | typedef 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); | |||
365 | extern int AVCTuner_DSIT(struct firesat *firesat, | 423 | extern 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 | ||
370 | extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); | 428 | extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); |
371 | extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status); | 429 | extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status); |
372 | extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); | 430 | extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); |
373 | extern int AVCTuner_GetTS(struct firesat *firesat); | 431 | extern int AVCTuner_GetTS(struct firesat *firesat); |
374 | 432 | ||
375 | extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci); | 433 | extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport); |
376 | extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); | 434 | extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd); |
377 | extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); | 435 | extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); |
378 | extern int AVCRegisterRemoteControl(struct firesat *firesat); | 436 | extern int AVCRegisterRemoteControl(struct firesat *firesat); |
437 | extern int AVCTuner_Host2Ca(struct firesat *firesat); | ||
438 | extern int avc_ca_app_info(struct firesat *firesat, char *app_info, | ||
439 | int *length); | ||
440 | extern int avc_ca_info(struct firesat *firesat, char *app_info, int *length); | ||
441 | extern int avc_ca_reset(struct firesat *firesat); | ||
442 | extern int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); | ||
443 | extern int avc_ca_get_time_date(struct firesat *firesat, int *interval); | ||
444 | extern int avc_ca_enter_menu(struct firesat *firesat); | ||
445 | extern 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 | ||
11 | typedef struct _OPCR | 23 | typedef 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 | /* | ||
8 | static 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); | 19 | static unsigned int ca_debug = 0; |
20 | module_param(ca_debug, int, 0644); | ||
21 | MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)"); | ||
13 | 22 | ||
14 | switch(cmd) { | 23 | static 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 | |||
39 | static 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 | |||
51 | static 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 | |||
60 | static 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 | |||
74 | static 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 | |||
95 | static 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 | |||
112 | static 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 | |||
129 | static 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 | |||
146 | static 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 | ||
174 | static 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 | |||
189 | static 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 | |||
231 | static 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 | ||
47 | static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { | 269 | static 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 | ||
52 | static int firesat_ca_io_open(struct inode *inode, struct file *file) { | 283 | static 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 | ||
57 | static int firesat_ca_io_release(struct inode *inode, struct file *file) { | 290 | static 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 | ||
62 | static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) { | 297 | static 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 | ||
85 | int firesat_ca_init(struct firesat *firesat) { | 323 | int 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 | ||
93 | void firesat_ca_release(struct firesat *firesat) { | 349 | void 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 | ||
13 | enum model_type { | 118 | enum 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 | ||
20 | struct firesat { | 125 | struct 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 | |||
178 | struct 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; | 193 | struct 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 | ||
72 | extern struct list_head firesat_list; | 212 | extern struct list_head firesat_list; |
@@ -76,11 +216,15 @@ extern spinlock_t firesat_list_lock; | |||
76 | extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); | 216 | extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); |
77 | extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); | 217 | extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); |
78 | extern int firesat_dvbdev_init(struct firesat *firesat, | 218 | extern 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 */ |
83 | extern int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); | 223 | extern int firesat_frontend_attach(struct firesat *firesat, |
224 | struct dvb_frontend *fe); | ||
84 | 225 | ||
226 | /* firesat_iso.c */ | ||
227 | extern int setup_iso_channel(struct firesat *firesat); | ||
228 | extern 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); | |||
79 | static void firesat_remove_host(struct hpsb_host *host); | 79 | static void firesat_remove_host(struct hpsb_host *host); |
80 | static void firesat_host_reset(struct hpsb_host *host); | 80 | static void firesat_host_reset(struct hpsb_host *host); |
81 | 81 | ||
82 | /* | ||
83 | static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data, | ||
84 | size_t length); | ||
85 | */ | ||
86 | |||
87 | static void fcp_request(struct hpsb_host *host, | 82 | static 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 | ||
130 | struct 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 | |||
145 | struct 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 | |||
164 | struct 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 | ||
181 | static 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 | |||
224 | static void fcp_request(struct hpsb_host *host, | 124 | static 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 | ||
257 | static int firesat_probe(struct device *dev) | 159 | static 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) | |||
382 | static int firesat_remove(struct device *dev) | 284 | static 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 | ||
23 | static int firesat_dvb_init(struct dvb_frontend *fe) | 34 | static 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 | ||
36 | static int firesat_sleep(struct dvb_frontend *fe) | 54 | static 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 | ||
98 | static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber) | 117 | static 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 | ||
128 | static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) | 146 | static 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 | ||
133 | static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks) | 162 | static 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 | |||
14 | static void rawiso_activity_cb(struct hpsb_iso *iso); | ||
15 | |||
16 | void 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 | |||
25 | int 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 | |||
48 | static 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 | |||