aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/firesat/avc_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/firesat/avc_api.c')
-rw-r--r--drivers/media/dvb/firesat/avc_api.c1074
1 files changed, 416 insertions, 658 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}