diff options
| -rw-r--r-- | drivers/media/dvb/firesat/avc_api.c | 1074 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/avc_api.h | 38 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/cmp.c | 252 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/cmp.h | 6 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat-ci.c | 244 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat-ci.h | 2 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat-rc.c | 42 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat-rc.h | 9 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat.h | 68 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat_1394.c | 301 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat_dvb.c | 178 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat_fe.c | 223 | ||||
| -rw-r--r-- | drivers/media/dvb/firesat/firesat_iso.c | 11 |
13 files changed, 964 insertions, 1484 deletions
diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 6337f9f21d0f..56911f3df7f6 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c | |||
| @@ -11,14 +11,16 @@ | |||
| 11 | * the License, or (at your option) any later version. | 11 | * the License, or (at your option) any later version. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <linux/bug.h> | ||
| 14 | #include <linux/crc32.h> | 15 | #include <linux/crc32.h> |
| 15 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
| 17 | #include <linux/device.h> | ||
| 16 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
| 17 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
| 18 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
| 21 | #include <linux/string.h> | ||
| 19 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
| 20 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
| 21 | #include <asm/atomic.h> | ||
| 22 | 24 | ||
| 23 | #include <ieee1394_transactions.h> | 25 | #include <ieee1394_transactions.h> |
| 24 | #include <nodemgr.h> | 26 | #include <nodemgr.h> |
| @@ -27,230 +29,61 @@ | |||
| 27 | #include "firesat.h" | 29 | #include "firesat.h" |
| 28 | #include "firesat-rc.h" | 30 | #include "firesat-rc.h" |
| 29 | 31 | ||
| 30 | #define RESPONSE_REGISTER 0xFFFFF0000D00ULL | 32 | #define FCP_COMMAND_REGISTER 0xfffff0000b00ULL |
| 31 | #define COMMAND_REGISTER 0xFFFFF0000B00ULL | ||
| 32 | #define PCR_BASE_ADDRESS 0xFFFFF0000900ULL | ||
| 33 | 33 | ||
| 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 | } |
diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h index 66f419a6f7c6..9d2efd8ff17b 100644 --- a/drivers/media/dvb/firesat/avc_api.h +++ b/drivers/media/dvb/firesat/avc_api.h | |||
| @@ -26,15 +26,6 @@ | |||
| 26 | **************************************************************/ | 26 | **************************************************************/ |
| 27 | #define LIST_MANAGEMENT_ONLY 0x03 | 27 | #define LIST_MANAGEMENT_ONLY 0x03 |
| 28 | 28 | ||
| 29 | /************************************************************* | ||
| 30 | FCP Address range | ||
| 31 | **************************************************************/ | ||
| 32 | |||
| 33 | #define RESPONSE_REGISTER 0xFFFFF0000D00ULL | ||
| 34 | #define COMMAND_REGISTER 0xFFFFF0000B00ULL | ||
| 35 | #define PCR_BASE_ADDRESS 0xFFFFF0000900ULL | ||
| 36 | |||
| 37 | |||
| 38 | /************************************************************ | 29 | /************************************************************ |
| 39 | definition of structures | 30 | definition of structures |
| 40 | *************************************************************/ | 31 | *************************************************************/ |
| @@ -413,34 +404,29 @@ struct dvb_diseqc_master_cmd; | |||
| 413 | struct dvb_frontend_parameters; | 404 | struct dvb_frontend_parameters; |
| 414 | struct firesat; | 405 | struct firesat; |
| 415 | 406 | ||
| 416 | int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, | 407 | int avc_recv(struct firesat *firesat, u8 *data, size_t length); |
| 417 | AVCRspFrm *RspFrm); | ||
| 418 | int AVCRecv(struct firesat *firesat, u8 *data, size_t length); | ||
| 419 | 408 | ||
| 420 | int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, | 409 | int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, |
| 421 | struct dvb_frontend_parameters *params, __u8 *status); | 410 | struct dvb_frontend_parameters *params, __u8 *status); |
| 422 | 411 | ||
| 423 | int AVCTunerStatus(struct firesat *firesat, | 412 | int avc_tuner_status(struct firesat *firesat, |
| 424 | ANTENNA_INPUT_INFO *antenna_input_info); | 413 | ANTENNA_INPUT_INFO *antenna_input_info); |
| 425 | int AVCTuner_DSD(struct firesat *firesat, | 414 | int avc_tuner_dsd(struct firesat *firesat, |
| 426 | struct dvb_frontend_parameters *params, __u8 *status); | 415 | struct dvb_frontend_parameters *params); |
| 427 | int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); | 416 | int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]); |
| 428 | int AVCTuner_GetTS(struct firesat *firesat); | 417 | int avc_tuner_get_ts(struct firesat *firesat); |
| 429 | 418 | int avc_identify_subunit(struct firesat *firesat); | |
| 430 | int AVCIdentifySubunit(struct firesat *firesat); | 419 | int avc_lnb_control(struct firesat *firesat, char voltage, char burst, |
| 431 | int AVCLNBControl(struct firesat *firesat, char voltage, char burst, | ||
| 432 | char conttone, char nrdiseq, | 420 | char conttone, char nrdiseq, |
| 433 | struct dvb_diseqc_master_cmd *diseqcmd); | 421 | struct dvb_diseqc_master_cmd *diseqcmd); |
| 434 | int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); | ||
| 435 | void avc_remote_ctrl_work(struct work_struct *work); | 422 | void avc_remote_ctrl_work(struct work_struct *work); |
| 436 | int AVCRegisterRemoteControl(struct firesat *firesat); | 423 | int avc_register_remote_control(struct firesat *firesat); |
| 437 | int AVCTuner_Host2Ca(struct firesat *firesat); | 424 | int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len); |
| 438 | int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); | 425 | int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len); |
| 439 | int avc_ca_info(struct firesat *firesat, char *app_info, int *length); | ||
| 440 | int avc_ca_reset(struct firesat *firesat); | 426 | int avc_ca_reset(struct firesat *firesat); |
| 441 | int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); | 427 | int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); |
| 442 | int avc_ca_get_time_date(struct firesat *firesat, int *interval); | 428 | int avc_ca_get_time_date(struct firesat *firesat, int *interval); |
| 443 | int avc_ca_enter_menu(struct firesat *firesat); | 429 | int avc_ca_enter_menu(struct firesat *firesat); |
| 444 | int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); | 430 | int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len); |
| 445 | 431 | ||
| 446 | #endif /* _AVC_API_H */ | 432 | #endif /* _AVC_API_H */ |
diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c index d1bafba615e4..8e98b814e430 100644 --- a/drivers/media/dvb/firesat/cmp.c +++ b/drivers/media/dvb/firesat/cmp.c | |||
| @@ -10,37 +10,21 @@ | |||
| 10 | * the License, or (at your option) any later version. | 10 | * the License, or (at your option) any later version. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/device.h> | ||
| 13 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 14 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 16 | 17 | ||
| 17 | #include <hosts.h> | 18 | #include <asm/byteorder.h> |
| 19 | |||
| 18 | #include <ieee1394.h> | 20 | #include <ieee1394.h> |
| 19 | #include <ieee1394_core.h> | ||
| 20 | #include <ieee1394_transactions.h> | ||
| 21 | #include <nodemgr.h> | 21 | #include <nodemgr.h> |
| 22 | 22 | ||
| 23 | #include "avc_api.h" | 23 | #include "avc_api.h" |
| 24 | #include "cmp.h" | 24 | #include "cmp.h" |
| 25 | #include "firesat.h" | 25 | #include "firesat.h" |
| 26 | 26 | ||
| 27 | typedef struct _OPCR | 27 | #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL |
| 28 | { | ||
| 29 | __u8 PTPConnCount : 6 ; // Point to point connect. counter | ||
| 30 | __u8 BrConnCount : 1 ; // Broadcast connection counter | ||
| 31 | __u8 OnLine : 1 ; // On Line | ||
| 32 | |||
| 33 | __u8 ChNr : 6 ; // Channel number | ||
| 34 | __u8 Res : 2 ; // Reserved | ||
| 35 | |||
| 36 | __u8 PayloadHi : 2 ; // Payoad high bits | ||
| 37 | __u8 OvhdID : 4 ; // Overhead ID | ||
| 38 | __u8 DataRate : 2 ; // Data Rate | ||
| 39 | |||
| 40 | __u8 PayloadLo ; // Payoad low byte | ||
| 41 | } OPCR ; | ||
| 42 | |||
| 43 | #define FIRESAT_SPEED IEEE1394_SPEED_400 | ||
| 44 | 28 | ||
| 45 | static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) | 29 | static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) |
| 46 | { | 30 | { |
| @@ -49,151 +33,139 @@ static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) | |||
| 49 | if (mutex_lock_interruptible(&firesat->avc_mutex)) | 33 | if (mutex_lock_interruptible(&firesat->avc_mutex)) |
| 50 | return -EINTR; | 34 | return -EINTR; |
| 51 | 35 | ||
| 52 | ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, | 36 | ret = hpsb_node_read(firesat->ud->ne, addr, buf, len); |
| 53 | firesat->nodeentry->generation, addr, buf, len); | 37 | if (ret < 0) |
| 38 | dev_err(&firesat->ud->device, "CMP: read I/O error\n"); | ||
| 54 | 39 | ||
| 55 | mutex_unlock(&firesat->avc_mutex); | 40 | mutex_unlock(&firesat->avc_mutex); |
| 56 | return ret; | 41 | return ret; |
| 57 | } | 42 | } |
| 58 | 43 | ||
| 59 | static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, | 44 | static int cmp_lock(struct firesat *firesat, void *data, u64 addr, __be32 arg, |
| 60 | quadlet_t arg, int ext_tcode) | 45 | int ext_tcode) |
| 61 | { | 46 | { |
| 62 | int ret; | 47 | int ret; |
| 63 | 48 | ||
| 64 | if (mutex_lock_interruptible(&firesat->avc_mutex)) | 49 | if (mutex_lock_interruptible(&firesat->avc_mutex)) |
| 65 | return -EINTR; | 50 | return -EINTR; |
| 66 | 51 | ||
| 67 | ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, | 52 | ret = hpsb_node_lock(firesat->ud->ne, addr, ext_tcode, data, |
| 68 | firesat->nodeentry->generation, | 53 | (__force quadlet_t)arg); |
| 69 | addr, ext_tcode, data, arg); | 54 | if (ret < 0) |
| 55 | dev_err(&firesat->ud->device, "CMP: lock I/O error\n"); | ||
| 70 | 56 | ||
| 71 | mutex_unlock(&firesat->avc_mutex); | 57 | mutex_unlock(&firesat->avc_mutex); |
| 72 | return ret; | 58 | return ret; |
| 73 | } | 59 | } |
| 74 | 60 | ||
| 75 | //try establishing a point-to-point connection (may be interrupted by a busreset | 61 | static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift) |
| 76 | int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) { | 62 | { |
| 77 | unsigned int BWU; //bandwidth to allocate | 63 | return (be32_to_cpu(opcr) >> shift) & mask; |
| 64 | } | ||
| 65 | |||
| 66 | static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift) | ||
| 67 | { | ||
| 68 | *opcr &= ~cpu_to_be32(mask << shift); | ||
| 69 | *opcr |= cpu_to_be32((value & mask) << shift); | ||
| 70 | } | ||
| 78 | 71 | ||
| 79 | quadlet_t old_oPCR,test_oPCR = 0x0; | 72 | #define get_opcr_online(v) get_opcr((v), 0x1, 31) |
| 80 | u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); | 73 | #define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24) |
| 81 | int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); | 74 | #define get_opcr_channel(v) get_opcr((v), 0x3f, 16) |
| 82 | 75 | ||
| 83 | /* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */ | 76 | #define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24) |
| 77 | #define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16) | ||
| 78 | #define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14) | ||
| 79 | #define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10) | ||
| 84 | 80 | ||
| 85 | if (result < 0) { | 81 | int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel) |
| 86 | printk("%s: cannot read oPCR\n", __func__); | 82 | { |
| 87 | return result; | 83 | __be32 old_opcr, opcr; |
| 88 | } else { | 84 | u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); |
| 89 | /* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */ | 85 | int attempts = 0; |
| 90 | do { | 86 | int ret; |
| 91 | OPCR *hilf= (OPCR*) &test_oPCR; | 87 | |
| 92 | 88 | ret = cmp_read(firesat, &opcr, opcr_address, 4); | |
| 93 | if (!hilf->OnLine) { | 89 | if (ret < 0) |
| 94 | printk("%s: Output offline; oPCR: %08x\n", __func__, test_oPCR); | 90 | return ret; |
| 95 | return -EBUSY; | 91 | |
| 96 | } else { | 92 | repeat: |
| 97 | quadlet_t new_oPCR; | 93 | if (!get_opcr_online(opcr)) { |
| 98 | 94 | dev_err(&firesat->ud->device, "CMP: output offline\n"); | |
| 99 | old_oPCR=test_oPCR; | 95 | return -EBUSY; |
| 100 | if (hilf->PTPConnCount) { | 96 | } |
| 101 | if (hilf->ChNr != iso_channel) { | 97 | |
| 102 | printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__func__,hilf->ChNr,iso_channel); | 98 | old_opcr = opcr; |
| 103 | return -EBUSY; | 99 | |
| 104 | } else | 100 | if (get_opcr_p2p_connections(opcr)) { |
| 105 | printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__func__, hilf->PTPConnCount); | 101 | if (get_opcr_channel(opcr) != channel) { |
| 106 | BWU=0; //we allocate no bandwidth (is this necessary?) | 102 | dev_err(&firesat->ud->device, |
| 107 | } else { | 103 | "CMP: cannot change channel\n"); |
| 108 | hilf->ChNr=iso_channel; | 104 | return -EBUSY; |
| 109 | hilf->DataRate=FIRESAT_SPEED; | ||
| 110 | |||
| 111 | hilf->OvhdID=0; //FIXME: that is for worst case -> optimize | ||
| 112 | BWU=hilf->OvhdID?hilf->OvhdID*32:512; | ||
| 113 | BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate)); | ||
| 114 | /* if (allocate_1394_resources(iso_channel,BWU)) | ||
| 115 | { | ||
| 116 | cout << "Allocation of resources failed\n"; | ||
| 117 | return -2; | ||
| 118 | }*/ | ||
| 119 | } | ||
| 120 | |||
| 121 | hilf->PTPConnCount++; | ||
| 122 | new_oPCR=test_oPCR; | ||
| 123 | /* printk(KERN_INFO "%s: trying compare_swap...\n",__func__); */ | ||
| 124 | /* printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); */ | ||
| 125 | result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); | ||
| 126 | |||
| 127 | if (result < 0) { | ||
| 128 | printk("%s: cannot compare_swap oPCR\n",__func__); | ||
| 129 | return result; | ||
| 130 | } | ||
| 131 | if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount)) | ||
| 132 | { | ||
| 133 | printk("%s: change of oPCR failed -> freeing resources\n",__func__); | ||
| 134 | // hilf= (OPCR*) &new_oPCR; | ||
| 135 | // unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512; | ||
| 136 | // BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate)); | ||
| 137 | /* if (deallocate_1394_resources(iso_channel,BWU)) | ||
| 138 | { | ||
| 139 | |||
| 140 | cout << "Deallocation of resources failed\n"; | ||
| 141 | return -3; | ||
| 142 | }*/ | ||
| 143 | } | ||
| 144 | } | ||
| 145 | } | 105 | } |
| 146 | while (old_oPCR != test_oPCR); | 106 | dev_info(&firesat->ud->device, |
| 107 | "CMP: overlaying existing connection\n"); | ||
| 108 | |||
| 109 | /* We don't allocate isochronous resources. */ | ||
| 110 | } else { | ||
| 111 | set_opcr_channel(&opcr, channel); | ||
| 112 | set_opcr_data_rate(&opcr, IEEE1394_SPEED_400); | ||
| 113 | |||
| 114 | /* FIXME: this is for the worst case - optimize */ | ||
| 115 | set_opcr_overhead_id(&opcr, 0); | ||
| 116 | |||
| 117 | /* FIXME: allocate isochronous channel and bandwidth at IRM */ | ||
| 147 | } | 118 | } |
| 119 | |||
| 120 | set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1); | ||
| 121 | |||
| 122 | ret = cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2); | ||
| 123 | if (ret < 0) | ||
| 124 | return ret; | ||
| 125 | |||
| 126 | if (old_opcr != opcr) { | ||
| 127 | /* | ||
| 128 | * FIXME: if old_opcr.P2P_Connections > 0, | ||
| 129 | * deallocate isochronous channel and bandwidth at IRM | ||
| 130 | */ | ||
| 131 | |||
| 132 | if (++attempts < 6) /* arbitrary limit */ | ||
| 133 | goto repeat; | ||
| 134 | return -EBUSY; | ||
| 135 | } | ||
| 136 | |||
| 148 | return 0; | 137 | return 0; |
| 149 | } | 138 | } |
| 150 | 139 | ||
| 151 | //try breaking a point-to-point connection (may be interrupted by a busreset | 140 | void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel) |
| 152 | int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) { | 141 | { |
| 153 | quadlet_t old_oPCR,test_oPCR; | 142 | __be32 old_opcr, opcr; |
| 143 | u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2); | ||
| 144 | int attempts = 0; | ||
| 145 | |||
| 146 | if (cmp_read(firesat, &opcr, opcr_address, 4) < 0) | ||
| 147 | return; | ||
| 148 | |||
| 149 | repeat: | ||
| 150 | if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) || | ||
| 151 | get_opcr_channel(opcr) != channel) { | ||
| 152 | dev_err(&firesat->ud->device, "CMP: no connection to break\n"); | ||
| 153 | return; | ||
| 154 | } | ||
| 155 | |||
| 156 | old_opcr = opcr; | ||
| 157 | set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1); | ||
| 154 | 158 | ||
| 155 | u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); | 159 | if (cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2) < 0) |
| 156 | int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); | 160 | return; |
| 157 | 161 | ||
| 158 | /* printk(KERN_INFO "%s\n",__func__); */ | 162 | if (old_opcr != opcr) { |
| 163 | /* | ||
| 164 | * FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last | ||
| 165 | * owner, deallocate isochronous channel and bandwidth at IRM | ||
| 166 | */ | ||
| 159 | 167 | ||
| 160 | if (result < 0) { | 168 | if (++attempts < 6) /* arbitrary limit */ |
| 161 | printk("%s: cannot read oPCR\n", __func__); | 169 | goto repeat; |
| 162 | return result; | 170 | } |
| 163 | } else { | ||
| 164 | do { | ||
| 165 | OPCR *hilf= (OPCR*) &test_oPCR; | ||
| 166 | |||
| 167 | if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) { | ||
| 168 | printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __func__, test_oPCR); | ||
| 169 | return -EINVAL; | ||
| 170 | } else { | ||
| 171 | quadlet_t new_oPCR; | ||
| 172 | old_oPCR=test_oPCR; | ||
| 173 | hilf->PTPConnCount--; | ||
| 174 | new_oPCR=test_oPCR; | ||
| 175 | |||
| 176 | // printk(KERN_INFO "%s: trying compare_swap...\n", __func__); | ||
| 177 | result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2); | ||
| 178 | if (result < 0) { | ||
| 179 | printk("%s: cannot compare_swap oPCR\n",__func__); | ||
| 180 | return result; | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | } while (old_oPCR != test_oPCR); | ||
| 185 | |||
| 186 | /* hilf = (OPCR*) &old_oPCR; | ||
| 187 | if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection | ||
| 188 | cout << "deallocating 1394 resources\n"; | ||
| 189 | unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512; | ||
| 190 | BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate)); | ||
| 191 | if (deallocate_1394_resources(iso_channel,BWU)) | ||
| 192 | { | ||
| 193 | cout << "Deallocation of resources failed\n"; | ||
| 194 | return -3; | ||
| 195 | } | ||
| 196 | }*/ | ||
| 197 | } | ||
| 198 | return 0; | ||
| 199 | } | 171 | } |
diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h index 600d5784dc72..d92f6c7fb5d5 100644 --- a/drivers/media/dvb/firesat/cmp.h +++ b/drivers/media/dvb/firesat/cmp.h | |||
| @@ -3,9 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | struct firesat; | 4 | struct firesat; |
| 5 | 5 | ||
| 6 | int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, | 6 | int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel); |
| 7 | int iso_channel); | 7 | void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel); |
| 8 | int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug, | ||
| 9 | int iso_channel); | ||
| 10 | 8 | ||
| 11 | #endif /* _CMP_H */ | 9 | #endif /* _CMP_H */ |
diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c index 3ef25cc4bfdb..0deb47eefa10 100644 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ b/drivers/media/dvb/firesat/firesat-ci.c | |||
| @@ -20,29 +20,18 @@ | |||
| 20 | #include "firesat.h" | 20 | #include "firesat.h" |
| 21 | #include "firesat-ci.h" | 21 | #include "firesat-ci.h" |
| 22 | 22 | ||
| 23 | static unsigned int ca_debug = 0; | ||
| 24 | module_param(ca_debug, int, 0644); | ||
| 25 | MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)"); | ||
| 26 | |||
| 27 | static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) | 23 | static int firesat_ca_ready(ANTENNA_INPUT_INFO *info) |
| 28 | { | 24 | { |
| 29 | if (ca_debug != 0) | ||
| 30 | printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, " | ||
| 31 | "CaModule=%d, CaAppInfo=%d, CaDateTime=%d, " | ||
| 32 | "CaPmt=%d\n", __func__, info->CaMmi, | ||
| 33 | info->CaInitializationStatus, info->CaErrorFlag, | ||
| 34 | info->CaDvbFlag, info->CaModulePresentStatus, | ||
| 35 | info->CaApplicationInfo, | ||
| 36 | info->CaDateTimeRequest, info->CaPmtReply); | ||
| 37 | return info->CaInitializationStatus == 1 && | 25 | return info->CaInitializationStatus == 1 && |
| 38 | info->CaErrorFlag == 0 && | 26 | info->CaErrorFlag == 0 && |
| 39 | info->CaDvbFlag == 1 && | 27 | info->CaDvbFlag == 1 && |
| 40 | info->CaModulePresentStatus == 1; | 28 | info->CaModulePresentStatus == 1; |
| 41 | } | 29 | } |
| 42 | 30 | ||
| 43 | static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) | 31 | static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) |
| 44 | { | 32 | { |
| 45 | int flags = 0; | 33 | int flags = 0; |
| 34 | |||
| 46 | if (info->CaModulePresentStatus == 1) | 35 | if (info->CaModulePresentStatus == 1) |
| 47 | flags |= CA_CI_MODULE_PRESENT; | 36 | flags |= CA_CI_MODULE_PRESENT; |
| 48 | if (info->CaInitializationStatus == 1 && | 37 | if (info->CaInitializationStatus == 1 && |
| @@ -54,103 +43,63 @@ static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info) | |||
| 54 | 43 | ||
| 55 | static int firesat_ca_reset(struct firesat *firesat) | 44 | static int firesat_ca_reset(struct firesat *firesat) |
| 56 | { | 45 | { |
| 57 | if (ca_debug) | 46 | return avc_ca_reset(firesat) ? -EFAULT : 0; |
| 58 | printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__); | ||
| 59 | if (avc_ca_reset(firesat)) | ||
| 60 | return -EFAULT; | ||
| 61 | return 0; | ||
| 62 | } | 47 | } |
| 63 | 48 | ||
| 64 | static int firesat_ca_get_caps(struct firesat *firesat, void *arg) | 49 | static int firesat_ca_get_caps(void *arg) |
| 65 | { | 50 | { |
| 66 | struct ca_caps *cap_p = (struct ca_caps*)arg; | 51 | struct ca_caps *cap = arg; |
| 67 | int err = 0; | 52 | |
| 68 | 53 | cap->slot_num = 1; | |
| 69 | cap_p->slot_num = 1; | 54 | cap->slot_type = CA_CI; |
| 70 | cap_p->slot_type = CA_CI; | 55 | cap->descr_num = 1; |
| 71 | cap_p->descr_num = 1; | 56 | cap->descr_type = CA_ECD; |
| 72 | cap_p->descr_type = CA_ECD; | 57 | return 0; |
| 73 | if (ca_debug) | ||
| 74 | printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__); | ||
| 75 | return err; | ||
| 76 | } | 58 | } |
| 77 | 59 | ||
| 78 | static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) | 60 | static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg) |
| 79 | { | 61 | { |
| 80 | ANTENNA_INPUT_INFO info; | 62 | ANTENNA_INPUT_INFO info; |
| 81 | struct ca_slot_info *slot_p = (struct ca_slot_info*)arg; | 63 | struct ca_slot_info *slot = arg; |
| 82 | 64 | ||
| 83 | if (ca_debug) | 65 | if (avc_tuner_status(firesat, &info)) |
| 84 | printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n", | ||
| 85 | __func__, slot_p->num); | ||
| 86 | if (AVCTunerStatus(firesat, &info)) | ||
| 87 | return -EFAULT; | 66 | return -EFAULT; |
| 88 | 67 | ||
| 89 | if (slot_p->num == 0) { | 68 | if (slot->num != 0) |
| 90 | slot_p->type = CA_CI; | ||
| 91 | slot_p->flags = firesat_get_ca_flags(&info); | ||
| 92 | } | ||
| 93 | else { | ||
| 94 | return -EFAULT; | 69 | return -EFAULT; |
| 95 | } | 70 | |
| 71 | slot->type = CA_CI; | ||
| 72 | slot->flags = firesat_get_ca_flags(&info); | ||
| 96 | return 0; | 73 | return 0; |
| 97 | } | 74 | } |
| 98 | 75 | ||
| 99 | static int firesat_ca_app_info(struct firesat *firesat, void *arg) | 76 | static int firesat_ca_app_info(struct firesat *firesat, void *arg) |
| 100 | { | 77 | { |
| 101 | struct ca_msg *reply_p = (struct ca_msg*)arg; | 78 | struct ca_msg *reply = arg; |
| 102 | int i; | ||
| 103 | 79 | ||
| 104 | if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length)) | 80 | return |
| 105 | return -EFAULT; | 81 | avc_ca_app_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0; |
| 106 | if (ca_debug) { | ||
| 107 | printk(KERN_INFO "%s: Creating TAG_APP_INFO message:", | ||
| 108 | __func__); | ||
| 109 | for (i = 0; i < reply_p->length; i++) | ||
| 110 | printk("0x%02X, ", (unsigned char)reply_p->msg[i]); | ||
| 111 | printk("\n"); | ||
| 112 | } | ||
| 113 | return 0; | ||
| 114 | } | 82 | } |
| 115 | 83 | ||
| 116 | static int firesat_ca_info(struct firesat *firesat, void *arg) | 84 | static int firesat_ca_info(struct firesat *firesat, void *arg) |
| 117 | { | 85 | { |
| 118 | struct ca_msg *reply_p = (struct ca_msg*)arg; | 86 | struct ca_msg *reply = arg; |
| 119 | int i; | ||
| 120 | 87 | ||
| 121 | if (avc_ca_info(firesat, reply_p->msg, &reply_p->length)) | 88 | return avc_ca_info(firesat, reply->msg, &reply->length) ? -EFAULT : 0; |
| 122 | return -EFAULT; | ||
| 123 | if (ca_debug) { | ||
| 124 | printk(KERN_INFO "%s: Creating TAG_CA_INFO message:", | ||
| 125 | __func__); | ||
| 126 | for (i = 0; i < reply_p->length; i++) | ||
| 127 | printk("0x%02X, ", (unsigned char)reply_p->msg[i]); | ||
| 128 | printk("\n"); | ||
| 129 | } | ||
| 130 | return 0; | ||
| 131 | } | 89 | } |
| 132 | 90 | ||
| 133 | static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) | 91 | static int firesat_ca_get_mmi(struct firesat *firesat, void *arg) |
| 134 | { | 92 | { |
| 135 | struct ca_msg *reply_p = (struct ca_msg*)arg; | 93 | struct ca_msg *reply = arg; |
| 136 | int i; | ||
| 137 | 94 | ||
| 138 | if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length)) | 95 | return |
| 139 | return -EFAULT; | 96 | avc_ca_get_mmi(firesat, reply->msg, &reply->length) ? -EFAULT : 0; |
| 140 | if (ca_debug) { | ||
| 141 | printk(KERN_INFO "%s: Creating MMI reply INFO message:", | ||
| 142 | __func__); | ||
| 143 | for (i = 0; i < reply_p->length; i++) | ||
| 144 | printk("0x%02X, ", (unsigned char)reply_p->msg[i]); | ||
| 145 | printk("\n"); | ||
| 146 | } | ||
| 147 | return 0; | ||
| 148 | } | 97 | } |
| 149 | 98 | ||
| 150 | static int firesat_ca_get_msg(struct firesat *firesat, void *arg) | 99 | static int firesat_ca_get_msg(struct firesat *firesat, void *arg) |
| 151 | { | 100 | { |
| 152 | int err; | ||
| 153 | ANTENNA_INPUT_INFO info; | 101 | ANTENNA_INPUT_INFO info; |
| 102 | int err; | ||
| 154 | 103 | ||
| 155 | switch (firesat->ca_last_command) { | 104 | switch (firesat->ca_last_command) { |
| 156 | case TAG_APP_INFO_ENQUIRY: | 105 | case TAG_APP_INFO_ENQUIRY: |
| @@ -160,11 +109,10 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg) | |||
| 160 | err = firesat_ca_info(firesat, arg); | 109 | err = firesat_ca_info(firesat, arg); |
| 161 | break; | 110 | break; |
| 162 | default: | 111 | default: |
| 163 | if (AVCTunerStatus(firesat, &info)) | 112 | if (avc_tuner_status(firesat, &info)) |
| 164 | err = -EFAULT; | 113 | err = -EFAULT; |
| 165 | else if (info.CaMmi == 1) { | 114 | else if (info.CaMmi == 1) |
| 166 | err = firesat_ca_get_mmi(firesat, arg); | 115 | err = firesat_ca_get_mmi(firesat, arg); |
| 167 | } | ||
| 168 | else { | 116 | else { |
| 169 | printk(KERN_INFO "%s: Unhandled message 0x%08X\n", | 117 | printk(KERN_INFO "%s: Unhandled message 0x%08X\n", |
| 170 | __func__, firesat->ca_last_command); | 118 | __func__, firesat->ca_last_command); |
| @@ -177,51 +125,39 @@ static int firesat_ca_get_msg(struct firesat *firesat, void *arg) | |||
| 177 | 125 | ||
| 178 | static int firesat_ca_pmt(struct firesat *firesat, void *arg) | 126 | static int firesat_ca_pmt(struct firesat *firesat, void *arg) |
| 179 | { | 127 | { |
| 180 | struct ca_msg *msg_p = (struct ca_msg*)arg; | 128 | struct ca_msg *msg = arg; |
| 181 | int data_pos; | 129 | int data_pos; |
| 182 | 130 | ||
| 183 | if (msg_p->msg[3] & 0x80) | 131 | if (msg->msg[3] & 0x80) |
| 184 | data_pos = (msg_p->msg[4] && 0x7F) + 4; | 132 | data_pos = (msg->msg[4] && 0x7F) + 4; |
| 185 | else | 133 | else |
| 186 | data_pos = 4; | 134 | data_pos = 4; |
| 187 | if (avc_ca_pmt(firesat, &msg_p->msg[data_pos], | 135 | |
| 188 | msg_p->length - data_pos)) | 136 | return avc_ca_pmt(firesat, &msg->msg[data_pos], |
| 189 | return -EFAULT; | 137 | msg->length - data_pos) ? -EFAULT : 0; |
| 190 | return 0; | ||
| 191 | } | 138 | } |
| 192 | 139 | ||
| 193 | static int firesat_ca_send_msg(struct firesat *firesat, void *arg) | 140 | static int firesat_ca_send_msg(struct firesat *firesat, void *arg) |
| 194 | { | 141 | { |
| 142 | struct ca_msg *msg = arg; | ||
| 195 | int err; | 143 | int err; |
| 196 | struct ca_msg *msg_p = (struct ca_msg*)arg; | ||
| 197 | 144 | ||
| 198 | // Do we need a semaphore for this? | 145 | /* Do we need a semaphore for this? */ |
| 199 | firesat->ca_last_command = | 146 | firesat->ca_last_command = |
| 200 | (msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2]; | 147 | (msg->msg[0] << 16) + (msg->msg[1] << 8) + msg->msg[2]; |
| 201 | switch (firesat->ca_last_command) { | 148 | switch (firesat->ca_last_command) { |
| 202 | case TAG_CA_PMT: | 149 | case TAG_CA_PMT: |
| 203 | if (ca_debug != 0) | ||
| 204 | printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n", | ||
| 205 | __func__); | ||
| 206 | err = firesat_ca_pmt(firesat, arg); | 150 | err = firesat_ca_pmt(firesat, arg); |
| 207 | break; | 151 | break; |
| 208 | case TAG_APP_INFO_ENQUIRY: | 152 | case TAG_APP_INFO_ENQUIRY: |
| 209 | // This is all handled in ca_get_msg | 153 | /* handled in ca_get_msg */ |
| 210 | if (ca_debug != 0) | ||
| 211 | printk(KERN_INFO "%s: Message received: " | ||
| 212 | "TAG_APP_INFO_ENQUIRY\n", __func__); | ||
| 213 | err = 0; | 154 | err = 0; |
| 214 | break; | 155 | break; |
| 215 | case TAG_CA_INFO_ENQUIRY: | 156 | case TAG_CA_INFO_ENQUIRY: |
| 216 | // This is all handled in ca_get_msg | 157 | /* handled in ca_get_msg */ |
| 217 | if (ca_debug != 0) | ||
| 218 | printk(KERN_INFO "%s: Message received: " | ||
| 219 | "TAG_CA_APP_INFO_ENQUIRY\n", __func__); | ||
| 220 | err = 0; | 158 | err = 0; |
| 221 | break; | 159 | break; |
| 222 | case TAG_ENTER_MENU: | 160 | case TAG_ENTER_MENU: |
| 223 | if (ca_debug != 0) | ||
| 224 | printk(KERN_INFO "%s: Entering CA menu.\n", __func__); | ||
| 225 | err = avc_ca_enter_menu(firesat); | 161 | err = avc_ca_enter_menu(firesat); |
| 226 | break; | 162 | break; |
| 227 | default: | 163 | default: |
| @@ -235,17 +171,17 @@ static int firesat_ca_send_msg(struct firesat *firesat, void *arg) | |||
| 235 | static int firesat_ca_ioctl(struct inode *inode, struct file *file, | 171 | static int firesat_ca_ioctl(struct inode *inode, struct file *file, |
| 236 | unsigned int cmd, void *arg) | 172 | unsigned int cmd, void *arg) |
| 237 | { | 173 | { |
| 238 | struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; | 174 | struct dvb_device *dvbdev = file->private_data; |
| 239 | struct firesat *firesat = dvbdev->priv; | 175 | struct firesat *firesat = dvbdev->priv; |
| 240 | int err; | ||
| 241 | ANTENNA_INPUT_INFO info; | 176 | ANTENNA_INPUT_INFO info; |
| 177 | int err; | ||
| 242 | 178 | ||
| 243 | switch(cmd) { | 179 | switch(cmd) { |
| 244 | case CA_RESET: | 180 | case CA_RESET: |
| 245 | err = firesat_ca_reset(firesat); | 181 | err = firesat_ca_reset(firesat); |
| 246 | break; | 182 | break; |
| 247 | case CA_GET_CAP: | 183 | case CA_GET_CAP: |
| 248 | err = firesat_ca_get_caps(firesat, arg); | 184 | err = firesat_ca_get_caps(arg); |
| 249 | break; | 185 | break; |
| 250 | case CA_GET_SLOT_INFO: | 186 | case CA_GET_SLOT_INFO: |
| 251 | err = firesat_ca_get_slot_info(firesat, arg); | 187 | err = firesat_ca_get_slot_info(firesat, arg); |
| @@ -262,90 +198,52 @@ static int firesat_ca_ioctl(struct inode *inode, struct file *file, | |||
| 262 | err = -EOPNOTSUPP; | 198 | err = -EOPNOTSUPP; |
| 263 | } | 199 | } |
| 264 | 200 | ||
| 265 | if (AVCTunerStatus(firesat, &info)) | 201 | /* FIXME Is this necessary? */ |
| 266 | return err; | 202 | avc_tuner_status(firesat, &info); |
| 267 | |||
| 268 | firesat_ca_ready(&info); | ||
| 269 | 203 | ||
| 270 | return err; | 204 | return err; |
| 271 | } | 205 | } |
| 272 | 206 | ||
| 273 | static int firesat_get_date_time_request(struct firesat *firesat) | ||
| 274 | { | ||
| 275 | if (ca_debug) | ||
| 276 | printk(KERN_INFO "%s: Retrieving Time/Date request\n", | ||
| 277 | __func__); | ||
| 278 | if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval)) | ||
| 279 | return -EFAULT; | ||
| 280 | if (ca_debug) | ||
| 281 | printk(KERN_INFO "%s: Time/Date interval is %d\n", | ||
| 282 | __func__, firesat->ca_time_interval); | ||
| 283 | |||
| 284 | return 0; | ||
| 285 | } | ||
| 286 | |||
| 287 | static int firesat_ca_io_open(struct inode *inode, struct file *file) | ||
| 288 | { | ||
| 289 | if (ca_debug != 0) | ||
| 290 | printk(KERN_INFO "%s\n",__func__); | ||
| 291 | return dvb_generic_open(inode, file); | ||
| 292 | } | ||
| 293 | |||
| 294 | static int firesat_ca_io_release(struct inode *inode, struct file *file) | ||
| 295 | { | ||
| 296 | if (ca_debug != 0) | ||
| 297 | printk(KERN_INFO "%s\n",__func__); | ||
| 298 | return dvb_generic_release(inode, file); | ||
| 299 | } | ||
| 300 | |||
| 301 | static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) | 207 | static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) |
| 302 | { | 208 | { |
| 303 | if (ca_debug != 0) | ||
| 304 | printk(KERN_INFO "%s\n",__func__); | ||
| 305 | return POLLIN; | 209 | return POLLIN; |
| 306 | } | 210 | } |
| 307 | 211 | ||
| 308 | static struct file_operations firesat_ca_fops = { | 212 | static struct file_operations firesat_ca_fops = { |
| 309 | .owner = THIS_MODULE, | 213 | .owner = THIS_MODULE, |
| 310 | .read = NULL, // There is no low level read anymore | 214 | .ioctl = dvb_generic_ioctl, |
| 311 | .write = NULL, // There is no low level write anymore | 215 | .open = dvb_generic_open, |
| 312 | .ioctl = dvb_generic_ioctl, | 216 | .release = dvb_generic_release, |
| 313 | .open = firesat_ca_io_open, | 217 | .poll = firesat_ca_io_poll, |
| 314 | .release = firesat_ca_io_release, | ||
| 315 | .poll = firesat_ca_io_poll, | ||
| 316 | }; | 218 | }; |
| 317 | 219 | ||
| 318 | static struct dvb_device firesat_ca = { | 220 | static struct dvb_device firesat_ca = { |
| 319 | .priv = NULL, | 221 | .users = 1, |
| 320 | .users = 1, | 222 | .readers = 1, |
| 321 | .readers = 1, | 223 | .writers = 1, |
| 322 | .writers = 1, | 224 | .fops = &firesat_ca_fops, |
| 323 | .fops = &firesat_ca_fops, | 225 | .kernel_ioctl = firesat_ca_ioctl, |
| 324 | .kernel_ioctl = firesat_ca_ioctl, | ||
| 325 | }; | 226 | }; |
| 326 | 227 | ||
| 327 | int firesat_ca_init(struct firesat *firesat) | 228 | int firesat_ca_register(struct firesat *firesat) |
| 328 | { | 229 | { |
| 329 | int err; | ||
| 330 | ANTENNA_INPUT_INFO info; | 230 | ANTENNA_INPUT_INFO info; |
| 231 | int err; | ||
| 331 | 232 | ||
| 332 | if (AVCTunerStatus(firesat, &info)) | 233 | if (avc_tuner_status(firesat, &info)) |
| 333 | return -EINVAL; | 234 | return -EINVAL; |
| 334 | 235 | ||
| 335 | if (firesat_ca_ready(&info)) { | 236 | if (!firesat_ca_ready(&info)) |
| 336 | err = dvb_register_device(firesat->adapter, | 237 | return -EFAULT; |
| 337 | &firesat->cadev, | 238 | |
| 338 | &firesat_ca, firesat, | 239 | err = dvb_register_device(&firesat->adapter, &firesat->cadev, |
| 339 | DVB_DEVICE_CA); | 240 | &firesat_ca, firesat, DVB_DEVICE_CA); |
| 340 | 241 | ||
| 341 | if (info.CaApplicationInfo == 0) | 242 | if (info.CaApplicationInfo == 0) |
| 342 | printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", | 243 | printk(KERN_ERR "%s: CaApplicationInfo is not set.\n", |
| 343 | __func__); | 244 | __func__); |
| 344 | if (info.CaDateTimeRequest == 1) | 245 | if (info.CaDateTimeRequest == 1) |
| 345 | firesat_get_date_time_request(firesat); | 246 | avc_ca_get_time_date(firesat, &firesat->ca_time_interval); |
| 346 | } | ||
| 347 | else | ||
| 348 | err = -EFAULT; | ||
| 349 | 247 | ||
| 350 | return err; | 248 | return err; |
| 351 | } | 249 | } |
| @@ -353,5 +251,5 @@ int firesat_ca_init(struct firesat *firesat) | |||
| 353 | void firesat_ca_release(struct firesat *firesat) | 251 | void firesat_ca_release(struct firesat *firesat) |
| 354 | { | 252 | { |
| 355 | if (firesat->cadev) | 253 | if (firesat->cadev) |
| 356 | dvb_unregister_device(firesat->cadev); | 254 | dvb_unregister_device(firesat->cadev); |
| 357 | } | 255 | } |
diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h index 04fe4061c778..9c68cd2246a7 100644 --- a/drivers/media/dvb/firesat/firesat-ci.h +++ b/drivers/media/dvb/firesat/firesat-ci.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | 3 | ||
| 4 | struct firesat; | 4 | struct firesat; |
| 5 | 5 | ||
| 6 | int firesat_ca_init(struct firesat *firesat); | 6 | int firesat_ca_register(struct firesat *firesat); |
| 7 | void firesat_ca_release(struct firesat *firesat); | 7 | void firesat_ca_release(struct firesat *firesat); |
| 8 | 8 | ||
| 9 | #endif /* _FIREDTV_CI_H */ | 9 | #endif /* _FIREDTV_CI_H */ |
diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c index d3e08f9fe9f7..5f9de142ee3e 100644 --- a/drivers/media/dvb/firesat/firesat-rc.c +++ b/drivers/media/dvb/firesat/firesat-rc.c | |||
| @@ -12,9 +12,11 @@ | |||
| 12 | #include <linux/bitops.h> | 12 | #include <linux/bitops.h> |
| 13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/string.h> | ||
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 16 | 17 | ||
| 17 | #include "firesat-rc.h" | 18 | #include "firesat-rc.h" |
| 19 | #include "firesat.h" | ||
| 18 | 20 | ||
| 19 | /* fixed table with older keycodes, geared towards MythTV */ | 21 | /* fixed table with older keycodes, geared towards MythTV */ |
| 20 | const static u16 oldtable[] = { | 22 | const static u16 oldtable[] = { |
| @@ -61,7 +63,7 @@ const static u16 oldtable[] = { | |||
| 61 | }; | 63 | }; |
| 62 | 64 | ||
| 63 | /* user-modifiable table for a remote as sold in 2008 */ | 65 | /* user-modifiable table for a remote as sold in 2008 */ |
| 64 | static u16 keytable[] = { | 66 | const static u16 keytable[] = { |
| 65 | 67 | ||
| 66 | /* code from device: 0x0300...0x031f */ | 68 | /* code from device: 0x0300...0x031f */ |
| 67 | 69 | ||
| @@ -123,19 +125,24 @@ static u16 keytable[] = { | |||
| 123 | [0x34] = KEY_EXIT, | 125 | [0x34] = KEY_EXIT, |
| 124 | }; | 126 | }; |
| 125 | 127 | ||
| 126 | static struct input_dev *idev; | 128 | int firesat_register_rc(struct firesat *firesat, struct device *dev) |
| 127 | |||
| 128 | int firesat_register_rc(void) | ||
| 129 | { | 129 | { |
| 130 | struct input_dev *idev; | ||
| 130 | int i, err; | 131 | int i, err; |
| 131 | 132 | ||
| 132 | idev = input_allocate_device(); | 133 | idev = input_allocate_device(); |
| 133 | if (!idev) | 134 | if (!idev) |
| 134 | return -ENOMEM; | 135 | return -ENOMEM; |
| 135 | 136 | ||
| 137 | firesat->remote_ctrl_dev = idev; | ||
| 136 | idev->name = "FireDTV remote control"; | 138 | idev->name = "FireDTV remote control"; |
| 139 | idev->dev.parent = dev; | ||
| 137 | idev->evbit[0] = BIT_MASK(EV_KEY); | 140 | idev->evbit[0] = BIT_MASK(EV_KEY); |
| 138 | idev->keycode = keytable; | 141 | idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL); |
| 142 | if (!idev->keycode) { | ||
| 143 | err = -ENOMEM; | ||
| 144 | goto fail; | ||
| 145 | } | ||
| 139 | idev->keycodesize = sizeof(keytable[0]); | 146 | idev->keycodesize = sizeof(keytable[0]); |
| 140 | idev->keycodemax = ARRAY_SIZE(keytable); | 147 | idev->keycodemax = ARRAY_SIZE(keytable); |
| 141 | 148 | ||
| @@ -144,22 +151,31 @@ int firesat_register_rc(void) | |||
| 144 | 151 | ||
| 145 | err = input_register_device(idev); | 152 | err = input_register_device(idev); |
| 146 | if (err) | 153 | if (err) |
| 147 | input_free_device(idev); | 154 | goto fail_free_keymap; |
| 148 | 155 | ||
| 156 | return 0; | ||
| 157 | |||
| 158 | fail_free_keymap: | ||
| 159 | kfree(idev->keycode); | ||
| 160 | fail: | ||
| 161 | input_free_device(idev); | ||
| 149 | return err; | 162 | return err; |
| 150 | } | 163 | } |
| 151 | 164 | ||
| 152 | void firesat_unregister_rc(void) | 165 | void firesat_unregister_rc(struct firesat *firesat) |
| 153 | { | 166 | { |
| 154 | input_unregister_device(idev); | 167 | kfree(firesat->remote_ctrl_dev->keycode); |
| 168 | input_unregister_device(firesat->remote_ctrl_dev); | ||
| 155 | } | 169 | } |
| 156 | 170 | ||
| 157 | void firesat_handle_rc(unsigned int code) | 171 | void firesat_handle_rc(struct firesat *firesat, unsigned int code) |
| 158 | { | 172 | { |
| 173 | u16 *keycode = firesat->remote_ctrl_dev->keycode; | ||
| 174 | |||
| 159 | if (code >= 0x0300 && code <= 0x031f) | 175 | if (code >= 0x0300 && code <= 0x031f) |
| 160 | code = keytable[code - 0x0300]; | 176 | code = keycode[code - 0x0300]; |
| 161 | else if (code >= 0x0340 && code <= 0x0354) | 177 | else if (code >= 0x0340 && code <= 0x0354) |
| 162 | code = keytable[code - 0x0320]; | 178 | code = keycode[code - 0x0320]; |
| 163 | else if (code >= 0x4501 && code <= 0x451f) | 179 | else if (code >= 0x4501 && code <= 0x451f) |
| 164 | code = oldtable[code - 0x4501]; | 180 | code = oldtable[code - 0x4501]; |
| 165 | else if (code >= 0x4540 && code <= 0x4542) | 181 | else if (code >= 0x4540 && code <= 0x4542) |
| @@ -170,6 +186,6 @@ void firesat_handle_rc(unsigned int code) | |||
| 170 | return; | 186 | return; |
| 171 | } | 187 | } |
| 172 | 188 | ||
| 173 | input_report_key(idev, code, 1); | 189 | input_report_key(firesat->remote_ctrl_dev, code, 1); |
| 174 | input_report_key(idev, code, 0); | 190 | input_report_key(firesat->remote_ctrl_dev, code, 0); |
| 175 | } | 191 | } |
diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h index 81f4fdec60f1..12c1c5c28b36 100644 --- a/drivers/media/dvb/firesat/firesat-rc.h +++ b/drivers/media/dvb/firesat/firesat-rc.h | |||
| @@ -1,8 +1,11 @@ | |||
| 1 | #ifndef _FIREDTV_RC_H | 1 | #ifndef _FIREDTV_RC_H |
| 2 | #define _FIREDTV_RC_H | 2 | #define _FIREDTV_RC_H |
| 3 | 3 | ||
| 4 | int firesat_register_rc(void); | 4 | struct firesat; |
| 5 | void firesat_unregister_rc(void); | 5 | struct device; |
| 6 | void firesat_handle_rc(unsigned int code); | 6 | |
| 7 | int firesat_register_rc(struct firesat *firesat, struct device *dev); | ||
| 8 | void firesat_unregister_rc(struct firesat *firesat); | ||
| 9 | void firesat_handle_rc(struct firesat *firesat, unsigned int code); | ||
| 7 | 10 | ||
| 8 | #endif /* _FIREDTV_RC_H */ | 11 | #endif /* _FIREDTV_RC_H */ |
diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h index 5f0de88e41a6..51f64c0afcdb 100644 --- a/drivers/media/dvb/firesat/firesat.h +++ b/drivers/media/dvb/firesat/firesat.h | |||
| @@ -21,11 +21,11 @@ | |||
| 21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
| 22 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
| 23 | #include <linux/workqueue.h> | 23 | #include <linux/workqueue.h> |
| 24 | #include <asm/atomic.h> | ||
| 25 | 24 | ||
| 26 | #include <demux.h> | 25 | #include <demux.h> |
| 27 | #include <dmxdev.h> | 26 | #include <dmxdev.h> |
| 28 | #include <dvb_demux.h> | 27 | #include <dvb_demux.h> |
| 28 | #include <dvb_frontend.h> | ||
| 29 | #include <dvb_net.h> | 29 | #include <dvb_net.h> |
| 30 | #include <dvbdev.h> | 30 | #include <dvbdev.h> |
| 31 | 31 | ||
| @@ -127,50 +127,35 @@ enum model_type { | |||
| 127 | FireSAT_DVB_S2 = 4, | 127 | FireSAT_DVB_S2 = 4, |
| 128 | }; | 128 | }; |
| 129 | 129 | ||
| 130 | struct hpsb_host; | 130 | struct input_dev; |
| 131 | struct hpsb_iso; | 131 | struct hpsb_iso; |
| 132 | struct node_entry; | 132 | struct unit_directory; |
| 133 | 133 | ||
| 134 | struct firesat { | 134 | struct firesat { |
| 135 | struct dvb_demux dvb_demux; | 135 | struct dvb_adapter adapter; |
| 136 | 136 | struct dmxdev dmxdev; | |
| 137 | /* DVB bits */ | 137 | struct dvb_demux demux; |
| 138 | struct dvb_adapter *adapter; | 138 | struct dmx_frontend frontend; |
| 139 | struct dmxdev dmxdev; | 139 | struct dvb_net dvbnet; |
| 140 | struct dvb_demux demux; | 140 | struct dvb_frontend fe; |
| 141 | struct dmx_frontend frontend; | 141 | |
| 142 | struct dvb_net dvbnet; | 142 | struct dvb_device *cadev; |
| 143 | struct dvb_frontend_info *frontend_info; | 143 | int ca_last_command; |
| 144 | struct dvb_frontend *fe; | 144 | int ca_time_interval; |
| 145 | 145 | ||
| 146 | struct dvb_device *cadev; | 146 | struct mutex avc_mutex; |
| 147 | int ca_last_command; | 147 | wait_queue_head_t avc_wait; |
| 148 | int ca_time_interval; | 148 | bool avc_reply_received; |
| 149 | 149 | struct work_struct remote_ctrl_work; | |
| 150 | struct mutex avc_mutex; | 150 | struct input_dev *remote_ctrl_dev; |
| 151 | wait_queue_head_t avc_wait; | ||
| 152 | atomic_t avc_reply_received; | ||
| 153 | struct work_struct remote_ctrl_work; | ||
| 154 | 151 | ||
| 155 | struct firesat_channel { | 152 | struct firesat_channel { |
| 156 | struct firesat *firesat; | 153 | bool active; |
| 157 | struct dvb_demux_feed *dvbdmxfeed; | ||
| 158 | |||
| 159 | int active; | ||
| 160 | int id; | ||
| 161 | int pid; | 154 | int pid; |
| 162 | int type; /* 1 - TS, 2 - Filter */ | ||
| 163 | } channel[16]; | 155 | } channel[16]; |
| 164 | struct mutex demux_mutex; | 156 | struct mutex demux_mutex; |
| 165 | |||
| 166 | /* needed by avc_api */ | ||
| 167 | void *respfrm; | ||
| 168 | int resp_length; | ||
| 169 | 157 | ||
| 170 | struct hpsb_host *host; | 158 | struct unit_directory *ud; |
| 171 | u64 guid; /* GUID of this node */ | ||
| 172 | u32 guid_vendor_id; /* Top 24bits of guid */ | ||
| 173 | struct node_entry *nodeentry; | ||
| 174 | 159 | ||
| 175 | enum model_type type; | 160 | enum model_type type; |
| 176 | char subunit; | 161 | char subunit; |
| @@ -181,6 +166,10 @@ struct firesat { | |||
| 181 | struct hpsb_iso *iso_handle; | 166 | struct hpsb_iso *iso_handle; |
| 182 | 167 | ||
| 183 | struct list_head list; | 168 | struct list_head list; |
| 169 | |||
| 170 | /* needed by avc_api */ | ||
| 171 | int resp_length; | ||
| 172 | u8 respfrm[512]; | ||
| 184 | }; | 173 | }; |
| 185 | 174 | ||
| 186 | struct firewireheader { | 175 | struct firewireheader { |
| @@ -226,11 +215,10 @@ struct device; | |||
| 226 | /* firesat_dvb.c */ | 215 | /* firesat_dvb.c */ |
| 227 | int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); | 216 | int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); |
| 228 | int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); | 217 | int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); |
| 229 | int firesat_dvbdev_init(struct firesat *firesat, struct device *dev, | 218 | int firesat_dvbdev_init(struct firesat *firesat, struct device *dev); |
| 230 | struct dvb_frontend *fe); | ||
| 231 | 219 | ||
| 232 | /* firesat_fe.c */ | 220 | /* firesat_fe.c */ |
| 233 | int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); | 221 | void firesat_frontend_init(struct firesat *firesat); |
| 234 | 222 | ||
| 235 | /* firesat_iso.c */ | 223 | /* firesat_iso.c */ |
| 236 | int setup_iso_channel(struct firesat *firesat); | 224 | int setup_iso_channel(struct firesat *firesat); |
diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index a13fbe6b3a3c..82bd9786571d 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| 22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
| 23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
| 24 | #include <asm/atomic.h> | ||
| 25 | 24 | ||
| 26 | #include <dmxdev.h> | 25 | #include <dmxdev.h> |
| 27 | #include <dvb_demux.h> | 26 | #include <dvb_demux.h> |
| @@ -40,40 +39,54 @@ | |||
| 40 | #include "firesat-ci.h" | 39 | #include "firesat-ci.h" |
| 41 | #include "firesat-rc.h" | 40 | #include "firesat-rc.h" |
| 42 | 41 | ||
| 43 | #define FIRESAT_Vendor_ID 0x001287 | 42 | #define MATCH_FLAGS IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \ |
| 43 | IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION | ||
| 44 | #define DIGITAL_EVERYWHERE_OUI 0x001287 | ||
| 44 | 45 | ||
| 45 | static struct ieee1394_device_id firesat_id_table[] = { | 46 | static struct ieee1394_device_id firesat_id_table[] = { |
| 46 | 47 | ||
| 47 | { | 48 | { |
| 48 | /* FloppyDTV S/CI and FloppyDTV S2 */ | 49 | /* FloppyDTV S/CI and FloppyDTV S2 */ |
| 49 | .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, | 50 | .match_flags = MATCH_FLAGS, |
| 50 | .model_id = 0x000024, | 51 | .vendor_id = DIGITAL_EVERYWHERE_OUI, |
| 51 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, | 52 | .model_id = 0x000024, |
| 53 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
| 54 | .version = AVC_SW_VERSION_ENTRY, | ||
| 52 | },{ | 55 | },{ |
| 53 | /* FloppyDTV T/CI */ | 56 | /* FloppyDTV T/CI */ |
| 54 | .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, | 57 | .match_flags = MATCH_FLAGS, |
| 55 | .model_id = 0x000025, | 58 | .vendor_id = DIGITAL_EVERYWHERE_OUI, |
| 56 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, | 59 | .model_id = 0x000025, |
| 60 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
| 61 | .version = AVC_SW_VERSION_ENTRY, | ||
| 57 | },{ | 62 | },{ |
| 58 | /* FloppyDTV C/CI */ | 63 | /* FloppyDTV C/CI */ |
| 59 | .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, | 64 | .match_flags = MATCH_FLAGS, |
| 60 | .model_id = 0x000026, | 65 | .vendor_id = DIGITAL_EVERYWHERE_OUI, |
| 61 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, | 66 | .model_id = 0x000026, |
| 67 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
| 68 | .version = AVC_SW_VERSION_ENTRY, | ||
| 62 | },{ | 69 | },{ |
| 63 | /* FireDTV S/CI and FloppyDTV S2 */ | 70 | /* FireDTV S/CI and FloppyDTV S2 */ |
| 64 | .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, | 71 | .match_flags = MATCH_FLAGS, |
| 65 | .model_id = 0x000034, | 72 | .vendor_id = DIGITAL_EVERYWHERE_OUI, |
| 66 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, | 73 | .model_id = 0x000034, |
| 74 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
| 75 | .version = AVC_SW_VERSION_ENTRY, | ||
| 67 | },{ | 76 | },{ |
| 68 | /* FireDTV T/CI */ | 77 | /* FireDTV T/CI */ |
| 69 | .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, | 78 | .match_flags = MATCH_FLAGS, |
| 70 | .model_id = 0x000035, | 79 | .vendor_id = DIGITAL_EVERYWHERE_OUI, |
| 71 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, | 80 | .model_id = 0x000035, |
| 81 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
| 82 | .version = AVC_SW_VERSION_ENTRY, | ||
| 72 | },{ | 83 | },{ |
| 73 | /* FireDTV C/CI */ | 84 | /* FireDTV C/CI */ |
| 74 | .match_flags = IEEE1394_MATCH_MODEL_ID | IEEE1394_MATCH_SPECIFIER_ID, | 85 | .match_flags = MATCH_FLAGS, |
| 75 | .model_id = 0x000036, | 86 | .vendor_id = DIGITAL_EVERYWHERE_OUI, |
| 76 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY & 0xffffff, | 87 | .model_id = 0x000036, |
| 88 | .specifier_id = AVC_UNIT_SPEC_ID_ENTRY, | ||
| 89 | .version = AVC_SW_VERSION_ENTRY, | ||
| 77 | }, { } | 90 | }, { } |
| 78 | }; | 91 | }; |
| 79 | 92 | ||
| @@ -98,8 +111,8 @@ static void fcp_request(struct hpsb_host *host, | |||
| 98 | 111 | ||
| 99 | spin_lock_irqsave(&firesat_list_lock, flags); | 112 | spin_lock_irqsave(&firesat_list_lock, flags); |
| 100 | list_for_each_entry(firesat_entry,&firesat_list,list) { | 113 | list_for_each_entry(firesat_entry,&firesat_list,list) { |
| 101 | if (firesat_entry->host == host && | 114 | if (firesat_entry->ud->ne->host == host && |
| 102 | firesat_entry->nodeentry->nodeid == nodeid && | 115 | firesat_entry->ud->ne->nodeid == nodeid && |
| 103 | (firesat_entry->subunit == (data[1]&0x7) || | 116 | (firesat_entry->subunit == (data[1]&0x7) || |
| 104 | (firesat_entry->subunit == 0 && | 117 | (firesat_entry->subunit == 0 && |
| 105 | (data[1]&0x7) == 0x7))) { | 118 | (data[1]&0x7) == 0x7))) { |
| @@ -110,12 +123,8 @@ static void fcp_request(struct hpsb_host *host, | |||
| 110 | spin_unlock_irqrestore(&firesat_list_lock, flags); | 123 | spin_unlock_irqrestore(&firesat_list_lock, flags); |
| 111 | 124 | ||
| 112 | if (firesat) | 125 | if (firesat) |
| 113 | AVCRecv(firesat,data,length); | 126 | avc_recv(firesat, data, length); |
| 114 | else | ||
| 115 | printk("%s: received fcp request from unknown source, ignored\n", __func__); | ||
| 116 | } | 127 | } |
| 117 | else | ||
| 118 | printk("%s: received invalid fcp request, ignored\n", __func__); | ||
| 119 | } | 128 | } |
| 120 | 129 | ||
| 121 | const char *firedtv_model_names[] = { | 130 | const char *firedtv_model_names[] = { |
| @@ -128,175 +137,108 @@ const char *firedtv_model_names[] = { | |||
| 128 | 137 | ||
| 129 | static int firesat_probe(struct device *dev) | 138 | static int firesat_probe(struct device *dev) |
| 130 | { | 139 | { |
| 131 | struct unit_directory *ud = container_of(dev, struct unit_directory, device); | 140 | struct unit_directory *ud = |
| 141 | container_of(dev, struct unit_directory, device); | ||
| 132 | struct firesat *firesat; | 142 | struct firesat *firesat; |
| 133 | struct dvb_frontend *fe; | ||
| 134 | unsigned long flags; | 143 | unsigned long flags; |
| 135 | unsigned char subunitcount = 0xff, subunit; | ||
| 136 | struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); | ||
| 137 | int kv_len; | 144 | int kv_len; |
| 145 | void *kv_str; | ||
| 138 | int i; | 146 | int i; |
| 139 | char *kv_buf; | 147 | int err = -ENOMEM; |
| 140 | 148 | ||
| 141 | if (!firesats) { | 149 | firesat = kzalloc(sizeof(*firesat), GFP_KERNEL); |
| 142 | printk("%s: couldn't allocate memory.\n", __func__); | 150 | if (!firesat) |
| 143 | return -ENOMEM; | 151 | return -ENOMEM; |
| 144 | } | ||
| 145 | |||
| 146 | // printk(KERN_INFO "FireSAT: Detected device with GUID %08lx%04lx%04lx\n",(unsigned long)((ud->ne->guid)>>32),(unsigned long)(ud->ne->guid & 0xFFFF),(unsigned long)ud->ne->guid_vendor_id); | ||
| 147 | printk(KERN_INFO "%s: loading device\n", __func__); | ||
| 148 | |||
| 149 | firesats[0] = NULL; | ||
| 150 | firesats[1] = NULL; | ||
| 151 | |||
| 152 | ud->device.driver_data = firesats; | ||
| 153 | |||
| 154 | for (subunit = 0; subunit < subunitcount; subunit++) { | ||
| 155 | |||
| 156 | if (!(firesat = kmalloc(sizeof (struct firesat), GFP_KERNEL)) || | ||
| 157 | !(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) { | ||
| 158 | |||
| 159 | printk("%s: couldn't allocate memory.\n", __func__); | ||
| 160 | kfree(firesats); | ||
| 161 | return -ENOMEM; | ||
| 162 | } | ||
| 163 | |||
| 164 | memset(firesat, 0, sizeof (struct firesat)); | ||
| 165 | |||
| 166 | firesat->host = ud->ne->host; | ||
| 167 | firesat->guid = ud->ne->guid; | ||
| 168 | firesat->guid_vendor_id = ud->ne->guid_vendor_id; | ||
| 169 | firesat->nodeentry = ud->ne; | ||
| 170 | firesat->isochannel = -1; | ||
| 171 | firesat->tone = 0xff; | ||
| 172 | firesat->voltage = 0xff; | ||
| 173 | firesat->fe = fe; | ||
| 174 | |||
| 175 | if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) { | ||
| 176 | printk("%s: couldn't allocate memory.\n", __func__); | ||
| 177 | kfree(firesat); | ||
| 178 | return -ENOMEM; | ||
| 179 | } | ||
| 180 | |||
| 181 | mutex_init(&firesat->avc_mutex); | ||
| 182 | init_waitqueue_head(&firesat->avc_wait); | ||
| 183 | atomic_set(&firesat->avc_reply_received, 1); | ||
| 184 | mutex_init(&firesat->demux_mutex); | ||
| 185 | INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); | ||
| 186 | |||
| 187 | spin_lock_irqsave(&firesat_list_lock, flags); | ||
| 188 | INIT_LIST_HEAD(&firesat->list); | ||
| 189 | list_add_tail(&firesat->list, &firesat_list); | ||
| 190 | spin_unlock_irqrestore(&firesat_list_lock, flags); | ||
| 191 | |||
| 192 | if (subunit == 0) { | ||
| 193 | firesat->subunit = 0x7; // 0x7 = don't care | ||
| 194 | if (AVCSubUnitInfo(firesat, &subunitcount)) { | ||
| 195 | printk("%s: AVC subunit info command failed.\n",__func__); | ||
| 196 | spin_lock_irqsave(&firesat_list_lock, flags); | ||
| 197 | list_del(&firesat->list); | ||
| 198 | spin_unlock_irqrestore(&firesat_list_lock, flags); | ||
| 199 | kfree(firesat); | ||
| 200 | return -EIO; | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | printk(KERN_INFO "%s: subunit count = %d\n", __func__, subunitcount); | ||
| 205 | |||
| 206 | firesat->subunit = subunit; | ||
| 207 | |||
| 208 | /* Reading device model from ROM */ | ||
| 209 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * | ||
| 210 | sizeof(quadlet_t); | ||
| 211 | kv_buf = kmalloc((sizeof(quadlet_t) * kv_len), GFP_KERNEL); | ||
| 212 | memcpy(kv_buf, | ||
| 213 | CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv), | ||
| 214 | kv_len); | ||
| 215 | while ((kv_buf + kv_len - 1) == '\0') kv_len--; | ||
| 216 | kv_buf[kv_len++] = '\0'; | ||
| 217 | 152 | ||
| 218 | for (i = ARRAY_SIZE(firedtv_model_names); --i;) | 153 | dev->driver_data = firesat; |
| 219 | if (strcmp(kv_buf, firedtv_model_names[i]) == 0) | 154 | firesat->ud = ud; |
| 220 | break; | 155 | firesat->subunit = 0; |
| 221 | firesat->type = i; | 156 | firesat->isochannel = -1; |
| 222 | kfree(kv_buf); | 157 | firesat->tone = 0xff; |
| 223 | 158 | firesat->voltage = 0xff; | |
| 224 | if (AVCIdentifySubunit(firesat)) { | 159 | |
| 225 | printk("%s: cannot identify subunit %d\n", __func__, subunit); | 160 | mutex_init(&firesat->avc_mutex); |
| 226 | spin_lock_irqsave(&firesat_list_lock, flags); | 161 | init_waitqueue_head(&firesat->avc_wait); |
| 227 | list_del(&firesat->list); | 162 | firesat->avc_reply_received = true; |
| 228 | spin_unlock_irqrestore(&firesat_list_lock, flags); | 163 | mutex_init(&firesat->demux_mutex); |
| 229 | kfree(firesat); | 164 | INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); |
| 230 | continue; | 165 | |
| 231 | } | 166 | /* Reading device model from ROM */ |
| 167 | kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); | ||
| 168 | kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); | ||
| 169 | for (i = ARRAY_SIZE(firedtv_model_names); --i;) | ||
| 170 | if (strlen(firedtv_model_names[i]) <= kv_len && | ||
| 171 | strncmp(kv_str, firedtv_model_names[i], kv_len) == 0) | ||
| 172 | break; | ||
| 173 | firesat->type = i; | ||
| 174 | |||
| 175 | /* | ||
| 176 | * Work around a bug in udev's path_id script: Use the fw-host's dev | ||
| 177 | * instead of the unit directory's dev as parent of the input device. | ||
| 178 | */ | ||
| 179 | err = firesat_register_rc(firesat, dev->parent->parent); | ||
| 180 | if (err) | ||
| 181 | goto fail_free; | ||
| 182 | |||
| 183 | INIT_LIST_HEAD(&firesat->list); | ||
| 184 | spin_lock_irqsave(&firesat_list_lock, flags); | ||
| 185 | list_add_tail(&firesat->list, &firesat_list); | ||
| 186 | spin_unlock_irqrestore(&firesat_list_lock, flags); | ||
| 187 | |||
| 188 | err = avc_identify_subunit(firesat); | ||
| 189 | if (err) | ||
| 190 | goto fail; | ||
| 232 | 191 | ||
| 233 | // ---- | 192 | err = firesat_dvbdev_init(firesat, dev); |
| 234 | /* FIXME: check for error return */ | 193 | if (err) |
| 235 | firesat_dvbdev_init(firesat, dev, fe); | 194 | goto fail; |
| 236 | // ---- | ||
| 237 | firesats[subunit] = firesat; | ||
| 238 | } // loop for all tuners | ||
| 239 | 195 | ||
| 240 | if (firesats[0]) | 196 | avc_register_remote_control(firesat); |
| 241 | AVCRegisterRemoteControl(firesats[0]); | 197 | return 0; |
| 242 | 198 | ||
| 243 | return 0; | 199 | fail: |
| 200 | spin_lock_irqsave(&firesat_list_lock, flags); | ||
| 201 | list_del(&firesat->list); | ||
| 202 | spin_unlock_irqrestore(&firesat_list_lock, flags); | ||
| 203 | firesat_unregister_rc(firesat); | ||
| 204 | fail_free: | ||
| 205 | kfree(firesat); | ||
| 206 | return err; | ||
| 244 | } | 207 | } |
| 245 | 208 | ||
| 246 | static int firesat_remove(struct device *dev) | 209 | static int firesat_remove(struct device *dev) |
| 247 | { | 210 | { |
| 248 | struct unit_directory *ud = container_of(dev, struct unit_directory, device); | 211 | struct firesat *firesat = dev->driver_data; |
| 249 | struct firesat **firesats = ud->device.driver_data; | ||
| 250 | int k; | ||
| 251 | unsigned long flags; | 212 | unsigned long flags; |
| 252 | 213 | ||
| 253 | if (firesats) { | 214 | firesat_ca_release(firesat); |
| 254 | for (k = 0; k < 2; k++) | 215 | dvb_unregister_frontend(&firesat->fe); |
| 255 | if (firesats[k]) { | 216 | dvb_net_release(&firesat->dvbnet); |
| 256 | firesat_ca_release(firesats[k]); | 217 | firesat->demux.dmx.close(&firesat->demux.dmx); |
| 257 | 218 | firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, | |
| 258 | dvb_unregister_frontend(firesats[k]->fe); | 219 | &firesat->frontend); |
| 259 | dvb_net_release(&firesats[k]->dvbnet); | 220 | dvb_dmxdev_release(&firesat->dmxdev); |
| 260 | firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx); | 221 | dvb_dmx_release(&firesat->demux); |
| 261 | firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend); | 222 | dvb_unregister_adapter(&firesat->adapter); |
| 262 | dvb_dmxdev_release(&firesats[k]->dmxdev); | 223 | |
| 263 | dvb_dmx_release(&firesats[k]->demux); | 224 | spin_lock_irqsave(&firesat_list_lock, flags); |
| 264 | dvb_unregister_adapter(firesats[k]->adapter); | 225 | list_del(&firesat->list); |
| 265 | 226 | spin_unlock_irqrestore(&firesat_list_lock, flags); | |
| 266 | spin_lock_irqsave(&firesat_list_lock, flags); | ||
| 267 | list_del(&firesats[k]->list); | ||
| 268 | spin_unlock_irqrestore(&firesat_list_lock, flags); | ||
| 269 | |||
| 270 | cancel_work_sync(&firesats[k]->remote_ctrl_work); | ||
| 271 | |||
| 272 | kfree(firesats[k]->fe); | ||
| 273 | kfree(firesats[k]->adapter); | ||
| 274 | kfree(firesats[k]->respfrm); | ||
| 275 | kfree(firesats[k]); | ||
| 276 | } | ||
| 277 | kfree(firesats); | ||
| 278 | } else | ||
| 279 | printk("%s: can't get firesat handle\n", __func__); | ||
| 280 | 227 | ||
| 281 | printk(KERN_INFO "FireSAT: Removing device with vendor id 0x%x, model id 0x%x.\n",ud->vendor_id,ud->model_id); | 228 | cancel_work_sync(&firesat->remote_ctrl_work); |
| 229 | firesat_unregister_rc(firesat); | ||
| 282 | 230 | ||
| 231 | kfree(firesat); | ||
| 283 | return 0; | 232 | return 0; |
| 284 | } | 233 | } |
| 285 | 234 | ||
| 286 | static int firesat_update(struct unit_directory *ud) | 235 | static int firesat_update(struct unit_directory *ud) |
| 287 | { | 236 | { |
| 288 | struct firesat **firesats = ud->device.driver_data; | 237 | struct firesat *firesat = ud->device.driver_data; |
| 289 | int k; | ||
| 290 | // loop over subunits | ||
| 291 | |||
| 292 | for (k = 0; k < 2; k++) | ||
| 293 | if (firesats[k]) { | ||
| 294 | firesats[k]->nodeentry = ud->ne; | ||
| 295 | |||
| 296 | if (firesats[k]->isochannel >= 0) | ||
| 297 | try_CMPEstablishPPconnection(firesats[k], firesats[k]->subunit, firesats[k]->isochannel); | ||
| 298 | } | ||
| 299 | 238 | ||
| 239 | if (firesat->isochannel >= 0) | ||
| 240 | cmp_establish_pp_connection(firesat, firesat->subunit, | ||
| 241 | firesat->isochannel); | ||
| 300 | return 0; | 242 | return 0; |
| 301 | } | 243 | } |
| 302 | 244 | ||
| @@ -328,26 +270,13 @@ static int __init firesat_init(void) | |||
| 328 | ret = hpsb_register_protocol(&firesat_driver); | 270 | ret = hpsb_register_protocol(&firesat_driver); |
| 329 | if (ret) { | 271 | if (ret) { |
| 330 | printk(KERN_ERR "firedtv: failed to register protocol\n"); | 272 | printk(KERN_ERR "firedtv: failed to register protocol\n"); |
| 331 | goto fail; | 273 | hpsb_unregister_highlevel(&firesat_highlevel); |
| 332 | } | ||
| 333 | |||
| 334 | ret = firesat_register_rc(); | ||
| 335 | if (ret) { | ||
| 336 | printk(KERN_ERR "firedtv: failed to register input device\n"); | ||
| 337 | goto fail_rc; | ||
| 338 | } | 274 | } |
| 339 | |||
| 340 | return 0; | ||
| 341 | fail_rc: | ||
| 342 | hpsb_unregister_protocol(&firesat_driver); | ||
| 343 | fail: | ||
| 344 | hpsb_unregister_highlevel(&firesat_highlevel); | ||
| 345 | return ret; | 275 | return ret; |
| 346 | } | 276 | } |
| 347 | 277 | ||
| 348 | static void __exit firesat_exit(void) | 278 | static void __exit firesat_exit(void) |
| 349 | { | 279 | { |
| 350 | firesat_unregister_rc(); | ||
| 351 | hpsb_unregister_protocol(&firesat_driver); | 280 | hpsb_unregister_protocol(&firesat_driver); |
| 352 | hpsb_unregister_highlevel(&firesat_highlevel); | 281 | hpsb_unregister_highlevel(&firesat_highlevel); |
| 353 | } | 282 | } |
diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c index e944cee19f0a..cfa3a2e8edd1 100644 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ b/drivers/media/dvb/firesat/firesat_dvb.c | |||
| @@ -34,8 +34,8 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) | |||
| 34 | return NULL; | 34 | return NULL; |
| 35 | 35 | ||
| 36 | for (k = 0; k < 16; k++) | 36 | for (k = 0; k < 16; k++) |
| 37 | if (firesat->channel[k].active == 0) { | 37 | if (!firesat->channel[k].active) { |
| 38 | firesat->channel[k].active = 1; | 38 | firesat->channel[k].active = true; |
| 39 | c = &firesat->channel[k]; | 39 | c = &firesat->channel[k]; |
| 40 | break; | 40 | break; |
| 41 | } | 41 | } |
| @@ -52,7 +52,7 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[] | |||
| 52 | return -EINTR; | 52 | return -EINTR; |
| 53 | 53 | ||
| 54 | for (k = 0; k < 16; k++) | 54 | for (k = 0; k < 16; k++) |
| 55 | if (firesat->channel[k].active == 1) | 55 | if (firesat->channel[k].active) |
| 56 | pid[l++] = firesat->channel[k].pid; | 56 | pid[l++] = firesat->channel[k].pid; |
| 57 | 57 | ||
| 58 | mutex_unlock(&firesat->demux_mutex); | 58 | mutex_unlock(&firesat->demux_mutex); |
| @@ -68,7 +68,7 @@ static int firesat_channel_release(struct firesat *firesat, | |||
| 68 | if (mutex_lock_interruptible(&firesat->demux_mutex)) | 68 | if (mutex_lock_interruptible(&firesat->demux_mutex)) |
| 69 | return -EINTR; | 69 | return -EINTR; |
| 70 | 70 | ||
| 71 | channel->active = 0; | 71 | channel->active = false; |
| 72 | 72 | ||
| 73 | mutex_unlock(&firesat->demux_mutex); | 73 | mutex_unlock(&firesat->demux_mutex); |
| 74 | return 0; | 74 | return 0; |
| @@ -81,8 +81,6 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 81 | int pidc,k; | 81 | int pidc,k; |
| 82 | u16 pids[16]; | 82 | u16 pids[16]; |
| 83 | 83 | ||
| 84 | // printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); | ||
| 85 | |||
| 86 | switch (dvbdmxfeed->type) { | 84 | switch (dvbdmxfeed->type) { |
| 87 | case DMX_TYPE_TS: | 85 | case DMX_TYPE_TS: |
| 88 | case DMX_TYPE_SEC: | 86 | case DMX_TYPE_SEC: |
| @@ -102,7 +100,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 102 | case DMX_TS_PES_OTHER: | 100 | case DMX_TS_PES_OTHER: |
| 103 | //Dirty fix to keep firesat->channel pid-list up to date | 101 | //Dirty fix to keep firesat->channel pid-list up to date |
| 104 | for(k=0;k<16;k++){ | 102 | for(k=0;k<16;k++){ |
| 105 | if(firesat->channel[k].active == 0) | 103 | if (!firesat->channel[k].active) |
| 106 | firesat->channel[k].pid = | 104 | firesat->channel[k].pid = |
| 107 | dvbdmxfeed->pid; | 105 | dvbdmxfeed->pid; |
| 108 | break; | 106 | break; |
| @@ -124,11 +122,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 124 | } | 122 | } |
| 125 | 123 | ||
| 126 | dvbdmxfeed->priv = channel; | 124 | dvbdmxfeed->priv = channel; |
| 127 | |||
| 128 | channel->dvbdmxfeed = dvbdmxfeed; | ||
| 129 | channel->pid = dvbdmxfeed->pid; | 125 | channel->pid = dvbdmxfeed->pid; |
| 130 | channel->type = dvbdmxfeed->type; | ||
| 131 | channel->firesat = firesat; | ||
| 132 | 126 | ||
| 133 | if (firesat_channel_collect(firesat, &pidc, pids)) { | 127 | if (firesat_channel_collect(firesat, &pidc, pids)) { |
| 134 | firesat_channel_release(firesat, channel); | 128 | firesat_channel_release(firesat, channel); |
| @@ -136,16 +130,17 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 136 | return -EINTR; | 130 | return -EINTR; |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 139 | if(dvbdmxfeed->pid == 8192) { | 133 | if (dvbdmxfeed->pid == 8192) { |
| 140 | if((k = AVCTuner_GetTS(firesat))) { | 134 | k = avc_tuner_get_ts(firesat); |
| 135 | if (k) { | ||
| 141 | firesat_channel_release(firesat, channel); | 136 | firesat_channel_release(firesat, channel); |
| 142 | printk("%s: AVCTuner_GetTS failed with error %d\n", | 137 | printk("%s: AVCTuner_GetTS failed with error %d\n", |
| 143 | __func__, k); | 138 | __func__, k); |
| 144 | return k; | 139 | return k; |
| 145 | } | 140 | } |
| 146 | } | 141 | } else { |
| 147 | else { | 142 | k = avc_tuner_set_pids(firesat, pidc, pids); |
| 148 | if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) { | 143 | if (k) { |
| 149 | firesat_channel_release(firesat, channel); | 144 | firesat_channel_release(firesat, channel); |
| 150 | printk("%s: AVCTuner_SetPIDs failed with error %d\n", | 145 | printk("%s: AVCTuner_SetPIDs failed with error %d\n", |
| 151 | __func__, k); | 146 | __func__, k); |
| @@ -164,8 +159,6 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 164 | int k, l; | 159 | int k, l; |
| 165 | u16 pids[16]; | 160 | u16 pids[16]; |
| 166 | 161 | ||
| 167 | //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); | ||
| 168 | |||
| 169 | if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && | 162 | if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) && |
| 170 | (demux->dmx.frontend->source != DMX_MEMORY_FE))) { | 163 | (demux->dmx.frontend->source != DMX_MEMORY_FE))) { |
| 171 | 164 | ||
| @@ -177,7 +170,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 177 | return -EINVAL; | 170 | return -EINVAL; |
| 178 | 171 | ||
| 179 | demux->pids[dvbdmxfeed->pes_type] |= 0x8000; | 172 | demux->pids[dvbdmxfeed->pes_type] |= 0x8000; |
| 180 | demux->pesfilter[dvbdmxfeed->pes_type] = 0; | 173 | demux->pesfilter[dvbdmxfeed->pes_type] = NULL; |
| 181 | } | 174 | } |
| 182 | 175 | ||
| 183 | if (!(dvbdmxfeed->ts_type & TS_DECODER && | 176 | if (!(dvbdmxfeed->ts_type & TS_DECODER && |
| @@ -191,118 +184,93 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | |||
| 191 | 184 | ||
| 192 | /* list except channel to be removed */ | 185 | /* list except channel to be removed */ |
| 193 | for (k = 0, l = 0; k < 16; k++) | 186 | for (k = 0, l = 0; k < 16; k++) |
| 194 | if (firesat->channel[k].active == 1) { | 187 | if (firesat->channel[k].active) { |
| 195 | if (&firesat->channel[k] != c) | 188 | if (&firesat->channel[k] != c) |
| 196 | pids[l++] = firesat->channel[k].pid; | 189 | pids[l++] = firesat->channel[k].pid; |
| 197 | else | 190 | else |
| 198 | firesat->channel[k].active = 0; | 191 | firesat->channel[k].active = false; |
| 199 | } | 192 | } |
| 200 | 193 | ||
| 201 | k = AVCTuner_SetPIDs(firesat, l, pids); | 194 | k = avc_tuner_set_pids(firesat, l, pids); |
| 202 | if (!k) | 195 | if (!k) |
| 203 | c->active = 0; | 196 | c->active = false; |
| 204 | 197 | ||
| 205 | mutex_unlock(&firesat->demux_mutex); | 198 | mutex_unlock(&firesat->demux_mutex); |
| 206 | return k; | 199 | return k; |
| 207 | } | 200 | } |
| 208 | 201 | ||
| 209 | int firesat_dvbdev_init(struct firesat *firesat, | 202 | int firesat_dvbdev_init(struct firesat *firesat, struct device *dev) |
| 210 | struct device *dev, | ||
| 211 | struct dvb_frontend *fe) | ||
| 212 | { | 203 | { |
| 213 | int result; | 204 | int err; |
| 214 | |||
| 215 | firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL); | ||
| 216 | if (!firesat->adapter) { | ||
| 217 | printk(KERN_ERR "firedtv: couldn't allocate memory\n"); | ||
| 218 | return -ENOMEM; | ||
| 219 | } | ||
| 220 | |||
| 221 | result = DVB_REGISTER_ADAPTER(firesat->adapter, | ||
| 222 | firedtv_model_names[firesat->type], | ||
| 223 | THIS_MODULE, dev, adapter_nr); | ||
| 224 | if (result < 0) { | ||
| 225 | printk(KERN_ERR "firedtv: dvb_register_adapter failed\n"); | ||
| 226 | kfree(firesat->adapter); | ||
| 227 | return result; | ||
| 228 | } | ||
| 229 | |||
| 230 | memset(&firesat->demux, 0, sizeof(struct dvb_demux)); | ||
| 231 | firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/; | ||
| 232 | |||
| 233 | firesat->demux.priv = (void *)firesat; | ||
| 234 | firesat->demux.filternum = 16; | ||
| 235 | firesat->demux.feednum = 16; | ||
| 236 | firesat->demux.start_feed = firesat_start_feed; | ||
| 237 | firesat->demux.stop_feed = firesat_stop_feed; | ||
| 238 | firesat->demux.write_to_decoder = NULL; | ||
| 239 | 205 | ||
| 240 | if ((result = dvb_dmx_init(&firesat->demux)) < 0) { | 206 | err = DVB_REGISTER_ADAPTER(&firesat->adapter, |
| 241 | printk("%s: dvb_dmx_init failed: error %d\n", __func__, | 207 | firedtv_model_names[firesat->type], |
| 242 | result); | 208 | THIS_MODULE, dev, adapter_nr); |
| 209 | if (err) | ||
| 210 | goto fail_log; | ||
| 243 | 211 | ||
| 244 | dvb_unregister_adapter(firesat->adapter); | 212 | /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/ |
| 213 | firesat->demux.dmx.capabilities = 0; | ||
| 245 | 214 | ||
| 246 | return result; | 215 | firesat->demux.priv = (void *)firesat; |
| 247 | } | 216 | firesat->demux.filternum = 16; |
| 248 | 217 | firesat->demux.feednum = 16; | |
| 249 | firesat->dmxdev.filternum = 16; | 218 | firesat->demux.start_feed = firesat_start_feed; |
| 250 | firesat->dmxdev.demux = &firesat->demux.dmx; | 219 | firesat->demux.stop_feed = firesat_stop_feed; |
| 251 | firesat->dmxdev.capabilities = 0; | 220 | firesat->demux.write_to_decoder = NULL; |
| 252 | |||
| 253 | if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) { | ||
| 254 | printk("%s: dvb_dmxdev_init failed: error %d\n", | ||
| 255 | __func__, result); | ||
| 256 | 221 | ||
| 257 | dvb_dmx_release(&firesat->demux); | 222 | err = dvb_dmx_init(&firesat->demux); |
| 258 | dvb_unregister_adapter(firesat->adapter); | 223 | if (err) |
| 224 | goto fail_unreg_adapter; | ||
| 259 | 225 | ||
| 260 | return result; | 226 | firesat->dmxdev.filternum = 16; |
| 261 | } | 227 | firesat->dmxdev.demux = &firesat->demux.dmx; |
| 228 | firesat->dmxdev.capabilities = 0; | ||
| 262 | 229 | ||
| 263 | firesat->frontend.source = DMX_FRONTEND_0; | 230 | err = dvb_dmxdev_init(&firesat->dmxdev, &firesat->adapter); |
| 231 | if (err) | ||
| 232 | goto fail_dmx_release; | ||
| 264 | 233 | ||
| 265 | if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, | 234 | firesat->frontend.source = DMX_FRONTEND_0; |
| 266 | &firesat->frontend)) < 0) { | ||
| 267 | printk("%s: dvb_dmx_init failed: error %d\n", __func__, | ||
| 268 | result); | ||
| 269 | 235 | ||
| 270 | dvb_dmxdev_release(&firesat->dmxdev); | 236 | err = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, |
| 271 | dvb_dmx_release(&firesat->demux); | 237 | &firesat->frontend); |
| 272 | dvb_unregister_adapter(firesat->adapter); | 238 | if (err) |
| 239 | goto fail_dmxdev_release; | ||
| 273 | 240 | ||
| 274 | return result; | 241 | err = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, |
| 275 | } | 242 | &firesat->frontend); |
| 243 | if (err) | ||
| 244 | goto fail_rem_frontend; | ||
| 276 | 245 | ||
| 277 | if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, | 246 | dvb_net_init(&firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); |
| 278 | &firesat->frontend)) < 0) { | ||
| 279 | printk("%s: dvb_dmx_init failed: error %d\n", __func__, | ||
| 280 | result); | ||
| 281 | 247 | ||
| 282 | firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend); | 248 | firesat_frontend_init(firesat); |
| 283 | dvb_dmxdev_release(&firesat->dmxdev); | 249 | err = dvb_register_frontend(&firesat->adapter, &firesat->fe); |
| 284 | dvb_dmx_release(&firesat->demux); | 250 | if (err) |
| 285 | dvb_unregister_adapter(firesat->adapter); | 251 | goto fail_net_release; |
| 286 | 252 | ||
| 287 | return result; | 253 | err = firesat_ca_register(firesat); |
| 288 | } | 254 | if (err) |
| 255 | dev_info(dev, "Conditional Access Module not enabled\n"); | ||
| 289 | 256 | ||
| 290 | dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); | 257 | return 0; |
| 291 | |||
| 292 | // fe->ops = firesat_ops; | ||
| 293 | // fe->dvb = firesat->adapter; | ||
| 294 | firesat_frontend_attach(firesat, fe); | ||
| 295 | |||
| 296 | fe->sec_priv = firesat; //IMPORTANT, functions depend on this!!! | ||
| 297 | if ((result= dvb_register_frontend(firesat->adapter, fe)) < 0) { | ||
| 298 | printk("%s: dvb_register_frontend_new failed: error %d\n", __func__, result); | ||
| 299 | /* ### cleanup */ | ||
| 300 | return result; | ||
| 301 | } | ||
| 302 | |||
| 303 | firesat_ca_init(firesat); | ||
| 304 | 258 | ||
| 305 | return 0; | 259 | fail_net_release: |
| 260 | dvb_net_release(&firesat->dvbnet); | ||
| 261 | firesat->demux.dmx.close(&firesat->demux.dmx); | ||
| 262 | fail_rem_frontend: | ||
| 263 | firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, | ||
| 264 | &firesat->frontend); | ||
| 265 | fail_dmxdev_release: | ||
| 266 | dvb_dmxdev_release(&firesat->dmxdev); | ||
| 267 | fail_dmx_release: | ||
| 268 | dvb_dmx_release(&firesat->demux); | ||
| 269 | fail_unreg_adapter: | ||
| 270 | dvb_unregister_adapter(&firesat->adapter); | ||
| 271 | fail_log: | ||
| 272 | dev_err(dev, "DVB initialization failed\n"); | ||
| 273 | return err; | ||
| 306 | } | 274 | } |
| 307 | 275 | ||
| 308 | 276 | ||
diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c index ec614ea8de22..1ed972b79573 100644 --- a/drivers/media/dvb/firesat/firesat_fe.c +++ b/drivers/media/dvb/firesat/firesat_fe.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
| 14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| 15 | #include <linux/string.h> | ||
| 15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
| 16 | 17 | ||
| 17 | #include <dvb_frontend.h> | 18 | #include <dvb_frontend.h> |
| @@ -22,22 +23,21 @@ | |||
| 22 | 23 | ||
| 23 | static int firesat_dvb_init(struct dvb_frontend *fe) | 24 | static int firesat_dvb_init(struct dvb_frontend *fe) |
| 24 | { | 25 | { |
| 25 | int result; | ||
| 26 | struct firesat *firesat = fe->sec_priv; | 26 | struct firesat *firesat = fe->sec_priv; |
| 27 | // printk("fdi: 1\n"); | 27 | int err; |
| 28 | firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM | 28 | |
| 29 | // printk("fdi: 2\n"); | 29 | /* FIXME - allocate free channel at IRM */ |
| 30 | result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); | 30 | firesat->isochannel = firesat->adapter.num; |
| 31 | if (result != 0) { | 31 | |
| 32 | err = cmp_establish_pp_connection(firesat, firesat->subunit, | ||
| 33 | firesat->isochannel); | ||
| 34 | if (err) { | ||
| 32 | printk(KERN_ERR "Could not establish point to point " | 35 | printk(KERN_ERR "Could not establish point to point " |
| 33 | "connection.\n"); | 36 | "connection.\n"); |
| 34 | return -1; | 37 | return err; |
| 35 | } | 38 | } |
| 36 | // printk("fdi: 3\n"); | ||
| 37 | 39 | ||
| 38 | result = setup_iso_channel(firesat); | 40 | return setup_iso_channel(firesat); |
| 39 | // printk("fdi: 4. Result was %d\n", result); | ||
| 40 | return result; | ||
| 41 | } | 41 | } |
| 42 | 42 | ||
| 43 | static int firesat_sleep(struct dvb_frontend *fe) | 43 | static int firesat_sleep(struct dvb_frontend *fe) |
| @@ -45,7 +45,7 @@ static int firesat_sleep(struct dvb_frontend *fe) | |||
| 45 | struct firesat *firesat = fe->sec_priv; | 45 | struct firesat *firesat = fe->sec_priv; |
| 46 | 46 | ||
| 47 | tear_down_iso_channel(firesat); | 47 | tear_down_iso_channel(firesat); |
| 48 | try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); | 48 | cmp_break_pp_connection(firesat, firesat->subunit, firesat->isochannel); |
| 49 | firesat->isochannel = -1; | 49 | firesat->isochannel = -1; |
| 50 | return 0; | 50 | return 0; |
| 51 | } | 51 | } |
| @@ -55,8 +55,8 @@ static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe, | |||
| 55 | { | 55 | { |
| 56 | struct firesat *firesat = fe->sec_priv; | 56 | struct firesat *firesat = fe->sec_priv; |
| 57 | 57 | ||
| 58 | return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, | 58 | return avc_lnb_control(firesat, LNBCONTROL_DONTCARE, |
| 59 | LNBCONTROL_DONTCARE, 1, cmd); | 59 | LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd); |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static int firesat_diseqc_send_burst(struct dvb_frontend *fe, | 62 | static int firesat_diseqc_send_burst(struct dvb_frontend *fe, |
| @@ -82,24 +82,19 @@ static int firesat_set_voltage(struct dvb_frontend *fe, | |||
| 82 | return 0; | 82 | return 0; |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) | 85 | static int firesat_read_status(struct dvb_frontend *fe, fe_status_t *status) |
| 86 | { | 86 | { |
| 87 | struct firesat *firesat = fe->sec_priv; | 87 | struct firesat *firesat = fe->sec_priv; |
| 88 | ANTENNA_INPUT_INFO info; | 88 | ANTENNA_INPUT_INFO info; |
| 89 | 89 | ||
| 90 | if (AVCTunerStatus(firesat, &info)) | 90 | if (avc_tuner_status(firesat, &info)) |
| 91 | return -EINVAL; | 91 | return -EINVAL; |
| 92 | 92 | ||
| 93 | if (info.NoRF) { | 93 | if (info.NoRF) |
| 94 | *status = 0; | 94 | *status = 0; |
| 95 | } else { | 95 | else |
| 96 | *status = FE_HAS_SIGNAL | | 96 | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | |
| 97 | FE_HAS_VITERBI | | 97 | FE_HAS_CARRIER | FE_HAS_LOCK; |
| 98 | FE_HAS_SYNC | | ||
| 99 | FE_HAS_CARRIER | | ||
| 100 | FE_HAS_LOCK; | ||
| 101 | } | ||
| 102 | |||
| 103 | return 0; | 98 | return 0; |
| 104 | } | 99 | } |
| 105 | 100 | ||
| @@ -108,14 +103,11 @@ static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber) | |||
| 108 | struct firesat *firesat = fe->sec_priv; | 103 | struct firesat *firesat = fe->sec_priv; |
| 109 | ANTENNA_INPUT_INFO info; | 104 | ANTENNA_INPUT_INFO info; |
| 110 | 105 | ||
| 111 | if (AVCTunerStatus(firesat, &info)) | 106 | if (avc_tuner_status(firesat, &info)) |
| 112 | return -EINVAL; | 107 | return -EINVAL; |
| 113 | 108 | ||
| 114 | *ber = (info.BER[0] << 24) | | 109 | *ber = info.BER[0] << 24 | info.BER[1] << 16 | |
| 115 | (info.BER[1] << 16) | | 110 | info.BER[2] << 8 | info.BER[3]; |
| 116 | (info.BER[2] << 8) | | ||
| 117 | info.BER[3]; | ||
| 118 | |||
| 119 | return 0; | 111 | return 0; |
| 120 | } | 112 | } |
| 121 | 113 | ||
| @@ -124,11 +116,10 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength) | |||
| 124 | struct firesat *firesat = fe->sec_priv; | 116 | struct firesat *firesat = fe->sec_priv; |
| 125 | ANTENNA_INPUT_INFO info; | 117 | ANTENNA_INPUT_INFO info; |
| 126 | 118 | ||
| 127 | if (AVCTunerStatus(firesat, &info)) | 119 | if (avc_tuner_status(firesat, &info)) |
| 128 | return -EINVAL; | 120 | return -EINVAL; |
| 129 | 121 | ||
| 130 | *strength = info.SignalStrength << 8; | 122 | *strength = info.SignalStrength << 8; |
| 131 | |||
| 132 | return 0; | 123 | return 0; |
| 133 | } | 124 | } |
| 134 | 125 | ||
| @@ -137,14 +128,12 @@ static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) | |||
| 137 | struct firesat *firesat = fe->sec_priv; | 128 | struct firesat *firesat = fe->sec_priv; |
| 138 | ANTENNA_INPUT_INFO info; | 129 | ANTENNA_INPUT_INFO info; |
| 139 | 130 | ||
| 140 | if (AVCTunerStatus(firesat, &info)) | 131 | if (avc_tuner_status(firesat, &info)) |
| 141 | return -EINVAL; | 132 | return -EINVAL; |
| 142 | 133 | ||
| 143 | *snr = (info.CarrierNoiseRatio[0] << 8) + | 134 | /* C/N[dB] = -10 * log10(snr / 65535) */ |
| 144 | info.CarrierNoiseRatio[1]; | 135 | *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1]; |
| 145 | *snr *= 257; | 136 | *snr *= 257; |
| 146 | // C/N[dB] = -10 * log10(snr / 65535) | ||
| 147 | |||
| 148 | return 0; | 137 | return 0; |
| 149 | } | 138 | } |
| 150 | 139 | ||
| @@ -158,10 +147,11 @@ static int firesat_set_frontend(struct dvb_frontend *fe, | |||
| 158 | { | 147 | { |
| 159 | struct firesat *firesat = fe->sec_priv; | 148 | struct firesat *firesat = fe->sec_priv; |
| 160 | 149 | ||
| 161 | if (AVCTuner_DSD(firesat, params, NULL) != ACCEPTED) | 150 | /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */ |
| 151 | if (avc_tuner_dsd(firesat, params) != ACCEPTED) | ||
| 162 | return -EINVAL; | 152 | return -EINVAL; |
| 163 | else | 153 | else |
| 164 | return 0; //not sure of this... | 154 | return 0; /* not sure of this... */ |
| 165 | } | 155 | } |
| 166 | 156 | ||
| 167 | static int firesat_get_frontend(struct dvb_frontend *fe, | 157 | static int firesat_get_frontend(struct dvb_frontend *fe, |
| @@ -170,107 +160,86 @@ static int firesat_get_frontend(struct dvb_frontend *fe, | |||
| 170 | return -EOPNOTSUPP; | 160 | return -EOPNOTSUPP; |
| 171 | } | 161 | } |
| 172 | 162 | ||
| 173 | static struct dvb_frontend_info firesat_S_frontend_info; | 163 | void firesat_frontend_init(struct firesat *firesat) |
| 174 | static struct dvb_frontend_info firesat_C_frontend_info; | 164 | { |
| 175 | static struct dvb_frontend_info firesat_T_frontend_info; | 165 | struct dvb_frontend_ops *ops = &firesat->fe.ops; |
| 176 | 166 | struct dvb_frontend_info *fi = &ops->info; | |
| 177 | static struct dvb_frontend_ops firesat_ops = { | ||
| 178 | 167 | ||
| 179 | .init = firesat_dvb_init, | 168 | ops->init = firesat_dvb_init; |
| 180 | .sleep = firesat_sleep, | 169 | ops->sleep = firesat_sleep; |
| 181 | 170 | ||
| 182 | .set_frontend = firesat_set_frontend, | 171 | ops->set_frontend = firesat_set_frontend; |
| 183 | .get_frontend = firesat_get_frontend, | 172 | ops->get_frontend = firesat_get_frontend; |
| 184 | 173 | ||
| 185 | .read_status = firesat_read_status, | 174 | ops->read_status = firesat_read_status; |
| 186 | .read_ber = firesat_read_ber, | 175 | ops->read_ber = firesat_read_ber; |
| 187 | .read_signal_strength = firesat_read_signal_strength, | 176 | ops->read_signal_strength = firesat_read_signal_strength; |
| 188 | .read_snr = firesat_read_snr, | 177 | ops->read_snr = firesat_read_snr; |
| 189 | .read_ucblocks = firesat_read_uncorrected_blocks, | 178 | ops->read_ucblocks = firesat_read_uncorrected_blocks; |
| 190 | 179 | ||
| 191 | .diseqc_send_master_cmd = firesat_diseqc_send_master_cmd, | 180 | ops->diseqc_send_master_cmd = firesat_diseqc_send_master_cmd; |
| 192 | .diseqc_send_burst = firesat_diseqc_send_burst, | 181 | ops->diseqc_send_burst = firesat_diseqc_send_burst; |
| 193 | .set_tone = firesat_set_tone, | 182 | ops->set_tone = firesat_set_tone; |
| 194 | .set_voltage = firesat_set_voltage, | 183 | ops->set_voltage = firesat_set_voltage; |
| 195 | }; | ||
| 196 | 184 | ||
| 197 | int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) | ||
| 198 | { | ||
| 199 | switch (firesat->type) { | 185 | switch (firesat->type) { |
| 200 | case FireSAT_DVB_S: | 186 | case FireSAT_DVB_S: |
| 201 | firesat->frontend_info = &firesat_S_frontend_info; | 187 | fi->type = FE_QPSK; |
| 188 | |||
| 189 | fi->frequency_min = 950000; | ||
| 190 | fi->frequency_max = 2150000; | ||
| 191 | fi->frequency_stepsize = 125; | ||
| 192 | fi->symbol_rate_min = 1000000; | ||
| 193 | fi->symbol_rate_max = 40000000; | ||
| 194 | |||
| 195 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
| 196 | FE_CAN_FEC_1_2 | | ||
| 197 | FE_CAN_FEC_2_3 | | ||
| 198 | FE_CAN_FEC_3_4 | | ||
| 199 | FE_CAN_FEC_5_6 | | ||
| 200 | FE_CAN_FEC_7_8 | | ||
| 201 | FE_CAN_FEC_AUTO | | ||
| 202 | FE_CAN_QPSK; | ||
| 202 | break; | 203 | break; |
| 204 | |||
| 203 | case FireSAT_DVB_C: | 205 | case FireSAT_DVB_C: |
| 204 | firesat->frontend_info = &firesat_C_frontend_info; | 206 | fi->type = FE_QAM; |
| 207 | |||
| 208 | fi->frequency_min = 47000000; | ||
| 209 | fi->frequency_max = 866000000; | ||
| 210 | fi->frequency_stepsize = 62500; | ||
| 211 | fi->symbol_rate_min = 870000; | ||
| 212 | fi->symbol_rate_max = 6900000; | ||
| 213 | |||
| 214 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
| 215 | FE_CAN_QAM_16 | | ||
| 216 | FE_CAN_QAM_32 | | ||
| 217 | FE_CAN_QAM_64 | | ||
| 218 | FE_CAN_QAM_128 | | ||
| 219 | FE_CAN_QAM_256 | | ||
| 220 | FE_CAN_QAM_AUTO; | ||
| 205 | break; | 221 | break; |
| 222 | |||
| 206 | case FireSAT_DVB_T: | 223 | case FireSAT_DVB_T: |
| 207 | firesat->frontend_info = &firesat_T_frontend_info; | 224 | fi->type = FE_OFDM; |
| 225 | |||
| 226 | fi->frequency_min = 49000000; | ||
| 227 | fi->frequency_max = 861000000; | ||
| 228 | fi->frequency_stepsize = 62500; | ||
| 229 | |||
| 230 | fi->caps = FE_CAN_INVERSION_AUTO | | ||
| 231 | FE_CAN_FEC_2_3 | | ||
| 232 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
| 233 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
| 234 | FE_CAN_HIERARCHY_AUTO; | ||
| 208 | break; | 235 | break; |
| 236 | |||
| 209 | default: | 237 | default: |
| 210 | printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", | 238 | printk(KERN_ERR "FireDTV: no frontend for model type %d\n", |
| 211 | firesat->type); | 239 | firesat->type); |
| 212 | firesat->frontend_info = NULL; | ||
| 213 | } | 240 | } |
| 214 | fe->ops = firesat_ops; | 241 | strcpy(fi->name, firedtv_model_names[firesat->type]); |
| 215 | fe->ops.info = *(firesat->frontend_info); | ||
| 216 | fe->dvb = firesat->adapter; | ||
| 217 | 242 | ||
| 218 | return 0; | 243 | firesat->fe.dvb = &firesat->adapter; |
| 244 | firesat->fe.sec_priv = firesat; | ||
| 219 | } | 245 | } |
| 220 | |||
| 221 | static struct dvb_frontend_info firesat_S_frontend_info = { | ||
| 222 | |||
| 223 | .name = "FireDTV DVB-S Frontend", | ||
| 224 | .type = FE_QPSK, | ||
| 225 | |||
| 226 | .frequency_min = 950000, | ||
| 227 | .frequency_max = 2150000, | ||
| 228 | .frequency_stepsize = 125, | ||
| 229 | .symbol_rate_min = 1000000, | ||
| 230 | .symbol_rate_max = 40000000, | ||
| 231 | |||
| 232 | .caps = FE_CAN_INVERSION_AUTO | | ||
| 233 | FE_CAN_FEC_1_2 | | ||
| 234 | FE_CAN_FEC_2_3 | | ||
| 235 | FE_CAN_FEC_3_4 | | ||
| 236 | FE_CAN_FEC_5_6 | | ||
| 237 | FE_CAN_FEC_7_8 | | ||
| 238 | FE_CAN_FEC_AUTO | | ||
| 239 | FE_CAN_QPSK, | ||
| 240 | }; | ||
| 241 | |||
| 242 | static struct dvb_frontend_info firesat_C_frontend_info = { | ||
| 243 | |||
| 244 | .name = "FireDTV DVB-C Frontend", | ||
| 245 | .type = FE_QAM, | ||
| 246 | |||
| 247 | .frequency_min = 47000000, | ||
| 248 | .frequency_max = 866000000, | ||
| 249 | .frequency_stepsize = 62500, | ||
| 250 | .symbol_rate_min = 870000, | ||
| 251 | .symbol_rate_max = 6900000, | ||
| 252 | |||
| 253 | .caps = FE_CAN_INVERSION_AUTO | | ||
| 254 | FE_CAN_QAM_16 | | ||
| 255 | FE_CAN_QAM_32 | | ||
| 256 | FE_CAN_QAM_64 | | ||
| 257 | FE_CAN_QAM_128 | | ||
| 258 | FE_CAN_QAM_256 | | ||
| 259 | FE_CAN_QAM_AUTO, | ||
| 260 | }; | ||
| 261 | |||
| 262 | static struct dvb_frontend_info firesat_T_frontend_info = { | ||
| 263 | |||
| 264 | .name = "FireDTV DVB-T Frontend", | ||
| 265 | .type = FE_OFDM, | ||
| 266 | |||
| 267 | .frequency_min = 49000000, | ||
| 268 | .frequency_max = 861000000, | ||
| 269 | .frequency_stepsize = 62500, | ||
| 270 | |||
| 271 | .caps = FE_CAN_INVERSION_AUTO | | ||
| 272 | FE_CAN_FEC_2_3 | | ||
| 273 | FE_CAN_TRANSMISSION_MODE_AUTO | | ||
| 274 | FE_CAN_GUARD_INTERVAL_AUTO | | ||
| 275 | FE_CAN_HIERARCHY_AUTO, | ||
| 276 | }; | ||
diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c index bc94afe57f63..b3c61f95fa94 100644 --- a/drivers/media/dvb/firesat/firesat_iso.c +++ b/drivers/media/dvb/firesat/firesat_iso.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | #include <dma.h> | 19 | #include <dma.h> |
| 20 | #include <iso.h> | 20 | #include <iso.h> |
| 21 | #include <nodemgr.h> | ||
| 21 | 22 | ||
| 22 | #include "firesat.h" | 23 | #include "firesat.h" |
| 23 | 24 | ||
| @@ -36,7 +37,7 @@ int setup_iso_channel(struct firesat *firesat) | |||
| 36 | { | 37 | { |
| 37 | int result; | 38 | int result; |
| 38 | firesat->iso_handle = | 39 | firesat->iso_handle = |
| 39 | hpsb_iso_recv_init(firesat->host, | 40 | hpsb_iso_recv_init(firesat->ud->ne->host, |
| 40 | 256 * 200, //data_buf_size, | 41 | 256 * 200, //data_buf_size, |
| 41 | 256, //buf_packets, | 42 | 256, //buf_packets, |
| 42 | firesat->isochannel, | 43 | firesat->isochannel, |
| @@ -59,7 +60,6 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) | |||
| 59 | { | 60 | { |
| 60 | unsigned int num; | 61 | unsigned int num; |
| 61 | unsigned int i; | 62 | unsigned int i; |
| 62 | /* unsigned int j; */ | ||
| 63 | unsigned int packet; | 63 | unsigned int packet; |
| 64 | unsigned long flags; | 64 | unsigned long flags; |
| 65 | struct firesat *firesat = NULL; | 65 | struct firesat *firesat = NULL; |
| @@ -88,12 +88,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) | |||
| 88 | (188 + sizeof(struct firewireheader)); | 88 | (188 + sizeof(struct firewireheader)); |
| 89 | if (iso->infos[packet].len <= sizeof(struct CIPHeader)) | 89 | if (iso->infos[packet].len <= sizeof(struct CIPHeader)) |
| 90 | continue; // ignore empty packet | 90 | continue; // ignore empty packet |
| 91 | /* printk("%s: Handling packets (%d): ", __func__, */ | 91 | |
| 92 | /* iso->infos[packet].len); */ | ||
| 93 | /* for (j = 0; j < iso->infos[packet].len - */ | ||
| 94 | /* sizeof(struct CIPHeader); j++) */ | ||
| 95 | /* printk("%02X,", buf[j]); */ | ||
| 96 | /* printk("\n"); */ | ||
| 97 | while (count --) { | 92 | while (count --) { |
| 98 | if (buf[sizeof(struct firewireheader)] == 0x47) | 93 | if (buf[sizeof(struct firewireheader)] == 0x47) |
| 99 | dvb_dmx_swfilter_packets(&firesat->demux, | 94 | dvb_dmx_swfilter_packets(&firesat->demux, |
