aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/firesat/avc_api.c1074
-rw-r--r--drivers/media/dvb/firesat/avc_api.h38
-rw-r--r--drivers/media/dvb/firesat/cmp.c252
-rw-r--r--drivers/media/dvb/firesat/cmp.h6
-rw-r--r--drivers/media/dvb/firesat/firesat-ci.c244
-rw-r--r--drivers/media/dvb/firesat/firesat-ci.h2
-rw-r--r--drivers/media/dvb/firesat/firesat-rc.c42
-rw-r--r--drivers/media/dvb/firesat/firesat-rc.h9
-rw-r--r--drivers/media/dvb/firesat/firesat.h68
-rw-r--r--drivers/media/dvb/firesat/firesat_1394.c301
-rw-r--r--drivers/media/dvb/firesat/firesat_dvb.c178
-rw-r--r--drivers/media/dvb/firesat/firesat_fe.c223
-rw-r--r--drivers/media/dvb/firesat/firesat_iso.c11
13 files changed, 964 insertions, 1484 deletions
diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c
index 6337f9f21d0f..56911f3df7f6 100644
--- a/drivers/media/dvb/firesat/avc_api.c
+++ b/drivers/media/dvb/firesat/avc_api.c
@@ -11,14 +11,16 @@
11 * the License, or (at your option) any later version. 11 * the License, or (at your option) any later version.
12 */ 12 */
13 13
14#include <linux/bug.h>
14#include <linux/crc32.h> 15#include <linux/crc32.h>
15#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/device.h>
16#include <linux/kernel.h> 18#include <linux/kernel.h>
17#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
18#include <linux/mutex.h> 20#include <linux/mutex.h>
21#include <linux/string.h>
19#include <linux/wait.h> 22#include <linux/wait.h>
20#include <linux/workqueue.h> 23#include <linux/workqueue.h>
21#include <asm/atomic.h>
22 24
23#include <ieee1394_transactions.h> 25#include <ieee1394_transactions.h>
24#include <nodemgr.h> 26#include <nodemgr.h>
@@ -27,230 +29,61 @@
27#include "firesat.h" 29#include "firesat.h"
28#include "firesat-rc.h" 30#include "firesat-rc.h"
29 31
30#define RESPONSE_REGISTER 0xFFFFF0000D00ULL 32#define FCP_COMMAND_REGISTER 0xfffff0000b00ULL
31#define COMMAND_REGISTER 0xFFFFF0000B00ULL
32#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
33 33
34static unsigned int avc_comm_debug = 0; 34static int __avc_write(struct firesat *firesat,
35module_param(avc_comm_debug, int, 0644); 35 const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm)
36MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)");
37
38/* Frees an allocated packet */
39static void avc_free_packet(struct hpsb_packet *packet)
40{
41 hpsb_free_tlabel(packet);
42 hpsb_free_packet(packet);
43}
44
45static const char* get_ctype_string(__u8 ctype)
46{
47 switch(ctype)
48 {
49 case 0:
50 return "CONTROL";
51 case 1:
52 return "STATUS";
53 case 2:
54 return "SPECIFIC_INQUIRY";
55 case 3:
56 return "NOTIFY";
57 case 4:
58 return "GENERAL_INQUIRY";
59 }
60 return "UNKNOWN";
61}
62
63static const char* get_resp_string(__u8 ctype)
64{
65 switch(ctype)
66 {
67 case 8:
68 return "NOT_IMPLEMENTED";
69 case 9:
70 return "ACCEPTED";
71 case 10:
72 return "REJECTED";
73 case 11:
74 return "IN_TRANSITION";
75 case 12:
76 return "IMPLEMENTED_STABLE";
77 case 13:
78 return "CHANGED";
79 case 15:
80 return "INTERIM";
81 }
82 return "UNKNOWN";
83}
84
85static const char* get_subunit_address(__u8 subunit_id, __u8 subunit_type)
86{
87 if (subunit_id == 7 && subunit_type == 0x1F)
88 return "Unit";
89 if (subunit_id == 0 && subunit_type == 0x05)
90 return "Tuner(0)";
91 return "Unsupported";
92}
93
94static const char* get_opcode_string(__u8 opcode)
95{
96 switch(opcode)
97 {
98 case 0x02:
99 return "PlugInfo";
100 case 0x08:
101 return "OpenDescriptor";
102 case 0x09:
103 return "ReadDescriptor";
104 case 0x18:
105 return "OutputPlugSignalFormat";
106 case 0x31:
107 return "SubunitInfo";
108 case 0x30:
109 return "UnitInfo";
110 case 0xB2:
111 return "Power";
112 case 0xC8:
113 return "DirectSelectInformationType";
114 case 0xCB:
115 return "DirectSelectData";
116 case 0x00:
117 return "Vendor";
118
119 }
120 return "Unknown";
121}
122
123static void log_command_frame(const AVCCmdFrm *CmdFrm)
124{
125 int k;
126 printk(KERN_INFO "AV/C Command Frame:\n");
127 printk(KERN_INFO "CommandType=%s, Address=%s(0x%02X,0x%02X), "
128 "opcode=%s(0x%02X), length=%d\n",
129 get_ctype_string(CmdFrm->ctype),
130 get_subunit_address(CmdFrm->suid, CmdFrm->sutyp),
131 CmdFrm->suid, CmdFrm->sutyp, get_opcode_string(CmdFrm->opcode),
132 CmdFrm->opcode, CmdFrm->length);
133 if (avc_comm_debug > 1) {
134 for(k = 0; k < CmdFrm->length - 3; k++) {
135 if (k % 5 != 0)
136 printk(", ");
137 else if (k != 0)
138 printk("\n");
139 printk(KERN_INFO "operand[%d] = %02X", k,
140 CmdFrm->operand[k]);
141 }
142 printk(KERN_INFO "\n");
143 }
144}
145
146static void log_response_frame(const AVCRspFrm *RspFrm)
147{ 36{
148 int k; 37 int err, retry;
149 printk(KERN_INFO "AV/C Response Frame:\n"); 38
150 printk(KERN_INFO "Response=%s, Address=%s(0x%02X,0x%02X), " 39 if (RspFrm)
151 "opcode=%s(0x%02X), length=%d\n", get_resp_string(RspFrm->resp), 40 firesat->avc_reply_received = false;
152 get_subunit_address(RspFrm->suid, RspFrm->sutyp), 41
153 RspFrm->suid, RspFrm->sutyp, get_opcode_string(RspFrm->opcode), 42 for (retry = 0; retry < 6; retry++) {
154 RspFrm->opcode, RspFrm->length); 43 err = hpsb_node_write(firesat->ud->ne, FCP_COMMAND_REGISTER,
155 if (avc_comm_debug > 1) { 44 (quadlet_t *)CmdFrm, CmdFrm->length);
156 for(k = 0; k < RspFrm->length - 3; k++) { 45 if (err) {
157 if (k % 5 != 0) 46 firesat->avc_reply_received = true;
158 printk(KERN_INFO ", "); 47 dev_err(&firesat->ud->device,
159 else if (k != 0) 48 "FCP command write failed\n");
160 printk(KERN_INFO "\n"); 49 return err;
161 printk(KERN_INFO "operand[%d] = %02X", k,
162 RspFrm->operand[k]);
163 } 50 }
164 printk(KERN_INFO "\n");
165 }
166}
167
168static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm,
169 AVCRspFrm *RspFrm) {
170 struct hpsb_packet *packet;
171 struct node_entry *ne;
172 int num_tries = 0;
173 int packet_ok = 0;
174
175 ne = firesat->nodeentry;
176 if(!ne) {
177 printk(KERN_ERR "%s: lost node!\n",__func__);
178 return -EIO;
179 }
180
181 /* need all input data */
182 if(!firesat || !ne || !CmdFrm) {
183 printk(KERN_ERR "%s: missing input data!\n",__func__);
184 return -EINVAL;
185 }
186 51
187 if (avc_comm_debug > 0) { 52 if (!RspFrm)
188 log_command_frame(CmdFrm); 53 return 0;
189 }
190 54
191 if(RspFrm) 55 /*
192 atomic_set(&firesat->avc_reply_received, 0); 56 * AV/C specs say that answers should be sent within 150 ms.
193 57 * Time out after 200 ms.
194 while (packet_ok == 0 && num_tries < 6) { 58 */
195 num_tries++; 59 if (wait_event_timeout(firesat->avc_wait,
196 packet_ok = 1; 60 firesat->avc_reply_received,
197 packet = hpsb_make_writepacket(ne->host, ne->nodeid, 61 HZ / 5) != 0) {
198 COMMAND_REGISTER, 62 memcpy(RspFrm, firesat->respfrm, firesat->resp_length);
199 (quadlet_t*)CmdFrm, 63 RspFrm->length = firesat->resp_length;
200 CmdFrm->length);
201 hpsb_set_packet_complete_task(packet,
202 (void (*)(void*))avc_free_packet,
203 packet);
204 hpsb_node_fill_packet(ne, packet);
205
206 if (hpsb_send_packet(packet) < 0) {
207 avc_free_packet(packet);
208 atomic_set(&firesat->avc_reply_received, 1);
209 printk(KERN_ERR "%s: send failed!\n",__func__);
210 return -EIO;
211 }
212 64
213 if(RspFrm) { 65 return 0;
214 // AV/C specs say that answers should be send within
215 // 150 ms so let's time out after 200 ms
216 if (wait_event_timeout(firesat->avc_wait,
217 atomic_read(&firesat->avc_reply_received) == 1,
218 HZ / 5) == 0) {
219 packet_ok = 0;
220 }
221 else {
222 memcpy(RspFrm, firesat->respfrm,
223 firesat->resp_length);
224 RspFrm->length = firesat->resp_length;
225 if (avc_comm_debug > 0) {
226 log_response_frame(RspFrm);
227 }
228 }
229 } 66 }
230 } 67 }
231 if (packet_ok == 0) { 68 dev_err(&firesat->ud->device, "FCP response timed out\n");
232 printk(KERN_ERR "%s: AV/C response timed out 6 times.\n", 69 return -ETIMEDOUT;
233 __func__);
234 return -ETIMEDOUT;
235 }
236
237 return 0;
238} 70}
239 71
240int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) 72static int avc_write(struct firesat *firesat,
73 const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm)
241{ 74{
242 int ret; 75 int ret;
243 76
244 if (mutex_lock_interruptible(&firesat->avc_mutex)) 77 if (mutex_lock_interruptible(&firesat->avc_mutex))
245 return -EINTR; 78 return -EINTR;
246 79
247 ret = __AVCWrite(firesat, CmdFrm, RspFrm); 80 ret = __avc_write(firesat, CmdFrm, RspFrm);
248 81
249 mutex_unlock(&firesat->avc_mutex); 82 mutex_unlock(&firesat->avc_mutex);
250 return ret; 83 return ret;
251} 84}
252 85
253int AVCRecv(struct firesat *firesat, u8 *data, size_t length) 86int avc_recv(struct firesat *firesat, u8 *data, size_t length)
254{ 87{
255 AVCRspFrm *RspFrm = (AVCRspFrm *)data; 88 AVCRspFrm *RspFrm = (AVCRspFrm *)data;
256 89
@@ -260,87 +93,64 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length)
260 RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && 93 RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 &&
261 RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { 94 RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) {
262 if (RspFrm->resp == CHANGED) { 95 if (RspFrm->resp == CHANGED) {
263 firesat_handle_rc(RspFrm->operand[4] << 8 | 96 firesat_handle_rc(firesat,
264 RspFrm->operand[5]); 97 RspFrm->operand[4] << 8 | RspFrm->operand[5]);
265 schedule_work(&firesat->remote_ctrl_work); 98 schedule_work(&firesat->remote_ctrl_work);
266 } else if (RspFrm->resp != INTERIM) { 99 } else if (RspFrm->resp != INTERIM) {
267 printk(KERN_INFO "firedtv: remote control result = " 100 dev_info(&firesat->ud->device,
268 "%d\n", RspFrm->resp); 101 "remote control result = %d\n", RspFrm->resp);
269 } 102 }
270 return 0; 103 return 0;
271 } 104 }
272 105
273 if(atomic_read(&firesat->avc_reply_received) == 1) { 106 if (firesat->avc_reply_received) {
274 printk(KERN_ERR "%s: received out-of-order AVC response, " 107 dev_err(&firesat->ud->device,
275 "ignored\n",__func__); 108 "received out-of-order AVC response, ignored\n");
276 return -EINVAL; 109 return -EIO;
277 } 110 }
278// AVCRspFrm *resp=(AVCRspFrm *)data;
279// int k;
280
281// printk(KERN_INFO "resp=0x%x\n",resp->resp);
282// printk(KERN_INFO "cts=0x%x\n",resp->cts);
283// printk(KERN_INFO "suid=0x%x\n",resp->suid);
284// printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
285// printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
286// printk(KERN_INFO "length=%d\n",resp->length);
287 111
288// for(k=0;k<2;k++) 112 memcpy(firesat->respfrm, data, length);
289// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]); 113 firesat->resp_length = length;
290 114
291 memcpy(firesat->respfrm,data,length); 115 firesat->avc_reply_received = true;
292 firesat->resp_length=length;
293
294 atomic_set(&firesat->avc_reply_received, 1);
295 wake_up(&firesat->avc_wait); 116 wake_up(&firesat->avc_wait);
296 117
297 return 0; 118 return 0;
298} 119}
299 120
300// tuning command for setting the relative LNB frequency (not supported by the AVC standard) 121/*
301static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) { 122 * tuning command for setting the relative LNB frequency
302 123 * (not supported by the AVC standard)
303 memset(CmdFrm, 0, sizeof(AVCCmdFrm)); 124 */
304 125static void avc_tuner_tuneqpsk(struct firesat *firesat,
305 CmdFrm->cts = AVC; 126 struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm)
306 CmdFrm->ctype = CONTROL; 127{
307 CmdFrm->sutyp = 0x5;
308 CmdFrm->suid = firesat->subunit;
309 CmdFrm->opcode = VENDOR; 128 CmdFrm->opcode = VENDOR;
310 129
311 CmdFrm->operand[0]=SFE_VENDOR_DE_COMPANYID_0; 130 CmdFrm->operand[0] = SFE_VENDOR_DE_COMPANYID_0;
312 CmdFrm->operand[1]=SFE_VENDOR_DE_COMPANYID_1; 131 CmdFrm->operand[1] = SFE_VENDOR_DE_COMPANYID_1;
313 CmdFrm->operand[2]=SFE_VENDOR_DE_COMPANYID_2; 132 CmdFrm->operand[2] = SFE_VENDOR_DE_COMPANYID_2;
314 CmdFrm->operand[3]=SFE_VENDOR_OPCODE_TUNE_QPSK; 133 CmdFrm->operand[3] = SFE_VENDOR_OPCODE_TUNE_QPSK;
315
316 printk(KERN_INFO "%s: tuning to frequency %u\n",__func__,params->frequency);
317
318 CmdFrm->operand[4] = (params->frequency >> 24) & 0xFF;
319 CmdFrm->operand[5] = (params->frequency >> 16) & 0xFF;
320 CmdFrm->operand[6] = (params->frequency >> 8) & 0xFF;
321 CmdFrm->operand[7] = params->frequency & 0xFF;
322 134
323 printk(KERN_INFO "%s: symbol rate = %uBd\n",__func__,params->u.qpsk.symbol_rate); 135 CmdFrm->operand[4] = (params->frequency >> 24) & 0xff;
136 CmdFrm->operand[5] = (params->frequency >> 16) & 0xff;
137 CmdFrm->operand[6] = (params->frequency >> 8) & 0xff;
138 CmdFrm->operand[7] = params->frequency & 0xff;
324 139
325 CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate/1000) >> 8) & 0xFF; 140 CmdFrm->operand[8] = ((params->u.qpsk.symbol_rate / 1000) >> 8) & 0xff;
326 CmdFrm->operand[9] = (params->u.qpsk.symbol_rate/1000) & 0xFF; 141 CmdFrm->operand[9] = (params->u.qpsk.symbol_rate / 1000) & 0xff;
327 142
328 switch(params->u.qpsk.fec_inner) { 143 switch(params->u.qpsk.fec_inner) {
329 case FEC_1_2: 144 case FEC_1_2:
330 CmdFrm->operand[10] = 0x1; 145 CmdFrm->operand[10] = 0x1; break;
331 break;
332 case FEC_2_3: 146 case FEC_2_3:
333 CmdFrm->operand[10] = 0x2; 147 CmdFrm->operand[10] = 0x2; break;
334 break;
335 case FEC_3_4: 148 case FEC_3_4:
336 CmdFrm->operand[10] = 0x3; 149 CmdFrm->operand[10] = 0x3; break;
337 break;
338 case FEC_5_6: 150 case FEC_5_6:
339 CmdFrm->operand[10] = 0x4; 151 CmdFrm->operand[10] = 0x4; break;
340 break;
341 case FEC_7_8: 152 case FEC_7_8:
342 CmdFrm->operand[10] = 0x5; 153 CmdFrm->operand[10] = 0x5; break;
343 break;
344 case FEC_4_5: 154 case FEC_4_5:
345 case FEC_8_9: 155 case FEC_8_9:
346 case FEC_AUTO: 156 case FEC_AUTO:
@@ -348,278 +158,287 @@ static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_param
348 CmdFrm->operand[10] = 0x0; 158 CmdFrm->operand[10] = 0x0;
349 } 159 }
350 160
351 if(firesat->voltage == 0xff) 161 if (firesat->voltage == 0xff)
352 CmdFrm->operand[11] = 0xff; 162 CmdFrm->operand[11] = 0xff;
163 else if (firesat->voltage == SEC_VOLTAGE_18) /* polarisation */
164 CmdFrm->operand[11] = 0;
353 else 165 else
354 CmdFrm->operand[11] = (firesat->voltage==SEC_VOLTAGE_18)?0:1; // polarisation 166 CmdFrm->operand[11] = 1;
355 if(firesat->tone == 0xff) 167
168 if (firesat->tone == 0xff)
356 CmdFrm->operand[12] = 0xff; 169 CmdFrm->operand[12] = 0xff;
170 else if (firesat->tone == SEC_TONE_ON) /* band */
171 CmdFrm->operand[12] = 1;
357 else 172 else
358 CmdFrm->operand[12] = (firesat->tone==SEC_TONE_ON)?1:0; // band 173 CmdFrm->operand[12] = 0;
359 174
360 if (firesat->type == FireSAT_DVB_S2) { 175 if (firesat->type == FireSAT_DVB_S2) {
361 CmdFrm->operand[13] = 0x1; 176 CmdFrm->operand[13] = 0x1;
362 CmdFrm->operand[14] = 0xFF; 177 CmdFrm->operand[14] = 0xff;
363 CmdFrm->operand[15] = 0xFF; 178 CmdFrm->operand[15] = 0xff;
179 CmdFrm->length = 20;
180 } else {
181 CmdFrm->length = 16;
364 } 182 }
183}
184
185static void avc_tuner_dsd_dvb_c(struct dvb_frontend_parameters *params,
186 AVCCmdFrm *CmdFrm)
187{
188 M_VALID_FLAGS flags;
365 189
366 CmdFrm->length = 16; 190 flags.Bits.Modulation = params->u.qam.modulation != QAM_AUTO;
191 flags.Bits.FEC_inner = params->u.qam.fec_inner != FEC_AUTO;
192 flags.Bits.FEC_outer = 0;
193 flags.Bits.Symbol_Rate = 1;
194 flags.Bits.Frequency = 1;
195 flags.Bits.Orbital_Pos = 0;
196 flags.Bits.Polarisation = 0;
197 flags.Bits.reserved_fields = 0;
198 flags.Bits.reserved1 = 0;
199 flags.Bits.Network_ID = 0;
200
201 CmdFrm->opcode = DSD;
202
203 CmdFrm->operand[0] = 0; /* source plug */
204 CmdFrm->operand[1] = 0xd2; /* subfunction replace */
205 CmdFrm->operand[2] = 0x20; /* system id = DVB */
206 CmdFrm->operand[3] = 0x00; /* antenna number */
207 /* system_specific_multiplex selection_length */
208 CmdFrm->operand[4] = 0x11;
209 CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */
210 CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */
211 CmdFrm->operand[7] = 0x00;
212 CmdFrm->operand[8] = 0x00;
213 CmdFrm->operand[9] = 0x00;
214 CmdFrm->operand[10] = 0x00;
215
216 CmdFrm->operand[11] =
217 (((params->frequency / 4000) >> 16) & 0xff) | (2 << 6);
218 CmdFrm->operand[12] =
219 ((params->frequency / 4000) >> 8) & 0xff;
220 CmdFrm->operand[13] = (params->frequency / 4000) & 0xff;
221 CmdFrm->operand[14] =
222 ((params->u.qpsk.symbol_rate / 1000) >> 12) & 0xff;
223 CmdFrm->operand[15] =
224 ((params->u.qpsk.symbol_rate / 1000) >> 4) & 0xff;
225 CmdFrm->operand[16] =
226 ((params->u.qpsk.symbol_rate / 1000) << 4) & 0xf0;
227 CmdFrm->operand[17] = 0x00;
228
229 switch (params->u.qpsk.fec_inner) {
230 case FEC_1_2:
231 CmdFrm->operand[18] = 0x1; break;
232 case FEC_2_3:
233 CmdFrm->operand[18] = 0x2; break;
234 case FEC_3_4:
235 CmdFrm->operand[18] = 0x3; break;
236 case FEC_5_6:
237 CmdFrm->operand[18] = 0x4; break;
238 case FEC_7_8:
239 CmdFrm->operand[18] = 0x5; break;
240 case FEC_8_9:
241 CmdFrm->operand[18] = 0x6; break;
242 case FEC_4_5:
243 CmdFrm->operand[18] = 0x8; break;
244 case FEC_AUTO:
245 default:
246 CmdFrm->operand[18] = 0x0;
247 }
248 switch (params->u.qam.modulation) {
249 case QAM_16:
250 CmdFrm->operand[19] = 0x08; break;
251 case QAM_32:
252 CmdFrm->operand[19] = 0x10; break;
253 case QAM_64:
254 CmdFrm->operand[19] = 0x18; break;
255 case QAM_128:
256 CmdFrm->operand[19] = 0x20; break;
257 case QAM_256:
258 CmdFrm->operand[19] = 0x28; break;
259 case QAM_AUTO:
260 default:
261 CmdFrm->operand[19] = 0x00;
262 }
263 CmdFrm->operand[20] = 0x00;
264 CmdFrm->operand[21] = 0x00;
265 /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
266 CmdFrm->operand[22] = 0x00;
267
268 CmdFrm->length = 28;
367} 269}
368 270
369int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status) { 271static void avc_tuner_dsd_dvb_t(struct dvb_frontend_parameters *params,
272 AVCCmdFrm *CmdFrm)
273{
274 M_VALID_FLAGS flags;
275
276 flags.Bits_T.GuardInterval =
277 params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO;
278 flags.Bits_T.CodeRateLPStream =
279 params->u.ofdm.code_rate_LP != FEC_AUTO;
280 flags.Bits_T.CodeRateHPStream =
281 params->u.ofdm.code_rate_HP != FEC_AUTO;
282 flags.Bits_T.HierarchyInfo =
283 params->u.ofdm.hierarchy_information != HIERARCHY_AUTO;
284 flags.Bits_T.Constellation =
285 params->u.ofdm.constellation != QAM_AUTO;
286 flags.Bits_T.Bandwidth =
287 params->u.ofdm.bandwidth != BANDWIDTH_AUTO;
288 flags.Bits_T.CenterFrequency = 1;
289 flags.Bits_T.reserved1 = 0;
290 flags.Bits_T.reserved2 = 0;
291 flags.Bits_T.OtherFrequencyFlag = 0;
292 flags.Bits_T.TransmissionMode =
293 params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO;
294 flags.Bits_T.NetworkId = 0;
295
296 CmdFrm->opcode = DSD;
297
298 CmdFrm->operand[0] = 0; /* source plug */
299 CmdFrm->operand[1] = 0xd2; /* subfunction replace */
300 CmdFrm->operand[2] = 0x20; /* system id = DVB */
301 CmdFrm->operand[3] = 0x00; /* antenna number */
302 /* system_specific_multiplex selection_length */
303 CmdFrm->operand[4] = 0x0c;
304 CmdFrm->operand[5] = flags.Valid_Word.ByteHi; /* valid_flags [0] */
305 CmdFrm->operand[6] = flags.Valid_Word.ByteLo; /* valid_flags [1] */
306 CmdFrm->operand[7] = 0x0;
307 CmdFrm->operand[8] = (params->frequency / 10) >> 24;
308 CmdFrm->operand[9] = ((params->frequency / 10) >> 16) & 0xff;
309 CmdFrm->operand[10] = ((params->frequency / 10) >> 8) & 0xff;
310 CmdFrm->operand[11] = (params->frequency / 10) & 0xff;
311
312 switch (params->u.ofdm.bandwidth) {
313 case BANDWIDTH_7_MHZ:
314 CmdFrm->operand[12] = 0x20; break;
315 case BANDWIDTH_8_MHZ:
316 case BANDWIDTH_6_MHZ: /* not defined by AVC spec */
317 case BANDWIDTH_AUTO:
318 default:
319 CmdFrm->operand[12] = 0x00;
320 }
321 switch (params->u.ofdm.constellation) {
322 case QAM_16:
323 CmdFrm->operand[13] = 1 << 6; break;
324 case QAM_64:
325 CmdFrm->operand[13] = 2 << 6; break;
326 case QPSK:
327 default:
328 CmdFrm->operand[13] = 0x00;
329 }
330 switch (params->u.ofdm.hierarchy_information) {
331 case HIERARCHY_1:
332 CmdFrm->operand[13] |= 1 << 3; break;
333 case HIERARCHY_2:
334 CmdFrm->operand[13] |= 2 << 3; break;
335 case HIERARCHY_4:
336 CmdFrm->operand[13] |= 3 << 3; break;
337 case HIERARCHY_AUTO:
338 case HIERARCHY_NONE:
339 default:
340 break;
341 }
342 switch (params->u.ofdm.code_rate_HP) {
343 case FEC_2_3:
344 CmdFrm->operand[13] |= 1; break;
345 case FEC_3_4:
346 CmdFrm->operand[13] |= 2; break;
347 case FEC_5_6:
348 CmdFrm->operand[13] |= 3; break;
349 case FEC_7_8:
350 CmdFrm->operand[13] |= 4; break;
351 case FEC_1_2:
352 default:
353 break;
354 }
355 switch (params->u.ofdm.code_rate_LP) {
356 case FEC_2_3:
357 CmdFrm->operand[14] = 1 << 5; break;
358 case FEC_3_4:
359 CmdFrm->operand[14] = 2 << 5; break;
360 case FEC_5_6:
361 CmdFrm->operand[14] = 3 << 5; break;
362 case FEC_7_8:
363 CmdFrm->operand[14] = 4 << 5; break;
364 case FEC_1_2:
365 default:
366 CmdFrm->operand[14] = 0x00; break;
367 }
368 switch (params->u.ofdm.guard_interval) {
369 case GUARD_INTERVAL_1_16:
370 CmdFrm->operand[14] |= 1 << 3; break;
371 case GUARD_INTERVAL_1_8:
372 CmdFrm->operand[14] |= 2 << 3; break;
373 case GUARD_INTERVAL_1_4:
374 CmdFrm->operand[14] |= 3 << 3; break;
375 case GUARD_INTERVAL_1_32:
376 case GUARD_INTERVAL_AUTO:
377 default:
378 break;
379 }
380 switch (params->u.ofdm.transmission_mode) {
381 case TRANSMISSION_MODE_8K:
382 CmdFrm->operand[14] |= 1 << 1; break;
383 case TRANSMISSION_MODE_2K:
384 case TRANSMISSION_MODE_AUTO:
385 default:
386 break;
387 }
388
389 CmdFrm->operand[15] = 0x00; /* network_ID[0] */
390 CmdFrm->operand[16] = 0x00; /* network_ID[1] */
391 /* Nr_of_dsd_sel_specs = 0 -> no PIDs are transmitted */
392 CmdFrm->operand[17] = 0x00;
393
394 CmdFrm->length = 24;
395}
396
397int avc_tuner_dsd(struct firesat *firesat,
398 struct dvb_frontend_parameters *params)
399{
370 AVCCmdFrm CmdFrm; 400 AVCCmdFrm CmdFrm;
371 AVCRspFrm RspFrm; 401 AVCRspFrm RspFrm;
372 M_VALID_FLAGS flags;
373 int k;
374
375// printk(KERN_INFO "%s\n", __func__);
376
377 if (firesat->type == FireSAT_DVB_S || firesat->type == FireSAT_DVB_S2)
378 AVCTuner_tuneQPSK(firesat, params, &CmdFrm);
379 else {
380 if(firesat->type == FireSAT_DVB_T) {
381 flags.Bits_T.GuardInterval = (params->u.ofdm.guard_interval != GUARD_INTERVAL_AUTO);
382 flags.Bits_T.CodeRateLPStream = (params->u.ofdm.code_rate_LP != FEC_AUTO);
383 flags.Bits_T.CodeRateHPStream = (params->u.ofdm.code_rate_HP != FEC_AUTO);
384 flags.Bits_T.HierarchyInfo = (params->u.ofdm.hierarchy_information != HIERARCHY_AUTO);
385 flags.Bits_T.Constellation = (params->u.ofdm.constellation != QAM_AUTO);
386 flags.Bits_T.Bandwidth = (params->u.ofdm.bandwidth != BANDWIDTH_AUTO);
387 flags.Bits_T.CenterFrequency = 1;
388 flags.Bits_T.reserved1 = 0;
389 flags.Bits_T.reserved2 = 0;
390 flags.Bits_T.OtherFrequencyFlag = 0;
391 flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
392 flags.Bits_T.NetworkId = 0;
393 } else {
394 flags.Bits.Modulation =
395 (params->u.qam.modulation != QAM_AUTO);
396 flags.Bits.FEC_inner =
397 (params->u.qam.fec_inner != FEC_AUTO);
398 flags.Bits.FEC_outer = 0;
399 flags.Bits.Symbol_Rate = 1;
400 flags.Bits.Frequency = 1;
401 flags.Bits.Orbital_Pos = 0;
402 flags.Bits.Polarisation = 0;
403 flags.Bits.reserved_fields = 0;
404 flags.Bits.reserved1 = 0;
405 flags.Bits.Network_ID = 0;
406 }
407 402
408 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 403 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
409
410 CmdFrm.cts = AVC;
411 CmdFrm.ctype = CONTROL;
412 CmdFrm.sutyp = 0x5;
413 CmdFrm.suid = firesat->subunit;
414 CmdFrm.opcode = DSD;
415
416 CmdFrm.operand[0] = 0; // source plug
417 CmdFrm.operand[1] = 0xD2; // subfunction replace
418 CmdFrm.operand[2] = 0x20; // system id = DVB
419 CmdFrm.operand[3] = 0x00; // antenna number
420 // system_specific_multiplex selection_length
421 CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11;
422 CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
423 CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
424
425 if(firesat->type == FireSAT_DVB_T) {
426 CmdFrm.operand[7] = 0x0;
427 CmdFrm.operand[8] = (params->frequency/10) >> 24;
428 CmdFrm.operand[9] =
429 ((params->frequency/10) >> 16) & 0xFF;
430 CmdFrm.operand[10] =
431 ((params->frequency/10) >> 8) & 0xFF;
432 CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
433 switch(params->u.ofdm.bandwidth) {
434 case BANDWIDTH_7_MHZ:
435 CmdFrm.operand[12] = 0x20;
436 break;
437 case BANDWIDTH_8_MHZ:
438 case BANDWIDTH_6_MHZ: // not defined by AVC spec
439 case BANDWIDTH_AUTO:
440 default:
441 CmdFrm.operand[12] = 0x00;
442 }
443 switch(params->u.ofdm.constellation) {
444 case QAM_16:
445 CmdFrm.operand[13] = 1 << 6;
446 break;
447 case QAM_64:
448 CmdFrm.operand[13] = 2 << 6;
449 break;
450 case QPSK:
451 default:
452 CmdFrm.operand[13] = 0x00;
453 }
454 switch(params->u.ofdm.hierarchy_information) {
455 case HIERARCHY_1:
456 CmdFrm.operand[13] |= 1 << 3;
457 break;
458 case HIERARCHY_2:
459 CmdFrm.operand[13] |= 2 << 3;
460 break;
461 case HIERARCHY_4:
462 CmdFrm.operand[13] |= 3 << 3;
463 break;
464 case HIERARCHY_AUTO:
465 case HIERARCHY_NONE:
466 default:
467 break;
468 }
469 switch(params->u.ofdm.code_rate_HP) {
470 case FEC_2_3:
471 CmdFrm.operand[13] |= 1;
472 break;
473 case FEC_3_4:
474 CmdFrm.operand[13] |= 2;
475 break;
476 case FEC_5_6:
477 CmdFrm.operand[13] |= 3;
478 break;
479 case FEC_7_8:
480 CmdFrm.operand[13] |= 4;
481 break;
482 case FEC_1_2:
483 default:
484 break;
485 }
486 switch(params->u.ofdm.code_rate_LP) {
487 case FEC_2_3:
488 CmdFrm.operand[14] = 1 << 5;
489 break;
490 case FEC_3_4:
491 CmdFrm.operand[14] = 2 << 5;
492 break;
493 case FEC_5_6:
494 CmdFrm.operand[14] = 3 << 5;
495 break;
496 case FEC_7_8:
497 CmdFrm.operand[14] = 4 << 5;
498 break;
499 case FEC_1_2:
500 default:
501 CmdFrm.operand[14] = 0x00;
502 break;
503 }
504 switch(params->u.ofdm.guard_interval) {
505 case GUARD_INTERVAL_1_16:
506 CmdFrm.operand[14] |= 1 << 3;
507 break;
508 case GUARD_INTERVAL_1_8:
509 CmdFrm.operand[14] |= 2 << 3;
510 break;
511 case GUARD_INTERVAL_1_4:
512 CmdFrm.operand[14] |= 3 << 3;
513 break;
514 case GUARD_INTERVAL_1_32:
515 case GUARD_INTERVAL_AUTO:
516 default:
517 break;
518 }
519 switch(params->u.ofdm.transmission_mode) {
520 case TRANSMISSION_MODE_8K:
521 CmdFrm.operand[14] |= 1 << 1;
522 break;
523 case TRANSMISSION_MODE_2K:
524 case TRANSMISSION_MODE_AUTO:
525 default:
526 break;
527 }
528
529 CmdFrm.operand[15] = 0x00; // network_ID[0]
530 CmdFrm.operand[16] = 0x00; // network_ID[1]
531 CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
532
533 CmdFrm.length = 24;
534 } else {
535 CmdFrm.operand[7] = 0x00;
536 CmdFrm.operand[8] = 0x00;
537 CmdFrm.operand[9] = 0x00;
538 CmdFrm.operand[10] = 0x00;
539
540 CmdFrm.operand[11] =
541 (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
542 CmdFrm.operand[12] =
543 ((params->frequency/4000) >> 8) & 0xFF;
544 CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
545 CmdFrm.operand[14] =
546 ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
547 CmdFrm.operand[15] =
548 ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
549 CmdFrm.operand[16] =
550 ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
551 CmdFrm.operand[17] = 0x00;
552 switch(params->u.qpsk.fec_inner) {
553 case FEC_1_2:
554 CmdFrm.operand[18] = 0x1;
555 break;
556 case FEC_2_3:
557 CmdFrm.operand[18] = 0x2;
558 break;
559 case FEC_3_4:
560 CmdFrm.operand[18] = 0x3;
561 break;
562 case FEC_5_6:
563 CmdFrm.operand[18] = 0x4;
564 break;
565 case FEC_7_8:
566 CmdFrm.operand[18] = 0x5;
567 break;
568 case FEC_8_9:
569 CmdFrm.operand[18] = 0x6;
570 break;
571 case FEC_4_5:
572 CmdFrm.operand[18] = 0x8;
573 break;
574 case FEC_AUTO:
575 default:
576 CmdFrm.operand[18] = 0x0;
577 }
578 switch(params->u.qam.modulation) {
579 case QAM_16:
580 CmdFrm.operand[19] = 0x08; // modulation
581 break;
582 case QAM_32:
583 CmdFrm.operand[19] = 0x10; // modulation
584 break;
585 case QAM_64:
586 CmdFrm.operand[19] = 0x18; // modulation
587 break;
588 case QAM_128:
589 CmdFrm.operand[19] = 0x20; // modulation
590 break;
591 case QAM_256:
592 CmdFrm.operand[19] = 0x28; // modulation
593 break;
594 case QAM_AUTO:
595 default:
596 CmdFrm.operand[19] = 0x00; // modulation
597 }
598 CmdFrm.operand[20] = 0x00;
599 CmdFrm.operand[21] = 0x00;
600 CmdFrm.operand[22] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
601
602 CmdFrm.length=28;
603 }
604 } // AVCTuner_DSD_direct
605 404
606 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) 405 CmdFrm.cts = AVC;
607 return k; 406 CmdFrm.ctype = CONTROL;
407 CmdFrm.sutyp = 0x5;
408 CmdFrm.suid = firesat->subunit;
608 409
609 mdelay(500); 410 switch (firesat->type) {
411 case FireSAT_DVB_S:
412 case FireSAT_DVB_S2:
413 avc_tuner_tuneqpsk(firesat, params, &CmdFrm); break;
414 case FireSAT_DVB_C:
415 avc_tuner_dsd_dvb_c(params, &CmdFrm); break;
416 case FireSAT_DVB_T:
417 avc_tuner_dsd_dvb_t(params, &CmdFrm); break;
418 default:
419 BUG();
420 }
610 421
422 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
423 return -EIO;
424
425 msleep(500);
426#if 0
427 /* FIXME: */
428 /* u8 *status was an out-parameter of avc_tuner_dsd, unused by caller */
611 if(status) 429 if(status)
612 *status=RspFrm.operand[2]; 430 *status=RspFrm.operand[2];
431#endif
613 return 0; 432 return 0;
614} 433}
615 434
616int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) 435int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[])
617{ 436{
618 AVCCmdFrm CmdFrm; 437 AVCCmdFrm CmdFrm;
619 AVCRspFrm RspFrm; 438 AVCRspFrm RspFrm;
620 int pos,k; 439 int pos, k;
621 440
622 if(pidc > 16 && pidc != 0xFF) 441 if (pidc > 16 && pidc != 0xff)
623 return -EINVAL; 442 return -EINVAL;
624 443
625 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 444 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
@@ -637,9 +456,9 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[])
637 CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length 456 CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length
638 CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs 457 CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs
639 458
640 pos=6; 459 pos = 6;
641 if(pidc != 0xFF) { 460 if (pidc != 0xff)
642 for(k=0;k<pidc;k++) { 461 for (k = 0; k < pidc; k++) {
643 CmdFrm.operand[pos++] = 0x13; // flowfunction relay 462 CmdFrm.operand[pos++] = 0x13; // flowfunction relay
644 CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID 463 CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
645 CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F; 464 CmdFrm.operand[pos++] = (pid[k] >> 8) & 0x1F;
@@ -647,25 +466,20 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[])
647 CmdFrm.operand[pos++] = 0x00; // tableID 466 CmdFrm.operand[pos++] = 0x00; // tableID
648 CmdFrm.operand[pos++] = 0x00; // filter_length 467 CmdFrm.operand[pos++] = 0x00; // filter_length
649 } 468 }
650 }
651 469
652 CmdFrm.length = pos+3; 470 CmdFrm.length = ALIGN(3 + pos, 4);
653 if((pos+3)%4)
654 CmdFrm.length += 4 - ((pos+3)%4);
655 471
656 if((k=AVCWrite(firesat,&CmdFrm,&RspFrm))) 472 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
657 return k; 473 return -EIO;
658 474
659 mdelay(50); 475 msleep(50);
660 return 0; 476 return 0;
661} 477}
662 478
663int AVCTuner_GetTS(struct firesat *firesat){ 479int avc_tuner_get_ts(struct firesat *firesat)
480{
664 AVCCmdFrm CmdFrm; 481 AVCCmdFrm CmdFrm;
665 AVCRspFrm RspFrm; 482 AVCRspFrm RspFrm;
666 int k;
667
668 //printk(KERN_INFO "%s\n", __func__);
669 483
670 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 484 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
671 485
@@ -688,14 +502,14 @@ int AVCTuner_GetTS(struct firesat *firesat){
688 502
689 CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28; 503 CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28;
690 504
691 if ((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) 505 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
692 return k; 506 return -EIO;
693 507
694 mdelay(250); 508 msleep(250);
695 return 0; 509 return 0;
696} 510}
697 511
698int AVCIdentifySubunit(struct firesat *firesat) 512int avc_identify_subunit(struct firesat *firesat)
699{ 513{
700 AVCCmdFrm CmdFrm; 514 AVCCmdFrm CmdFrm;
701 AVCRspFrm RspFrm; 515 AVCRspFrm RspFrm;
@@ -718,22 +532,21 @@ int AVCIdentifySubunit(struct firesat *firesat)
718 532
719 CmdFrm.length=12; 533 CmdFrm.length=12;
720 534
721 if(AVCWrite(firesat,&CmdFrm,&RspFrm)<0) 535 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
722 return -EIO; 536 return -EIO;
723 537
724 if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { 538 if ((RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) ||
725 printk(KERN_ERR "%s: AVCWrite returned error code %d\n", 539 (RspFrm.operand[3] << 8) + RspFrm.operand[4] != 8) {
726 __func__, RspFrm.resp); 540 dev_err(&firesat->ud->device,
727 return -EINVAL; 541 "cannot read subunit identifier\n");
728 }
729 if(((RspFrm.operand[3] << 8) + RspFrm.operand[4]) != 8) {
730 printk(KERN_ERR "%s: Invalid response length\n", __func__);
731 return -EINVAL; 542 return -EINVAL;
732 } 543 }
733 return 0; 544 return 0;
734} 545}
735 546
736int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) { 547int avc_tuner_status(struct firesat *firesat,
548 ANTENNA_INPUT_INFO *antenna_input_info)
549{
737 AVCCmdFrm CmdFrm; 550 AVCCmdFrm CmdFrm;
738 AVCRspFrm RspFrm; 551 AVCRspFrm RspFrm;
739 int length; 552 int length;
@@ -754,37 +567,32 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in
754 CmdFrm.operand[5]=0x00; 567 CmdFrm.operand[5]=0x00;
755 CmdFrm.operand[6]=0x00; 568 CmdFrm.operand[6]=0x00;
756 CmdFrm.length=12; 569 CmdFrm.length=12;
757 if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 570
571 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
758 return -EIO; 572 return -EIO;
759 573
760 if(RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) { 574 if (RspFrm.resp != STABLE && RspFrm.resp != ACCEPTED) {
761 printk(KERN_ERR "%s: AVCWrite returned code %d\n", 575 dev_err(&firesat->ud->device, "cannot read tuner status\n");
762 __func__, RspFrm.resp);
763 return -EINVAL; 576 return -EINVAL;
764 } 577 }
765 578
766 length = RspFrm.operand[9]; 579 length = RspFrm.operand[9];
767 if(RspFrm.operand[1] == 0x10 && length == sizeof(ANTENNA_INPUT_INFO)) 580 if (RspFrm.operand[1] != 0x10 || length != sizeof(ANTENNA_INPUT_INFO)) {
768 { 581 dev_err(&firesat->ud->device, "got invalid tuner status\n");
769 memcpy(antenna_input_info, &RspFrm.operand[10], 582 return -EINVAL;
770 sizeof(ANTENNA_INPUT_INFO));
771 return 0;
772 } 583 }
773 printk(KERN_ERR "%s: invalid tuner status (op=%d,length=%d) returned " 584
774 "from AVC\n", __func__, RspFrm.operand[1], length); 585 memcpy(antenna_input_info, &RspFrm.operand[10], length);
775 return -EINVAL; 586 return 0;
776} 587}
777 588
778int AVCLNBControl(struct firesat *firesat, char voltage, char burst, 589int avc_lnb_control(struct firesat *firesat, char voltage, char burst,
779 char conttone, char nrdiseq, 590 char conttone, char nrdiseq,
780 struct dvb_diseqc_master_cmd *diseqcmd) 591 struct dvb_diseqc_master_cmd *diseqcmd)
781{ 592{
782 AVCCmdFrm CmdFrm; 593 AVCCmdFrm CmdFrm;
783 AVCRspFrm RspFrm; 594 AVCRspFrm RspFrm;
784 int i,j; 595 int i, j, k;
785
786 printk(KERN_INFO "%s: voltage = %x, burst = %x, conttone = %x\n",
787 __func__, voltage, burst, conttone);
788 596
789 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 597 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
790 598
@@ -804,85 +612,33 @@ int AVCLNBControl(struct firesat *firesat, char voltage, char burst,
804 612
805 i=6; 613 i=6;
806 614
807 for(j=0;j<nrdiseq;j++) { 615 for (j = 0; j < nrdiseq; j++) {
808 int k; 616 CmdFrm.operand[i++] = diseqcmd[j].msg_len;
809 printk(KERN_INFO "%s: diseq %d len %x\n",
810 __func__, j, diseqcmd[j].msg_len);
811 CmdFrm.operand[i++]=diseqcmd[j].msg_len;
812 617
813 for(k=0;k<diseqcmd[j].msg_len;k++) { 618 for (k = 0; k < diseqcmd[j].msg_len; k++)
814 printk(KERN_INFO "%s: diseq %d msg[%d] = %x\n", 619 CmdFrm.operand[i++] = diseqcmd[j].msg[k];
815 __func__, j, k, diseqcmd[j].msg[k]);
816 CmdFrm.operand[i++]=diseqcmd[j].msg[k];
817 }
818 } 620 }
819 621
820 CmdFrm.operand[i++]=burst; 622 CmdFrm.operand[i++]=burst;
821 CmdFrm.operand[i++]=conttone; 623 CmdFrm.operand[i++]=conttone;
822 624
823 CmdFrm.length=i+3; 625 CmdFrm.length = ALIGN(3 + i, 4);
824 if((i+3)%4)
825 CmdFrm.length += 4 - ((i+3)%4);
826 626
827/* for(j=0;j<CmdFrm.length;j++) 627 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
828 printk(KERN_INFO "%s: CmdFrm.operand[%d]=0x%x\n",__func__,j,CmdFrm.operand[j]);
829
830 printk(KERN_INFO "%s: cmdfrm.length = %u\n",__func__,CmdFrm.length);
831 */
832 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
833 return -EIO; 628 return -EIO;
834 629
835 if(RspFrm.resp != ACCEPTED) { 630 if (RspFrm.resp != ACCEPTED) {
836 printk(KERN_ERR "%s: AVCWrite returned code %d\n", 631 dev_err(&firesat->ud->device, "LNB control failed\n");
837 __func__, RspFrm.resp);
838 return -EINVAL;
839 }
840
841 return 0;
842}
843
844int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount)
845{
846 AVCCmdFrm CmdFrm;
847 AVCRspFrm RspFrm;
848
849 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
850
851 CmdFrm.cts = AVC;
852 CmdFrm.ctype = STATUS;
853 CmdFrm.sutyp = 0x1f;
854 CmdFrm.suid = 0x7;
855 CmdFrm.opcode = SUBUNIT_Info;
856
857 CmdFrm.operand[0] = 0x07;
858 CmdFrm.operand[1] = 0xff;
859 CmdFrm.operand[2] = 0xff;
860 CmdFrm.operand[3] = 0xff;
861 CmdFrm.operand[4] = 0xff;
862
863 CmdFrm.length = 8;
864
865 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
866 return -EIO;
867
868 if(RspFrm.resp != STABLE) {
869 printk(KERN_ERR "%s: AVCWrite returned code %d\n",
870 __func__, RspFrm.resp);
871 return -EINVAL; 632 return -EINVAL;
872 } 633 }
873 634
874 if(subunitcount)
875 *subunitcount = (RspFrm.operand[1] & 0x7) + 1;
876
877 return 0; 635 return 0;
878} 636}
879 637
880int AVCRegisterRemoteControl(struct firesat *firesat) 638int avc_register_remote_control(struct firesat *firesat)
881{ 639{
882 AVCCmdFrm CmdFrm; 640 AVCCmdFrm CmdFrm;
883 641
884// printk(KERN_INFO "%s\n",__func__);
885
886 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 642 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
887 643
888 CmdFrm.cts = AVC; 644 CmdFrm.cts = AVC;
@@ -898,7 +654,7 @@ int AVCRegisterRemoteControl(struct firesat *firesat)
898 654
899 CmdFrm.length = 8; 655 CmdFrm.length = 8;
900 656
901 return AVCWrite(firesat, &CmdFrm, NULL); 657 return avc_write(firesat, &CmdFrm, NULL);
902} 658}
903 659
904void avc_remote_ctrl_work(struct work_struct *work) 660void avc_remote_ctrl_work(struct work_struct *work)
@@ -907,12 +663,12 @@ void avc_remote_ctrl_work(struct work_struct *work)
907 container_of(work, struct firesat, remote_ctrl_work); 663 container_of(work, struct firesat, remote_ctrl_work);
908 664
909 /* Should it be rescheduled in failure cases? */ 665 /* Should it be rescheduled in failure cases? */
910 AVCRegisterRemoteControl(firesat); 666 avc_register_remote_control(firesat);
911} 667}
912 668
913int AVCTuner_Host2Ca(struct firesat *firesat) 669#if 0 /* FIXME: unused */
670int avc_tuner_host2ca(struct firesat *firesat)
914{ 671{
915
916 AVCCmdFrm CmdFrm; 672 AVCCmdFrm CmdFrm;
917 AVCRspFrm RspFrm; 673 AVCRspFrm RspFrm;
918 674
@@ -933,37 +689,39 @@ int AVCTuner_Host2Ca(struct firesat *firesat)
933 CmdFrm.operand[7] = 0; // length 689 CmdFrm.operand[7] = 0; // length
934 CmdFrm.length = 12; 690 CmdFrm.length = 12;
935 691
936 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 692 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
937 return -EIO; 693 return -EIO;
938 694
939 return 0; 695 return 0;
940} 696}
697#endif
941 698
942static int get_ca_object_pos(AVCRspFrm *RspFrm) 699static int get_ca_object_pos(AVCRspFrm *RspFrm)
943{ 700{
944 int length = 1; 701 int length = 1;
945 702
946 // Check length of length field 703 /* Check length of length field */
947 if (RspFrm->operand[7] & 0x80) 704 if (RspFrm->operand[7] & 0x80)
948 length = (RspFrm->operand[7] & 0x7F) + 1; 705 length = (RspFrm->operand[7] & 0x7f) + 1;
949 return length + 7; 706 return length + 7;
950} 707}
951 708
952static int get_ca_object_length(AVCRspFrm *RspFrm) 709static int get_ca_object_length(AVCRspFrm *RspFrm)
953{ 710{
711#if 0 /* FIXME: unused */
954 int size = 0; 712 int size = 0;
955 int i; 713 int i;
956 714
957 if (RspFrm->operand[7] & 0x80) { 715 if (RspFrm->operand[7] & 0x80)
958 for (i = 0; i < (RspFrm->operand[7] & 0x7F); i++) { 716 for (i = 0; i < (RspFrm->operand[7] & 0x7f); i++) {
959 size <<= 8; 717 size <<= 8;
960 size += RspFrm->operand[8 + i]; 718 size += RspFrm->operand[8 + i];
961 } 719 }
962 } 720#endif
963 return RspFrm->operand[7]; 721 return RspFrm->operand[7];
964} 722}
965 723
966int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) 724int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len)
967{ 725{
968 AVCCmdFrm CmdFrm; 726 AVCCmdFrm CmdFrm;
969 AVCRspFrm RspFrm; 727 AVCRspFrm RspFrm;
@@ -984,9 +742,10 @@ int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length)
984 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag 742 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
985 CmdFrm.length = 12; 743 CmdFrm.length = 12;
986 744
987 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 745 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
988 return -EIO; 746 return -EIO;
989 747
748 /* FIXME: check response code and validate response data */
990 749
991 pos = get_ca_object_pos(&RspFrm); 750 pos = get_ca_object_pos(&RspFrm);
992 app_info[0] = (TAG_APP_INFO >> 16) & 0xFF; 751 app_info[0] = (TAG_APP_INFO >> 16) & 0xFF;
@@ -995,16 +754,16 @@ int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length)
995 app_info[3] = 6 + RspFrm.operand[pos + 4]; 754 app_info[3] = 6 + RspFrm.operand[pos + 4];
996 app_info[4] = 0x01; 755 app_info[4] = 0x01;
997 memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); 756 memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]);
998 *length = app_info[3] + 4; 757 *len = app_info[3] + 4;
999 758
1000 return 0; 759 return 0;
1001} 760}
1002 761
1003int avc_ca_info(struct firesat *firesat, char *app_info, int *length) 762int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len)
1004{ 763{
1005 AVCCmdFrm CmdFrm; 764 AVCCmdFrm CmdFrm;
1006 AVCRspFrm RspFrm; 765 AVCRspFrm RspFrm;
1007 int pos; 766 /* int pos; FIXME: unused */
1008 767
1009 memset(&CmdFrm, 0, sizeof(AVCCmdFrm)); 768 memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
1010 CmdFrm.cts = AVC; 769 CmdFrm.cts = AVC;
@@ -1021,17 +780,17 @@ int avc_ca_info(struct firesat *firesat, char *app_info, int *length)
1021 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag 780 CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
1022 CmdFrm.length = 12; 781 CmdFrm.length = 12;
1023 782
1024 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 783 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
1025 return -EIO; 784 return -EIO;
1026 785
1027 pos = get_ca_object_pos(&RspFrm); 786 /* pos = get_ca_object_pos(&RspFrm); FIXME: unused */
1028 app_info[0] = (TAG_CA_INFO >> 16) & 0xFF; 787 app_info[0] = (TAG_CA_INFO >> 16) & 0xFF;
1029 app_info[1] = (TAG_CA_INFO >> 8) & 0xFF; 788 app_info[1] = (TAG_CA_INFO >> 8) & 0xFF;
1030 app_info[2] = (TAG_CA_INFO >> 0) & 0xFF; 789 app_info[2] = (TAG_CA_INFO >> 0) & 0xFF;
1031 app_info[3] = 2; 790 app_info[3] = 2;
1032 app_info[4] = app_info[5]; 791 app_info[4] = app_info[5];
1033 app_info[5] = app_info[6]; 792 app_info[5] = app_info[6];
1034 *length = app_info[3] + 4; 793 *len = app_info[3] + 4;
1035 794
1036 return 0; 795 return 0;
1037} 796}
@@ -1059,7 +818,7 @@ int avc_ca_reset(struct firesat *firesat)
1059 CmdFrm.operand[8] = 0; // force hardware reset 818 CmdFrm.operand[8] = 0; // force hardware reset
1060 CmdFrm.length = 12; 819 CmdFrm.length = 12;
1061 820
1062 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 821 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
1063 return -EIO; 822 return -EIO;
1064 823
1065 return 0; 824 return 0;
@@ -1085,9 +844,8 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length)
1085 CmdFrm.opcode = VENDOR; 844 CmdFrm.opcode = VENDOR;
1086 845
1087 if (msg[0] != LIST_MANAGEMENT_ONLY) { 846 if (msg[0] != LIST_MANAGEMENT_ONLY) {
1088 printk(KERN_INFO "%s: list_management %d not support. " 847 dev_info(&firesat->ud->device,
1089 "Forcing list_management to \"only\" (3). \n", 848 "forcing list_management to ONLY\n");
1090 __func__, msg[0]);
1091 msg[0] = LIST_MANAGEMENT_ONLY; 849 msg[0] = LIST_MANAGEMENT_ONLY;
1092 } 850 }
1093 // We take the cmd_id from the programme level only! 851 // We take the cmd_id from the programme level only!
@@ -1134,20 +892,17 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length)
1134 read_pos = 6; 892 read_pos = 6;
1135 write_pos = 22; 893 write_pos = 22;
1136 if (program_info_length > 0) { 894 if (program_info_length > 0) {
1137/* printk(KERN_INFO "Copying descriptors at programme level.\n"); */
1138 pmt_cmd_id = msg[read_pos++]; 895 pmt_cmd_id = msg[read_pos++];
1139 if (pmt_cmd_id != 1 && pmt_cmd_id !=4) { 896 if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
1140 printk(KERN_ERR "Invalid pmt_cmd_id=%d.\n", 897 dev_err(&firesat->ud->device,
1141 pmt_cmd_id); 898 "invalid pmt_cmd_id %d\n", pmt_cmd_id);
1142 } 899
1143 memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], 900 memcpy(&CmdFrm.operand[write_pos], &msg[read_pos],
1144 program_info_length); 901 program_info_length);
1145 read_pos += program_info_length; 902 read_pos += program_info_length;
1146 write_pos += program_info_length; 903 write_pos += program_info_length;
1147 } 904 }
1148 while (read_pos < length) { 905 while (read_pos < length) {
1149/* printk(KERN_INFO "Copying descriptors at stream level for " */
1150/* "stream type %d.\n", msg[read_pos]); */
1151 CmdFrm.operand[write_pos++] = msg[read_pos++]; 906 CmdFrm.operand[write_pos++] = msg[read_pos++];
1152 CmdFrm.operand[write_pos++] = msg[read_pos++]; 907 CmdFrm.operand[write_pos++] = msg[read_pos++];
1153 CmdFrm.operand[write_pos++] = msg[read_pos++]; 908 CmdFrm.operand[write_pos++] = msg[read_pos++];
@@ -1160,10 +915,11 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length)
1160 CmdFrm.operand[write_pos++] = es_info_length & 0xFF; 915 CmdFrm.operand[write_pos++] = es_info_length & 0xFF;
1161 if (es_info_length > 0) { 916 if (es_info_length > 0) {
1162 pmt_cmd_id = msg[read_pos++]; 917 pmt_cmd_id = msg[read_pos++];
1163 if (pmt_cmd_id != 1 && pmt_cmd_id !=4) { 918 if (pmt_cmd_id != 1 && pmt_cmd_id != 4)
1164 printk(KERN_ERR "Invalid pmt_cmd_id=%d at " 919 dev_err(&firesat->ud->device,
1165 "stream level.\n", pmt_cmd_id); 920 "invalid pmt_cmd_id %d "
1166 } 921 "at stream level\n", pmt_cmd_id);
922
1167 memcpy(&CmdFrm.operand[write_pos], &msg[read_pos], 923 memcpy(&CmdFrm.operand[write_pos], &msg[read_pos],
1168 es_info_length); 924 es_info_length);
1169 read_pos += es_info_length; 925 read_pos += es_info_length;
@@ -1187,20 +943,18 @@ int avc_ca_pmt(struct firesat *firesat, char *msg, int length)
1187 CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF; 943 CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF;
1188 CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF; 944 CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF;
1189 945
1190 CmdFrm.length = write_pos + 3; 946 CmdFrm.length = ALIGN(3 + write_pos, 4);
1191 if ((write_pos + 3) % 4)
1192 CmdFrm.length += 4 - ((write_pos + 3) % 4);
1193 947
1194 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 948 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
1195 return -EIO; 949 return -EIO;
1196 950
1197 if (RspFrm.resp != ACCEPTED) { 951 if (RspFrm.resp != ACCEPTED) {
1198 printk(KERN_ERR "Answer to CA PMT was %d\n", RspFrm.resp); 952 dev_err(&firesat->ud->device,
953 "CA PMT failed with response 0x%x\n", RspFrm.resp);
1199 return -EFAULT; 954 return -EFAULT;
1200 } 955 }
1201 956
1202 return 0; 957 return 0;
1203
1204} 958}
1205 959
1206int avc_ca_get_time_date(struct firesat *firesat, int *interval) 960int avc_ca_get_time_date(struct firesat *firesat, int *interval)
@@ -1225,9 +979,11 @@ int avc_ca_get_time_date(struct firesat *firesat, int *interval)
1225 CmdFrm.operand[7] = 0; // length 979 CmdFrm.operand[7] = 0; // length
1226 CmdFrm.length = 12; 980 CmdFrm.length = 12;
1227 981
1228 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 982 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
1229 return -EIO; 983 return -EIO;
1230 984
985 /* FIXME: check response code and validate response data */
986
1231 *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)]; 987 *interval = RspFrm.operand[get_ca_object_pos(&RspFrm)];
1232 988
1233 return 0; 989 return 0;
@@ -1255,13 +1011,13 @@ int avc_ca_enter_menu(struct firesat *firesat)
1255 CmdFrm.operand[7] = 0; // length 1011 CmdFrm.operand[7] = 0; // length
1256 CmdFrm.length = 12; 1012 CmdFrm.length = 12;
1257 1013
1258 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 1014 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
1259 return -EIO; 1015 return -EIO;
1260 1016
1261 return 0; 1017 return 0;
1262} 1018}
1263 1019
1264int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length) 1020int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len)
1265{ 1021{
1266 AVCCmdFrm CmdFrm; 1022 AVCCmdFrm CmdFrm;
1267 AVCRspFrm RspFrm; 1023 AVCRspFrm RspFrm;
@@ -1283,11 +1039,13 @@ int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length)
1283 CmdFrm.operand[7] = 0; // length 1039 CmdFrm.operand[7] = 0; // length
1284 CmdFrm.length = 12; 1040 CmdFrm.length = 12;
1285 1041
1286 if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) 1042 if (avc_write(firesat, &CmdFrm, &RspFrm) < 0)
1287 return -EIO; 1043 return -EIO;
1288 1044
1289 *length = get_ca_object_length(&RspFrm); 1045 /* FIXME: check response code and validate response data */
1290 memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *length); 1046
1047 *len = get_ca_object_length(&RspFrm);
1048 memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *len);
1291 1049
1292 return 0; 1050 return 0;
1293} 1051}
diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h
index 66f419a6f7c6..9d2efd8ff17b 100644
--- a/drivers/media/dvb/firesat/avc_api.h
+++ b/drivers/media/dvb/firesat/avc_api.h
@@ -26,15 +26,6 @@
26**************************************************************/ 26**************************************************************/
27#define LIST_MANAGEMENT_ONLY 0x03 27#define LIST_MANAGEMENT_ONLY 0x03
28 28
29/*************************************************************
30 FCP Address range
31**************************************************************/
32
33#define RESPONSE_REGISTER 0xFFFFF0000D00ULL
34#define COMMAND_REGISTER 0xFFFFF0000B00ULL
35#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
36
37
38/************************************************************ 29/************************************************************
39 definition of structures 30 definition of structures
40*************************************************************/ 31*************************************************************/
@@ -413,34 +404,29 @@ struct dvb_diseqc_master_cmd;
413struct dvb_frontend_parameters; 404struct dvb_frontend_parameters;
414struct firesat; 405struct firesat;
415 406
416int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, 407int avc_recv(struct firesat *firesat, u8 *data, size_t length);
417 AVCRspFrm *RspFrm);
418int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
419 408
420int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, 409int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug,
421 struct dvb_frontend_parameters *params, __u8 *status); 410 struct dvb_frontend_parameters *params, __u8 *status);
422 411
423int AVCTunerStatus(struct firesat *firesat, 412int avc_tuner_status(struct firesat *firesat,
424 ANTENNA_INPUT_INFO *antenna_input_info); 413 ANTENNA_INPUT_INFO *antenna_input_info);
425int AVCTuner_DSD(struct firesat *firesat, 414int avc_tuner_dsd(struct firesat *firesat,
426 struct dvb_frontend_parameters *params, __u8 *status); 415 struct dvb_frontend_parameters *params);
427int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); 416int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]);
428int AVCTuner_GetTS(struct firesat *firesat); 417int avc_tuner_get_ts(struct firesat *firesat);
429 418int avc_identify_subunit(struct firesat *firesat);
430int AVCIdentifySubunit(struct firesat *firesat); 419int avc_lnb_control(struct firesat *firesat, char voltage, char burst,
431int AVCLNBControl(struct firesat *firesat, char voltage, char burst,
432 char conttone, char nrdiseq, 420 char conttone, char nrdiseq,
433 struct dvb_diseqc_master_cmd *diseqcmd); 421 struct dvb_diseqc_master_cmd *diseqcmd);
434int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
435void avc_remote_ctrl_work(struct work_struct *work); 422void avc_remote_ctrl_work(struct work_struct *work);
436int AVCRegisterRemoteControl(struct firesat *firesat); 423int avc_register_remote_control(struct firesat *firesat);
437int AVCTuner_Host2Ca(struct firesat *firesat); 424int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len);
438int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); 425int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len);
439int avc_ca_info(struct firesat *firesat, char *app_info, int *length);
440int avc_ca_reset(struct firesat *firesat); 426int avc_ca_reset(struct firesat *firesat);
441int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); 427int avc_ca_pmt(struct firesat *firesat, char *app_info, int length);
442int avc_ca_get_time_date(struct firesat *firesat, int *interval); 428int avc_ca_get_time_date(struct firesat *firesat, int *interval);
443int avc_ca_enter_menu(struct firesat *firesat); 429int avc_ca_enter_menu(struct firesat *firesat);
444int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); 430int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len);
445 431
446#endif /* _AVC_API_H */ 432#endif /* _AVC_API_H */
diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c
index d1bafba615e4..8e98b814e430 100644
--- a/drivers/media/dvb/firesat/cmp.c
+++ b/drivers/media/dvb/firesat/cmp.c
@@ -10,37 +10,21 @@
10 * the License, or (at your option) any later version. 10 * the License, or (at your option) any later version.
11 */ 11 */
12 12
13#include <linux/device.h>
13#include <linux/kernel.h> 14#include <linux/kernel.h>
14#include <linux/mutex.h> 15#include <linux/mutex.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#include <hosts.h> 18#include <asm/byteorder.h>
19
18#include <ieee1394.h> 20#include <ieee1394.h>
19#include <ieee1394_core.h>
20#include <ieee1394_transactions.h>
21#include <nodemgr.h> 21#include <nodemgr.h>
22 22
23#include "avc_api.h" 23#include "avc_api.h"
24#include "cmp.h" 24#include "cmp.h"
25#include "firesat.h" 25#include "firesat.h"
26 26
27typedef struct _OPCR 27#define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
28{
29 __u8 PTPConnCount : 6 ; // Point to point connect. counter
30 __u8 BrConnCount : 1 ; // Broadcast connection counter
31 __u8 OnLine : 1 ; // On Line
32
33 __u8 ChNr : 6 ; // Channel number
34 __u8 Res : 2 ; // Reserved
35
36 __u8 PayloadHi : 2 ; // Payoad high bits
37 __u8 OvhdID : 4 ; // Overhead ID
38 __u8 DataRate : 2 ; // Data Rate
39
40 __u8 PayloadLo ; // Payoad low byte
41} OPCR ;
42
43#define FIRESAT_SPEED IEEE1394_SPEED_400
44 28
45static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) 29static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len)
46{ 30{
@@ -49,151 +33,139 @@ static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len)
49 if (mutex_lock_interruptible(&firesat->avc_mutex)) 33 if (mutex_lock_interruptible(&firesat->avc_mutex))
50 return -EINTR; 34 return -EINTR;
51 35
52 ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, 36 ret = hpsb_node_read(firesat->ud->ne, addr, buf, len);
53 firesat->nodeentry->generation, addr, buf, len); 37 if (ret < 0)
38 dev_err(&firesat->ud->device, "CMP: read I/O error\n");
54 39
55 mutex_unlock(&firesat->avc_mutex); 40 mutex_unlock(&firesat->avc_mutex);
56 return ret; 41 return ret;
57} 42}
58 43
59static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, 44static int cmp_lock(struct firesat *firesat, void *data, u64 addr, __be32 arg,
60 quadlet_t arg, int ext_tcode) 45 int ext_tcode)
61{ 46{
62 int ret; 47 int ret;
63 48
64 if (mutex_lock_interruptible(&firesat->avc_mutex)) 49 if (mutex_lock_interruptible(&firesat->avc_mutex))
65 return -EINTR; 50 return -EINTR;
66 51
67 ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, 52 ret = hpsb_node_lock(firesat->ud->ne, addr, ext_tcode, data,
68 firesat->nodeentry->generation, 53 (__force quadlet_t)arg);
69 addr, ext_tcode, data, arg); 54 if (ret < 0)
55 dev_err(&firesat->ud->device, "CMP: lock I/O error\n");
70 56
71 mutex_unlock(&firesat->avc_mutex); 57 mutex_unlock(&firesat->avc_mutex);
72 return ret; 58 return ret;
73} 59}
74 60
75//try establishing a point-to-point connection (may be interrupted by a busreset 61static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
76int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) { 62{
77 unsigned int BWU; //bandwidth to allocate 63 return (be32_to_cpu(opcr) >> shift) & mask;
64}
65
66static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
67{
68 *opcr &= ~cpu_to_be32(mask << shift);
69 *opcr |= cpu_to_be32((value & mask) << shift);
70}
78 71
79 quadlet_t old_oPCR,test_oPCR = 0x0; 72#define get_opcr_online(v) get_opcr((v), 0x1, 31)
80 u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); 73#define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
81 int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); 74#define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
82 75
83/* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */ 76#define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
77#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
78#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
79#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
84 80
85 if (result < 0) { 81int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel)
86 printk("%s: cannot read oPCR\n", __func__); 82{
87 return result; 83 __be32 old_opcr, opcr;
88 } else { 84 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
89/* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */ 85 int attempts = 0;
90 do { 86 int ret;
91 OPCR *hilf= (OPCR*) &test_oPCR; 87
92 88 ret = cmp_read(firesat, &opcr, opcr_address, 4);
93 if (!hilf->OnLine) { 89 if (ret < 0)
94 printk("%s: Output offline; oPCR: %08x\n", __func__, test_oPCR); 90 return ret;
95 return -EBUSY; 91
96 } else { 92repeat:
97 quadlet_t new_oPCR; 93 if (!get_opcr_online(opcr)) {
98 94 dev_err(&firesat->ud->device, "CMP: output offline\n");
99 old_oPCR=test_oPCR; 95 return -EBUSY;
100 if (hilf->PTPConnCount) { 96 }
101 if (hilf->ChNr != iso_channel) { 97
102 printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__func__,hilf->ChNr,iso_channel); 98 old_opcr = opcr;
103 return -EBUSY; 99
104 } else 100 if (get_opcr_p2p_connections(opcr)) {
105 printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__func__, hilf->PTPConnCount); 101 if (get_opcr_channel(opcr) != channel) {
106 BWU=0; //we allocate no bandwidth (is this necessary?) 102 dev_err(&firesat->ud->device,
107 } else { 103 "CMP: cannot change channel\n");
108 hilf->ChNr=iso_channel; 104 return -EBUSY;
109 hilf->DataRate=FIRESAT_SPEED;
110
111 hilf->OvhdID=0; //FIXME: that is for worst case -> optimize
112 BWU=hilf->OvhdID?hilf->OvhdID*32:512;
113 BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
114/* if (allocate_1394_resources(iso_channel,BWU))
115 {
116 cout << "Allocation of resources failed\n";
117 return -2;
118 }*/
119 }
120
121 hilf->PTPConnCount++;
122 new_oPCR=test_oPCR;
123/* printk(KERN_INFO "%s: trying compare_swap...\n",__func__); */
124/* printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); */
125 result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
126
127 if (result < 0) {
128 printk("%s: cannot compare_swap oPCR\n",__func__);
129 return result;
130 }
131 if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount))
132 {
133 printk("%s: change of oPCR failed -> freeing resources\n",__func__);
134// hilf= (OPCR*) &new_oPCR;
135// unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
136// BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate));
137/* if (deallocate_1394_resources(iso_channel,BWU))
138 {
139
140 cout << "Deallocation of resources failed\n";
141 return -3;
142 }*/
143 }
144 }
145 } 105 }
146 while (old_oPCR != test_oPCR); 106 dev_info(&firesat->ud->device,
107 "CMP: overlaying existing connection\n");
108
109 /* We don't allocate isochronous resources. */
110 } else {
111 set_opcr_channel(&opcr, channel);
112 set_opcr_data_rate(&opcr, IEEE1394_SPEED_400);
113
114 /* FIXME: this is for the worst case - optimize */
115 set_opcr_overhead_id(&opcr, 0);
116
117 /* FIXME: allocate isochronous channel and bandwidth at IRM */
147 } 118 }
119
120 set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
121
122 ret = cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2);
123 if (ret < 0)
124 return ret;
125
126 if (old_opcr != opcr) {
127 /*
128 * FIXME: if old_opcr.P2P_Connections > 0,
129 * deallocate isochronous channel and bandwidth at IRM
130 */
131
132 if (++attempts < 6) /* arbitrary limit */
133 goto repeat;
134 return -EBUSY;
135 }
136
148 return 0; 137 return 0;
149} 138}
150 139
151//try breaking a point-to-point connection (may be interrupted by a busreset 140void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel)
152int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) { 141{
153 quadlet_t old_oPCR,test_oPCR; 142 __be32 old_opcr, opcr;
143 u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
144 int attempts = 0;
145
146 if (cmp_read(firesat, &opcr, opcr_address, 4) < 0)
147 return;
148
149repeat:
150 if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
151 get_opcr_channel(opcr) != channel) {
152 dev_err(&firesat->ud->device, "CMP: no connection to break\n");
153 return;
154 }
155
156 old_opcr = opcr;
157 set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
154 158
155 u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); 159 if (cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2) < 0)
156 int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); 160 return;
157 161
158/* printk(KERN_INFO "%s\n",__func__); */ 162 if (old_opcr != opcr) {
163 /*
164 * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
165 * owner, deallocate isochronous channel and bandwidth at IRM
166 */
159 167
160 if (result < 0) { 168 if (++attempts < 6) /* arbitrary limit */
161 printk("%s: cannot read oPCR\n", __func__); 169 goto repeat;
162 return result; 170 }
163 } else {
164 do {
165 OPCR *hilf= (OPCR*) &test_oPCR;
166
167 if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) {
168 printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __func__, test_oPCR);
169 return -EINVAL;
170 } else {
171 quadlet_t new_oPCR;
172 old_oPCR=test_oPCR;
173 hilf->PTPConnCount--;
174 new_oPCR=test_oPCR;
175
176// printk(KERN_INFO "%s: trying compare_swap...\n", __func__);
177 result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
178 if (result < 0) {
179 printk("%s: cannot compare_swap oPCR\n",__func__);
180 return result;
181 }
182 }
183
184 } while (old_oPCR != test_oPCR);
185
186/* hilf = (OPCR*) &old_oPCR;
187 if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection
188 cout << "deallocating 1394 resources\n";
189 unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
190 BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
191 if (deallocate_1394_resources(iso_channel,BWU))
192 {
193 cout << "Deallocation of resources failed\n";
194 return -3;
195 }
196 }*/
197 }
198 return 0;
199} 171}
diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h
index 600d5784dc72..d92f6c7fb5d5 100644
--- a/drivers/media/dvb/firesat/cmp.h
+++ b/drivers/media/dvb/firesat/cmp.h
@@ -3,9 +3,7 @@
3 3
4struct firesat; 4struct firesat;
5 5
6int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, 6int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel);
7 int iso_channel); 7void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel);
8int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,
9 int iso_channel);
10 8
11#endif /* _CMP_H */ 9#endif /* _CMP_H */
diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c
index 3ef25cc4bfdb..0deb47eefa10 100644
--- a/drivers/media/dvb/firesat/firesat-ci.c
+++ b/drivers/media/dvb/firesat/firesat-ci.c
@@ -20,29 +20,18 @@
20#include "firesat.h" 20#include "firesat.h"
21#include "firesat-ci.h" 21#include "firesat-ci.h"
22 22
23static unsigned int ca_debug = 0;
24module_param(ca_debug, int, 0644);
25MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)");
26
27static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) 23static int firesat_ca_ready(ANTENNA_INPUT_INFO *info)
28{ 24{
29 if (ca_debug != 0)
30 printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, "
31 "CaModule=%d, CaAppInfo=%d, CaDateTime=%d, "
32 "CaPmt=%d\n", __func__, info->CaMmi,
33 info->CaInitializationStatus, info->CaErrorFlag,
34 info->CaDvbFlag, info->CaModulePresentStatus,
35 info->CaApplicationInfo,
36 info->CaDateTimeRequest, info->CaPmtReply);
37 return info->CaInitializationStatus == 1 && 25 return info->CaInitializationStatus == 1 &&
38 info->CaErrorFlag == 0 && 26 info->CaErrorFlag == 0 &&
39 info->CaDvbFlag == 1 && 27 info->CaDvbFlag == 1 &&
40 info->CaModulePresentStatus == 1; 28 info->CaModulePresentStatus == 1;
41} 29}
42 30
43static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) 31static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info)
44{ 32{
45 int flags = 0; 33 int flags = 0;
34
46 if (info->CaModulePresentStatus == 1) 35 if (info->CaModulePresentStatus == 1)
47 flags |= CA_CI_MODULE_PRESENT; 36 flags |= CA_CI_MODULE_PRESENT;
48 if (info->CaInitializationStatus == 1 && 37 if (info->CaInitializationStatus == 1 &&
@@ -54,103 +43,63 @@ static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info)
54 43
55static int firesat_ca_reset(struct firesat *firesat) 44static int firesat_ca_reset(struct firesat *firesat)
56{ 45{
57 if (ca_debug) 46 return avc_ca_reset(firesat) ? -EFAULT : 0;
58 printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__);
59 if (avc_ca_reset(firesat))
60 return -EFAULT;
61 return 0;
62} 47}
63 48
64static int firesat_ca_get_caps(struct firesat *firesat, void *arg) 49static int firesat_ca_get_caps(void *arg)
65{ 50{
66 struct ca_caps *cap_p = (struct ca_caps*)arg; 51 struct ca_caps *cap = arg;
67 int err = 0; 52
68 53 cap->slot_num = 1;
69 cap_p->slot_num = 1; 54 cap->slot_type = CA_CI;
70 cap_p->slot_type = CA_CI; 55 cap->descr_num = 1;
71 cap_p->descr_num = 1; 56 cap->descr_type = CA_ECD;
72 cap_p->descr_type = CA_ECD; 57 return 0;
73 if (ca_debug)
74 printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__);
75 return err;
76} 58}
77 59
78static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) 60static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg)
79{ 61{
80 ANTENNA_INPUT_INFO info; 62 ANTENNA_INPUT_INFO info;
81 struct ca_slot_info *slot_p = (struct ca_slot_info*)arg; 63 struct ca_slot_info *slot = arg;
82 64
83 if (ca_debug) 65 if (avc_tuner_status(firesat, &info))
84 printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n",
85 __func__, slot_p->num);
86 if (AVCTunerStatus(firesat, &info))
87 return -EFAULT; 66 return -EFAULT;
88 67
89 if (slot_p->num == 0) { 68 if (slot->num != 0)
90 slot_p->type = CA_CI;
91 slot_p->flags = firesat_get_ca_flags(&info);
92 }
93 else {
94 return -EFAULT; 69 return -EFAULT;
95 } 70
71 slot->type = CA_CI;
72 slot->flags = firesat_get_ca_flags(&info);
96 return 0; 73 return 0;
97} 74}
98 75
99static int firesat_ca_app_info(struct firesat *firesat, void *arg) 76static int firesat_ca_app_info(struct firesat *firesat, void *arg)
100{ 77{
101 struct ca_msg *reply_p = (struct ca_msg*)arg; 78 struct ca_msg *reply = arg;
102 int i;
103 79
104 if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length)) 80 return
105 return -EFAULT; 81 avc_ca_app_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0;
106 if (ca_debug) {
107 printk(KERN_INFO "%s: Creating TAG_APP_INFO message:",
108 __func__);
109 for (i = 0; i < reply_p->length; i++)
110 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
111 printk("\n");
112 }
113 return 0;
114} 82}
115 83
116static int firesat_ca_info(struct firesat *firesat, void *arg) 84static int firesat_ca_info(struct firesat *firesat, void *arg)
117{ 85{
118 struct ca_msg *reply_p = (struct ca_msg*)arg; 86 struct ca_msg *reply = arg;
119 int i;
120 87
121 if (avc_ca_info(firesat, reply_p->msg, &reply_p->length)) 88 return avc_ca_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0;
122 return -EFAULT;
123 if (ca_debug) {
124 printk(KERN_INFO "%s: Creating TAG_CA_INFO message:",
125 __func__);
126 for (i = 0; i < reply_p->length; i++)
127 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
128 printk("\n");
129 }
130 return 0;
131} 89}
132 90
133static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) 91static int firesat_ca_get_mmi(struct firesat *firesat, void *arg)
134{ 92{
135 struct ca_msg *reply_p = (struct ca_msg*)arg; 93 struct ca_msg *reply = arg;
136 int i;
137 94
138 if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length)) 95 return
139 return -EFAULT; 96 avc_ca_get_mmi(firesat, reply->msg, &reply->length) ? -EFAULT : 0;
140 if (ca_debug) {
141 printk(KERN_INFO "%s: Creating MMI reply INFO message:",
142 __func__);
143 for (i = 0; i < reply_p->length; i++)
144 printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
145 printk("\n");
146 }
147 return 0;
148} 97}
149 98
150static int firesat_ca_get_msg(struct firesat *firesat, void *arg) 99static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
151{ 100{
152 int err;
153 ANTENNA_INPUT_INFO info; 101 ANTENNA_INPUT_INFO info;
102 int err;
154 103
155 switch (firesat->ca_last_command) { 104 switch (firesat->ca_last_command) {
156 case TAG_APP_INFO_ENQUIRY: 105 case TAG_APP_INFO_ENQUIRY:
@@ -160,11 +109,10 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
160 err = firesat_ca_info(firesat, arg); 109 err = firesat_ca_info(firesat, arg);
161 break; 110 break;
162 default: 111 default:
163 if (AVCTunerStatus(firesat, &info)) 112 if (avc_tuner_status(firesat, &info))
164 err = -EFAULT; 113 err = -EFAULT;
165 else if (info.CaMmi == 1) { 114 else if (info.CaMmi == 1)
166 err = firesat_ca_get_mmi(firesat, arg); 115 err = firesat_ca_get_mmi(firesat, arg);
167 }
168 else { 116 else {
169 printk(KERN_INFO "%s: Unhandled message 0x%08X\n", 117 printk(KERN_INFO "%s: Unhandled message 0x%08X\n",
170 __func__, firesat->ca_last_command); 118 __func__, firesat->ca_last_command);
@@ -177,51 +125,39 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
177 125
178static int firesat_ca_pmt(struct firesat *firesat, void *arg) 126static int firesat_ca_pmt(struct firesat *firesat, void *arg)
179{ 127{
180 struct ca_msg *msg_p = (struct ca_msg*)arg; 128 struct ca_msg *msg = arg;
181 int data_pos; 129 int data_pos;
182 130
183 if (msg_p->msg[3] & 0x80) 131 if (msg->msg[3] & 0x80)
184 data_pos = (msg_p->msg[4] && 0x7F) + 4; 132 data_pos = (msg->msg[4] && 0x7F) + 4;
185 else 133 else
186 data_pos = 4; 134 data_pos = 4;
187 if (avc_ca_pmt(firesat, &msg_p->msg[data_pos], 135
188 msg_p->length - data_pos)) 136 return avc_ca_pmt(firesat, &msg->msg[data_pos],
189 return -EFAULT; 137 msg->length - data_pos) ? -EFAULT : 0;
190 return 0;
191} 138}
192 139
193static int firesat_ca_send_msg(struct firesat *firesat, void *arg) 140static int firesat_ca_send_msg(struct firesat *firesat, void *arg)
194{ 141{
142 struct ca_msg *msg = arg;
195 int err; 143 int err;
196 struct ca_msg *msg_p = (struct ca_msg*)arg;
197 144
198 // Do we need a semaphore for this? 145 /* Do we need a semaphore for this? */
199 firesat->ca_last_command = 146 firesat->ca_last_command =
200 (msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2]; 147 (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2];
201 switch (firesat->ca_last_command) { 148 switch (firesat->ca_last_command) {
202 case TAG_CA_PMT: 149 case TAG_CA_PMT:
203 if (ca_debug != 0)
204 printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n",
205 __func__);
206 err = firesat_ca_pmt(firesat, arg); 150 err = firesat_ca_pmt(firesat, arg);
207 break; 151 break;
208 case TAG_APP_INFO_ENQUIRY: 152 case TAG_APP_INFO_ENQUIRY:
209 // This is all handled in ca_get_msg 153 /* handled in ca_get_msg */
210 if (ca_debug != 0)
211 printk(KERN_INFO "%s: Message received: "
212 "TAG_APP_INFO_ENQUIRY\n", __func__);
213 err = 0; 154 err = 0;
214 break; 155 break;
215 case TAG_CA_INFO_ENQUIRY: 156 case TAG_CA_INFO_ENQUIRY:
216 // This is all handled in ca_get_msg 157 /* handled in ca_get_msg */
217 if (ca_debug != 0)
218 printk(KERN_INFO "%s: Message received: "
219 "TAG_CA_APP_INFO_ENQUIRY\n", __func__);
220 err = 0; 158 err = 0;
221 break; 159 break;
222 case TAG_ENTER_MENU: 160 case TAG_ENTER_MENU:
223 if (ca_debug != 0)
224 printk(KERN_INFO "%s: Entering CA menu.\n", __func__);
225 err = avc_ca_enter_menu(firesat); 161 err = avc_ca_enter_menu(firesat);
226 break; 162 break;
227 default: 163 default:
@@ -235,17 +171,17 @@ static int firesat_ca_send_msg(struct firesat *firesat, void *arg)
235static int firesat_ca_ioctl(struct inode *inode, struct file *file, 171static int firesat_ca_ioctl(struct inode *inode, struct file *file,
236 unsigned int cmd, void *arg) 172 unsigned int cmd, void *arg)
237{ 173{
238 struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; 174 struct dvb_device *dvbdev = file->private_data;
239 struct firesat *firesat = dvbdev->priv; 175 struct firesat *firesat = dvbdev->priv;
240 int err;
241 ANTENNA_INPUT_INFO info; 176 ANTENNA_INPUT_INFO info;
177 int err;
242 178
243 switch(cmd) { 179 switch(cmd) {
244 case CA_RESET: 180 case CA_RESET:
245 err = firesat_ca_reset(firesat); 181 err = firesat_ca_reset(firesat);
246 break; 182 break;
247 case CA_GET_CAP: 183 case CA_GET_CAP:
248 err = firesat_ca_get_caps(firesat, arg); 184 err = firesat_ca_get_caps(arg);
249 break; 185 break;
250 case CA_GET_SLOT_INFO: 186 case CA_GET_SLOT_INFO:
251 err = firesat_ca_get_slot_info(firesat, arg); 187 err = firesat_ca_get_slot_info(firesat, arg);
@@ -262,90 +198,52 @@ static int firesat_ca_ioctl(struct inode *inode, struct file *file,
262 err = -EOPNOTSUPP; 198 err = -EOPNOTSUPP;
263 } 199 }
264 200
265 if (AVCTunerStatus(firesat, &info)) 201 /* FIXME Is this necessary? */
266 return err; 202 avc_tuner_status(firesat, &info);
267
268 firesat_ca_ready(&info);
269 203
270 return err; 204 return err;
271} 205}
272 206
273static int firesat_get_date_time_request(struct firesat *firesat)
274{
275 if (ca_debug)
276 printk(KERN_INFO "%s: Retrieving Time/Date request\n",
277 __func__);
278 if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval))
279 return -EFAULT;
280 if (ca_debug)
281 printk(KERN_INFO "%s: Time/Date interval is %d\n",
282 __func__, firesat->ca_time_interval);
283
284 return 0;
285}
286
287static int firesat_ca_io_open(struct inode *inode, struct file *file)
288{
289 if (ca_debug != 0)
290 printk(KERN_INFO "%s\n",__func__);
291 return dvb_generic_open(inode, file);
292}
293
294static int firesat_ca_io_release(struct inode *inode, struct file *file)
295{
296 if (ca_debug != 0)
297 printk(KERN_INFO "%s\n",__func__);
298 return dvb_generic_release(inode, file);
299}
300
301static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) 207static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait)
302{ 208{
303 if (ca_debug != 0)
304 printk(KERN_INFO "%s\n",__func__);
305 return POLLIN; 209 return POLLIN;
306} 210}
307 211
308static struct file_operations firesat_ca_fops = { 212static struct file_operations firesat_ca_fops = {
309 .owner = THIS_MODULE, 213 .owner = THIS_MODULE,
310 .read = NULL, // There is no low level read anymore 214 .ioctl = dvb_generic_ioctl,
311 .write = NULL, // There is no low level write anymore 215 .open = dvb_generic_open,
312 .ioctl = dvb_generic_ioctl, 216 .release = dvb_generic_release,
313 .open = firesat_ca_io_open, 217 .poll = firesat_ca_io_poll,
314 .release = firesat_ca_io_release,
315 .poll = firesat_ca_io_poll,
316}; 218};
317 219
318static struct dvb_device firesat_ca = { 220static struct dvb_device firesat_ca = {
319 .priv = NULL, 221 .users = 1,
320 .users = 1, 222 .readers = 1,
321 .readers = 1, 223 .writers = 1,
322 .writers = 1, 224 .fops = &firesat_ca_fops,
323 .fops = &firesat_ca_fops, 225 .kernel_ioctl = firesat_ca_ioctl,
324 .kernel_ioctl = firesat_ca_ioctl,
325}; 226};
326 227
327int firesat_ca_init(struct firesat *firesat) 228int firesat_ca_register(struct firesat *firesat)
328{ 229{
329 int err;
330 ANTENNA_INPUT_INFO info; 230 ANTENNA_INPUT_INFO info;
231 int err;
331 232
332 if (AVCTunerStatus(firesat, &info)) 233 if (avc_tuner_status(firesat, &info))
333 return -EINVAL; 234 return -EINVAL;
334 235
335 if (firesat_ca_ready(&info)) { 236 if (!firesat_ca_ready(&info))
336 err = dvb_register_device(firesat->adapter, 237 return -EFAULT;
337 &firesat->cadev, 238
338 &firesat_ca, firesat, 239 err = dvb_register_device(&firesat->adapter, &firesat->cadev,
339 DVB_DEVICE_CA); 240 &firesat_ca, firesat, DVB_DEVICE_CA);
340 241
341 if (info.CaApplicationInfo == 0) 242 if (info.CaApplicationInfo == 0)
342 printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", 243 printk(KERN_ERR "%s: CaApplicationInfo is not set.\n",
343 __func__); 244 __func__);
344 if (info.CaDateTimeRequest == 1) 245 if (info.CaDateTimeRequest == 1)
345 firesat_get_date_time_request(firesat); 246 avc_ca_get_time_date(firesat, &firesat->ca_time_interval);
346 }
347 else
348 err = -EFAULT;
349 247
350 return err; 248 return err;
351} 249}
@@ -353,5 +251,5 @@ int firesat_ca_init(struct firesat *firesat)
353void firesat_ca_release(struct firesat *firesat) 251void firesat_ca_release(struct firesat *firesat)
354{ 252{
355 if (firesat->cadev) 253 if (firesat->cadev)
356 dvb_unregister_device(firesat->cadev); 254 dvb_unregister_device(firesat->cadev);
357} 255}
diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h
index 04fe4061c778..9c68cd2246a7 100644
--- a/drivers/media/dvb/firesat/firesat-ci.h
+++ b/drivers/media/dvb/firesat/firesat-ci.h
@@ -3,7 +3,7 @@
3 3
4struct firesat; 4struct firesat;
5 5
6int firesat_ca_init(struct firesat *firesat); 6int firesat_ca_register(struct firesat *firesat);
7void firesat_ca_release(struct firesat *firesat); 7void firesat_ca_release(struct firesat *firesat);
8 8
9#endif /* _FIREDTV_CI_H */ 9#endif /* _FIREDTV_CI_H */
diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c
index d3e08f9fe9f7..5f9de142ee3e 100644
--- a/drivers/media/dvb/firesat/firesat-rc.c
+++ b/drivers/media/dvb/firesat/firesat-rc.c
@@ -12,9 +12,11 @@
12#include <linux/bitops.h> 12#include <linux/bitops.h>
13#include <linux/input.h> 13#include <linux/input.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#include "firesat-rc.h" 18#include "firesat-rc.h"
19#include "firesat.h"
18 20
19/* fixed table with older keycodes, geared towards MythTV */ 21/* fixed table with older keycodes, geared towards MythTV */
20const static u16 oldtable[] = { 22const static u16 oldtable[] = {
@@ -61,7 +63,7 @@ const static u16 oldtable[] = {
61}; 63};
62 64
63/* user-modifiable table for a remote as sold in 2008 */ 65/* user-modifiable table for a remote as sold in 2008 */
64static u16 keytable[] = { 66const static u16 keytable[] = {
65 67
66 /* code from device: 0x0300...0x031f */ 68 /* code from device: 0x0300...0x031f */
67 69
@@ -123,19 +125,24 @@ static u16 keytable[] = {
123 [0x34] = KEY_EXIT, 125 [0x34] = KEY_EXIT,
124}; 126};
125 127
126static struct input_dev *idev; 128int firesat_register_rc(struct firesat *firesat, struct device *dev)
127
128int firesat_register_rc(void)
129{ 129{
130 struct input_dev *idev;
130 int i, err; 131 int i, err;
131 132
132 idev = input_allocate_device(); 133 idev = input_allocate_device();
133 if (!idev) 134 if (!idev)
134 return -ENOMEM; 135 return -ENOMEM;
135 136
137 firesat->remote_ctrl_dev = idev;
136 idev->name = "FireDTV remote control"; 138 idev->name = "FireDTV remote control";
139 idev->dev.parent = dev;
137 idev->evbit[0] = BIT_MASK(EV_KEY); 140 idev->evbit[0] = BIT_MASK(EV_KEY);
138 idev->keycode = keytable; 141 idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
142 if (!idev->keycode) {
143 err = -ENOMEM;
144 goto fail;
145 }
139 idev->keycodesize = sizeof(keytable[0]); 146 idev->keycodesize = sizeof(keytable[0]);
140 idev->keycodemax = ARRAY_SIZE(keytable); 147 idev->keycodemax = ARRAY_SIZE(keytable);
141 148
@@ -144,22 +151,31 @@ int firesat_register_rc(void)
144 151
145 err = input_register_device(idev); 152 err = input_register_device(idev);
146 if (err) 153 if (err)
147 input_free_device(idev); 154 goto fail_free_keymap;
148 155
156 return 0;
157
158fail_free_keymap:
159 kfree(idev->keycode);
160fail:
161 input_free_device(idev);
149 return err; 162 return err;
150} 163}
151 164
152void firesat_unregister_rc(void) 165void firesat_unregister_rc(struct firesat *firesat)
153{ 166{
154 input_unregister_device(idev); 167 kfree(firesat->remote_ctrl_dev->keycode);
168 input_unregister_device(firesat->remote_ctrl_dev);
155} 169}
156 170
157void firesat_handle_rc(unsigned int code) 171void firesat_handle_rc(struct firesat *firesat, unsigned int code)
158{ 172{
173 u16 *keycode = firesat->remote_ctrl_dev->keycode;
174
159 if (code >= 0x0300 && code <= 0x031f) 175 if (code >= 0x0300 && code <= 0x031f)
160 code = keytable[code - 0x0300]; 176 code = keycode[code - 0x0300];
161 else if (code >= 0x0340 && code <= 0x0354) 177 else if (code >= 0x0340 && code <= 0x0354)
162 code = keytable[code - 0x0320]; 178 code = keycode[code - 0x0320];
163 else if (code >= 0x4501 && code <= 0x451f) 179 else if (code >= 0x4501 && code <= 0x451f)
164 code = oldtable[code - 0x4501]; 180 code = oldtable[code - 0x4501];
165 else if (code >= 0x4540 && code <= 0x4542) 181 else if (code >= 0x4540 && code <= 0x4542)
@@ -170,6 +186,6 @@ void firesat_handle_rc(unsigned int code)
170 return; 186 return;
171 } 187 }
172 188
173 input_report_key(idev, code, 1); 189 input_report_key(firesat->remote_ctrl_dev, code, 1);
174 input_report_key(idev, code, 0); 190 input_report_key(firesat->remote_ctrl_dev, code, 0);
175} 191}
diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h
index 81f4fdec60f1..12c1c5c28b36 100644
--- a/drivers/media/dvb/firesat/firesat-rc.h
+++ b/drivers/media/dvb/firesat/firesat-rc.h
@@ -1,8 +1,11 @@
1#ifndef _FIREDTV_RC_H 1#ifndef _FIREDTV_RC_H
2#define _FIREDTV_RC_H 2#define _FIREDTV_RC_H
3 3
4int firesat_register_rc(void); 4struct firesat;
5void firesat_unregister_rc(void); 5struct device;
6void firesat_handle_rc(unsigned int code); 6
7int firesat_register_rc(struct firesat *firesat, struct device *dev);
8void firesat_unregister_rc(struct firesat *firesat);
9void firesat_handle_rc(struct firesat *firesat, unsigned int code);
7 10
8#endif /* _FIREDTV_RC_H */ 11#endif /* _FIREDTV_RC_H */
diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h
index 5f0de88e41a6..51f64c0afcdb 100644
--- a/drivers/media/dvb/firesat/firesat.h
+++ b/drivers/media/dvb/firesat/firesat.h
@@ -21,11 +21,11 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/wait.h> 22#include <linux/wait.h>
23#include <linux/workqueue.h> 23#include <linux/workqueue.h>
24#include <asm/atomic.h>
25 24
26#include <demux.h> 25#include <demux.h>
27#include <dmxdev.h> 26#include <dmxdev.h>
28#include <dvb_demux.h> 27#include <dvb_demux.h>
28#include <dvb_frontend.h>
29#include <dvb_net.h> 29#include <dvb_net.h>
30#include <dvbdev.h> 30#include <dvbdev.h>
31 31
@@ -127,50 +127,35 @@ enum model_type {
127 FireSAT_DVB_S2 = 4, 127 FireSAT_DVB_S2 = 4,
128}; 128};
129 129
130struct hpsb_host; 130struct input_dev;
131struct hpsb_iso; 131struct hpsb_iso;
132struct node_entry; 132struct unit_directory;
133 133
134struct firesat { 134struct firesat {
135 struct dvb_demux dvb_demux; 135 struct dvb_adapter adapter;
136 136 struct dmxdev dmxdev;
137 /* DVB bits */ 137 struct dvb_demux demux;
138 struct dvb_adapter *adapter; 138 struct dmx_frontend frontend;
139 struct dmxdev dmxdev; 139 struct dvb_net dvbnet;
140 struct dvb_demux demux; 140 struct dvb_frontend fe;
141 struct dmx_frontend frontend; 141
142 struct dvb_net dvbnet; 142 struct dvb_device *cadev;
143 struct dvb_frontend_info *frontend_info; 143 int ca_last_command;
144 struct dvb_frontend *fe; 144 int ca_time_interval;
145 145
146 struct dvb_device *cadev; 146 struct mutex avc_mutex;
147 int ca_last_command; 147 wait_queue_head_t avc_wait;
148 int ca_time_interval; 148 bool avc_reply_received;
149 149 struct work_struct remote_ctrl_work;
150 struct mutex avc_mutex; 150 struct input_dev *remote_ctrl_dev;
151 wait_queue_head_t avc_wait;
152 atomic_t avc_reply_received;
153 struct work_struct remote_ctrl_work;
154 151
155 struct firesat_channel { 152 struct firesat_channel {
156 struct firesat *firesat; 153 bool active;
157 struct dvb_demux_feed *dvbdmxfeed;
158
159 int active;
160 int id;
161 int pid; 154 int pid;
162 int type; /* 1 - TS, 2 - Filter */
163 } channel[16]; 155 } channel[16];
164 struct mutex demux_mutex; 156 struct mutex demux_mutex;
165
166 /* needed by avc_api */
167 void *respfrm;
168 int resp_length;
169 157
170 struct hpsb_host *host; 158 struct unit_directory *ud;
171 u64 guid; /* GUID of this node */
172 u32 guid_vendor_id; /* Top 24bits of guid */
173 struct node_entry *nodeentry;
174 159
175 enum model_type type; 160 enum model_type type;
176 char subunit; 161 char subunit;
@@ -181,6 +166,10 @@ struct firesat {
181 struct hpsb_iso *iso_handle; 166 struct hpsb_iso *iso_handle;
182 167
183 struct list_head list; 168 struct list_head list;
169
170 /* needed by avc_api */
171 int resp_length;
172 u8 respfrm[512];
184}; 173};
185 174
186struct firewireheader { 175struct firewireheader {
@@ -226,11 +215,10 @@ struct device;
226/* firesat_dvb.c */ 215/* firesat_dvb.c */
227int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); 216int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
228int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); 217int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
229int firesat_dvbdev_init(struct firesat *firesat, struct device *dev, 218int firesat_dvbdev_init(struct firesat *firesat, struct device *dev);
230 struct dvb_frontend *fe);
231 219
232/* firesat_fe.c */ 220/* firesat_fe.c */
233int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); 221void firesat_frontend_init(struct firesat *firesat);
234 222
235/* firesat_iso.c */ 223/* firesat_iso.c */
236int setup_iso_channel(struct firesat *firesat); 224int setup_iso_channel(struct firesat *firesat);
diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c
index a13fbe6b3a3c..82bd9786571d 100644
--- a/drivers/media/dvb/firesat/firesat_1394.c
+++ b/drivers/media/dvb/firesat/firesat_1394.c
@@ -21,7 +21,6 @@
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/types.h> 23#include <linux/types.h>
24#include <asm/atomic.h>
25 24
26#include <dmxdev.h> 25#include <dmxdev.h>
27#include <dvb_demux.h> 26#include <dvb_demux.h>
@@ -40,40 +39,54 @@
40#include "firesat-ci.h" 39#include "firesat-ci.h"
41#include "firesat-rc.h" 40#include "firesat-rc.h"
42 41
43#define FIRESAT_Vendor_ID 0x001287 42#define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
43 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION
44#define DIGITAL_EVERYWHERE_OUI 0x001287
44 45
45static struct ieee1394_device_id firesat_id_table[] = { 46static struct ieee1394_device_id firesat_id_table[] = {
46 47
47 { 48 {
48 /* FloppyDTV S/CI and FloppyDTV S2 */ 49 /* FloppyDTV S/CI and FloppyDTV S2 */
49 .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, 50 .match_flags = MATCH_FLAGS,
50 .model_id = 0x000024, 51 .vendor_id = DIGITAL_EVERYWHERE_OUI,
51 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, 52 .model_id = 0x000024,
53 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
54 .version = AVC_SW_VERSION_ENTRY,
52 },{ 55 },{
53 /* FloppyDTV T/CI */ 56 /* FloppyDTV T/CI */
54 .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, 57 .match_flags = MATCH_FLAGS,
55 .model_id = 0x000025, 58 .vendor_id = DIGITAL_EVERYWHERE_OUI,
56 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, 59 .model_id = 0x000025,
60 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
61 .version = AVC_SW_VERSION_ENTRY,
57 },{ 62 },{
58 /* FloppyDTV C/CI */ 63 /* FloppyDTV C/CI */
59 .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, 64 .match_flags = MATCH_FLAGS,
60 .model_id = 0x000026, 65 .vendor_id = DIGITAL_EVERYWHERE_OUI,
61 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, 66 .model_id = 0x000026,
67 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
68 .version = AVC_SW_VERSION_ENTRY,
62 },{ 69 },{
63 /* FireDTV S/CI and FloppyDTV S2 */ 70 /* FireDTV S/CI and FloppyDTV S2 */
64 .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, 71 .match_flags = MATCH_FLAGS,
65 .model_id = 0x000034, 72 .vendor_id = DIGITAL_EVERYWHERE_OUI,
66 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, 73 .model_id = 0x000034,
74 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
75 .version = AVC_SW_VERSION_ENTRY,
67 },{ 76 },{
68 /* FireDTV T/CI */ 77 /* FireDTV T/CI */
69 .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, 78 .match_flags = MATCH_FLAGS,
70 .model_id = 0x000035, 79 .vendor_id = DIGITAL_EVERYWHERE_OUI,
71 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, 80 .model_id = 0x000035,
81 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
82 .version = AVC_SW_VERSION_ENTRY,
72 },{ 83 },{
73 /* FireDTV C/CI */ 84 /* FireDTV C/CI */
74 .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, 85 .match_flags = MATCH_FLAGS,
75 .model_id = 0x000036, 86 .vendor_id = DIGITAL_EVERYWHERE_OUI,
76 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, 87 .model_id = 0x000036,
88 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
89 .version = AVC_SW_VERSION_ENTRY,
77 }, { } 90 }, { }
78}; 91};
79 92
@@ -98,8 +111,8 @@ static void fcp_request(struct hpsb_host *host,
98 111
99 spin_lock_irqsave(&firesat_list_lock, flags); 112 spin_lock_irqsave(&firesat_list_lock, flags);
100 list_for_each_entry(firesat_entry,&firesat_list,list) { 113 list_for_each_entry(firesat_entry,&firesat_list,list) {
101 if (firesat_entry->host == host && 114 if (firesat_entry->ud->ne->host == host &&
102 firesat_entry->nodeentry->nodeid == nodeid && 115 firesat_entry->ud->ne->nodeid == nodeid &&
103 (firesat_entry->subunit == (data[1]&0x7) || 116 (firesat_entry->subunit == (data[1]&0x7) ||
104 (firesat_entry->subunit == 0 && 117 (firesat_entry->subunit == 0 &&
105 (data[1]&0x7) == 0x7))) { 118 (data[1]&0x7) == 0x7))) {
@@ -110,12 +123,8 @@ static void fcp_request(struct hpsb_host *host,
110 spin_unlock_irqrestore(&firesat_list_lock, flags); 123 spin_unlock_irqrestore(&firesat_list_lock, flags);
111 124
112 if (firesat) 125 if (firesat)
113 AVCRecv(firesat,data,length); 126 avc_recv(firesat, data, length);
114 else
115 printk("%s: received fcp request from unknown source, ignored\n", __func__);
116 } 127 }
117 else
118 printk("%s: received invalid fcp request, ignored\n", __func__);
119} 128}
120 129
121const char *firedtv_model_names[] = { 130const char *firedtv_model_names[] = {
@@ -128,175 +137,108 @@ const char *firedtv_model_names[] = {
128 137
129static int firesat_probe(struct device *dev) 138static int firesat_probe(struct device *dev)
130{ 139{
131 struct unit_directory *ud = container_of(dev, struct unit_directory, device); 140 struct unit_directory *ud =
141 container_of(dev, struct unit_directory, device);
132 struct firesat *firesat; 142 struct firesat *firesat;
133 struct dvb_frontend *fe;
134 unsigned long flags; 143 unsigned long flags;
135 unsigned char subunitcount = 0xff, subunit;
136 struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL);
137 int kv_len; 144 int kv_len;
145 void *kv_str;
138 int i; 146 int i;
139 char *kv_buf; 147 int err = -ENOMEM;
140 148
141 if (!firesats) { 149 firesat = kzalloc(sizeof(*firesat), GFP_KERNEL);
142 printk("%s: couldn't allocate memory.\n", __func__); 150 if (!firesat)
143 return -ENOMEM; 151 return -ENOMEM;
144 }
145
146// printk(KERN_INFO "FireSAT: Detected device with GUID %08lx%04lx%04lx\n",(unsigned long)((ud->ne->guid)>>32),(unsigned long)(ud->ne->guid & 0xFFFF),(unsigned long)ud->ne->guid_vendor_id);
147 printk(KERN_INFO "%s: loading device\n", __func__);
148
149 firesats[0] = NULL;
150 firesats[1] = NULL;
151
152 ud->device.driver_data = firesats;
153
154 for (subunit = 0; subunit < subunitcount; subunit++) {
155
156 if (!(firesat = kmalloc(sizeof (struct firesat), GFP_KERNEL)) ||
157 !(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) {
158
159 printk("%s: couldn't allocate memory.\n", __func__);
160 kfree(firesats);
161 return -ENOMEM;
162 }
163
164 memset(firesat, 0, sizeof (struct firesat));
165
166 firesat->host = ud->ne->host;
167 firesat->guid = ud->ne->guid;
168 firesat->guid_vendor_id = ud->ne->guid_vendor_id;
169 firesat->nodeentry = ud->ne;
170 firesat->isochannel = -1;
171 firesat->tone = 0xff;
172 firesat->voltage = 0xff;
173 firesat->fe = fe;
174
175 if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) {
176 printk("%s: couldn't allocate memory.\n", __func__);
177 kfree(firesat);
178 return -ENOMEM;
179 }
180
181 mutex_init(&firesat->avc_mutex);
182 init_waitqueue_head(&firesat->avc_wait);
183 atomic_set(&firesat->avc_reply_received, 1);
184 mutex_init(&firesat->demux_mutex);
185 INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work);
186
187 spin_lock_irqsave(&firesat_list_lock, flags);
188 INIT_LIST_HEAD(&firesat->list);
189 list_add_tail(&firesat->list, &firesat_list);
190 spin_unlock_irqrestore(&firesat_list_lock, flags);
191
192 if (subunit == 0) {
193 firesat->subunit = 0x7; // 0x7 = don't care
194 if (AVCSubUnitInfo(firesat, &subunitcount)) {
195 printk("%s: AVC subunit info command failed.\n",__func__);
196 spin_lock_irqsave(&firesat_list_lock, flags);
197 list_del(&firesat->list);
198 spin_unlock_irqrestore(&firesat_list_lock, flags);
199 kfree(firesat);
200 return -EIO;
201 }
202 }
203
204 printk(KERN_INFO "%s: subunit count = %d\n", __func__, subunitcount);
205
206 firesat->subunit = subunit;
207
208 /* Reading device model from ROM */
209 kv_len = (ud->model_name_kv->value.leaf.len - 2) *
210 sizeof(quadlet_t);
211 kv_buf = kmalloc((sizeof(quadlet_t) * kv_len), GFP_KERNEL);
212 memcpy(kv_buf,
213 CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv),
214 kv_len);
215 while ((kv_buf + kv_len - 1) == '\0') kv_len--;
216 kv_buf[kv_len++] = '\0';
217 152
218 for (i = ARRAY_SIZE(firedtv_model_names); --i;) 153 dev->driver_data = firesat;
219 if (strcmp(kv_buf, firedtv_model_names[i]) == 0) 154 firesat->ud = ud;
220 break; 155 firesat->subunit = 0;
221 firesat->type = i; 156 firesat->isochannel = -1;
222 kfree(kv_buf); 157 firesat->tone = 0xff;
223 158 firesat->voltage = 0xff;
224 if (AVCIdentifySubunit(firesat)) { 159
225 printk("%s: cannot identify subunit %d\n", __func__, subunit); 160 mutex_init(&firesat->avc_mutex);
226 spin_lock_irqsave(&firesat_list_lock, flags); 161 init_waitqueue_head(&firesat->avc_wait);
227 list_del(&firesat->list); 162 firesat->avc_reply_received = true;
228 spin_unlock_irqrestore(&firesat_list_lock, flags); 163 mutex_init(&firesat->demux_mutex);
229 kfree(firesat); 164 INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work);
230 continue; 165
231 } 166 /* Reading device model from ROM */
167 kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t);
168 kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
169 for (i = ARRAY_SIZE(firedtv_model_names); --i;)
170 if (strlen(firedtv_model_names[i]) <= kv_len &&
171 strncmp(kv_str, firedtv_model_names[i], kv_len) == 0)
172 break;
173 firesat->type = i;
174
175 /*
176 * Work around a bug in udev's path_id script: Use the fw-host's dev
177 * instead of the unit directory's dev as parent of the input device.
178 */
179 err = firesat_register_rc(firesat, dev->parent->parent);
180 if (err)
181 goto fail_free;
182
183 INIT_LIST_HEAD(&firesat->list);
184 spin_lock_irqsave(&firesat_list_lock, flags);
185 list_add_tail(&firesat->list, &firesat_list);
186 spin_unlock_irqrestore(&firesat_list_lock, flags);
187
188 err = avc_identify_subunit(firesat);
189 if (err)
190 goto fail;
232 191
233// ---- 192 err = firesat_dvbdev_init(firesat, dev);
234 /* FIXME: check for error return */ 193 if (err)
235 firesat_dvbdev_init(firesat, dev, fe); 194 goto fail;
236// ----
237 firesats[subunit] = firesat;
238 } // loop for all tuners
239 195
240 if (firesats[0]) 196 avc_register_remote_control(firesat);
241 AVCRegisterRemoteControl(firesats[0]); 197 return 0;
242 198
243 return 0; 199fail:
200 spin_lock_irqsave(&firesat_list_lock, flags);
201 list_del(&firesat->list);
202 spin_unlock_irqrestore(&firesat_list_lock, flags);
203 firesat_unregister_rc(firesat);
204fail_free:
205 kfree(firesat);
206 return err;
244} 207}
245 208
246static int firesat_remove(struct device *dev) 209static int firesat_remove(struct device *dev)
247{ 210{
248 struct unit_directory *ud = container_of(dev, struct unit_directory, device); 211 struct firesat *firesat = dev->driver_data;
249 struct firesat **firesats = ud->device.driver_data;
250 int k;
251 unsigned long flags; 212 unsigned long flags;
252 213
253 if (firesats) { 214 firesat_ca_release(firesat);
254 for (k = 0; k < 2; k++) 215 dvb_unregister_frontend(&firesat->fe);
255 if (firesats[k]) { 216 dvb_net_release(&firesat->dvbnet);
256 firesat_ca_release(firesats[k]); 217 firesat->demux.dmx.close(&firesat->demux.dmx);
257 218 firesat->demux.dmx.remove_frontend(&firesat->demux.dmx,
258 dvb_unregister_frontend(firesats[k]->fe); 219 &firesat->frontend);
259 dvb_net_release(&firesats[k]->dvbnet); 220 dvb_dmxdev_release(&firesat->dmxdev);
260 firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); 221 dvb_dmx_release(&firesat->demux);
261 firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); 222 dvb_unregister_adapter(&firesat->adapter);
262 dvb_dmxdev_release(&firesats[k]->dmxdev); 223
263 dvb_dmx_release(&firesats[k]->demux); 224 spin_lock_irqsave(&firesat_list_lock, flags);
264 dvb_unregister_adapter(firesats[k]->adapter); 225 list_del(&firesat->list);
265 226 spin_unlock_irqrestore(&firesat_list_lock, flags);
266 spin_lock_irqsave(&firesat_list_lock, flags);
267 list_del(&firesats[k]->list);
268 spin_unlock_irqrestore(&firesat_list_lock, flags);
269
270 cancel_work_sync(&firesats[k]->remote_ctrl_work);
271
272 kfree(firesats[k]->fe);
273 kfree(firesats[k]->adapter);
274 kfree(firesats[k]->respfrm);
275 kfree(firesats[k]);
276 }
277 kfree(firesats);
278 } else
279 printk("%s: can't get firesat handle\n", __func__);
280 227
281 printk(KERN_INFO "FireSAT: Removing device with vendor id 0x%x, model id 0x%x.\n",ud->vendor_id,ud->model_id); 228 cancel_work_sync(&firesat->remote_ctrl_work);
229 firesat_unregister_rc(firesat);
282 230
231 kfree(firesat);
283 return 0; 232 return 0;
284} 233}
285 234
286static int firesat_update(struct unit_directory *ud) 235static int firesat_update(struct unit_directory *ud)
287{ 236{
288 struct firesat **firesats = ud->device.driver_data; 237 struct firesat *firesat = ud->device.driver_data;
289 int k;
290 // loop over subunits
291
292 for (k = 0; k < 2; k++)
293 if (firesats[k]) {
294 firesats[k]->nodeentry = ud->ne;
295
296 if (firesats[k]->isochannel >= 0)
297 try_CMPEstablishPPconnection(firesats[k], firesats[k]->subunit, firesats[k]->isochannel);
298 }
299 238
239 if (firesat->isochannel >= 0)
240 cmp_establish_pp_connection(firesat, firesat->subunit,
241 firesat->isochannel);
300 return 0; 242 return 0;
301} 243}
302 244
@@ -328,26 +270,13 @@ static int __init firesat_init(void)
328 ret = hpsb_register_protocol(&firesat_driver); 270 ret = hpsb_register_protocol(&firesat_driver);
329 if (ret) { 271 if (ret) {
330 printk(KERN_ERR "firedtv: failed to register protocol\n"); 272 printk(KERN_ERR "firedtv: failed to register protocol\n");
331 goto fail; 273 hpsb_unregister_highlevel(&firesat_highlevel);
332 }
333
334 ret = firesat_register_rc();
335 if (ret) {
336 printk(KERN_ERR "firedtv: failed to register input device\n");
337 goto fail_rc;
338 } 274 }
339
340 return 0;
341fail_rc:
342 hpsb_unregister_protocol(&firesat_driver);
343fail:
344 hpsb_unregister_highlevel(&firesat_highlevel);
345 return ret; 275 return ret;
346} 276}
347 277
348static void __exit firesat_exit(void) 278static void __exit firesat_exit(void)
349{ 279{
350 firesat_unregister_rc();
351 hpsb_unregister_protocol(&firesat_driver); 280 hpsb_unregister_protocol(&firesat_driver);
352 hpsb_unregister_highlevel(&firesat_highlevel); 281 hpsb_unregister_highlevel(&firesat_highlevel);
353} 282}
diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c
index e944cee19f0a..cfa3a2e8edd1 100644
--- a/drivers/media/dvb/firesat/firesat_dvb.c
+++ b/drivers/media/dvb/firesat/firesat_dvb.c
@@ -34,8 +34,8 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat)
34 return NULL; 34 return NULL;
35 35
36 for (k = 0; k < 16; k++) 36 for (k = 0; k < 16; k++)
37 if (firesat->channel[k].active == 0) { 37 if (!firesat->channel[k].active) {
38 firesat->channel[k].active = 1; 38 firesat->channel[k].active = true;
39 c = &firesat->channel[k]; 39 c = &firesat->channel[k];
40 break; 40 break;
41 } 41 }
@@ -52,7 +52,7 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]
52 return -EINTR; 52 return -EINTR;
53 53
54 for (k = 0; k < 16; k++) 54 for (k = 0; k < 16; k++)
55 if (firesat->channel[k].active == 1) 55 if (firesat->channel[k].active)
56 pid[l++] = firesat->channel[k].pid; 56 pid[l++] = firesat->channel[k].pid;
57 57
58 mutex_unlock(&firesat->demux_mutex); 58 mutex_unlock(&firesat->demux_mutex);
@@ -68,7 +68,7 @@ static int firesat_channel_release(struct firesat *firesat,
68 if (mutex_lock_interruptible(&firesat->demux_mutex)) 68 if (mutex_lock_interruptible(&firesat->demux_mutex))
69 return -EINTR; 69 return -EINTR;
70 70
71 channel->active = 0; 71 channel->active = false;
72 72
73 mutex_unlock(&firesat->demux_mutex); 73 mutex_unlock(&firesat->demux_mutex);
74 return 0; 74 return 0;
@@ -81,8 +81,6 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
81 int pidc,k; 81 int pidc,k;
82 u16 pids[16]; 82 u16 pids[16];
83 83
84// printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
85
86 switch (dvbdmxfeed->type) { 84 switch (dvbdmxfeed->type) {
87 case DMX_TYPE_TS: 85 case DMX_TYPE_TS:
88 case DMX_TYPE_SEC: 86 case DMX_TYPE_SEC:
@@ -102,7 +100,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
102 case DMX_TS_PES_OTHER: 100 case DMX_TS_PES_OTHER:
103 //Dirty fix to keep firesat->channel pid-list up to date 101 //Dirty fix to keep firesat->channel pid-list up to date
104 for(k=0;k<16;k++){ 102 for(k=0;k<16;k++){
105 if(firesat->channel[k].active == 0) 103 if (!firesat->channel[k].active)
106 firesat->channel[k].pid = 104 firesat->channel[k].pid =
107 dvbdmxfeed->pid; 105 dvbdmxfeed->pid;
108 break; 106 break;
@@ -124,11 +122,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
124 } 122 }
125 123
126 dvbdmxfeed->priv = channel; 124 dvbdmxfeed->priv = channel;
127
128 channel->dvbdmxfeed = dvbdmxfeed;
129 channel->pid = dvbdmxfeed->pid; 125 channel->pid = dvbdmxfeed->pid;
130 channel->type = dvbdmxfeed->type;
131 channel->firesat = firesat;
132 126
133 if (firesat_channel_collect(firesat, &pidc, pids)) { 127 if (firesat_channel_collect(firesat, &pidc, pids)) {
134 firesat_channel_release(firesat, channel); 128 firesat_channel_release(firesat, channel);
@@ -136,16 +130,17 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
136 return -EINTR; 130 return -EINTR;
137 } 131 }
138 132
139 if(dvbdmxfeed->pid == 8192) { 133 if (dvbdmxfeed->pid == 8192) {
140 if((k = AVCTuner_GetTS(firesat))) { 134 k = avc_tuner_get_ts(firesat);
135 if (k) {
141 firesat_channel_release(firesat, channel); 136 firesat_channel_release(firesat, channel);
142 printk("%s: AVCTuner_GetTS failed with error %d\n", 137 printk("%s: AVCTuner_GetTS failed with error %d\n",
143 __func__, k); 138 __func__, k);
144 return k; 139 return k;
145 } 140 }
146 } 141 } else {
147 else { 142 k = avc_tuner_set_pids(firesat, pidc, pids);
148 if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) { 143 if (k) {
149 firesat_channel_release(firesat, channel); 144 firesat_channel_release(firesat, channel);
150 printk("%s: AVCTuner_SetPIDs failed with error %d\n", 145 printk("%s: AVCTuner_SetPIDs failed with error %d\n",
151 __func__, k); 146 __func__, k);
@@ -164,8 +159,6 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
164 int k, l; 159 int k, l;
165 u16 pids[16]; 160 u16 pids[16];
166 161
167 //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
168
169 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && 162 if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
170 (demux->dmx.frontend->source != DMX_MEMORY_FE))) { 163 (demux->dmx.frontend->source != DMX_MEMORY_FE))) {
171 164
@@ -177,7 +170,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
177 return -EINVAL; 170 return -EINVAL;
178 171
179 demux->pids[dvbdmxfeed->pes_type] |= 0x8000; 172 demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
180 demux->pesfilter[dvbdmxfeed->pes_type] = 0; 173 demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
181 } 174 }
182 175
183 if (!(dvbdmxfeed->ts_type & TS_DECODER && 176 if (!(dvbdmxfeed->ts_type & TS_DECODER &&
@@ -191,118 +184,93 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
191 184
192 /* list except channel to be removed */ 185 /* list except channel to be removed */
193 for (k = 0, l = 0; k < 16; k++) 186 for (k = 0, l = 0; k < 16; k++)
194 if (firesat->channel[k].active == 1) { 187 if (firesat->channel[k].active) {
195 if (&firesat->channel[k] != c) 188 if (&firesat->channel[k] != c)
196 pids[l++] = firesat->channel[k].pid; 189 pids[l++] = firesat->channel[k].pid;
197 else 190 else
198 firesat->channel[k].active = 0; 191 firesat->channel[k].active = false;
199 } 192 }
200 193
201 k = AVCTuner_SetPIDs(firesat, l, pids); 194 k = avc_tuner_set_pids(firesat, l, pids);
202 if (!k) 195 if (!k)
203 c->active = 0; 196 c->active = false;
204 197
205 mutex_unlock(&firesat->demux_mutex); 198 mutex_unlock(&firesat->demux_mutex);
206 return k; 199 return k;
207} 200}
208 201
209int firesat_dvbdev_init(struct firesat *firesat, 202int firesat_dvbdev_init(struct firesat *firesat, struct device *dev)
210 struct device *dev,
211 struct dvb_frontend *fe)
212{ 203{
213 int result; 204 int err;
214
215 firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL);
216 if (!firesat->adapter) {
217 printk(KERN_ERR "firedtv: couldn't allocate memory\n");
218 return -ENOMEM;
219 }
220
221 result = DVB_REGISTER_ADAPTER(firesat->adapter,
222 firedtv_model_names[firesat->type],
223 THIS_MODULE, dev, adapter_nr);
224 if (result < 0) {
225 printk(KERN_ERR "firedtv: dvb_register_adapter failed\n");
226 kfree(firesat->adapter);
227 return result;
228 }
229
230 memset(&firesat->demux, 0, sizeof(struct dvb_demux));
231 firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
232
233 firesat->demux.priv = (void *)firesat;
234 firesat->demux.filternum = 16;
235 firesat->demux.feednum = 16;
236 firesat->demux.start_feed = firesat_start_feed;
237 firesat->demux.stop_feed = firesat_stop_feed;
238 firesat->demux.write_to_decoder = NULL;
239 205
240 if ((result = dvb_dmx_init(&firesat->demux)) < 0) { 206 err = DVB_REGISTER_ADAPTER(&firesat->adapter,
241 printk("%s: dvb_dmx_init failed: error %d\n", __func__, 207 firedtv_model_names[firesat->type],
242 result); 208 THIS_MODULE, dev, adapter_nr);
209 if (err)
210 goto fail_log;
243 211
244 dvb_unregister_adapter(firesat->adapter); 212 /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
213 firesat->demux.dmx.capabilities = 0;
245 214
246 return result; 215 firesat->demux.priv = (void *)firesat;
247 } 216 firesat->demux.filternum = 16;
248 217 firesat->demux.feednum = 16;
249 firesat->dmxdev.filternum = 16; 218 firesat->demux.start_feed = firesat_start_feed;
250 firesat->dmxdev.demux = &firesat->demux.dmx; 219 firesat->demux.stop_feed = firesat_stop_feed;
251 firesat->dmxdev.capabilities = 0; 220 firesat->demux.write_to_decoder = NULL;
252
253 if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) {
254 printk("%s: dvb_dmxdev_init failed: error %d\n",
255 __func__, result);
256 221
257 dvb_dmx_release(&firesat->demux); 222 err = dvb_dmx_init(&firesat->demux);
258 dvb_unregister_adapter(firesat->adapter); 223 if (err)
224 goto fail_unreg_adapter;
259 225
260 return result; 226 firesat->dmxdev.filternum = 16;
261 } 227 firesat->dmxdev.demux = &firesat->demux.dmx;
228 firesat->dmxdev.capabilities = 0;
262 229
263 firesat->frontend.source = DMX_FRONTEND_0; 230 err = dvb_dmxdev_init(&firesat->dmxdev, &firesat->adapter);
231 if (err)
232 goto fail_dmx_release;
264 233
265 if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, 234 firesat->frontend.source = DMX_FRONTEND_0;
266 &firesat->frontend)) < 0) {
267 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
268 result);
269 235
270 dvb_dmxdev_release(&firesat->dmxdev); 236 err = firesat->demux.dmx.add_frontend(&firesat->demux.dmx,
271 dvb_dmx_release(&firesat->demux); 237 &firesat->frontend);
272 dvb_unregister_adapter(firesat->adapter); 238 if (err)
239 goto fail_dmxdev_release;
273 240
274 return result; 241 err = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx,
275 } 242 &firesat->frontend);
243 if (err)
244 goto fail_rem_frontend;
276 245
277 if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, 246 dvb_net_init(&firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx);
278 &firesat->frontend)) < 0) {
279 printk("%s: dvb_dmx_init failed: error %d\n", __func__,
280 result);
281 247
282 firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend); 248 firesat_frontend_init(firesat);
283 dvb_dmxdev_release(&firesat->dmxdev); 249 err = dvb_register_frontend(&firesat->adapter, &firesat->fe);
284 dvb_dmx_release(&firesat->demux); 250 if (err)
285 dvb_unregister_adapter(firesat->adapter); 251 goto fail_net_release;
286 252
287 return result; 253 err = firesat_ca_register(firesat);
288 } 254 if (err)
255 dev_info(dev, "Conditional Access Module not enabled\n");
289 256
290 dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); 257 return 0;
291
292// fe->ops = firesat_ops;
293// fe->dvb = firesat->adapter;
294 firesat_frontend_attach(firesat, fe);
295
296 fe->sec_priv = firesat; //IMPORTANT, functions depend on this!!!
297 if ((result= dvb_register_frontend(firesat->adapter, fe)) < 0) {
298 printk("%s: dvb_register_frontend_new failed: error %d\n", __func__, result);
299 /* ### cleanup */
300 return result;
301 }
302
303 firesat_ca_init(firesat);
304 258
305 return 0; 259fail_net_release:
260 dvb_net_release(&firesat->dvbnet);
261 firesat->demux.dmx.close(&firesat->demux.dmx);
262fail_rem_frontend:
263 firesat->demux.dmx.remove_frontend(&firesat->demux.dmx,
264 &firesat->frontend);
265fail_dmxdev_release:
266 dvb_dmxdev_release(&firesat->dmxdev);
267fail_dmx_release:
268 dvb_dmx_release(&firesat->demux);
269fail_unreg_adapter:
270 dvb_unregister_adapter(&firesat->adapter);
271fail_log:
272 dev_err(dev, "DVB initialization failed\n");
273 return err;
306} 274}
307 275
308 276
diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c
index ec614ea8de22..1ed972b79573 100644
--- a/drivers/media/dvb/firesat/firesat_fe.c
+++ b/drivers/media/dvb/firesat/firesat_fe.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/string.h>
15#include <linux/types.h> 16#include <linux/types.h>
16 17
17#include <dvb_frontend.h> 18#include <dvb_frontend.h>
@@ -22,22 +23,21 @@
22 23
23static int firesat_dvb_init(struct dvb_frontend *fe) 24static int firesat_dvb_init(struct dvb_frontend *fe)
24{ 25{
25 int result;
26 struct firesat *firesat = fe->sec_priv; 26 struct firesat *firesat = fe->sec_priv;
27// printk("fdi: 1\n"); 27 int err;
28 firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM 28
29// printk("fdi: 2\n"); 29 /* FIXME - allocate free channel at IRM */
30 result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); 30 firesat->isochannel = firesat->adapter.num;
31 if (result != 0) { 31
32 err = cmp_establish_pp_connection(firesat, firesat->subunit,
33 firesat->isochannel);
34 if (err) {
32 printk(KERN_ERR "Could not establish point to point " 35 printk(KERN_ERR "Could not establish point to point "
33 "connection.\n"); 36 "connection.\n");
34 return -1; 37 return err;
35 } 38 }
36// printk("fdi: 3\n");
37 39
38 result = setup_iso_channel(firesat); 40 return setup_iso_channel(firesat);
39// printk("fdi: 4. Result was %d\n", result);
40 return result;
41} 41}
42 42
43static int firesat_sleep(struct dvb_frontend *fe) 43static int firesat_sleep(struct dvb_frontend *fe)
@@ -45,7 +45,7 @@ static int firesat_sleep(struct dvb_frontend *fe)
45 struct firesat *firesat = fe->sec_priv; 45 struct firesat *firesat = fe->sec_priv;
46 46
47 tear_down_iso_channel(firesat); 47 tear_down_iso_channel(firesat);
48 try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); 48 cmp_break_pp_connection(firesat, firesat->subunit, firesat->isochannel);
49 firesat->isochannel = -1; 49 firesat->isochannel = -1;
50 return 0; 50 return 0;
51} 51}
@@ -55,8 +55,8 @@ static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe,
55{ 55{
56 struct firesat *firesat = fe->sec_priv; 56 struct firesat *firesat = fe->sec_priv;
57 57
58 return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 58 return avc_lnb_control(firesat, LNBCONTROL_DONTCARE,
59 LNBCONTROL_DONTCARE, 1, cmd); 59 LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd);
60} 60}
61 61
62static int firesat_diseqc_send_burst(struct dvb_frontend *fe, 62static int firesat_diseqc_send_burst(struct dvb_frontend *fe,
@@ -82,24 +82,19 @@ static int firesat_set_voltage(struct dvb_frontend *fe,
82 return 0; 82 return 0;
83} 83}
84 84
85static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) 85static int firesat_read_status(struct dvb_frontend *fe, fe_status_t *status)
86{ 86{
87 struct firesat *firesat = fe->sec_priv; 87 struct firesat *firesat = fe->sec_priv;
88 ANTENNA_INPUT_INFO info; 88 ANTENNA_INPUT_INFO info;
89 89
90 if (AVCTunerStatus(firesat, &info)) 90 if (avc_tuner_status(firesat, &info))
91 return -EINVAL; 91 return -EINVAL;
92 92
93 if (info.NoRF) { 93 if (info.NoRF)
94 *status = 0; 94 *status = 0;
95 } else { 95 else
96 *status = FE_HAS_SIGNAL | 96 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
97 FE_HAS_VITERBI | 97 FE_HAS_CARRIER | FE_HAS_LOCK;
98 FE_HAS_SYNC |
99 FE_HAS_CARRIER |
100 FE_HAS_LOCK;
101 }
102
103 return 0; 98 return 0;
104} 99}
105 100
@@ -108,14 +103,11 @@ static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber)
108 struct firesat *firesat = fe->sec_priv; 103 struct firesat *firesat = fe->sec_priv;
109 ANTENNA_INPUT_INFO info; 104 ANTENNA_INPUT_INFO info;
110 105
111 if (AVCTunerStatus(firesat, &info)) 106 if (avc_tuner_status(firesat, &info))
112 return -EINVAL; 107 return -EINVAL;
113 108
114 *ber = (info.BER[0] << 24) | 109 *ber = info.BER[0] << 24 | info.BER[1] << 16 |
115 (info.BER[1] << 16) | 110 info.BER[2] << 8 | info.BER[3];
116 (info.BER[2] << 8) |
117 info.BER[3];
118
119 return 0; 111 return 0;
120} 112}
121 113
@@ -124,11 +116,10 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength)
124 struct firesat *firesat = fe->sec_priv; 116 struct firesat *firesat = fe->sec_priv;
125 ANTENNA_INPUT_INFO info; 117 ANTENNA_INPUT_INFO info;
126 118
127 if (AVCTunerStatus(firesat, &info)) 119 if (avc_tuner_status(firesat, &info))
128 return -EINVAL; 120 return -EINVAL;
129 121
130 *strength = info.SignalStrength << 8; 122 *strength = info.SignalStrength << 8;
131
132 return 0; 123 return 0;
133} 124}
134 125
@@ -137,14 +128,12 @@ static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr)
137 struct firesat *firesat = fe->sec_priv; 128 struct firesat *firesat = fe->sec_priv;
138 ANTENNA_INPUT_INFO info; 129 ANTENNA_INPUT_INFO info;
139 130
140 if (AVCTunerStatus(firesat, &info)) 131 if (avc_tuner_status(firesat, &info))
141 return -EINVAL; 132 return -EINVAL;
142 133
143 *snr = (info.CarrierNoiseRatio[0] << 8) + 134 /* C/N[dB] = -10 * log10(snr / 65535) */
144 info.CarrierNoiseRatio[1]; 135 *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1];
145 *snr *= 257; 136 *snr *= 257;
146 // C/N[dB] = -10 * log10(snr / 65535)
147
148 return 0; 137 return 0;
149} 138}
150 139
@@ -158,10 +147,11 @@ static int firesat_set_frontend(struct dvb_frontend *fe,
158{ 147{
159 struct firesat *firesat = fe->sec_priv; 148 struct firesat *firesat = fe->sec_priv;
160 149
161 if (AVCTuner_DSD(firesat, params, NULL) != ACCEPTED) 150 /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
151 if (avc_tuner_dsd(firesat, params) != ACCEPTED)
162 return -EINVAL; 152 return -EINVAL;
163 else 153 else
164 return 0; //not sure of this... 154 return 0; /* not sure of this... */
165} 155}
166 156
167static int firesat_get_frontend(struct dvb_frontend *fe, 157static int firesat_get_frontend(struct dvb_frontend *fe,
@@ -170,107 +160,86 @@ static int firesat_get_frontend(struct dvb_frontend *fe,
170 return -EOPNOTSUPP; 160 return -EOPNOTSUPP;
171} 161}
172 162
173static struct dvb_frontend_info firesat_S_frontend_info; 163void firesat_frontend_init(struct firesat *firesat)
174static struct dvb_frontend_info firesat_C_frontend_info; 164{
175static struct dvb_frontend_info firesat_T_frontend_info; 165 struct dvb_frontend_ops *ops = &firesat->fe.ops;
176 166 struct dvb_frontend_info *fi = &ops->info;
177static struct dvb_frontend_ops firesat_ops = {
178 167
179 .init = firesat_dvb_init, 168 ops->init = firesat_dvb_init;
180 .sleep = firesat_sleep, 169 ops->sleep = firesat_sleep;
181 170
182 .set_frontend = firesat_set_frontend, 171 ops->set_frontend = firesat_set_frontend;
183 .get_frontend = firesat_get_frontend, 172 ops->get_frontend = firesat_get_frontend;
184 173
185 .read_status = firesat_read_status, 174 ops->read_status = firesat_read_status;
186 .read_ber = firesat_read_ber, 175 ops->read_ber = firesat_read_ber;
187 .read_signal_strength = firesat_read_signal_strength, 176 ops->read_signal_strength = firesat_read_signal_strength;
188 .read_snr = firesat_read_snr, 177 ops->read_snr = firesat_read_snr;
189 .read_ucblocks = firesat_read_uncorrected_blocks, 178 ops->read_ucblocks = firesat_read_uncorrected_blocks;
190 179
191 .diseqc_send_master_cmd = firesat_diseqc_send_master_cmd, 180 ops->diseqc_send_master_cmd = firesat_diseqc_send_master_cmd;
192 .diseqc_send_burst = firesat_diseqc_send_burst, 181 ops->diseqc_send_burst = firesat_diseqc_send_burst;
193 .set_tone = firesat_set_tone, 182 ops->set_tone = firesat_set_tone;
194 .set_voltage = firesat_set_voltage, 183 ops->set_voltage = firesat_set_voltage;
195};
196 184
197int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe)
198{
199 switch (firesat->type) { 185 switch (firesat->type) {
200 case FireSAT_DVB_S: 186 case FireSAT_DVB_S:
201 firesat->frontend_info = &firesat_S_frontend_info; 187 fi->type = FE_QPSK;
188
189 fi->frequency_min = 950000;
190 fi->frequency_max = 2150000;
191 fi->frequency_stepsize = 125;
192 fi->symbol_rate_min = 1000000;
193 fi->symbol_rate_max = 40000000;
194
195 fi->caps = FE_CAN_INVERSION_AUTO |
196 FE_CAN_FEC_1_2 |
197 FE_CAN_FEC_2_3 |
198 FE_CAN_FEC_3_4 |
199 FE_CAN_FEC_5_6 |
200 FE_CAN_FEC_7_8 |
201 FE_CAN_FEC_AUTO |
202 FE_CAN_QPSK;
202 break; 203 break;
204
203 case FireSAT_DVB_C: 205 case FireSAT_DVB_C:
204 firesat->frontend_info = &firesat_C_frontend_info; 206 fi->type = FE_QAM;
207
208 fi->frequency_min = 47000000;
209 fi->frequency_max = 866000000;
210 fi->frequency_stepsize = 62500;
211 fi->symbol_rate_min = 870000;
212 fi->symbol_rate_max = 6900000;
213
214 fi->caps = FE_CAN_INVERSION_AUTO |
215 FE_CAN_QAM_16 |
216 FE_CAN_QAM_32 |
217 FE_CAN_QAM_64 |
218 FE_CAN_QAM_128 |
219 FE_CAN_QAM_256 |
220 FE_CAN_QAM_AUTO;
205 break; 221 break;
222
206 case FireSAT_DVB_T: 223 case FireSAT_DVB_T:
207 firesat->frontend_info = &firesat_T_frontend_info; 224 fi->type = FE_OFDM;
225
226 fi->frequency_min = 49000000;
227 fi->frequency_max = 861000000;
228 fi->frequency_stepsize = 62500;
229
230 fi->caps = FE_CAN_INVERSION_AUTO |
231 FE_CAN_FEC_2_3 |
232 FE_CAN_TRANSMISSION_MODE_AUTO |
233 FE_CAN_GUARD_INTERVAL_AUTO |
234 FE_CAN_HIERARCHY_AUTO;
208 break; 235 break;
236
209 default: 237 default:
210 printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", 238 printk(KERN_ERR "FireDTV: no frontend for model type %d\n",
211 firesat->type); 239 firesat->type);
212 firesat->frontend_info = NULL;
213 } 240 }
214 fe->ops = firesat_ops; 241 strcpy(fi->name, firedtv_model_names[firesat->type]);
215 fe->ops.info = *(firesat->frontend_info);
216 fe->dvb = firesat->adapter;
217 242
218 return 0; 243 firesat->fe.dvb = &firesat->adapter;
244 firesat->fe.sec_priv = firesat;
219} 245}
220
221static struct dvb_frontend_info firesat_S_frontend_info = {
222
223 .name = "FireDTV DVB-S Frontend",
224 .type = FE_QPSK,
225
226 .frequency_min = 950000,
227 .frequency_max = 2150000,
228 .frequency_stepsize = 125,
229 .symbol_rate_min = 1000000,
230 .symbol_rate_max = 40000000,
231
232 .caps = FE_CAN_INVERSION_AUTO |
233 FE_CAN_FEC_1_2 |
234 FE_CAN_FEC_2_3 |
235 FE_CAN_FEC_3_4 |
236 FE_CAN_FEC_5_6 |
237 FE_CAN_FEC_7_8 |
238 FE_CAN_FEC_AUTO |
239 FE_CAN_QPSK,
240};
241
242static struct dvb_frontend_info firesat_C_frontend_info = {
243
244 .name = "FireDTV DVB-C Frontend",
245 .type = FE_QAM,
246
247 .frequency_min = 47000000,
248 .frequency_max = 866000000,
249 .frequency_stepsize = 62500,
250 .symbol_rate_min = 870000,
251 .symbol_rate_max = 6900000,
252
253 .caps = FE_CAN_INVERSION_AUTO |
254 FE_CAN_QAM_16 |
255 FE_CAN_QAM_32 |
256 FE_CAN_QAM_64 |
257 FE_CAN_QAM_128 |
258 FE_CAN_QAM_256 |
259 FE_CAN_QAM_AUTO,
260};
261
262static struct dvb_frontend_info firesat_T_frontend_info = {
263
264 .name = "FireDTV DVB-T Frontend",
265 .type = FE_OFDM,
266
267 .frequency_min = 49000000,
268 .frequency_max = 861000000,
269 .frequency_stepsize = 62500,
270
271 .caps = FE_CAN_INVERSION_AUTO |
272 FE_CAN_FEC_2_3 |
273 FE_CAN_TRANSMISSION_MODE_AUTO |
274 FE_CAN_GUARD_INTERVAL_AUTO |
275 FE_CAN_HIERARCHY_AUTO,
276};
diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c
index bc94afe57f63..b3c61f95fa94 100644
--- a/drivers/media/dvb/firesat/firesat_iso.c
+++ b/drivers/media/dvb/firesat/firesat_iso.c
@@ -18,6 +18,7 @@
18 18
19#include <dma.h> 19#include <dma.h>
20#include <iso.h> 20#include <iso.h>
21#include <nodemgr.h>
21 22
22#include "firesat.h" 23#include "firesat.h"
23 24
@@ -36,7 +37,7 @@ int setup_iso_channel(struct firesat *firesat)
36{ 37{
37 int result; 38 int result;
38 firesat->iso_handle = 39 firesat->iso_handle =
39 hpsb_iso_recv_init(firesat->host, 40 hpsb_iso_recv_init(firesat->ud->ne->host,
40 256 * 200, //data_buf_size, 41 256 * 200, //data_buf_size,
41 256, //buf_packets, 42 256, //buf_packets,
42 firesat->isochannel, 43 firesat->isochannel,
@@ -59,7 +60,6 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
59{ 60{
60 unsigned int num; 61 unsigned int num;
61 unsigned int i; 62 unsigned int i;
62/* unsigned int j; */
63 unsigned int packet; 63 unsigned int packet;
64 unsigned long flags; 64 unsigned long flags;
65 struct firesat *firesat = NULL; 65 struct firesat *firesat = NULL;
@@ -88,12 +88,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
88 (188 + sizeof(struct firewireheader)); 88 (188 + sizeof(struct firewireheader));
89 if (iso->infos[packet].len <= sizeof(struct CIPHeader)) 89 if (iso->infos[packet].len <= sizeof(struct CIPHeader))
90 continue; // ignore empty packet 90 continue; // ignore empty packet
91/* printk("%s: Handling packets (%d): ", __func__, */ 91
92/* iso->infos[packet].len); */
93/* for (j = 0; j < iso->infos[packet].len - */
94/* sizeof(struct CIPHeader); j++) */
95/* printk("%02X,", buf[j]); */
96/* printk("\n"); */
97 while (count --) { 92 while (count --) {
98 if (buf[sizeof(struct firewireheader)] == 0x47) 93 if (buf[sizeof(struct firewireheader)] == 0x47)
99 dvb_dmx_swfilter_packets(&firesat->demux, 94 dvb_dmx_swfilter_packets(&firesat->demux,