mirror of https://gitee.com/openkylin/linux.git
firesat: update isochronous interface, add CI support
I have finally managed to get the CI support for the card working. The implementation is a bare minimum to get encrypted channels to work in kaffeine. It works fine with my T/CI card. Now and then I get an AVC timeout and have to retune a channel in order to get it to work. Once the CAM seemed to hang so I needed to remove and insert it again. I.e. there are a number of glitches. The latest version contains the following changes: - Implemented the new hpsb iso interface so that data can be received from the card - Reduced some timers for demux setup which caused scanning to timeout - Added possibility to unload driver - Added support for getting C/N ratio - Added two debug parameters to the driver; ca_debug and avc_comm_debug. - Added CI support that works for me in kaffeine - Started working on CI MMI support. It now supports: o Enter menu o Receiving MMI objects - Added support for 64-bit platforms - Corrected DVB-C modulations problems Signed-off-by: Henrik Kurelid <henrik@kurelid.se> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> (rebased, whitespace)
This commit is contained in:
parent
2c22861459
commit
df4846c352
|
@ -1,6 +1,7 @@
|
||||||
firesat-objs := firesat_1394.o \
|
firesat-objs := firesat_1394.o \
|
||||||
firesat_dvb.o \
|
firesat_dvb.o \
|
||||||
firesat_fe.o \
|
firesat_fe.o \
|
||||||
|
firesat_iso.o \
|
||||||
avc_api.o \
|
avc_api.o \
|
||||||
cmp.o \
|
cmp.o \
|
||||||
firesat-rc.o \
|
firesat-rc.o \
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
|
* Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
|
||||||
* Copyright (c) 2008 Ben Backx <ben@bbackx.com>
|
* Copyright (c) 2008 Ben Backx <ben@bbackx.com>
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
#include <nodemgr.h>
|
#include <nodemgr.h>
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
|
#include <linux/crc32.h>
|
||||||
#include "avc_api.h"
|
#include "avc_api.h"
|
||||||
#include "firesat-rc.h"
|
#include "firesat-rc.h"
|
||||||
|
|
||||||
|
@ -22,6 +24,10 @@
|
||||||
#define COMMAND_REGISTER 0xFFFFF0000B00ULL
|
#define COMMAND_REGISTER 0xFFFFF0000B00ULL
|
||||||
#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
|
#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
|
||||||
|
|
||||||
|
static unsigned int avc_comm_debug = 0;
|
||||||
|
module_param(avc_comm_debug, int, 0644);
|
||||||
|
MODULE_PARM_DESC(avc_comm_debug, "debug logging of AV/C communication, default is 0 (no)");
|
||||||
|
|
||||||
static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
|
static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal);
|
||||||
|
|
||||||
/* Frees an allocated packet */
|
/* Frees an allocated packet */
|
||||||
|
@ -47,7 +53,124 @@ static int avc_down_timeout(atomic_t *done, int timeout)
|
||||||
return ((i > 0) ? 0:1);
|
return ((i > 0) ? 0:1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) {
|
static const char* get_ctype_string(__u8 ctype)
|
||||||
|
{
|
||||||
|
switch(ctype)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "CONTROL";
|
||||||
|
case 1:
|
||||||
|
return "STATUS";
|
||||||
|
case 2:
|
||||||
|
return "SPECIFIC_INQUIRY";
|
||||||
|
case 3:
|
||||||
|
return "NOTIFY";
|
||||||
|
case 4:
|
||||||
|
return "GENERAL_INQUIRY";
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* get_resp_string(__u8 ctype)
|
||||||
|
{
|
||||||
|
switch(ctype)
|
||||||
|
{
|
||||||
|
case 8:
|
||||||
|
return "NOT_IMPLEMENTED";
|
||||||
|
case 9:
|
||||||
|
return "ACCEPTED";
|
||||||
|
case 10:
|
||||||
|
return "REJECTED";
|
||||||
|
case 11:
|
||||||
|
return "IN_TRANSITION";
|
||||||
|
case 12:
|
||||||
|
return "IMPLEMENTED_STABLE";
|
||||||
|
case 13:
|
||||||
|
return "CHANGED";
|
||||||
|
case 15:
|
||||||
|
return "INTERIM";
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* get_subunit_address(__u8 subunit_id, __u8 subunit_type)
|
||||||
|
{
|
||||||
|
if (subunit_id == 7 && subunit_type == 0x1F)
|
||||||
|
return "Unit";
|
||||||
|
if (subunit_id == 0 && subunit_type == 0x05)
|
||||||
|
return "Tuner(0)";
|
||||||
|
return "Unsupported";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* get_opcode_string(__u8 opcode)
|
||||||
|
{
|
||||||
|
switch(opcode)
|
||||||
|
{
|
||||||
|
case 0x02:
|
||||||
|
return "PlugInfo";
|
||||||
|
case 0x08:
|
||||||
|
return "OpenDescriptor";
|
||||||
|
case 0x09:
|
||||||
|
return "ReadDescriptor";
|
||||||
|
case 0x18:
|
||||||
|
return "OutputPlugSignalFormat";
|
||||||
|
case 0x31:
|
||||||
|
return "SubunitInfo";
|
||||||
|
case 0x30:
|
||||||
|
return "UnitInfo";
|
||||||
|
case 0xB2:
|
||||||
|
return "Power";
|
||||||
|
case 0xC8:
|
||||||
|
return "DirectSelectInformationType";
|
||||||
|
case 0xCB:
|
||||||
|
return "DirectSelectData";
|
||||||
|
case 0x00:
|
||||||
|
return "Vendor";
|
||||||
|
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_command_frame(const AVCCmdFrm *CmdFrm)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
printk(KERN_INFO "AV/C Command Frame:\n");
|
||||||
|
printk("CommandType=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), "
|
||||||
|
"length=%d\n", get_ctype_string(CmdFrm->ctype),
|
||||||
|
get_subunit_address(CmdFrm->suid, CmdFrm->sutyp),
|
||||||
|
CmdFrm->suid, CmdFrm->sutyp, get_opcode_string(CmdFrm->opcode),
|
||||||
|
CmdFrm->opcode, CmdFrm->length);
|
||||||
|
for(k = 0; k < CmdFrm->length - 3; k++) {
|
||||||
|
if (k % 5 != 0)
|
||||||
|
printk(", ");
|
||||||
|
else if (k != 0)
|
||||||
|
printk("\n");
|
||||||
|
printk("operand[%d] = %02X", k, CmdFrm->operand[k]);
|
||||||
|
}
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void log_response_frame(const AVCRspFrm *RspFrm)
|
||||||
|
{
|
||||||
|
int k;
|
||||||
|
printk(KERN_INFO "AV/C Response Frame:\n");
|
||||||
|
printk("Response=%s, Address=%s(0x%02X,0x%02X), opcode=%s(0x%02X), "
|
||||||
|
"length=%d\n", get_resp_string(RspFrm->resp),
|
||||||
|
get_subunit_address(RspFrm->suid, RspFrm->sutyp),
|
||||||
|
RspFrm->suid, RspFrm->sutyp, get_opcode_string(RspFrm->opcode),
|
||||||
|
RspFrm->opcode, RspFrm->length);
|
||||||
|
for(k = 0; k < RspFrm->length - 3; k++) {
|
||||||
|
if (k % 5 != 0)
|
||||||
|
printk(", ");
|
||||||
|
else if (k != 0)
|
||||||
|
printk("\n");
|
||||||
|
printk("operand[%d] = %02X", k, RspFrm->operand[k]);
|
||||||
|
}
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm,
|
||||||
|
AVCRspFrm *RspFrm) {
|
||||||
struct hpsb_packet *packet;
|
struct hpsb_packet *packet;
|
||||||
struct node_entry *ne;
|
struct node_entry *ne;
|
||||||
|
|
||||||
|
@ -58,39 +181,50 @@ static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFr
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need all input data */
|
/* need all input data */
|
||||||
if(!firesat || !ne || !CmdFrm)
|
if(!firesat || !ne || !CmdFrm) {
|
||||||
|
printk("%s: missing input data!\n",__func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
// printk(KERN_INFO "AVCWrite command %x\n",CmdFrm->opcode);
|
if (avc_comm_debug == 1) {
|
||||||
|
log_command_frame(CmdFrm);
|
||||||
// for(k=0;k<CmdFrm->length;k++)
|
}
|
||||||
// printk(KERN_INFO "CmdFrm[%d] = %08x\n", k, ((quadlet_t*)CmdFrm)[k]);
|
|
||||||
|
|
||||||
packet=hpsb_make_writepacket(ne->host, ne->nodeid, COMMAND_REGISTER,
|
|
||||||
(quadlet_t*)CmdFrm, CmdFrm->length);
|
|
||||||
|
|
||||||
hpsb_set_packet_complete_task(packet, (void (*)(void*))avc_free_packet,
|
|
||||||
packet);
|
|
||||||
|
|
||||||
hpsb_node_fill_packet(ne, packet);
|
|
||||||
|
|
||||||
if(RspFrm)
|
if(RspFrm)
|
||||||
atomic_set(&firesat->avc_reply_received, 0);
|
atomic_set(&firesat->avc_reply_received, 0);
|
||||||
|
|
||||||
|
packet=hpsb_make_writepacket(ne->host, ne->nodeid,
|
||||||
|
COMMAND_REGISTER,
|
||||||
|
(quadlet_t*)CmdFrm,
|
||||||
|
CmdFrm->length);
|
||||||
|
hpsb_set_packet_complete_task(packet,
|
||||||
|
(void (*)(void*))avc_free_packet,
|
||||||
|
packet);
|
||||||
|
hpsb_node_fill_packet(ne, packet);
|
||||||
|
|
||||||
if (hpsb_send_packet(packet) < 0) {
|
if (hpsb_send_packet(packet) < 0) {
|
||||||
avc_free_packet(packet);
|
avc_free_packet(packet);
|
||||||
atomic_set(&firesat->avc_reply_received, 1);
|
atomic_set(&firesat->avc_reply_received, 1);
|
||||||
|
printk("%s: send failed!\n",__func__);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RspFrm) {
|
if(RspFrm) {
|
||||||
if(avc_down_timeout(&firesat->avc_reply_received,HZ/2)) {
|
// AV/C specs say that answers should be send within
|
||||||
printk("%s: timeout waiting for avc response\n",__func__);
|
// 150 ms so let's time out after 200 ms
|
||||||
|
if(avc_down_timeout(&firesat->avc_reply_received,
|
||||||
|
HZ / 5)) {
|
||||||
|
printk("%s: timeout waiting for avc response\n",
|
||||||
|
__func__);
|
||||||
atomic_set(&firesat->avc_reply_received, 1);
|
atomic_set(&firesat->avc_reply_received, 1);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
memcpy(RspFrm, firesat->respfrm,
|
||||||
memcpy(RspFrm,firesat->respfrm,firesat->resp_length);
|
firesat->resp_length);
|
||||||
|
RspFrm->length = firesat->resp_length;
|
||||||
|
if (avc_comm_debug == 1) {
|
||||||
|
log_response_frame(RspFrm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -137,6 +271,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
|
||||||
|
|
||||||
// remote control handling
|
// remote control handling
|
||||||
|
|
||||||
|
#if 0
|
||||||
AVCRspFrm *RspFrm = (AVCRspFrm*)data;
|
AVCRspFrm *RspFrm = (AVCRspFrm*)data;
|
||||||
|
|
||||||
if(/*RspFrm->length >= 8 && ###*/
|
if(/*RspFrm->length >= 8 && ###*/
|
||||||
|
@ -155,21 +290,21 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
|
||||||
printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp);
|
printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if(atomic_read(&firesat->avc_reply_received) == 1) {
|
if(atomic_read(&firesat->avc_reply_received) == 1) {
|
||||||
printk("%s: received out-of-order AVC response, ignored\n",__func__);
|
printk("%s: received out-of-order AVC response, ignored\n",__func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
// AVCRspFrm *resp=(AVCRspFrm *)data;
|
// AVCRspFrm *resp=(AVCRspFrm *)data;
|
||||||
// int k;
|
// int k;
|
||||||
/*
|
|
||||||
printk(KERN_INFO "resp=0x%x\n",resp->resp);
|
// printk(KERN_INFO "resp=0x%x\n",resp->resp);
|
||||||
printk(KERN_INFO "cts=0x%x\n",resp->cts);
|
// printk(KERN_INFO "cts=0x%x\n",resp->cts);
|
||||||
printk(KERN_INFO "suid=0x%x\n",resp->suid);
|
// printk(KERN_INFO "suid=0x%x\n",resp->suid);
|
||||||
printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
|
// printk(KERN_INFO "sutyp=0x%x\n",resp->sutyp);
|
||||||
printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
|
// printk(KERN_INFO "opcode=0x%x\n",resp->opcode);
|
||||||
printk(KERN_INFO "length=%d\n",resp->length);
|
// printk(KERN_INFO "length=%d\n",resp->length);
|
||||||
*/
|
|
||||||
// for(k=0;k<2;k++)
|
// for(k=0;k<2;k++)
|
||||||
// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
|
// printk(KERN_INFO "operand[%d]=%02x\n",k,resp->operand[k]);
|
||||||
|
|
||||||
|
@ -183,6 +318,7 @@ int AVCRecv(struct firesat *firesat, u8 *data, size_t length) {
|
||||||
|
|
||||||
// tuning command for setting the relative LNB frequency (not supported by the AVC standard)
|
// tuning command for setting the relative LNB frequency (not supported by the AVC standard)
|
||||||
static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) {
|
static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_parameters *params, AVCCmdFrm *CmdFrm) {
|
||||||
|
|
||||||
memset(CmdFrm, 0, sizeof(AVCCmdFrm));
|
memset(CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
|
||||||
CmdFrm->cts = AVC;
|
CmdFrm->cts = AVC;
|
||||||
|
@ -249,7 +385,7 @@ static void AVCTuner_tuneQPSK(struct firesat *firesat, struct dvb_frontend_param
|
||||||
CmdFrm->length = 16;
|
CmdFrm->length = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status) {
|
int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status) {
|
||||||
AVCCmdFrm CmdFrm;
|
AVCCmdFrm CmdFrm;
|
||||||
AVCRspFrm RspFrm;
|
AVCRspFrm RspFrm;
|
||||||
M_VALID_FLAGS flags;
|
M_VALID_FLAGS flags;
|
||||||
|
@ -274,21 +410,15 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
|
||||||
flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
|
flags.Bits_T.TransmissionMode = (params->u.ofdm.transmission_mode != TRANSMISSION_MODE_AUTO);
|
||||||
flags.Bits_T.NetworkId = 0;
|
flags.Bits_T.NetworkId = 0;
|
||||||
} else {
|
} else {
|
||||||
flags.Bits.Modulation = 0;
|
flags.Bits.Modulation =
|
||||||
if(firesat->type == FireSAT_DVB_S) {
|
(params->u.qam.modulation != QAM_AUTO);
|
||||||
flags.Bits.FEC_inner = 1;
|
flags.Bits.FEC_inner =
|
||||||
} else if(firesat->type == FireSAT_DVB_C) {
|
(params->u.qam.fec_inner != FEC_AUTO);
|
||||||
flags.Bits.FEC_inner = 0;
|
|
||||||
}
|
|
||||||
flags.Bits.FEC_outer = 0;
|
flags.Bits.FEC_outer = 0;
|
||||||
flags.Bits.Symbol_Rate = 1;
|
flags.Bits.Symbol_Rate = 1;
|
||||||
flags.Bits.Frequency = 1;
|
flags.Bits.Frequency = 1;
|
||||||
flags.Bits.Orbital_Pos = 0;
|
flags.Bits.Orbital_Pos = 0;
|
||||||
if(firesat->type == FireSAT_DVB_S) {
|
flags.Bits.Polarisation = 0;
|
||||||
flags.Bits.Polarisation = 1;
|
|
||||||
} else if(firesat->type == FireSAT_DVB_C) {
|
|
||||||
flags.Bits.Polarisation = 0;
|
|
||||||
}
|
|
||||||
flags.Bits.reserved_fields = 0;
|
flags.Bits.reserved_fields = 0;
|
||||||
flags.Bits.reserved1 = 0;
|
flags.Bits.reserved1 = 0;
|
||||||
flags.Bits.Network_ID = 0;
|
flags.Bits.Network_ID = 0;
|
||||||
|
@ -306,15 +436,18 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
|
||||||
CmdFrm.operand[1] = 0xD2; // subfunction replace
|
CmdFrm.operand[1] = 0xD2; // subfunction replace
|
||||||
CmdFrm.operand[2] = 0x20; // system id = DVB
|
CmdFrm.operand[2] = 0x20; // system id = DVB
|
||||||
CmdFrm.operand[3] = 0x00; // antenna number
|
CmdFrm.operand[3] = 0x00; // antenna number
|
||||||
CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
|
// system_specific_multiplex selection_length
|
||||||
|
CmdFrm.operand[4] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11;
|
||||||
CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
|
CmdFrm.operand[5] = flags.Valid_Word.ByteHi; // valid_flags [0]
|
||||||
CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
|
CmdFrm.operand[6] = flags.Valid_Word.ByteLo; // valid_flags [1]
|
||||||
|
|
||||||
if(firesat->type == FireSAT_DVB_T) {
|
if(firesat->type == FireSAT_DVB_T) {
|
||||||
CmdFrm.operand[7] = 0x0;
|
CmdFrm.operand[7] = 0x0;
|
||||||
CmdFrm.operand[8] = (params->frequency/10) >> 24;
|
CmdFrm.operand[8] = (params->frequency/10) >> 24;
|
||||||
CmdFrm.operand[9] = ((params->frequency/10) >> 16) & 0xFF;
|
CmdFrm.operand[9] =
|
||||||
CmdFrm.operand[10] = ((params->frequency/10) >> 8) & 0xFF;
|
((params->frequency/10) >> 16) & 0xFF;
|
||||||
|
CmdFrm.operand[10] =
|
||||||
|
((params->frequency/10) >> 8) & 0xFF;
|
||||||
CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
|
CmdFrm.operand[11] = (params->frequency/10) & 0xFF;
|
||||||
switch(params->u.ofdm.bandwidth) {
|
switch(params->u.ofdm.bandwidth) {
|
||||||
case BANDWIDTH_7_MHZ:
|
case BANDWIDTH_7_MHZ:
|
||||||
|
@ -416,28 +549,24 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
|
||||||
CmdFrm.operand[16] = 0x00; // network_ID[1]
|
CmdFrm.operand[16] = 0x00; // network_ID[1]
|
||||||
CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
|
CmdFrm.operand[17] = 0x00; // Nr_of_dsd_sel_specs = 0 - > No PIDs are transmitted
|
||||||
|
|
||||||
CmdFrm.length = 20;
|
CmdFrm.length = 24;
|
||||||
} else {
|
} else {
|
||||||
CmdFrm.operand[7] = 0x00;
|
CmdFrm.operand[7] = 0x00;
|
||||||
CmdFrm.operand[8] = (((firesat->voltage==SEC_VOLTAGE_18)?0:1)<<6); /* 0 = H, 1 = V */
|
CmdFrm.operand[8] = 0x00;
|
||||||
CmdFrm.operand[9] = 0x00;
|
CmdFrm.operand[9] = 0x00;
|
||||||
CmdFrm.operand[10] = 0x00;
|
CmdFrm.operand[10] = 0x00;
|
||||||
|
|
||||||
if(firesat->type == FireSAT_DVB_S) {
|
CmdFrm.operand[11] =
|
||||||
/* ### relative frequency -> absolute frequency */
|
(((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
|
||||||
CmdFrm.operand[11] = (((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
|
CmdFrm.operand[12] =
|
||||||
CmdFrm.operand[12] = ((params->frequency/4) >> 8) & 0xFF;
|
((params->frequency/4000) >> 8) & 0xFF;
|
||||||
CmdFrm.operand[13] = (params->frequency/4) & 0xFF;
|
CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
|
||||||
} else if(firesat->type == FireSAT_DVB_C) {
|
CmdFrm.operand[14] =
|
||||||
CmdFrm.operand[11] = (((params->frequency/4000) >> 16) & 0xFF) | (2 << 6);
|
((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
|
||||||
CmdFrm.operand[12] = ((params->frequency/4000) >> 8) & 0xFF;
|
CmdFrm.operand[15] =
|
||||||
CmdFrm.operand[13] = (params->frequency/4000) & 0xFF;
|
((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
|
||||||
}
|
CmdFrm.operand[16] =
|
||||||
|
((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
|
||||||
CmdFrm.operand[14] = ((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
|
|
||||||
CmdFrm.operand[15] = ((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
|
|
||||||
CmdFrm.operand[16] = ((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
|
|
||||||
|
|
||||||
CmdFrm.operand[17] = 0x00;
|
CmdFrm.operand[17] = 0x00;
|
||||||
switch(params->u.qpsk.fec_inner) {
|
switch(params->u.qpsk.fec_inner) {
|
||||||
case FEC_1_2:
|
case FEC_1_2:
|
||||||
|
@ -455,35 +584,35 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
|
||||||
case FEC_7_8:
|
case FEC_7_8:
|
||||||
CmdFrm.operand[18] = 0x5;
|
CmdFrm.operand[18] = 0x5;
|
||||||
break;
|
break;
|
||||||
case FEC_4_5:
|
|
||||||
case FEC_8_9:
|
case FEC_8_9:
|
||||||
|
CmdFrm.operand[18] = 0x6;
|
||||||
|
break;
|
||||||
|
case FEC_4_5:
|
||||||
|
CmdFrm.operand[18] = 0x8;
|
||||||
|
break;
|
||||||
case FEC_AUTO:
|
case FEC_AUTO:
|
||||||
default:
|
default:
|
||||||
CmdFrm.operand[18] = 0x0;
|
CmdFrm.operand[18] = 0x0;
|
||||||
}
|
}
|
||||||
if(firesat->type == FireSAT_DVB_S) {
|
switch(params->u.qam.modulation) {
|
||||||
|
case QAM_16:
|
||||||
CmdFrm.operand[19] = 0x08; // modulation
|
CmdFrm.operand[19] = 0x08; // modulation
|
||||||
} else if(firesat->type == FireSAT_DVB_C) {
|
break;
|
||||||
switch(params->u.qam.modulation) {
|
case QAM_32:
|
||||||
case QAM_16:
|
CmdFrm.operand[19] = 0x10; // modulation
|
||||||
CmdFrm.operand[19] = 0x08; // modulation
|
break;
|
||||||
break;
|
case QAM_64:
|
||||||
case QAM_32:
|
CmdFrm.operand[19] = 0x18; // modulation
|
||||||
CmdFrm.operand[19] = 0x10; // modulation
|
break;
|
||||||
break;
|
case QAM_128:
|
||||||
case QAM_64:
|
CmdFrm.operand[19] = 0x20; // modulation
|
||||||
CmdFrm.operand[19] = 0x18; // modulation
|
break;
|
||||||
break;
|
case QAM_256:
|
||||||
case QAM_128:
|
CmdFrm.operand[19] = 0x28; // modulation
|
||||||
CmdFrm.operand[19] = 0x20; // modulation
|
break;
|
||||||
break;
|
case QAM_AUTO:
|
||||||
case QAM_256:
|
default:
|
||||||
CmdFrm.operand[19] = 0x28; // modulation
|
CmdFrm.operand[19] = 0x00; // modulation
|
||||||
break;
|
|
||||||
case QAM_AUTO:
|
|
||||||
default:
|
|
||||||
CmdFrm.operand[19] = 0x00; // modulation
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CmdFrm.operand[20] = 0x00;
|
CmdFrm.operand[20] = 0x00;
|
||||||
CmdFrm.operand[21] = 0x00;
|
CmdFrm.operand[21] = 0x00;
|
||||||
|
@ -496,7 +625,6 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
|
||||||
if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
|
if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
|
||||||
return k;
|
return k;
|
||||||
|
|
||||||
// msleep(250);
|
|
||||||
mdelay(500);
|
mdelay(500);
|
||||||
|
|
||||||
if(status)
|
if(status)
|
||||||
|
@ -504,13 +632,12 @@ int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
|
int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[])
|
||||||
|
{
|
||||||
AVCCmdFrm CmdFrm;
|
AVCCmdFrm CmdFrm;
|
||||||
AVCRspFrm RspFrm;
|
AVCRspFrm RspFrm;
|
||||||
int pos,k;
|
int pos,k;
|
||||||
|
|
||||||
printk(KERN_INFO "%s\n", __func__);
|
|
||||||
|
|
||||||
if(pidc > 16 && pidc != 0xFF)
|
if(pidc > 16 && pidc != 0xFF)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -526,49 +653,11 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
|
||||||
CmdFrm.operand[1] = 0xD2; // subfunction replace
|
CmdFrm.operand[1] = 0xD2; // subfunction replace
|
||||||
CmdFrm.operand[2] = 0x20; // system id = DVB
|
CmdFrm.operand[2] = 0x20; // system id = DVB
|
||||||
CmdFrm.operand[3] = 0x00; // antenna number
|
CmdFrm.operand[3] = 0x00; // antenna number
|
||||||
CmdFrm.operand[4] = 0x11; // system_specific_multiplex selection_length
|
CmdFrm.operand[4] = 0x00; // system_specific_multiplex selection_length
|
||||||
CmdFrm.operand[5] = 0x00; // valid_flags [0]
|
CmdFrm.operand[5] = pidc; // Nr_of_dsd_sel_specs
|
||||||
CmdFrm.operand[6] = 0x00; // valid_flags [1]
|
|
||||||
|
|
||||||
if(firesat->type == FireSAT_DVB_T) {
|
pos=6;
|
||||||
/* CmdFrm.operand[7] = 0x00;
|
if(pidc != 0xFF) {
|
||||||
CmdFrm.operand[8] = 0x00;//(params->frequency/10) >> 24;
|
|
||||||
CmdFrm.operand[9] = 0x00;//((params->frequency/10) >> 16) & 0xFF;
|
|
||||||
CmdFrm.operand[10] = 0x00;//((params->frequency/10) >> 8) & 0xFF;
|
|
||||||
CmdFrm.operand[11] = 0x00;//(params->frequency/10) & 0xFF;
|
|
||||||
CmdFrm.operand[12] = 0x00;
|
|
||||||
CmdFrm.operand[13] = 0x00;
|
|
||||||
CmdFrm.operand[14] = 0x00;
|
|
||||||
|
|
||||||
CmdFrm.operand[15] = 0x00; // network_ID[0]
|
|
||||||
CmdFrm.operand[16] = 0x00; // network_ID[1]
|
|
||||||
*/ CmdFrm.operand[17] = pidc; // Nr_of_dsd_sel_specs
|
|
||||||
|
|
||||||
pos=18;
|
|
||||||
} else {
|
|
||||||
/* CmdFrm.operand[7] = 0x00;
|
|
||||||
CmdFrm.operand[8] = 0x00;
|
|
||||||
CmdFrm.operand[9] = 0x00;
|
|
||||||
CmdFrm.operand[10] = 0x00;
|
|
||||||
|
|
||||||
CmdFrm.operand[11] = 0x00;//(((params->frequency/4) >> 16) & 0xFF) | (2 << 6);
|
|
||||||
CmdFrm.operand[12] = 0x00;//((params->frequency/4) >> 8) & 0xFF;
|
|
||||||
CmdFrm.operand[13] = 0x00;//(params->frequency/4) & 0xFF;
|
|
||||||
|
|
||||||
CmdFrm.operand[14] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 12) & 0xFF;
|
|
||||||
CmdFrm.operand[15] = 0x00;//((params->u.qpsk.symbol_rate/1000) >> 4) & 0xFF;
|
|
||||||
CmdFrm.operand[16] = 0x00;//((params->u.qpsk.symbol_rate/1000) << 4) & 0xF0;
|
|
||||||
|
|
||||||
CmdFrm.operand[17] = 0x00;
|
|
||||||
CmdFrm.operand[18] = 0x00;
|
|
||||||
CmdFrm.operand[19] = 0x00; // modulation
|
|
||||||
CmdFrm.operand[20] = 0x00;
|
|
||||||
CmdFrm.operand[21] = 0x00;*/
|
|
||||||
CmdFrm.operand[22] = pidc; // Nr_of_dsd_sel_specs
|
|
||||||
|
|
||||||
pos=23;
|
|
||||||
}
|
|
||||||
if(pidc != 0xFF)
|
|
||||||
for(k=0;k<pidc;k++) {
|
for(k=0;k<pidc;k++) {
|
||||||
CmdFrm.operand[pos++] = 0x13; // flowfunction relay
|
CmdFrm.operand[pos++] = 0x13; // flowfunction relay
|
||||||
CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
|
CmdFrm.operand[pos++] = 0x80; // dsd_sel_spec_valid_flags -> PID
|
||||||
|
@ -577,17 +666,16 @@ int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]) {
|
||||||
CmdFrm.operand[pos++] = 0x00; // tableID
|
CmdFrm.operand[pos++] = 0x00; // tableID
|
||||||
CmdFrm.operand[pos++] = 0x00; // filter_length
|
CmdFrm.operand[pos++] = 0x00; // filter_length
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CmdFrm.length = pos+3;
|
CmdFrm.length = pos+3;
|
||||||
|
|
||||||
if((pos+3)%4)
|
if((pos+3)%4)
|
||||||
CmdFrm.length += 4 - ((pos+3)%4);
|
CmdFrm.length += 4 - ((pos+3)%4);
|
||||||
|
|
||||||
if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
|
if((k=AVCWrite(firesat,&CmdFrm,&RspFrm)))
|
||||||
return k;
|
return k;
|
||||||
|
|
||||||
mdelay(250);
|
mdelay(50);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +684,7 @@ int AVCTuner_GetTS(struct firesat *firesat){
|
||||||
AVCRspFrm RspFrm;
|
AVCRspFrm RspFrm;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
printk(KERN_INFO "%s\n", __func__);
|
//printk(KERN_INFO "%s\n", __func__);
|
||||||
|
|
||||||
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
|
||||||
|
@ -612,20 +700,21 @@ int AVCTuner_GetTS(struct firesat *firesat){
|
||||||
CmdFrm.operand[3] = 0x20; // system id = DVB
|
CmdFrm.operand[3] = 0x20; // system id = DVB
|
||||||
CmdFrm.operand[4] = 0x00; // antenna number
|
CmdFrm.operand[4] = 0x00; // antenna number
|
||||||
CmdFrm.operand[5] = 0x0; // system_specific_search_flags
|
CmdFrm.operand[5] = 0x0; // system_specific_search_flags
|
||||||
CmdFrm.operand[6] = 0x11; // system_specific_multiplex selection_length
|
CmdFrm.operand[6] = (firesat->type == FireSAT_DVB_T)?0x0c:0x11; // system_specific_multiplex selection_length
|
||||||
CmdFrm.operand[7] = 0x00; // valid_flags [0]
|
CmdFrm.operand[7] = 0x00; // valid_flags [0]
|
||||||
CmdFrm.operand[8] = 0x00; // valid_flags [1]
|
CmdFrm.operand[8] = 0x00; // valid_flags [1]
|
||||||
CmdFrm.operand[24] = 0x00; // nr_of_dsit_sel_specs (always 0)
|
CmdFrm.operand[7 + (firesat->type == FireSAT_DVB_T)?0x0c:0x11] = 0x00; // nr_of_dsit_sel_specs (always 0)
|
||||||
|
|
||||||
CmdFrm.length = 28;
|
CmdFrm.length = (firesat->type == FireSAT_DVB_T)?24:28;
|
||||||
|
|
||||||
if((k=AVCWrite(firesat, &CmdFrm, &RspFrm))) return k;
|
if ((k=AVCWrite(firesat, &CmdFrm, &RspFrm)))
|
||||||
|
return k;
|
||||||
|
|
||||||
mdelay(250);
|
mdelay(250);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci) {
|
int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport) {
|
||||||
AVCCmdFrm CmdFrm;
|
AVCCmdFrm CmdFrm;
|
||||||
AVCRspFrm RspFrm;
|
AVCRspFrm RspFrm;
|
||||||
|
|
||||||
|
@ -660,8 +749,6 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr
|
||||||
}
|
}
|
||||||
if(systemId)
|
if(systemId)
|
||||||
*systemId = RspFrm.operand[7];
|
*systemId = RspFrm.operand[7];
|
||||||
if(has_ci)
|
|
||||||
*has_ci = (RspFrm.operand[14] >> 4) & 0x1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -679,14 +766,13 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in
|
||||||
CmdFrm.opcode=READ_DESCRIPTOR;
|
CmdFrm.opcode=READ_DESCRIPTOR;
|
||||||
|
|
||||||
CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
|
CmdFrm.operand[0]=DESCRIPTOR_TUNER_STATUS;
|
||||||
CmdFrm.operand[1]=0xff;
|
CmdFrm.operand[1]=0xff; //read_result_status
|
||||||
CmdFrm.operand[2]=0x00;
|
CmdFrm.operand[2]=0x00; // reserver
|
||||||
CmdFrm.operand[3]=sizeof(ANTENNA_INPUT_INFO) >> 8;
|
CmdFrm.operand[3]=0;//sizeof(ANTENNA_INPUT_INFO) >> 8;
|
||||||
CmdFrm.operand[4]=sizeof(ANTENNA_INPUT_INFO) & 0xFF;
|
CmdFrm.operand[4]=0;//sizeof(ANTENNA_INPUT_INFO) & 0xFF;
|
||||||
CmdFrm.operand[5]=0x00;
|
CmdFrm.operand[5]=0x00;
|
||||||
CmdFrm.operand[6]=0x03;
|
CmdFrm.operand[6]=0x00;
|
||||||
CmdFrm.length=12;
|
CmdFrm.length=12;
|
||||||
//Absenden des AVC request und warten auf response
|
|
||||||
if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
if (AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
|
@ -695,10 +781,11 @@ int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_in
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
length = (RspFrm.operand[3] << 8) + RspFrm.operand[4];
|
length = RspFrm.operand[9];
|
||||||
if(length == sizeof(ANTENNA_INPUT_INFO))
|
if(RspFrm.operand[1] == 0x10 && length == sizeof(ANTENNA_INPUT_INFO))
|
||||||
{
|
{
|
||||||
memcpy(antenna_input_info,&RspFrm.operand[7],length);
|
memcpy(antenna_input_info, &RspFrm.operand[10],
|
||||||
|
sizeof(ANTENNA_INPUT_INFO));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printk("%s: invalid info returned from AVC\n",__func__);
|
printk("%s: invalid info returned from AVC\n",__func__);
|
||||||
|
@ -837,3 +924,384 @@ int AVCRegisterRemoteControl(struct firesat*firesat)
|
||||||
{
|
{
|
||||||
return __AVCRegisterRemoteControl(firesat, 0);
|
return __AVCRegisterRemoteControl(firesat, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AVCTuner_Host2Ca(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = CONTROL;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
|
||||||
|
CmdFrm.operand[6] = 0; // more/last
|
||||||
|
CmdFrm.operand[7] = 0; // length
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_ca_object_pos(AVCRspFrm *RspFrm)
|
||||||
|
{
|
||||||
|
int length = 1;
|
||||||
|
|
||||||
|
// Check length of length field
|
||||||
|
if (RspFrm->operand[7] & 0x80)
|
||||||
|
length = (RspFrm->operand[7] & 0x7F) + 1;
|
||||||
|
return length + 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_ca_object_length(AVCRspFrm *RspFrm)
|
||||||
|
{
|
||||||
|
int size = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (RspFrm->operand[7] & 0x80) {
|
||||||
|
for (i = 0; i < (RspFrm->operand[7] & 0x7F); i++) {
|
||||||
|
size <<= 8;
|
||||||
|
size += RspFrm->operand[8 + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RspFrm->operand[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = STATUS;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
|
||||||
|
pos = get_ca_object_pos(&RspFrm);
|
||||||
|
app_info[0] = (TAG_APP_INFO >> 16) & 0xFF;
|
||||||
|
app_info[1] = (TAG_APP_INFO >> 8) & 0xFF;
|
||||||
|
app_info[2] = (TAG_APP_INFO >> 0) & 0xFF;
|
||||||
|
app_info[3] = 6 + RspFrm.operand[pos + 4];
|
||||||
|
app_info[4] = 0x01;
|
||||||
|
memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]);
|
||||||
|
*length = app_info[3] + 4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_info(struct firesat *firesat, char *app_info, int *length)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = STATUS;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_APPLICATION_INFO; // ca tag
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
pos = get_ca_object_pos(&RspFrm);
|
||||||
|
app_info[0] = (TAG_CA_INFO >> 16) & 0xFF;
|
||||||
|
app_info[1] = (TAG_CA_INFO >> 8) & 0xFF;
|
||||||
|
app_info[2] = (TAG_CA_INFO >> 0) & 0xFF;
|
||||||
|
app_info[3] = 2;
|
||||||
|
app_info[4] = app_info[5];
|
||||||
|
app_info[5] = app_info[6];
|
||||||
|
*length = app_info[3] + 4;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_reset(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = CONTROL;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_RESET; // ca tag
|
||||||
|
CmdFrm.operand[6] = 0; // more/last
|
||||||
|
CmdFrm.operand[7] = 1; // length
|
||||||
|
CmdFrm.operand[8] = 0; // force hardware reset
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_pmt(struct firesat *firesat, char *msg, int length)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
int list_management;
|
||||||
|
int program_info_length;
|
||||||
|
int pmt_cmd_id;
|
||||||
|
int read_pos;
|
||||||
|
int write_pos;
|
||||||
|
int es_info_length;
|
||||||
|
int crc32_csum;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = CONTROL;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
if (msg[0] != LIST_MANAGEMENT_ONLY) {
|
||||||
|
printk(KERN_ERR "The only list_manasgement parameter that is "
|
||||||
|
"supported by the firesat driver is \"only\" (3).");
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
// We take the cmd_id from the programme level only!
|
||||||
|
list_management = msg[0];
|
||||||
|
program_info_length = ((msg[4] & 0x0F) << 8) + msg[5];
|
||||||
|
if (program_info_length > 0)
|
||||||
|
program_info_length--; // Remove pmt_cmd_id
|
||||||
|
pmt_cmd_id = msg[6];
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_PMT; // ca tag
|
||||||
|
CmdFrm.operand[6] = 0; // more/last
|
||||||
|
//CmdFrm.operand[7] = XXXprogram_info_length + 17; // length
|
||||||
|
CmdFrm.operand[8] = list_management;
|
||||||
|
CmdFrm.operand[9] = 0x01; // pmt_cmd=OK_descramble
|
||||||
|
|
||||||
|
// TS program map table
|
||||||
|
|
||||||
|
// Table id=2
|
||||||
|
CmdFrm.operand[10] = 0x02;
|
||||||
|
// Section syntax + length
|
||||||
|
CmdFrm.operand[11] = 0x80;
|
||||||
|
//CmdFrm.operand[12] = XXXprogram_info_length + 12;
|
||||||
|
// Program number
|
||||||
|
CmdFrm.operand[13] = msg[1];
|
||||||
|
CmdFrm.operand[14] = msg[2];
|
||||||
|
// Version number=0 + current/next=1
|
||||||
|
CmdFrm.operand[15] = 0x01;
|
||||||
|
// Section number=0
|
||||||
|
CmdFrm.operand[16] = 0x00;
|
||||||
|
// Last section number=0
|
||||||
|
CmdFrm.operand[17] = 0x00;
|
||||||
|
// PCR_PID=1FFF
|
||||||
|
CmdFrm.operand[18] = 0x1F;
|
||||||
|
CmdFrm.operand[19] = 0xFF;
|
||||||
|
// Program info length
|
||||||
|
CmdFrm.operand[20] = (program_info_length >> 8);
|
||||||
|
CmdFrm.operand[21] = (program_info_length & 0xFF);
|
||||||
|
// CA descriptors at programme level
|
||||||
|
read_pos = 6;
|
||||||
|
write_pos = 22;
|
||||||
|
if (program_info_length > 0) {
|
||||||
|
/* printk(KERN_INFO "Copying descriptors at programme level.\n"); */
|
||||||
|
pmt_cmd_id = msg[read_pos++];
|
||||||
|
if (pmt_cmd_id != 1 && pmt_cmd_id !=4) {
|
||||||
|
printk(KERN_ERR "Invalid pmt_cmd_id=%d.\n",
|
||||||
|
pmt_cmd_id);
|
||||||
|
}
|
||||||
|
memcpy(&CmdFrm.operand[write_pos], &msg[read_pos],
|
||||||
|
program_info_length);
|
||||||
|
read_pos += program_info_length;
|
||||||
|
write_pos += program_info_length;
|
||||||
|
}
|
||||||
|
while (read_pos < length) {
|
||||||
|
/* printk(KERN_INFO "Copying descriptors at stream level for " */
|
||||||
|
/* "stream type %d.\n", msg[read_pos]); */
|
||||||
|
CmdFrm.operand[write_pos++] = msg[read_pos++];
|
||||||
|
CmdFrm.operand[write_pos++] = msg[read_pos++];
|
||||||
|
CmdFrm.operand[write_pos++] = msg[read_pos++];
|
||||||
|
es_info_length =
|
||||||
|
((msg[read_pos] & 0x0F) << 8) + msg[read_pos + 1];
|
||||||
|
read_pos += 2;
|
||||||
|
if (es_info_length > 0)
|
||||||
|
es_info_length--; // Remove pmt_cmd_id
|
||||||
|
CmdFrm.operand[write_pos++] = es_info_length >> 8;
|
||||||
|
CmdFrm.operand[write_pos++] = es_info_length & 0xFF;
|
||||||
|
if (es_info_length > 0) {
|
||||||
|
pmt_cmd_id = msg[read_pos++];
|
||||||
|
if (pmt_cmd_id != 1 && pmt_cmd_id !=4) {
|
||||||
|
printk(KERN_ERR "Invalid pmt_cmd_id=%d at "
|
||||||
|
"stream level.\n", pmt_cmd_id);
|
||||||
|
}
|
||||||
|
memcpy(&CmdFrm.operand[write_pos], &msg[read_pos],
|
||||||
|
es_info_length);
|
||||||
|
read_pos += es_info_length;
|
||||||
|
write_pos += es_info_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CRC
|
||||||
|
CmdFrm.operand[write_pos++] = 0x00;
|
||||||
|
CmdFrm.operand[write_pos++] = 0x00;
|
||||||
|
CmdFrm.operand[write_pos++] = 0x00;
|
||||||
|
CmdFrm.operand[write_pos++] = 0x00;
|
||||||
|
|
||||||
|
CmdFrm.operand[7] = write_pos - 8;
|
||||||
|
CmdFrm.operand[12] = write_pos - 13;
|
||||||
|
|
||||||
|
crc32_csum = crc32_be(0, &CmdFrm.operand[10],
|
||||||
|
CmdFrm.operand[12] - 1);
|
||||||
|
CmdFrm.operand[write_pos - 4] = (crc32_csum >> 24) & 0xFF;
|
||||||
|
CmdFrm.operand[write_pos - 3] = (crc32_csum >> 16) & 0xFF;
|
||||||
|
CmdFrm.operand[write_pos - 2] = (crc32_csum >> 8) & 0xFF;
|
||||||
|
CmdFrm.operand[write_pos - 1] = (crc32_csum >> 0) & 0xFF;
|
||||||
|
|
||||||
|
CmdFrm.length = write_pos + 3;
|
||||||
|
if ((write_pos + 3) % 4)
|
||||||
|
CmdFrm.length += 4 - ((write_pos + 3) % 4);
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
if (RspFrm.resp != ACCEPTED) {
|
||||||
|
printk(KERN_ERR "Answer to CA PMT was %d\n", RspFrm.resp);
|
||||||
|
return -EFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_get_time_date(struct firesat *firesat, int *interval)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = STATUS;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_DATE_TIME; // ca tag
|
||||||
|
CmdFrm.operand[6] = 0; // more/last
|
||||||
|
CmdFrm.operand[7] = 0; // length
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
*interval = RspFrm.operand[get_ca_object_pos(&RspFrm)];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_enter_menu(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = STATUS;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_HOST2CA;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_ENTER_MENU;
|
||||||
|
CmdFrm.operand[6] = 0; // more/last
|
||||||
|
CmdFrm.operand[7] = 0; // length
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length)
|
||||||
|
{
|
||||||
|
AVCCmdFrm CmdFrm;
|
||||||
|
AVCRspFrm RspFrm;
|
||||||
|
|
||||||
|
memset(&CmdFrm, 0, sizeof(AVCCmdFrm));
|
||||||
|
CmdFrm.cts = AVC;
|
||||||
|
CmdFrm.ctype = STATUS;
|
||||||
|
CmdFrm.sutyp = 0x5;
|
||||||
|
CmdFrm.suid = firesat->subunit;
|
||||||
|
CmdFrm.opcode = VENDOR;
|
||||||
|
|
||||||
|
CmdFrm.operand[0]=SFE_VENDOR_DE_COMPANYID_0;
|
||||||
|
CmdFrm.operand[1]=SFE_VENDOR_DE_COMPANYID_1;
|
||||||
|
CmdFrm.operand[2]=SFE_VENDOR_DE_COMPANYID_2;
|
||||||
|
CmdFrm.operand[3]=SFE_VENDOR_OPCODE_CA2HOST;
|
||||||
|
CmdFrm.operand[4] = 0; // slot
|
||||||
|
CmdFrm.operand[5] = SFE_VENDOR_TAG_CA_MMI;
|
||||||
|
CmdFrm.operand[6] = 0; // more/last
|
||||||
|
CmdFrm.operand[7] = 0; // length
|
||||||
|
CmdFrm.length = 12;
|
||||||
|
|
||||||
|
if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
*length = get_ca_object_length(&RspFrm);
|
||||||
|
memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
begin : Wed May 1 2000
|
begin : Wed May 1 2000
|
||||||
copyright : (C) 2000 by Manfred Weihs
|
copyright : (C) 2000 by Manfred Weihs
|
||||||
copyright : (C) 2003 by Philipp Gutgsell
|
copyright : (C) 2003 by Philipp Gutgsell
|
||||||
|
copyright : (C) 2008 by Henrik Kurelid (henrik@kurelid.se)
|
||||||
email : 0014guph@edu.fh-kaernten.ac.at
|
email : 0014guph@edu.fh-kaernten.ac.at
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
@ -27,12 +28,10 @@
|
||||||
|
|
||||||
#include <linux/dvb/frontend.h>
|
#include <linux/dvb/frontend.h>
|
||||||
|
|
||||||
#define BYTE unsigned char
|
/*************************************************************
|
||||||
#define WORD unsigned short
|
Constants from EN510221
|
||||||
#define DWORD unsigned long
|
**************************************************************/
|
||||||
#define ULONG unsigned long
|
#define LIST_MANAGEMENT_ONLY 0x03
|
||||||
#define LONG long
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
FCP Address range
|
FCP Address range
|
||||||
|
@ -68,12 +67,12 @@ typedef struct {
|
||||||
typedef struct _AVCCmdFrm
|
typedef struct _AVCCmdFrm
|
||||||
{
|
{
|
||||||
// AV/C command frame
|
// AV/C command frame
|
||||||
BYTE ctype : 4 ; // command type
|
__u8 ctype : 4 ; // command type
|
||||||
BYTE cts : 4 ; // always 0x0 for AVC
|
__u8 cts : 4 ; // always 0x0 for AVC
|
||||||
BYTE suid : 3 ; // subunit ID
|
__u8 suid : 3 ; // subunit ID
|
||||||
BYTE sutyp : 5 ; // subunit_typ
|
__u8 sutyp : 5 ; // subunit_typ
|
||||||
BYTE opcode : 8 ; // opcode
|
__u8 opcode : 8 ; // opcode
|
||||||
BYTE operand[509] ; // array of operands [1-507]
|
__u8 operand[509] ; // array of operands [1-507]
|
||||||
int length; //length of the command frame
|
int length; //length of the command frame
|
||||||
} AVCCmdFrm ;
|
} AVCCmdFrm ;
|
||||||
|
|
||||||
|
@ -81,12 +80,12 @@ typedef struct _AVCCmdFrm
|
||||||
typedef struct _AVCRspFrm
|
typedef struct _AVCRspFrm
|
||||||
{
|
{
|
||||||
// AV/C response frame
|
// AV/C response frame
|
||||||
BYTE resp : 4 ; // response type
|
__u8 resp : 4 ; // response type
|
||||||
BYTE cts : 4 ; // always 0x0 for AVC
|
__u8 cts : 4 ; // always 0x0 for AVC
|
||||||
BYTE suid : 3 ; // subunit ID
|
__u8 suid : 3 ; // subunit ID
|
||||||
BYTE sutyp : 5 ; // subunit_typ
|
__u8 sutyp : 5 ; // subunit_typ
|
||||||
BYTE opcode : 8 ; // opcode
|
__u8 opcode : 8 ; // opcode
|
||||||
BYTE operand[509] ; // array of operands [1-507]
|
__u8 operand[509] ; // array of operands [1-507]
|
||||||
int length; //length of the response frame
|
int length; //length of the response frame
|
||||||
} AVCRspFrm ;
|
} AVCRspFrm ;
|
||||||
|
|
||||||
|
@ -94,23 +93,23 @@ typedef struct _AVCRspFrm
|
||||||
|
|
||||||
typedef struct _AVCCmdFrm
|
typedef struct _AVCCmdFrm
|
||||||
{
|
{
|
||||||
BYTE cts:4;
|
__u8 cts:4;
|
||||||
BYTE ctype:4;
|
__u8 ctype:4;
|
||||||
BYTE sutyp:5;
|
__u8 sutyp:5;
|
||||||
BYTE suid:3;
|
__u8 suid:3;
|
||||||
BYTE opcode;
|
__u8 opcode;
|
||||||
BYTE operand[509];
|
__u8 operand[509];
|
||||||
int length;
|
int length;
|
||||||
} AVCCmdFrm;
|
} AVCCmdFrm;
|
||||||
|
|
||||||
typedef struct _AVCRspFrm
|
typedef struct _AVCRspFrm
|
||||||
{
|
{
|
||||||
BYTE cts:4;
|
__u8 cts:4;
|
||||||
BYTE resp:4;
|
__u8 resp:4;
|
||||||
BYTE sutyp:5;
|
__u8 sutyp:5;
|
||||||
BYTE suid:3;
|
__u8 suid:3;
|
||||||
BYTE opcode;
|
__u8 opcode;
|
||||||
BYTE operand[509];
|
__u8 operand[509];
|
||||||
int length;
|
int length;
|
||||||
} AVCRspFrm;
|
} AVCRspFrm;
|
||||||
|
|
||||||
|
@ -197,6 +196,14 @@ typedef struct _AVCRspFrm
|
||||||
#define SFE_VENDOR_OPCODE_CISTATUS 0x59
|
#define SFE_VENDOR_OPCODE_CISTATUS 0x59
|
||||||
#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices
|
#define SFE_VENDOR_OPCODE_TUNE_QPSK2 0x60 // QPSK command for DVB-S2 devices
|
||||||
|
|
||||||
|
// CA Tags
|
||||||
|
#define SFE_VENDOR_TAG_CA_RESET 0x00
|
||||||
|
#define SFE_VENDOR_TAG_CA_APPLICATION_INFO 0x01
|
||||||
|
#define SFE_VENDOR_TAG_CA_PMT 0x02
|
||||||
|
#define SFE_VENDOR_TAG_CA_DATE_TIME 0x04
|
||||||
|
#define SFE_VENDOR_TAG_CA_MMI 0x05
|
||||||
|
#define SFE_VENDOR_TAG_CA_ENTER_MENU 0x07
|
||||||
|
|
||||||
|
|
||||||
//AVCTuner DVB identifier service_ID
|
//AVCTuner DVB identifier service_ID
|
||||||
#define DVB 0x20
|
#define DVB 0x20
|
||||||
|
@ -209,8 +216,8 @@ typedef struct _AVCRspFrm
|
||||||
#define Tuner_Status_Descriptor 0x80
|
#define Tuner_Status_Descriptor 0x80
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BYTE Subunit_Type;
|
__u8 Subunit_Type;
|
||||||
BYTE Max_Subunit_ID;
|
__u8 Max_Subunit_ID;
|
||||||
} SUBUNIT_INFO;
|
} SUBUNIT_INFO;
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
@ -220,12 +227,12 @@ typedef struct {
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BYTE Byte0;
|
__u8 Byte0;
|
||||||
BYTE Byte1;
|
__u8 Byte1;
|
||||||
BYTE Byte2;
|
__u8 Byte2;
|
||||||
BYTE Byte3;
|
__u8 Byte3;
|
||||||
BYTE Byte4;
|
__u8 Byte4;
|
||||||
BYTE Byte5;
|
__u8 Byte5;
|
||||||
}OBJECT_ID;
|
}OBJECT_ID;
|
||||||
|
|
||||||
/*************************************************************
|
/*************************************************************
|
||||||
|
@ -234,14 +241,14 @@ typedef struct {
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
#ifdef __LITTLE_ENDIAN
|
#ifdef __LITTLE_ENDIAN
|
||||||
BYTE RF_frequency_hByte:6;
|
__u8 RF_frequency_hByte:6;
|
||||||
BYTE raster_Frequency:2;//Bit7,6 raster frequency
|
__u8 raster_Frequency:2;//Bit7,6 raster frequency
|
||||||
#else
|
#else
|
||||||
BYTE raster_Frequency:2;
|
__u8 raster_Frequency:2;
|
||||||
BYTE RF_frequency_hByte:6;
|
__u8 RF_frequency_hByte:6;
|
||||||
#endif
|
#endif
|
||||||
BYTE RF_frequency_mByte;
|
__u8 RF_frequency_mByte;
|
||||||
BYTE RF_frequency_lByte;
|
__u8 RF_frequency_lByte;
|
||||||
|
|
||||||
}FREQUENCY;
|
}FREQUENCY;
|
||||||
|
|
||||||
|
@ -249,63 +256,63 @@ typedef struct
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
BYTE Modulation :1;
|
__u8 Modulation :1;
|
||||||
BYTE FEC_inner :1;
|
__u8 FEC_inner :1;
|
||||||
BYTE FEC_outer :1;
|
__u8 FEC_outer :1;
|
||||||
BYTE Symbol_Rate :1;
|
__u8 Symbol_Rate :1;
|
||||||
BYTE Frequency :1;
|
__u8 Frequency :1;
|
||||||
BYTE Orbital_Pos :1;
|
__u8 Orbital_Pos :1;
|
||||||
BYTE Polarisation :1;
|
__u8 Polarisation :1;
|
||||||
BYTE reserved_fields :1;
|
__u8 reserved_fields :1;
|
||||||
BYTE reserved1 :7;
|
__u8 reserved1 :7;
|
||||||
BYTE Network_ID :1;
|
__u8 Network_ID :1;
|
||||||
|
|
||||||
}MULTIPLEX_VALID_FLAGS;
|
}MULTIPLEX_VALID_FLAGS;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
BYTE GuardInterval:1;
|
__u8 GuardInterval:1;
|
||||||
BYTE CodeRateLPStream:1;
|
__u8 CodeRateLPStream:1;
|
||||||
BYTE CodeRateHPStream:1;
|
__u8 CodeRateHPStream:1;
|
||||||
BYTE HierarchyInfo:1;
|
__u8 HierarchyInfo:1;
|
||||||
BYTE Constellation:1;
|
__u8 Constellation:1;
|
||||||
BYTE Bandwidth:1;
|
__u8 Bandwidth:1;
|
||||||
BYTE CenterFrequency:1;
|
__u8 CenterFrequency:1;
|
||||||
BYTE reserved1:1;
|
__u8 reserved1:1;
|
||||||
BYTE reserved2:5;
|
__u8 reserved2:5;
|
||||||
BYTE OtherFrequencyFlag:1;
|
__u8 OtherFrequencyFlag:1;
|
||||||
BYTE TransmissionMode:1;
|
__u8 TransmissionMode:1;
|
||||||
BYTE NetworkId:1;
|
__u8 NetworkId:1;
|
||||||
}MULTIPLEX_VALID_FLAGS_DVBT;
|
}MULTIPLEX_VALID_FLAGS_DVBT;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BYTE reserved_fields:1;
|
__u8 reserved_fields:1;
|
||||||
BYTE Polarisation:1;
|
__u8 Polarisation:1;
|
||||||
BYTE Orbital_Pos:1;
|
__u8 Orbital_Pos:1;
|
||||||
BYTE Frequency:1;
|
__u8 Frequency:1;
|
||||||
BYTE Symbol_Rate:1;
|
__u8 Symbol_Rate:1;
|
||||||
BYTE FEC_outer:1;
|
__u8 FEC_outer:1;
|
||||||
BYTE FEC_inner:1;
|
__u8 FEC_inner:1;
|
||||||
BYTE Modulation:1;
|
__u8 Modulation:1;
|
||||||
BYTE Network_ID:1;
|
__u8 Network_ID:1;
|
||||||
BYTE reserved1:7;
|
__u8 reserved1:7;
|
||||||
}MULTIPLEX_VALID_FLAGS;
|
}MULTIPLEX_VALID_FLAGS;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
BYTE reserved1:1;
|
__u8 reserved1:1;
|
||||||
BYTE CenterFrequency:1;
|
__u8 CenterFrequency:1;
|
||||||
BYTE Bandwidth:1;
|
__u8 Bandwidth:1;
|
||||||
BYTE Constellation:1;
|
__u8 Constellation:1;
|
||||||
BYTE HierarchyInfo:1;
|
__u8 HierarchyInfo:1;
|
||||||
BYTE CodeRateHPStream:1;
|
__u8 CodeRateHPStream:1;
|
||||||
BYTE CodeRateLPStream:1;
|
__u8 CodeRateLPStream:1;
|
||||||
BYTE GuardInterval:1;
|
__u8 GuardInterval:1;
|
||||||
BYTE NetworkId:1;
|
__u8 NetworkId:1;
|
||||||
BYTE TransmissionMode:1;
|
__u8 TransmissionMode:1;
|
||||||
BYTE OtherFrequencyFlag:1;
|
__u8 OtherFrequencyFlag:1;
|
||||||
BYTE reserved2:5;
|
__u8 reserved2:5;
|
||||||
}MULTIPLEX_VALID_FLAGS_DVBT;
|
}MULTIPLEX_VALID_FLAGS_DVBT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -314,47 +321,98 @@ typedef union {
|
||||||
MULTIPLEX_VALID_FLAGS Bits;
|
MULTIPLEX_VALID_FLAGS Bits;
|
||||||
MULTIPLEX_VALID_FLAGS_DVBT Bits_T;
|
MULTIPLEX_VALID_FLAGS_DVBT Bits_T;
|
||||||
struct {
|
struct {
|
||||||
BYTE ByteHi;
|
__u8 ByteHi;
|
||||||
BYTE ByteLo;
|
__u8 ByteLo;
|
||||||
} Valid_Word;
|
} Valid_Word;
|
||||||
} M_VALID_FLAGS;
|
} M_VALID_FLAGS;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
#ifdef __LITTLE_ENDIAN
|
#ifdef __LITTLE_ENDIAN
|
||||||
BYTE ActiveSystem;
|
__u8 ActiveSystem;
|
||||||
BYTE reserved:5;
|
__u8 reserved:5;
|
||||||
BYTE NoRF:1;
|
__u8 NoRF:1;
|
||||||
BYTE Moving:1;
|
__u8 Moving:1;
|
||||||
BYTE Searching:1;
|
__u8 Searching:1;
|
||||||
|
|
||||||
BYTE SelectedAntenna:7;
|
__u8 SelectedAntenna:7;
|
||||||
BYTE Input:1;
|
__u8 Input:1;
|
||||||
|
|
||||||
BYTE BER[4];
|
__u8 BER[4];
|
||||||
|
|
||||||
BYTE SignalStrength;
|
__u8 SignalStrength;
|
||||||
FREQUENCY Frequency;
|
FREQUENCY Frequency;
|
||||||
|
|
||||||
BYTE ManDepInfoLength;
|
__u8 ManDepInfoLength;
|
||||||
|
|
||||||
|
__u8 PowerSupply:1;
|
||||||
|
__u8 FrontEndPowerStatus:1;
|
||||||
|
__u8 reserved3:1;
|
||||||
|
__u8 AntennaError:1;
|
||||||
|
__u8 FrontEndError:1;
|
||||||
|
__u8 reserved2:3;
|
||||||
|
|
||||||
|
__u8 CarrierNoiseRatio[2];
|
||||||
|
__u8 reserved4[2];
|
||||||
|
__u8 PowerSupplyVoltage;
|
||||||
|
__u8 AntennaVoltage;
|
||||||
|
__u8 FirewireBusVoltage;
|
||||||
|
|
||||||
|
__u8 CaMmi:1;
|
||||||
|
__u8 reserved5:7;
|
||||||
|
|
||||||
|
__u8 reserved6:1;
|
||||||
|
__u8 CaInitializationStatus:1;
|
||||||
|
__u8 CaErrorFlag:1;
|
||||||
|
__u8 CaDvbFlag:1;
|
||||||
|
__u8 CaModulePresentStatus:1;
|
||||||
|
__u8 CaApplicationInfo:1;
|
||||||
|
__u8 CaDateTimeRequest:1;
|
||||||
|
__u8 CaPmtReply:1;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
BYTE ActiveSystem;
|
__u8 ActiveSystem;
|
||||||
BYTE Searching:1;
|
__u8 Searching:1;
|
||||||
BYTE Moving:1;
|
__u8 Moving:1;
|
||||||
BYTE NoRF:1;
|
__u8 NoRF:1;
|
||||||
BYTE reserved:5;
|
__u8 reserved:5;
|
||||||
|
|
||||||
BYTE Input:1;
|
__u8 Input:1;
|
||||||
BYTE SelectedAntenna:7;
|
__u8 SelectedAntenna:7;
|
||||||
|
|
||||||
BYTE BER[4];
|
__u8 BER[4];
|
||||||
|
|
||||||
BYTE SignalStrength;
|
__u8 SignalStrength;
|
||||||
FREQUENCY Frequency;
|
FREQUENCY Frequency;
|
||||||
|
|
||||||
BYTE ManDepInfoLength;
|
__u8 ManDepInfoLength;
|
||||||
|
|
||||||
|
__u8 reserved2:3;
|
||||||
|
__u8 FrontEndError:1;
|
||||||
|
__u8 AntennaError:1;
|
||||||
|
__u8 reserved3:1;
|
||||||
|
__u8 FrontEndPowerStatus:1;
|
||||||
|
__u8 PowerSupply:1;
|
||||||
|
|
||||||
|
__u8 CarrierNoiseRatio[2];
|
||||||
|
__u8 reserved4[2];
|
||||||
|
__u8 PowerSupplyVoltage;
|
||||||
|
__u8 AntennaVoltage;
|
||||||
|
__u8 FirewireBusVoltage;
|
||||||
|
|
||||||
|
__u8 reserved5:7;
|
||||||
|
__u8 CaMmi:1;
|
||||||
|
__u8 CaPmtReply:1;
|
||||||
|
__u8 CaDateTimeRequest:1;
|
||||||
|
__u8 CaApplicationInfo:1;
|
||||||
|
__u8 CaModulePresentStatus:1;
|
||||||
|
__u8 CaDvbFlag:1;
|
||||||
|
__u8 CaErrorFlag:1;
|
||||||
|
__u8 CaInitializationStatus:1;
|
||||||
|
__u8 reserved6:1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
} ANTENNA_INPUT_INFO; // 11 Byte
|
} ANTENNA_INPUT_INFO; // 22 Byte
|
||||||
|
|
||||||
#define LNBCONTROL_DONTCARE 0xff
|
#define LNBCONTROL_DONTCARE 0xff
|
||||||
|
|
||||||
|
@ -365,17 +423,27 @@ extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
|
||||||
extern int AVCTuner_DSIT(struct firesat *firesat,
|
extern int AVCTuner_DSIT(struct firesat *firesat,
|
||||||
int Source_Plug,
|
int Source_Plug,
|
||||||
struct dvb_frontend_parameters *params,
|
struct dvb_frontend_parameters *params,
|
||||||
BYTE *status);
|
__u8 *status);
|
||||||
|
|
||||||
extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info);
|
extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info);
|
||||||
extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, BYTE *status);
|
extern int AVCTuner_DSD(struct firesat *firesat, struct dvb_frontend_parameters *params, __u8 *status);
|
||||||
extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
|
extern int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]);
|
||||||
extern int AVCTuner_GetTS(struct firesat *firesat);
|
extern int AVCTuner_GetTS(struct firesat *firesat);
|
||||||
|
|
||||||
extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport, int *has_ci);
|
extern int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport);
|
||||||
extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd);
|
extern int AVCLNBControl(struct firesat *firesat, char voltage, char burst, char conttone, char nrdiseq, struct dvb_diseqc_master_cmd *diseqcmd);
|
||||||
extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
|
extern int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
|
||||||
extern int AVCRegisterRemoteControl(struct firesat *firesat);
|
extern int AVCRegisterRemoteControl(struct firesat *firesat);
|
||||||
|
extern int AVCTuner_Host2Ca(struct firesat *firesat);
|
||||||
|
extern int avc_ca_app_info(struct firesat *firesat, char *app_info,
|
||||||
|
int *length);
|
||||||
|
extern int avc_ca_info(struct firesat *firesat, char *app_info, int *length);
|
||||||
|
extern int avc_ca_reset(struct firesat *firesat);
|
||||||
|
extern int avc_ca_pmt(struct firesat *firesat, char *app_info, int length);
|
||||||
|
extern int avc_ca_get_time_date(struct firesat *firesat, int *interval);
|
||||||
|
extern int avc_ca_enter_menu(struct firesat *firesat);
|
||||||
|
extern int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object,
|
||||||
|
int *length);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
/*
|
||||||
|
* FireSAT DVB driver
|
||||||
|
*
|
||||||
|
* Copyright (c) ?
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "cmp.h"
|
#include "cmp.h"
|
||||||
#include <ieee1394.h>
|
#include <ieee1394.h>
|
||||||
#include <nodemgr.h>
|
#include <nodemgr.h>
|
||||||
|
@ -10,18 +22,18 @@
|
||||||
|
|
||||||
typedef struct _OPCR
|
typedef struct _OPCR
|
||||||
{
|
{
|
||||||
BYTE PTPConnCount : 6 ; // Point to point connect. counter
|
__u8 PTPConnCount : 6 ; // Point to point connect. counter
|
||||||
BYTE BrConnCount : 1 ; // Broadcast connection counter
|
__u8 BrConnCount : 1 ; // Broadcast connection counter
|
||||||
BYTE OnLine : 1 ; // On Line
|
__u8 OnLine : 1 ; // On Line
|
||||||
|
|
||||||
BYTE ChNr : 6 ; // Channel number
|
__u8 ChNr : 6 ; // Channel number
|
||||||
BYTE Res : 2 ; // Reserved
|
__u8 Res : 2 ; // Reserved
|
||||||
|
|
||||||
BYTE PayloadHi : 2 ; // Payoad high bits
|
__u8 PayloadHi : 2 ; // Payoad high bits
|
||||||
BYTE OvhdID : 4 ; // Overhead ID
|
__u8 OvhdID : 4 ; // Overhead ID
|
||||||
BYTE DataRate : 2 ; // Data Rate
|
__u8 DataRate : 2 ; // Data Rate
|
||||||
|
|
||||||
BYTE PayloadLo ; // Payoad low byte
|
__u8 PayloadLo ; // Payoad low byte
|
||||||
} OPCR ;
|
} OPCR ;
|
||||||
|
|
||||||
#define FIRESAT_SPEED IEEE1394_SPEED_400
|
#define FIRESAT_SPEED IEEE1394_SPEED_400
|
||||||
|
@ -94,13 +106,13 @@ int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int i
|
||||||
u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
|
u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
|
||||||
int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
|
int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
|
||||||
|
|
||||||
printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid);
|
/* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printk("%s: cannot read oPCR\n", __func__);
|
printk("%s: cannot read oPCR\n", __func__);
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR);
|
/* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */
|
||||||
do {
|
do {
|
||||||
OPCR *hilf= (OPCR*) &test_oPCR;
|
OPCR *hilf= (OPCR*) &test_oPCR;
|
||||||
|
|
||||||
|
@ -134,8 +146,8 @@ int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int i
|
||||||
|
|
||||||
hilf->PTPConnCount++;
|
hilf->PTPConnCount++;
|
||||||
new_oPCR=test_oPCR;
|
new_oPCR=test_oPCR;
|
||||||
printk(KERN_INFO "%s: trying compare_swap...\n",__func__);
|
/* printk(KERN_INFO "%s: trying compare_swap...\n",__func__); */
|
||||||
printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR);
|
/* printk(KERN_INFO "%s: oPCR_old: %08x, oPCR_new: %08x\n",__func__, old_oPCR, new_oPCR); */
|
||||||
result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
|
result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
|
@ -169,7 +181,7 @@ int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_ch
|
||||||
u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
|
u64 oPCR_address=0xfffff0000904ull+(output_plug << 2);
|
||||||
int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
|
int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4);
|
||||||
|
|
||||||
printk(KERN_INFO "%s\n",__func__);
|
/* printk(KERN_INFO "%s\n",__func__); */
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
printk("%s: cannot read oPCR\n", __func__);
|
printk("%s: cannot read oPCR\n", __func__);
|
||||||
|
|
|
@ -1,66 +1,303 @@
|
||||||
|
/*
|
||||||
|
* FireSAT DVB driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "firesat-ci.h"
|
#include "firesat-ci.h"
|
||||||
#include "firesat.h"
|
#include "firesat.h"
|
||||||
#include "avc_api.h"
|
#include "avc_api.h"
|
||||||
|
|
||||||
#include <linux/dvb/ca.h>
|
#include <linux/dvb/ca.h>
|
||||||
#include <dvbdev.h>
|
#include <dvbdev.h>
|
||||||
/*
|
|
||||||
static int firesat_ca_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *parg) {
|
|
||||||
//struct firesat *firesat = (struct firesat*)((struct dvb_device*)file->private_data)->priv;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
// printk(KERN_INFO "%s: ioctl %d\n",__func__,cmd);
|
static unsigned int ca_debug = 0;
|
||||||
|
module_param(ca_debug, int, 0644);
|
||||||
|
MODULE_PARM_DESC(ca_debug, "debug logging of ca system, default is 0 (no)");
|
||||||
|
|
||||||
switch(cmd) {
|
static int firesat_ca_ready(ANTENNA_INPUT_INFO *info)
|
||||||
case CA_RESET:
|
{
|
||||||
// TODO: Needs to be implemented with new AVC Vendor commands
|
if (ca_debug != 0)
|
||||||
break;
|
printk("%s: CaMmi=%d, CaInit=%d, CaError=%d, CaDvb=%d, "
|
||||||
case CA_GET_CAP: {
|
"CaModule=%d, CaAppInfo=%d, CaDateTime=%d, "
|
||||||
ca_caps_t *cap=(ca_caps_t*)parg;
|
"CaPmt=%d\n", __func__, info->CaMmi,
|
||||||
cap->slot_num = 1;
|
info->CaInitializationStatus, info->CaErrorFlag,
|
||||||
cap->slot_type = CA_CI_LINK;
|
info->CaDvbFlag, info->CaModulePresentStatus,
|
||||||
cap->descr_num = 1;
|
info->CaApplicationInfo,
|
||||||
cap->descr_type = CA_DSS;
|
info->CaDateTimeRequest, info->CaPmtReply);
|
||||||
|
return info->CaInitializationStatus == 1 &&
|
||||||
|
info->CaErrorFlag == 0 &&
|
||||||
|
info->CaDvbFlag == 1 &&
|
||||||
|
info->CaModulePresentStatus == 1;
|
||||||
|
}
|
||||||
|
|
||||||
err = 0;
|
static int firesat_get_ca_flags(ANTENNA_INPUT_INFO *info)
|
||||||
break;
|
{
|
||||||
|
int flags = 0;
|
||||||
|
if (info->CaModulePresentStatus == 1)
|
||||||
|
flags |= CA_CI_MODULE_PRESENT;
|
||||||
|
if (info->CaInitializationStatus == 1 &&
|
||||||
|
info->CaErrorFlag == 0 &&
|
||||||
|
info->CaDvbFlag == 1)
|
||||||
|
flags |= CA_CI_MODULE_READY;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_reset(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
if (ca_debug)
|
||||||
|
printk(KERN_INFO "%s: ioctl CA_RESET\n", __func__);
|
||||||
|
if (avc_ca_reset(firesat))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_get_caps(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
struct ca_caps *cap_p = (struct ca_caps*)arg;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
cap_p->slot_num = 1;
|
||||||
|
cap_p->slot_type = CA_CI;
|
||||||
|
cap_p->descr_num = 1;
|
||||||
|
cap_p->descr_type = CA_ECD;
|
||||||
|
if (ca_debug)
|
||||||
|
printk(KERN_INFO "%s: ioctl CA_GET_CAP\n", __func__);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_get_slot_info(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
ANTENNA_INPUT_INFO info;
|
||||||
|
struct ca_slot_info *slot_p = (struct ca_slot_info*)arg;
|
||||||
|
|
||||||
|
if (ca_debug)
|
||||||
|
printk(KERN_INFO "%s: ioctl CA_GET_SLOT_INFO on slot %d.\n",
|
||||||
|
__func__, slot_p->num);
|
||||||
|
if (AVCTunerStatus(firesat, &info))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
if (slot_p->num == 0) {
|
||||||
|
slot_p->type = CA_CI;
|
||||||
|
slot_p->flags = firesat_get_ca_flags(&info);
|
||||||
}
|
}
|
||||||
case CA_GET_SLOT_INFO: {
|
else {
|
||||||
ca_slot_info_t *slot=(ca_slot_info_t*)parg;
|
return -EFAULT;
|
||||||
if(slot->num == 0) {
|
}
|
||||||
slot->type = CA_CI | CA_CI_LINK | CA_DESCR;
|
return 0;
|
||||||
slot->flags = CA_CI_MODULE_PRESENT | CA_CI_MODULE_READY;
|
}
|
||||||
} else {
|
|
||||||
slot->type = 0;
|
static int firesat_ca_app_info(struct firesat *firesat, void *arg)
|
||||||
slot->flags = 0;
|
{
|
||||||
|
struct ca_msg *reply_p = (struct ca_msg*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (avc_ca_app_info(firesat, reply_p->msg, &reply_p->length))
|
||||||
|
return -EFAULT;
|
||||||
|
if (ca_debug) {
|
||||||
|
printk(KERN_INFO "%s: Creating TAG_APP_INFO message:",
|
||||||
|
__func__);
|
||||||
|
for (i = 0; i < reply_p->length; i++)
|
||||||
|
printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
|
||||||
|
printk("\n");
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_info(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
struct ca_msg *reply_p = (struct ca_msg*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (avc_ca_info(firesat, reply_p->msg, &reply_p->length))
|
||||||
|
return -EFAULT;
|
||||||
|
if (ca_debug) {
|
||||||
|
printk(KERN_INFO "%s: Creating TAG_CA_INFO message:",
|
||||||
|
__func__);
|
||||||
|
for (i = 0; i < reply_p->length; i++)
|
||||||
|
printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_get_mmi(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
struct ca_msg *reply_p = (struct ca_msg*)arg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (avc_ca_get_mmi(firesat, reply_p->msg, &reply_p->length))
|
||||||
|
return -EFAULT;
|
||||||
|
if (ca_debug) {
|
||||||
|
printk(KERN_INFO "%s: Creating MMI reply INFO message:",
|
||||||
|
__func__);
|
||||||
|
for (i = 0; i < reply_p->length; i++)
|
||||||
|
printk("0x%02X, ", (unsigned char)reply_p->msg[i]);
|
||||||
|
printk("\n");
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_get_msg(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
ANTENNA_INPUT_INFO info;
|
||||||
|
|
||||||
|
switch (firesat->ca_last_command) {
|
||||||
|
case TAG_APP_INFO_ENQUIRY:
|
||||||
|
err = firesat_ca_app_info(firesat, arg);
|
||||||
|
break;
|
||||||
|
case TAG_CA_INFO_ENQUIRY:
|
||||||
|
err = firesat_ca_info(firesat, arg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (AVCTunerStatus(firesat, &info))
|
||||||
|
err = -EFAULT;
|
||||||
|
else if (info.CaMmi == 1) {
|
||||||
|
err = firesat_ca_get_mmi(firesat, arg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printk(KERN_INFO "%s: Unhandled message 0x%08X\n",
|
||||||
|
__func__, firesat->ca_last_command);
|
||||||
|
err = -EFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
firesat->ca_last_command = 0;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_pmt(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
struct ca_msg *msg_p = (struct ca_msg*)arg;
|
||||||
|
int data_pos;
|
||||||
|
|
||||||
|
if (msg_p->msg[3] & 0x80)
|
||||||
|
data_pos = (msg_p->msg[4] && 0x7F) + 4;
|
||||||
|
else
|
||||||
|
data_pos = 4;
|
||||||
|
if (avc_ca_pmt(firesat, &msg_p->msg[data_pos],
|
||||||
|
msg_p->length - data_pos))
|
||||||
|
return -EFAULT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_send_msg(struct firesat *firesat, void *arg)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct ca_msg *msg_p = (struct ca_msg*)arg;
|
||||||
|
|
||||||
|
// Do we need a semaphore for this?
|
||||||
|
firesat->ca_last_command =
|
||||||
|
(msg_p->msg[0] << 16) + (msg_p->msg[1] << 8) + msg_p->msg[2];
|
||||||
|
switch (firesat->ca_last_command) {
|
||||||
|
case TAG_CA_PMT:
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s: Message received: TAG_CA_PMT\n",
|
||||||
|
__func__);
|
||||||
|
err = firesat_ca_pmt(firesat, arg);
|
||||||
|
break;
|
||||||
|
case TAG_APP_INFO_ENQUIRY:
|
||||||
|
// This is all handled in ca_get_msg
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s: Message received: "
|
||||||
|
"TAG_APP_INFO_ENQUIRY\n", __func__);
|
||||||
err = 0;
|
err = 0;
|
||||||
break;
|
break;
|
||||||
}
|
case TAG_CA_INFO_ENQUIRY:
|
||||||
|
// This is all handled in ca_get_msg
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s: Message received: "
|
||||||
|
"TAG_CA_APP_INFO_ENQUIRY\n", __func__);
|
||||||
|
err = 0;
|
||||||
|
break;
|
||||||
|
case TAG_ENTER_MENU:
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s: Entering CA menu.\n", __func__);
|
||||||
|
err = avc_ca_enter_menu(firesat);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
err=-EINVAL;
|
printk(KERN_ERR "%s: Unhandled unknown message 0x%08X\n",
|
||||||
|
__func__, firesat->ca_last_command);
|
||||||
|
err = -EFAULT;
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
static int firesat_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
|
static int firesat_ca_ioctl(struct inode *inode, struct file *file,
|
||||||
//return dvb_usercopy(inode, file, cmd, arg, firesat_ca_do_ioctl);
|
unsigned int cmd, void *arg)
|
||||||
return dvb_generic_ioctl(inode, file, cmd, arg);
|
{
|
||||||
|
struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
|
||||||
|
struct firesat *firesat = dvbdev->priv;
|
||||||
|
int err;
|
||||||
|
ANTENNA_INPUT_INFO info;
|
||||||
|
|
||||||
|
switch(cmd) {
|
||||||
|
case CA_RESET:
|
||||||
|
err = firesat_ca_reset(firesat);
|
||||||
|
break;
|
||||||
|
case CA_GET_CAP:
|
||||||
|
err = firesat_ca_get_caps(firesat, arg);
|
||||||
|
break;
|
||||||
|
case CA_GET_SLOT_INFO:
|
||||||
|
err = firesat_ca_get_slot_info(firesat, arg);
|
||||||
|
break;
|
||||||
|
case CA_GET_MSG:
|
||||||
|
err = firesat_ca_get_msg(firesat, arg);
|
||||||
|
break;
|
||||||
|
case CA_SEND_MSG:
|
||||||
|
err = firesat_ca_send_msg(firesat, arg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printk(KERN_INFO "%s: Unhandled ioctl, command: %u\n",__func__,
|
||||||
|
cmd);
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AVCTunerStatus(firesat, &info))
|
||||||
|
return err;
|
||||||
|
|
||||||
|
firesat_ca_ready(&info);
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_ca_io_open(struct inode *inode, struct file *file) {
|
static int firesat_get_date_time_request(struct firesat *firesat)
|
||||||
printk(KERN_INFO "%s!\n",__func__);
|
{
|
||||||
|
if (ca_debug)
|
||||||
|
printk(KERN_INFO "%s: Retrieving Time/Date request\n",
|
||||||
|
__func__);
|
||||||
|
if (avc_ca_get_time_date(firesat, &firesat->ca_time_interval))
|
||||||
|
return -EFAULT;
|
||||||
|
if (ca_debug)
|
||||||
|
printk(KERN_INFO "%s: Time/Date interval is %d\n",
|
||||||
|
__func__, firesat->ca_time_interval);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int firesat_ca_io_open(struct inode *inode, struct file *file)
|
||||||
|
{
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s\n",__func__);
|
||||||
return dvb_generic_open(inode, file);
|
return dvb_generic_open(inode, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_ca_io_release(struct inode *inode, struct file *file) {
|
static int firesat_ca_io_release(struct inode *inode, struct file *file)
|
||||||
printk(KERN_INFO "%s!\n",__func__);
|
{
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s\n",__func__);
|
||||||
return dvb_generic_release(inode, file);
|
return dvb_generic_release(inode, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait) {
|
static unsigned int firesat_ca_io_poll(struct file *file, poll_table *wait)
|
||||||
// printk(KERN_INFO "%s!\n",__func__);
|
{
|
||||||
|
if (ca_debug != 0)
|
||||||
|
printk(KERN_INFO "%s\n",__func__);
|
||||||
return POLLIN;
|
return POLLIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +305,7 @@ static struct file_operations firesat_ca_fops = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.read = NULL, // There is no low level read anymore
|
.read = NULL, // There is no low level read anymore
|
||||||
.write = NULL, // There is no low level write anymore
|
.write = NULL, // There is no low level write anymore
|
||||||
.ioctl = firesat_ca_ioctl,
|
.ioctl = dvb_generic_ioctl,
|
||||||
.open = firesat_ca_io_open,
|
.open = firesat_ca_io_open,
|
||||||
.release = firesat_ca_io_release,
|
.release = firesat_ca_io_release,
|
||||||
.poll = firesat_ca_io_poll,
|
.poll = firesat_ca_io_poll,
|
||||||
|
@ -80,16 +317,37 @@ static struct dvb_device firesat_ca = {
|
||||||
.readers = 1,
|
.readers = 1,
|
||||||
.writers = 1,
|
.writers = 1,
|
||||||
.fops = &firesat_ca_fops,
|
.fops = &firesat_ca_fops,
|
||||||
|
.kernel_ioctl = firesat_ca_ioctl,
|
||||||
};
|
};
|
||||||
|
|
||||||
int firesat_ca_init(struct firesat *firesat) {
|
int firesat_ca_init(struct firesat *firesat)
|
||||||
int ret = dvb_register_device(firesat->adapter, &firesat->cadev, &firesat_ca, firesat, DVB_DEVICE_CA);
|
{
|
||||||
if(ret) return ret;
|
int err;
|
||||||
|
ANTENNA_INPUT_INFO info;
|
||||||
|
|
||||||
// avoid unnecessary delays, we're not talking to the CI yet anyways
|
if (AVCTunerStatus(firesat, &info))
|
||||||
return 0;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (firesat_ca_ready(&info)) {
|
||||||
|
err = dvb_register_device(firesat->adapter,
|
||||||
|
&firesat->cadev,
|
||||||
|
&firesat_ca, firesat,
|
||||||
|
DVB_DEVICE_CA);
|
||||||
|
|
||||||
|
if (info.CaApplicationInfo == 0)
|
||||||
|
printk(KERN_ERR "%s: CaApplicationInfo is not set.\n",
|
||||||
|
__func__);
|
||||||
|
if (info.CaDateTimeRequest == 1)
|
||||||
|
firesat_get_date_time_request(firesat);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void firesat_ca_release(struct firesat *firesat) {
|
void firesat_ca_release(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
if (firesat->cadev)
|
||||||
dvb_unregister_device(firesat->cadev);
|
dvb_unregister_device(firesat->cadev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
/*
|
||||||
|
* FireSAT DVB driver
|
||||||
|
*
|
||||||
|
* Copyright (c) ?
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef __FIRESAT_H
|
#ifndef __FIRESAT_H
|
||||||
#define __FIRESAT_H
|
#define __FIRESAT_H
|
||||||
|
|
||||||
|
@ -6,15 +18,108 @@
|
||||||
#include "dvb_demux.h"
|
#include "dvb_demux.h"
|
||||||
#include "dvb_net.h"
|
#include "dvb_net.h"
|
||||||
|
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
|
||||||
#include <linux/semaphore.h>
|
#include <linux/semaphore.h>
|
||||||
|
#endif
|
||||||
#include <linux/dvb/frontend.h>
|
#include <linux/dvb/frontend.h>
|
||||||
#include <linux/dvb/dmx.h>
|
#include <linux/dvb/dmx.h>
|
||||||
|
#include <iso.h>
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25)
|
||||||
|
#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w, v)
|
||||||
|
#else
|
||||||
|
#define DVB_REGISTER_ADAPTER(x, y, z, w, v) dvb_register_adapter(x, y, z, w)
|
||||||
|
#define DVB_DEFINE_MOD_OPT_ADAPTER_NR(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************************************
|
||||||
|
* CA message command constants from en50221_app_tags.h of libdvb
|
||||||
|
*****************************************************************/
|
||||||
|
/* Resource Manager */
|
||||||
|
#define TAG_PROFILE_ENQUIRY 0x9f8010
|
||||||
|
#define TAG_PROFILE 0x9f8011
|
||||||
|
#define TAG_PROFILE_CHANGE 0x9f8012
|
||||||
|
|
||||||
|
/* Application Info */
|
||||||
|
#define TAG_APP_INFO_ENQUIRY 0x9f8020
|
||||||
|
#define TAG_APP_INFO 0x9f8021
|
||||||
|
#define TAG_ENTER_MENU 0x9f8022
|
||||||
|
|
||||||
|
/* CA Support */
|
||||||
|
#define TAG_CA_INFO_ENQUIRY 0x9f8030
|
||||||
|
#define TAG_CA_INFO 0x9f8031
|
||||||
|
#define TAG_CA_PMT 0x9f8032
|
||||||
|
#define TAG_CA_PMT_REPLY 0x9f8033
|
||||||
|
|
||||||
|
/* Host Control */
|
||||||
|
#define TAG_TUNE 0x9f8400
|
||||||
|
#define TAG_REPLACE 0x9f8401
|
||||||
|
#define TAG_CLEAR_REPLACE 0x9f8402
|
||||||
|
#define TAG_ASK_RELEASE 0x9f8403
|
||||||
|
|
||||||
|
/* Date and Time */
|
||||||
|
#define TAG_DATE_TIME_ENQUIRY 0x9f8440
|
||||||
|
#define TAG_DATE_TIME 0x9f8441
|
||||||
|
|
||||||
|
/* Man Machine Interface (MMI) */
|
||||||
|
#define TAG_CLOSE_MMI 0x9f8800
|
||||||
|
#define TAG_DISPLAY_CONTROL 0x9f8801
|
||||||
|
#define TAG_DISPLAY_REPLY 0x9f8802
|
||||||
|
#define TAG_TEXT_LAST 0x9f8803
|
||||||
|
#define TAG_TEXT_MORE 0x9f8804
|
||||||
|
#define TAG_KEYPAD_CONTROL 0x9f8805
|
||||||
|
#define TAG_KEYPRESS 0x9f8806
|
||||||
|
#define TAG_ENQUIRY 0x9f8807
|
||||||
|
#define TAG_ANSWER 0x9f8808
|
||||||
|
#define TAG_MENU_LAST 0x9f8809
|
||||||
|
#define TAG_MENU_MORE 0x9f880a
|
||||||
|
#define TAG_MENU_ANSWER 0x9f880b
|
||||||
|
#define TAG_LIST_LAST 0x9f880c
|
||||||
|
#define TAG_LIST_MORE 0x9f880d
|
||||||
|
#define TAG_SUBTITLE_SEGMENT_LAST 0x9f880e
|
||||||
|
#define TAG_SUBTITLE_SEGMENT_MORE 0x9f880f
|
||||||
|
#define TAG_DISPLAY_MESSAGE 0x9f8810
|
||||||
|
#define TAG_SCENE_END_MARK 0x9f8811
|
||||||
|
#define TAG_SCENE_DONE 0x9f8812
|
||||||
|
#define TAG_SCENE_CONTROL 0x9f8813
|
||||||
|
#define TAG_SUBTITLE_DOWNLOAD_LAST 0x9f8814
|
||||||
|
#define TAG_SUBTITLE_DOWNLOAD_MORE 0x9f8815
|
||||||
|
#define TAG_FLUSH_DOWNLOAD 0x9f8816
|
||||||
|
#define TAG_DOWNLOAD_REPLY 0x9f8817
|
||||||
|
|
||||||
|
/* Low Speed Communications */
|
||||||
|
#define TAG_COMMS_COMMAND 0x9f8c00
|
||||||
|
#define TAG_CONNECTION_DESCRIPTOR 0x9f8c01
|
||||||
|
#define TAG_COMMS_REPLY 0x9f8c02
|
||||||
|
#define TAG_COMMS_SEND_LAST 0x9f8c03
|
||||||
|
#define TAG_COMMS_SEND_MORE 0x9f8c04
|
||||||
|
#define TAG_COMMS_RECV_LAST 0x9f8c05
|
||||||
|
#define TAG_COMMS_RECV_MORE 0x9f8c06
|
||||||
|
|
||||||
|
/* Authentication */
|
||||||
|
#define TAG_AUTH_REQ 0x9f8200
|
||||||
|
#define TAG_AUTH_RESP 0x9f8201
|
||||||
|
|
||||||
|
/* Teletext */
|
||||||
|
#define TAG_TELETEXT_EBU 0x9f9000
|
||||||
|
|
||||||
|
/* Smartcard */
|
||||||
|
#define TAG_SMARTCARD_COMMAND 0x9f8e00
|
||||||
|
#define TAG_SMARTCARD_REPLY 0x9f8e01
|
||||||
|
#define TAG_SMARTCARD_SEND 0x9f8e02
|
||||||
|
#define TAG_SMARTCARD_RCV 0x9f8e03
|
||||||
|
|
||||||
|
/* EPG */
|
||||||
|
#define TAG_EPG_ENQUIRY 0x9f8f00
|
||||||
|
#define TAG_EPG_REPLY 0x9f8f01
|
||||||
|
|
||||||
|
|
||||||
enum model_type {
|
enum model_type {
|
||||||
FireSAT_DVB_S = 1,
|
FireSAT_DVB_S = 1,
|
||||||
FireSAT_DVB_C = 2,
|
FireSAT_DVB_C = 2,
|
||||||
FireSAT_DVB_T = 3,
|
FireSAT_DVB_T = 3,
|
||||||
FireSAT_DVB_S2 = 4
|
FireSAT_DVB_S2 = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct firesat {
|
struct firesat {
|
||||||
|
@ -31,12 +136,13 @@ struct firesat {
|
||||||
struct dvb_frontend *fe;
|
struct dvb_frontend *fe;
|
||||||
|
|
||||||
struct dvb_device *cadev;
|
struct dvb_device *cadev;
|
||||||
int has_ci;
|
int ca_last_command;
|
||||||
|
int ca_time_interval;
|
||||||
|
|
||||||
struct semaphore avc_sem;
|
struct semaphore avc_sem;
|
||||||
atomic_t avc_reply_received;
|
atomic_t avc_reply_received;
|
||||||
|
|
||||||
atomic_t reschedule_remotecontrol;
|
atomic_t reschedule_remotecontrol;
|
||||||
|
|
||||||
struct firesat_channel {
|
struct firesat_channel {
|
||||||
struct firesat *firesat;
|
struct firesat *firesat;
|
||||||
|
@ -53,20 +159,54 @@ struct firesat {
|
||||||
void *respfrm;
|
void *respfrm;
|
||||||
int resp_length;
|
int resp_length;
|
||||||
|
|
||||||
// nodeid_t nodeid;
|
struct hpsb_host *host;
|
||||||
struct hpsb_host *host;
|
|
||||||
u64 guid; /* GUID of this node */
|
u64 guid; /* GUID of this node */
|
||||||
u32 guid_vendor_id; /* Top 24bits of guid */
|
u32 guid_vendor_id; /* Top 24bits of guid */
|
||||||
struct node_entry *nodeentry;
|
struct node_entry *nodeentry;
|
||||||
|
|
||||||
enum model_type type;
|
enum model_type type;
|
||||||
char subunit;
|
char subunit;
|
||||||
fe_sec_voltage_t voltage;
|
fe_sec_voltage_t voltage;
|
||||||
fe_sec_tone_mode_t tone;
|
fe_sec_tone_mode_t tone;
|
||||||
|
|
||||||
int isochannel;
|
int isochannel;
|
||||||
|
struct hpsb_iso *iso_handle;
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct firewireheader {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
__u8 tcode:4;
|
||||||
|
__u8 sy:4;
|
||||||
|
__u8 tag:2;
|
||||||
|
__u8 channel:6;
|
||||||
|
|
||||||
|
__u8 length_l;
|
||||||
|
__u8 length_h;
|
||||||
|
} hdr;
|
||||||
|
__u32 val;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CIPHeader {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
__u8 syncbits:2;
|
||||||
|
__u8 sid:6;
|
||||||
|
__u8 dbs;
|
||||||
|
__u8 fn:2;
|
||||||
|
__u8 qpc:3;
|
||||||
|
__u8 sph:1;
|
||||||
|
__u8 rsv:2;
|
||||||
|
__u8 dbc;
|
||||||
|
__u8 syncbits2:2;
|
||||||
|
__u8 fmt:6;
|
||||||
|
__u32 fdf:24;
|
||||||
|
} cip;
|
||||||
|
__u64 val;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct list_head firesat_list;
|
extern struct list_head firesat_list;
|
||||||
|
@ -76,11 +216,15 @@ extern spinlock_t firesat_list_lock;
|
||||||
extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
|
extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
|
||||||
extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
|
extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
|
||||||
extern int firesat_dvbdev_init(struct firesat *firesat,
|
extern int firesat_dvbdev_init(struct firesat *firesat,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
struct dvb_frontend *fe);
|
struct dvb_frontend *fe);
|
||||||
|
|
||||||
/* firesat_fe.c */
|
/* firesat_fe.c */
|
||||||
extern int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe);
|
extern int firesat_frontend_attach(struct firesat *firesat,
|
||||||
|
struct dvb_frontend *fe);
|
||||||
|
|
||||||
|
/* firesat_iso.c */
|
||||||
|
extern int setup_iso_channel(struct firesat *firesat);
|
||||||
|
extern void tear_down_iso_channel(struct firesat *firesat);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
|
* Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com>
|
||||||
* Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com>
|
* Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com>
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License as
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
@ -18,7 +19,6 @@
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/semaphore.h>
|
|
||||||
#include <ieee1394_hotplug.h>
|
#include <ieee1394_hotplug.h>
|
||||||
#include <nodemgr.h>
|
#include <nodemgr.h>
|
||||||
#include <highlevel.h>
|
#include <highlevel.h>
|
||||||
|
@ -79,11 +79,6 @@ static void firesat_add_host(struct hpsb_host *host);
|
||||||
static void firesat_remove_host(struct hpsb_host *host);
|
static void firesat_remove_host(struct hpsb_host *host);
|
||||||
static void firesat_host_reset(struct hpsb_host *host);
|
static void firesat_host_reset(struct hpsb_host *host);
|
||||||
|
|
||||||
/*
|
|
||||||
static void iso_receive(struct hpsb_host *host, int channel, quadlet_t *data,
|
|
||||||
size_t length);
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void fcp_request(struct hpsb_host *host,
|
static void fcp_request(struct hpsb_host *host,
|
||||||
int nodeid,
|
int nodeid,
|
||||||
int direction,
|
int direction,
|
||||||
|
@ -96,7 +91,6 @@ static struct hpsb_highlevel firesat_highlevel = {
|
||||||
.add_host = firesat_add_host,
|
.add_host = firesat_add_host,
|
||||||
.remove_host = firesat_remove_host,
|
.remove_host = firesat_remove_host,
|
||||||
.host_reset = firesat_host_reset,
|
.host_reset = firesat_host_reset,
|
||||||
// FIXME .iso_receive = iso_receive,
|
|
||||||
.fcp_request = fcp_request,
|
.fcp_request = fcp_request,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -127,100 +121,6 @@ static void firesat_host_reset(struct hpsb_host *host)
|
||||||
printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
|
printk(KERN_INFO "FireSAT host_reset (nodeid = 0x%x, hosts active = %d)\n",host->node_id,host->nodes_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct firewireheader {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned char tcode:4;
|
|
||||||
unsigned char sy:4;
|
|
||||||
unsigned char tag:2;
|
|
||||||
unsigned char channel:6;
|
|
||||||
|
|
||||||
unsigned char length_l;
|
|
||||||
unsigned char length_h;
|
|
||||||
} hdr;
|
|
||||||
unsigned long val;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CIPHeader {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned char syncbits:2;
|
|
||||||
unsigned char sid:6;
|
|
||||||
unsigned char dbs;
|
|
||||||
unsigned char fn:2;
|
|
||||||
unsigned char qpc:3;
|
|
||||||
unsigned char sph:1;
|
|
||||||
unsigned char rsv:2;
|
|
||||||
unsigned char dbc;
|
|
||||||
unsigned char syncbits2:2;
|
|
||||||
unsigned char fmt:6;
|
|
||||||
unsigned long fdf:24;
|
|
||||||
} cip;
|
|
||||||
unsigned long long val;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MPEG2Header {
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned char sync; // must be 0x47
|
|
||||||
unsigned char transport_error_indicator:1;
|
|
||||||
unsigned char payload_unit_start_indicator:1;
|
|
||||||
unsigned char transport_priority:1;
|
|
||||||
unsigned short pid:13;
|
|
||||||
unsigned char transport_scrambling_control:2;
|
|
||||||
unsigned char adaption_field_control:2;
|
|
||||||
unsigned char continuity_counter:4;
|
|
||||||
} hdr;
|
|
||||||
unsigned long val;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void iso_receive(struct hpsb_host *host,
|
|
||||||
int channel,
|
|
||||||
quadlet_t *data,
|
|
||||||
size_t length)
|
|
||||||
{
|
|
||||||
struct firesat *firesat = NULL;
|
|
||||||
struct firesat *firesat_entry;
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
// printk(KERN_INFO "FireSAT iso_receive: channel %d, length = %d\n", channel, length);
|
|
||||||
|
|
||||||
if (length <= 12)
|
|
||||||
return; // ignore empty packets
|
|
||||||
else {
|
|
||||||
|
|
||||||
spin_lock_irqsave(&firesat_list_lock, flags);
|
|
||||||
list_for_each_entry(firesat_entry,&firesat_list,list) {
|
|
||||||
if(firesat_entry->host == host && firesat_entry->isochannel == channel) {
|
|
||||||
firesat=firesat_entry;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spin_unlock_irqrestore(&firesat_list_lock, flags);
|
|
||||||
|
|
||||||
if (firesat) {
|
|
||||||
char *buf= ((char*)data) + sizeof(struct firewireheader)+sizeof(struct CIPHeader);
|
|
||||||
int count = (length-sizeof(struct CIPHeader)) / 192;
|
|
||||||
|
|
||||||
// printk(KERN_INFO "%s: length = %u\n data[0] = %08x\n data[1] = %08x\n data[2] = %08x\n data[3] = %08x\n data[4] = %08x\n",__func__, length, data[0],data[1],data[2],data[3],data[4]);
|
|
||||||
|
|
||||||
while (count--) {
|
|
||||||
|
|
||||||
if (buf[sizeof(quadlet_t) /*timestamp*/] == 0x47)
|
|
||||||
dvb_dmx_swfilter_packets(&firesat->demux, &buf[sizeof(quadlet_t)], 1);
|
|
||||||
else
|
|
||||||
printk("%s: invalid packet, skipping\n", __func__);
|
|
||||||
buf += 188 + sizeof (quadlet_t) /* timestamp */;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void fcp_request(struct hpsb_host *host,
|
static void fcp_request(struct hpsb_host *host,
|
||||||
int nodeid,
|
int nodeid,
|
||||||
int direction,
|
int direction,
|
||||||
|
@ -251,7 +151,9 @@ static void fcp_request(struct hpsb_host *host,
|
||||||
AVCRecv(firesat,data,length);
|
AVCRecv(firesat,data,length);
|
||||||
else
|
else
|
||||||
printk("%s: received fcp request from unknown source, ignored\n", __func__);
|
printk("%s: received fcp request from unknown source, ignored\n", __func__);
|
||||||
} // else ignore
|
}
|
||||||
|
else
|
||||||
|
printk("%s: received invalid fcp request, ignored\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_probe(struct device *dev)
|
static int firesat_probe(struct device *dev)
|
||||||
|
@ -260,7 +162,6 @@ static int firesat_probe(struct device *dev)
|
||||||
struct firesat *firesat;
|
struct firesat *firesat;
|
||||||
struct dvb_frontend *fe;
|
struct dvb_frontend *fe;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int result;
|
|
||||||
unsigned char subunitcount = 0xff, subunit;
|
unsigned char subunitcount = 0xff, subunit;
|
||||||
struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL);
|
struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL);
|
||||||
int kv_len;
|
int kv_len;
|
||||||
|
@ -298,6 +199,7 @@ static int firesat_probe(struct device *dev)
|
||||||
firesat->isochannel = -1;
|
firesat->isochannel = -1;
|
||||||
firesat->tone = 0xff;
|
firesat->tone = 0xff;
|
||||||
firesat->voltage = 0xff;
|
firesat->voltage = 0xff;
|
||||||
|
firesat->fe = fe;
|
||||||
|
|
||||||
if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) {
|
if (!(firesat->respfrm = kmalloc(sizeof (AVCRspFrm), GFP_KERNEL))) {
|
||||||
printk("%s: couldn't allocate memory.\n", __func__);
|
printk("%s: couldn't allocate memory.\n", __func__);
|
||||||
|
@ -357,7 +259,7 @@ static int firesat_probe(struct device *dev)
|
||||||
}
|
}
|
||||||
kfree(kv_buf);
|
kfree(kv_buf);
|
||||||
|
|
||||||
if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type, &firesat->has_ci)) {
|
if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) {
|
||||||
printk("%s: cannot identify subunit %d\n", __func__, subunit);
|
printk("%s: cannot identify subunit %d\n", __func__, subunit);
|
||||||
spin_lock_irqsave(&firesat_list_lock, flags);
|
spin_lock_irqsave(&firesat_list_lock, flags);
|
||||||
list_del(&firesat->list);
|
list_del(&firesat->list);
|
||||||
|
@ -382,7 +284,6 @@ static int firesat_probe(struct device *dev)
|
||||||
static int firesat_remove(struct device *dev)
|
static int firesat_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
struct unit_directory *ud = container_of(dev, struct unit_directory, device);
|
struct unit_directory *ud = container_of(dev, struct unit_directory, device);
|
||||||
struct dvb_frontend* fe;
|
|
||||||
struct firesat **firesats = ud->device.driver_data;
|
struct firesat **firesats = ud->device.driver_data;
|
||||||
int k;
|
int k;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -390,18 +291,9 @@ static int firesat_remove(struct device *dev)
|
||||||
if (firesats) {
|
if (firesats) {
|
||||||
for (k = 0; k < 2; k++)
|
for (k = 0; k < 2; k++)
|
||||||
if (firesats[k]) {
|
if (firesats[k]) {
|
||||||
if (firesats[k]->has_ci)
|
|
||||||
firesat_ca_release(firesats[k]);
|
firesat_ca_release(firesats[k]);
|
||||||
|
|
||||||
#if 0
|
dvb_unregister_frontend(firesats[k]->fe);
|
||||||
if (!(fe = kmalloc(sizeof (struct dvb_frontend), GFP_KERNEL))) {
|
|
||||||
fe->ops = firesat_ops;
|
|
||||||
fe->dvb = firesats[k]->adapter;
|
|
||||||
|
|
||||||
dvb_unregister_frontend(fe);
|
|
||||||
kfree(fe);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
dvb_net_release(&firesats[k]->dvbnet);
|
dvb_net_release(&firesats[k]->dvbnet);
|
||||||
firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx);
|
firesats[k]->demux.dmx.close(&firesats[k]->demux.dmx);
|
||||||
firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend);
|
firesats[k]->demux.dmx.remove_frontend(&firesats[k]->demux.dmx, &firesats[k]->frontend);
|
||||||
|
@ -413,6 +305,7 @@ static int firesat_remove(struct device *dev)
|
||||||
list_del(&firesats[k]->list);
|
list_del(&firesats[k]->list);
|
||||||
spin_unlock_irqrestore(&firesat_list_lock, flags);
|
spin_unlock_irqrestore(&firesat_list_lock, flags);
|
||||||
|
|
||||||
|
kfree(firesats[k]->fe);
|
||||||
kfree(firesats[k]->adapter);
|
kfree(firesats[k]->adapter);
|
||||||
kfree(firesats[k]->respfrm);
|
kfree(firesats[k]->respfrm);
|
||||||
kfree(firesats[k]);
|
kfree(firesats[k]);
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
/*
|
||||||
|
* FireSAT DVB driver
|
||||||
|
*
|
||||||
|
* Copyright (c) ?
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
@ -6,7 +18,6 @@
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/semaphore.h>
|
|
||||||
#include <ieee1394_hotplug.h>
|
#include <ieee1394_hotplug.h>
|
||||||
#include <nodemgr.h>
|
#include <nodemgr.h>
|
||||||
#include <highlevel.h>
|
#include <highlevel.h>
|
||||||
|
@ -26,13 +37,13 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
printk(KERN_INFO "%s\n", __func__);
|
//printk(KERN_INFO "%s\n", __func__);
|
||||||
|
|
||||||
if (down_interruptible(&firesat->demux_sem))
|
if (down_interruptible(&firesat->demux_sem))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (k = 0; k < 16; k++) {
|
for (k = 0; k < 16; k++) {
|
||||||
printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid);
|
//printk(KERN_INFO "%s: channel %d: active = %d, pid = 0x%x\n",__func__,k,firesat->channel[k].active,firesat->channel[k].pid);
|
||||||
|
|
||||||
if (firesat->channel[k].active == 0) {
|
if (firesat->channel[k].active == 0) {
|
||||||
firesat->channel[k].active = 1;
|
firesat->channel[k].active = 1;
|
||||||
|
@ -82,14 +93,15 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||||
int pidc,k;
|
int pidc,k;
|
||||||
u16 pids[16];
|
u16 pids[16];
|
||||||
|
|
||||||
printk(KERN_INFO "%s (pid %u)\n",__func__,dvbdmxfeed->pid);
|
// printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
|
||||||
|
|
||||||
switch (dvbdmxfeed->type) {
|
switch (dvbdmxfeed->type) {
|
||||||
case DMX_TYPE_TS:
|
case DMX_TYPE_TS:
|
||||||
case DMX_TYPE_SEC:
|
case DMX_TYPE_SEC:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("%s: invalid type %u\n",__func__,dvbdmxfeed->type);
|
printk(KERN_ERR "%s: invalid type %u\n",
|
||||||
|
__func__, dvbdmxfeed->type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +122,8 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||||
channel = firesat_channel_allocate(firesat);
|
channel = firesat_channel_allocate(firesat);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk("%s: invalid pes type %u\n",__func__, dvbdmxfeed->pes_type);
|
printk(KERN_ERR "%s: invalid pes type %u\n",
|
||||||
|
__func__, dvbdmxfeed->pes_type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -118,7 +131,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!channel) {
|
if (!channel) {
|
||||||
printk("%s: busy!\n", __func__);
|
printk(KERN_ERR "%s: busy!\n", __func__);
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,22 +144,23 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||||
|
|
||||||
if (firesat_channel_collect(firesat, &pidc, pids)) {
|
if (firesat_channel_collect(firesat, &pidc, pids)) {
|
||||||
firesat_channel_release(firesat, channel);
|
firesat_channel_release(firesat, channel);
|
||||||
|
printk(KERN_ERR "%s: could not collect pids!\n", __func__);
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dvbdmxfeed->pid == 8192) {
|
if(dvbdmxfeed->pid == 8192) {
|
||||||
if((k=AVCTuner_GetTS(firesat))) {
|
if((k = AVCTuner_GetTS(firesat))) {
|
||||||
firesat_channel_release(firesat, channel);
|
firesat_channel_release(firesat, channel);
|
||||||
printk("%s: AVCTuner_GetTS failed with error %d\n",
|
printk("%s: AVCTuner_GetTS failed with error %d\n",
|
||||||
__func__,k);
|
__func__, k);
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((k=AVCTuner_SetPIDs(firesat, pidc, pids))) {
|
if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) {
|
||||||
firesat_channel_release(firesat, channel);
|
firesat_channel_release(firesat, channel);
|
||||||
printk("%s: AVCTuner_SetPIDs failed with error %d\n",
|
printk("%s: AVCTuner_SetPIDs failed with error %d\n",
|
||||||
__func__,k);
|
__func__, k);
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +175,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||||
int k, l = 0;
|
int k, l = 0;
|
||||||
u16 pids[16];
|
u16 pids[16];
|
||||||
|
|
||||||
printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
|
//printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid);
|
||||||
|
|
||||||
if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
|
if (dvbdmxfeed->type == DMX_TYPE_TS && !((dvbdmxfeed->ts_type & TS_PACKET) &&
|
||||||
(demux->dmx.frontend->source != DMX_MEMORY_FE))) {
|
(demux->dmx.frontend->source != DMX_MEMORY_FE))) {
|
||||||
|
@ -189,12 +203,13 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||||
|
|
||||||
// list except channel to be removed
|
// list except channel to be removed
|
||||||
for (k = 0; k < 16; k++)
|
for (k = 0; k < 16; k++)
|
||||||
if (firesat->channel[k].active == 1)
|
if (firesat->channel[k].active == 1) {
|
||||||
if (&firesat->channel[k] !=
|
if (&firesat->channel[k] !=
|
||||||
(struct firesat_channel *)dvbdmxfeed->priv)
|
(struct firesat_channel *)dvbdmxfeed->priv)
|
||||||
pids[l++] = firesat->channel[k].pid;
|
pids[l++] = firesat->channel[k].pid;
|
||||||
else
|
else
|
||||||
firesat->channel[k].active = 0;
|
firesat->channel[k].active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ((k = AVCTuner_SetPIDs(firesat, l, pids))) {
|
if ((k = AVCTuner_SetPIDs(firesat, l, pids))) {
|
||||||
up(&firesat->demux_sem);
|
up(&firesat->demux_sem);
|
||||||
|
@ -214,8 +229,6 @@ int firesat_dvbdev_init(struct firesat *firesat,
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
firesat->has_ci = 1; // TEMP workaround
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
switch (firesat->type) {
|
switch (firesat->type) {
|
||||||
case FireSAT_DVB_S:
|
case FireSAT_DVB_S:
|
||||||
|
@ -254,7 +267,7 @@ int firesat_dvbdev_init(struct firesat *firesat,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result = dvb_register_adapter(firesat->adapter,
|
if ((result = DVB_REGISTER_ADAPTER(firesat->adapter,
|
||||||
firesat->model_name,
|
firesat->model_name,
|
||||||
THIS_MODULE,
|
THIS_MODULE,
|
||||||
dev, adapter_nr)) < 0) {
|
dev, adapter_nr)) < 0) {
|
||||||
|
@ -271,6 +284,7 @@ int firesat_dvbdev_init(struct firesat *firesat,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(&firesat->demux, 0, sizeof(struct dvb_demux));
|
||||||
firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
|
firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
|
||||||
|
|
||||||
firesat->demux.priv = (void *)firesat;
|
firesat->demux.priv = (void *)firesat;
|
||||||
|
@ -343,8 +357,9 @@ int firesat_dvbdev_init(struct firesat *firesat,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firesat->has_ci)
|
|
||||||
firesat_ca_init(firesat);
|
firesat_ca_init(firesat);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,15 @@
|
||||||
|
/*
|
||||||
|
* FireSAT DVB driver
|
||||||
|
*
|
||||||
|
* Copyright (c) ?
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/wait.h>
|
#include <linux/wait.h>
|
||||||
|
@ -6,7 +18,6 @@
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/semaphore.h>
|
|
||||||
#include <ieee1394_hotplug.h>
|
#include <ieee1394_hotplug.h>
|
||||||
#include <nodemgr.h>
|
#include <nodemgr.h>
|
||||||
#include <highlevel.h>
|
#include <highlevel.h>
|
||||||
|
@ -22,22 +33,29 @@
|
||||||
|
|
||||||
static int firesat_dvb_init(struct dvb_frontend *fe)
|
static int firesat_dvb_init(struct dvb_frontend *fe)
|
||||||
{
|
{
|
||||||
|
int result;
|
||||||
struct firesat *firesat = fe->sec_priv;
|
struct firesat *firesat = fe->sec_priv;
|
||||||
printk("fdi: 1\n");
|
// printk("fdi: 1\n");
|
||||||
firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM
|
firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM
|
||||||
printk("fdi: 2\n");
|
// printk("fdi: 2\n");
|
||||||
try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel);
|
result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel);
|
||||||
printk("fdi: 3\n");
|
if (result != 0) {
|
||||||
//FIXME hpsb_listen_channel(&firesat_highlevel, firesat->host, firesat->isochannel);
|
printk(KERN_ERR "Could not establish point to point "
|
||||||
printk("fdi: 4\n");
|
"connection.\n");
|
||||||
return 0;
|
return -1;
|
||||||
|
}
|
||||||
|
// printk("fdi: 3\n");
|
||||||
|
|
||||||
|
result = setup_iso_channel(firesat);
|
||||||
|
// printk("fdi: 4. Result was %d\n", result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_sleep(struct dvb_frontend *fe)
|
static int firesat_sleep(struct dvb_frontend *fe)
|
||||||
{
|
{
|
||||||
struct firesat *firesat = fe->sec_priv;
|
struct firesat *firesat = fe->sec_priv;
|
||||||
|
|
||||||
//FIXME hpsb_unlisten_channel(&firesat_highlevel, firesat->host, firesat->isochannel);
|
tear_down_iso_channel(firesat);
|
||||||
try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel);
|
try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel);
|
||||||
firesat->isochannel = -1;
|
firesat->isochannel = -1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -83,19 +101,20 @@ static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status)
|
||||||
if (AVCTunerStatus(firesat, &info))
|
if (AVCTunerStatus(firesat, &info))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (info.NoRF)
|
if (info.NoRF) {
|
||||||
*status = 0;
|
*status = 0;
|
||||||
else
|
} else {
|
||||||
*status = *status = FE_HAS_SIGNAL |
|
*status = FE_HAS_SIGNAL |
|
||||||
FE_HAS_VITERBI |
|
FE_HAS_VITERBI |
|
||||||
FE_HAS_SYNC |
|
FE_HAS_SYNC |
|
||||||
FE_HAS_CARRIER |
|
FE_HAS_CARRIER |
|
||||||
FE_HAS_LOCK;
|
FE_HAS_LOCK;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber)
|
static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber)
|
||||||
{
|
{
|
||||||
struct firesat *firesat = fe->sec_priv;
|
struct firesat *firesat = fe->sec_priv;
|
||||||
ANTENNA_INPUT_INFO info;
|
ANTENNA_INPUT_INFO info;
|
||||||
|
@ -103,10 +122,10 @@ static int firesat_read_ber (struct dvb_frontend *fe, u32 *ber)
|
||||||
if (AVCTunerStatus(firesat, &info))
|
if (AVCTunerStatus(firesat, &info))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*ber = ((info.BER[0] << 24) & 0xff) |
|
*ber = (info.BER[0] << 24) |
|
||||||
((info.BER[1] << 16) & 0xff) |
|
(info.BER[1] << 16) |
|
||||||
((info.BER[2] << 8) & 0xff) |
|
(info.BER[2] << 8) |
|
||||||
(info.BER[3] & 0xff);
|
info.BER[3];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -115,19 +134,29 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength)
|
||||||
{
|
{
|
||||||
struct firesat *firesat = fe->sec_priv;
|
struct firesat *firesat = fe->sec_priv;
|
||||||
ANTENNA_INPUT_INFO info;
|
ANTENNA_INPUT_INFO info;
|
||||||
u16 *signal = strength;
|
|
||||||
|
|
||||||
if (AVCTunerStatus(firesat, &info))
|
if (AVCTunerStatus(firesat, &info))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
*signal = info.SignalStrength;
|
*strength = info.SignalStrength << 8;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr)
|
static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr)
|
||||||
{
|
{
|
||||||
return -EOPNOTSUPP;
|
struct firesat *firesat = fe->sec_priv;
|
||||||
|
ANTENNA_INPUT_INFO info;
|
||||||
|
|
||||||
|
if (AVCTunerStatus(firesat, &info))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*snr = (info.CarrierNoiseRatio[0] << 8) +
|
||||||
|
info.CarrierNoiseRatio[1];
|
||||||
|
*snr *= 257;
|
||||||
|
// C/N[dB] = -10 * log10(snr / 65535)
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
|
static int firesat_read_uncorrected_blocks(struct dvb_frontend *fe, u32 *ucblocks)
|
||||||
|
@ -192,14 +221,13 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe)
|
||||||
firesat->frontend_info = &firesat_T_frontend_info;
|
firesat->frontend_info = &firesat_T_frontend_info;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// printk("%s: unknown model type 0x%x on subunit %d!\n",
|
|
||||||
// __func__, firesat->type,subunit);
|
|
||||||
printk("%s: unknown model type 0x%x !\n",
|
printk("%s: unknown model type 0x%x !\n",
|
||||||
__func__, firesat->type);
|
__func__, firesat->type);
|
||||||
firesat->model_name = "Unknown";
|
firesat->model_name = "Unknown";
|
||||||
firesat->frontend_info = NULL;
|
firesat->frontend_info = NULL;
|
||||||
}
|
}
|
||||||
fe->ops = firesat_ops;
|
fe->ops = firesat_ops;
|
||||||
|
fe->ops.info = *(firesat->frontend_info);
|
||||||
fe->dvb = firesat->adapter;
|
fe->dvb = firesat->adapter;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* FireSAT DVB driver
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "firesat.h"
|
||||||
|
|
||||||
|
static void rawiso_activity_cb(struct hpsb_iso *iso);
|
||||||
|
|
||||||
|
void tear_down_iso_channel(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
if (firesat->iso_handle != NULL) {
|
||||||
|
hpsb_iso_stop(firesat->iso_handle);
|
||||||
|
hpsb_iso_shutdown(firesat->iso_handle);
|
||||||
|
}
|
||||||
|
firesat->iso_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int setup_iso_channel(struct firesat *firesat)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
firesat->iso_handle =
|
||||||
|
hpsb_iso_recv_init(firesat->host,
|
||||||
|
256 * 200, //data_buf_size,
|
||||||
|
256, //buf_packets,
|
||||||
|
firesat->isochannel,
|
||||||
|
HPSB_ISO_DMA_DEFAULT, //dma_mode,
|
||||||
|
-1, //stat.config.irq_interval,
|
||||||
|
rawiso_activity_cb);
|
||||||
|
if (firesat->iso_handle == NULL) {
|
||||||
|
printk(KERN_ERR "Cannot initialize iso receive.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
result = hpsb_iso_recv_start(firesat->iso_handle, -1, -1, 0);
|
||||||
|
if (result != 0) {
|
||||||
|
printk(KERN_ERR "Cannot start iso receive.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rawiso_activity_cb(struct hpsb_iso *iso)
|
||||||
|
{
|
||||||
|
unsigned int num;
|
||||||
|
unsigned int i;
|
||||||
|
/* unsigned int j; */
|
||||||
|
unsigned int packet;
|
||||||
|
unsigned long flags;
|
||||||
|
struct firesat *firesat = NULL;
|
||||||
|
struct firesat *firesat_iterator;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&firesat_list_lock, flags);
|
||||||
|
list_for_each_entry(firesat_iterator, &firesat_list, list) {
|
||||||
|
if(firesat_iterator->iso_handle == iso) {
|
||||||
|
firesat = firesat_iterator;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spin_unlock_irqrestore(&firesat_list_lock, flags);
|
||||||
|
|
||||||
|
if (firesat) {
|
||||||
|
packet = iso->first_packet;
|
||||||
|
num = hpsb_iso_n_ready(iso);
|
||||||
|
for (i = 0; i < num; i++,
|
||||||
|
packet = (packet + 1) % iso->buf_packets) {
|
||||||
|
unsigned char *buf =
|
||||||
|
dma_region_i(&iso->data_buf, unsigned char,
|
||||||
|
iso->infos[packet].offset +
|
||||||
|
sizeof(struct CIPHeader));
|
||||||
|
int count = (iso->infos[packet].len -
|
||||||
|
sizeof(struct CIPHeader)) /
|
||||||
|
(188 + sizeof(struct firewireheader));
|
||||||
|
if (iso->infos[packet].len <= sizeof(struct CIPHeader))
|
||||||
|
continue; // ignore empty packet
|
||||||
|
/* printk("%s: Handling packets (%d): ", __func__, */
|
||||||
|
/* iso->infos[packet].len); */
|
||||||
|
/* for (j = 0; j < iso->infos[packet].len - */
|
||||||
|
/* sizeof(struct CIPHeader); j++) */
|
||||||
|
/* printk("%02X,", buf[j]); */
|
||||||
|
/* printk("\n"); */
|
||||||
|
while (count --) {
|
||||||
|
if (buf[sizeof(struct firewireheader)] == 0x47)
|
||||||
|
dvb_dmx_swfilter_packets(&firesat->demux,
|
||||||
|
&buf[sizeof(struct firewireheader)], 1);
|
||||||
|
else
|
||||||
|
printk("%s: invalid packet, skipping\n", __func__);
|
||||||
|
buf += 188 + sizeof(struct firewireheader);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
hpsb_iso_recv_release_packets(iso, num);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printk("%s: packets for unknown iso channel, skipping\n",
|
||||||
|
__func__);
|
||||||
|
hpsb_iso_recv_release_packets(iso, hpsb_iso_n_ready(iso));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue