diff options
Diffstat (limited to 'drivers/media/dvb/firesat/avc_api.c')
| -rw-r--r-- | drivers/media/dvb/firesat/avc_api.c | 1074 |
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 | ||
| 34 | static unsigned int avc_comm_debug = 0; | 34 | static int __avc_write(struct firesat *firesat, |
| 35 | module_param(avc_comm_debug, int, 0644); | 35 | const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) |
| 36 | MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)"); | ||
| 37 | |||
| 38 | /* Frees an allocated packet */ | ||
| 39 | static void avc_free_packet(struct hpsb_packet *packet) | ||
| 40 | { | ||
| 41 | hpsb_free_tlabel(packet); | ||
| 42 | hpsb_free_packet(packet); | ||
| 43 | } | ||
| 44 | |||
| 45 | static 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 | |||
| 63 | static 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 | |||
| 85 | static 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 | |||
| 94 | static 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 | |||
| 123 | static 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 | |||
| 146 | static 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 | |||
| 168 | static 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 | ||
| 240 | int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) | 72 | static 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 | ||
| 253 | int AVCRecv(struct firesat *firesat, u8 *data, size_t length) | 86 | int 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 | /* |
| 301 | static 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 | 125 | static 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 | |||
| 185 | static 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 | ||
| 369 | int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status) { | 271 | static 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 | |||
| 397 | int 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 | ||
| 616 | int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) | 435 | int 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 | ||
| 663 | int AVCTuner_GetTS(struct firesat *firesat){ | 479 | int 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 | ||
| 698 | int AVCIdentifySubunit(struct firesat *firesat) | 512 | int 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 | ||
| 736 | int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info) { | 547 | int 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 | ||
| 778 | int AVCLNBControl(struct firesat *firesat, char voltage, char burst, | 589 | int 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 | |||
| 844 | int 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 | ||
| 880 | int AVCRegisterRemoteControl(struct firesat *firesat) | 638 | int 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 | ||
| 904 | void avc_remote_ctrl_work(struct work_struct *work) | 660 | void 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 | ||
| 913 | int AVCTuner_Host2Ca(struct firesat *firesat) | 669 | #if 0 /* FIXME: unused */ |
| 670 | int 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 | ||
| 942 | static int get_ca_object_pos(AVCRspFrm *RspFrm) | 699 | static 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 | ||
| 952 | static int get_ca_object_length(AVCRspFrm *RspFrm) | 709 | static 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 | ||
| 966 | int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) | 724 | int 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 | ||
| 1003 | int avc_ca_info(struct firesat *firesat, char *app_info, int *length) | 762 | int 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 | ||
| 1206 | int avc_ca_get_time_date(struct firesat *firesat, int *interval) | 960 | int 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 | ||
| 1264 | int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length) | 1020 | int 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 | } |
