Commit 8ae83cdf authored by Stefan Richter's avatar Stefan Richter

firedtv: cleanups and minor fixes

Combination of the following changes:

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: increase FCP frame length for DVB-S2 tune QSPK

    The last three bytes didn't go out to the wire.
    Effect of the fix not yet tested.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: replace mdelay by msleep

    These functions can sleep (and in fact sleep for the duration of a whole
    FCP transaction).  Hence msleep is more appropriate here.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: trivial reorganization in avc_api

    Reduce nesting level by factoring code out of avc_tuner_dsd() into
    helper functions.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: trivial cleanups in avc_api

    Use dev_err(), no CamelCase function names, adjust comment style, put
    #if 0 around unused code and add FIXME comments, standardize on
    lower-case hexadecimal constants, use ALIGN() for some frame length
    calculations, make a local function static...

    The code which writes FCP command frames and reads FCP response frames
    is not yet brought into canonical kernel coding style because this
    involves changes of typedefs (on-the-wire bitfields).

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: don't retry oPCR updates endlessly

    In the theoretical case that the target node wasn't handling the lock
    transactions as expected or there was continued interference by other
    initiating nodes, these functions wouldn't return for ages.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: remove bitfield typedefs from cmp, fix for big endian CPUs

    Use macros/ inline functions/ standard byte order accessors to read and
    write oPCR register values (big endian bitfields, on-the-wire data).
    The new code may not be the ultimate optimum, but it doesn't occur in a
    hot path.

    This fixes the CMP code for big endian CPUs.  So far I tested it only on
    a little endian CPU though.

    For now, include <asm/byteorder.h> instead of <linux/byteorder.h>
    because drivers/ieee1394/*.h also include the former.  I will fix this
    in drivers/ieee1394 and firedtv later.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: trivial cleanups in cmp

    Reduce nesting level by means of early exit and goto.
    Remove obsolete includes, use dev_err(), no CamelCase function names...

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: trivial cleanups in firesat-ci

    Whitespace, variable names, comment style...

    Also, use dvb_generic_open() and dvb_generic_release() directly as
    our hooks in struct file_operations because firedtv's wrappers merely
    called these generic functions.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: remove CA debug code

    This looks like it is not necessary to have available for endusers who
    cannot patch kernels for bug reporting and tests of fixes.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: remove AV/C debug code

    This looks like it is not necessary to have available for endusers who
    cannot patch kernels for bug reporting and tests of fixes.

Sun, 2 Nov 2008 13:45:00 +0100 (CET)
firedtv: remove various debug code

    Most of this was already commented out.  And that which wasn't is not
    relevant in normal use.

Mon, 29 Sep 2008 19:22:48 +0200 (CEST)
firedtv: register input device as child of a FireWire device

    Instead of one virtual input device which exists for the whole lifetime
    of the driver and receives events from all connected FireDTVs, register
    one input device for each firedtv device.  These input devices will show
    up as children of the respective firedtv devices in the sysfs hierarchy.

    However, the implementation falls short because of a bug in userspace:
    Udev's path_id script gets stuck with 100% CPU utilization, maybe
    because of an assumption about the maximum ieee1394 device hierarchy
    depth.

    To avoid this bug, we use the fw-host device instead of the proper
    unit_directory device as parent of the input device.

    There is hope that the port to the new firewire stack won't be inhibited
    by this userspace bug because there are no fw-host devices there.

Mon, 29 Sep 2008 19:21:52 +0200 (CEST)
firedtv: fix string comparison and a few sparse warnings

    Sparse found a bug:
    	while ((kv_buf + kv_len - 1) == '\0')
    should have been
    	while (kv_buf[kv_len - 1] == '\0')
    We fix it by a better implementation without a temporary copy.

    Also fix sparse warnings of 0 instead of NULL and signedness mismatches.

Mon, 29 Sep 2008 19:21:20 +0200 (CEST)
firedtv: remove unused struct members

    and redefine an int as a bool.

Mon, 29 Sep 2008 19:20:36 +0200 (CEST)
firedtv: fix initialization of dvb_frontend.ops

    There was a NULL pointer reference if no dvb_frontend_info was found.

    Also, don't directly assign struct typed values to struct typed
    variables.  Instead write out assignments to individual strcut members.
    This reduces module size by about 1 kB.

Mon, 29 Sep 2008 19:19:41 +0200 (CEST)
firedtv: remove unused dual subunit code from initialization

    No FireDTVs with more than one subunit exists, hence simplify the
    initialization for the special case of one subunit.  The driver was able
    to check for more than one subunit but was broken for more than two
    subunits.

    While we are at it, add several missing cleanups after failure, and
    include a few dynamically allocated structures diretly into struct
    firesat instead of allocating them separately.

Mon, 29 Sep 2008 19:19:08 +0200 (CEST)
firedtv: add vendor_id and version to driver match table

    Now that nodemgr was enhanced to match against the root directory's
    vendor ID if there isn't one in the unit directory, use this to
    prevent firedtv to be bound to wrong devices by accident.

    Also add the AV/C software version ID to the match flags for
    completeness; specifier ID and software only make sense as a pair.

Mon, 29 Sep 2008 19:18:30 +0200 (CEST)
firedtv: use hpsb_node_read(), _write(), _lock()

    because they are simpler and treat the node generation more correctly.
    While we are at it, clean up and simplify surrounding code.
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 00fc3072
This diff is collapsed.
...@@ -26,15 +26,6 @@ ...@@ -26,15 +26,6 @@
**************************************************************/ **************************************************************/
#define LIST_MANAGEMENT_ONLY 0x03 #define LIST_MANAGEMENT_ONLY 0x03
/*************************************************************
FCP Address range
**************************************************************/
#define RESPONSE_REGISTER 0xFFFFF0000D00ULL
#define COMMAND_REGISTER 0xFFFFF0000B00ULL
#define PCR_BASE_ADDRESS 0xFFFFF0000900ULL
/************************************************************ /************************************************************
definition of structures definition of structures
*************************************************************/ *************************************************************/
...@@ -413,34 +404,29 @@ struct dvb_diseqc_master_cmd; ...@@ -413,34 +404,29 @@ struct dvb_diseqc_master_cmd;
struct dvb_frontend_parameters; struct dvb_frontend_parameters;
struct firesat; struct firesat;
int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, int avc_recv(struct firesat *firesat, u8 *data, size_t length);
AVCRspFrm *RspFrm);
int AVCRecv(struct firesat *firesat, u8 *data, size_t length);
int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug,
struct dvb_frontend_parameters *params, __u8 *status); struct dvb_frontend_parameters *params, __u8 *status);
int AVCTunerStatus(struct firesat *firesat, int avc_tuner_status(struct firesat *firesat,
ANTENNA_INPUT_INFO *antenna_input_info); ANTENNA_INPUT_INFO *antenna_input_info);
int AVCTuner_DSD(struct firesat *firesat, int avc_tuner_dsd(struct firesat *firesat,
struct dvb_frontend_parameters *params, __u8 *status); struct dvb_frontend_parameters *params);
int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); int avc_tuner_set_pids(struct firesat *firesat, unsigned char pidc, u16 pid[]);
int AVCTuner_GetTS(struct firesat *firesat); int avc_tuner_get_ts(struct firesat *firesat);
int avc_identify_subunit(struct firesat *firesat);
int AVCIdentifySubunit(struct firesat *firesat); int avc_lnb_control(struct firesat *firesat, char voltage, char burst,
int AVCLNBControl(struct firesat *firesat, char voltage, char burst,
char conttone, char nrdiseq, char conttone, char nrdiseq,
struct dvb_diseqc_master_cmd *diseqcmd); struct dvb_diseqc_master_cmd *diseqcmd);
int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount);
void avc_remote_ctrl_work(struct work_struct *work); void avc_remote_ctrl_work(struct work_struct *work);
int AVCRegisterRemoteControl(struct firesat *firesat); int avc_register_remote_control(struct firesat *firesat);
int AVCTuner_Host2Ca(struct firesat *firesat); int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len);
int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len);
int avc_ca_info(struct firesat *firesat, char *app_info, int *length);
int avc_ca_reset(struct firesat *firesat); int avc_ca_reset(struct firesat *firesat);
int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); int avc_ca_pmt(struct firesat *firesat, char *app_info, int length);
int avc_ca_get_time_date(struct firesat *firesat, int *interval); int avc_ca_get_time_date(struct firesat *firesat, int *interval);
int avc_ca_enter_menu(struct firesat *firesat); int avc_ca_enter_menu(struct firesat *firesat);
int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len);
#endif /* _AVC_API_H */ #endif /* _AVC_API_H */
...@@ -10,37 +10,21 @@ ...@@ -10,37 +10,21 @@
* the License, or (at your option) any later version. * the License, or (at your option) any later version.
*/ */
#include <linux/device.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/types.h> #include <linux/types.h>
#include <hosts.h> #include <asm/byteorder.h>
#include <ieee1394.h> #include <ieee1394.h>
#include <ieee1394_core.h>
#include <ieee1394_transactions.h>
#include <nodemgr.h> #include <nodemgr.h>
#include "avc_api.h" #include "avc_api.h"
#include "cmp.h" #include "cmp.h"
#include "firesat.h" #include "firesat.h"
typedef struct _OPCR #define CMP_OUTPUT_PLUG_CONTROL_REG_0 0xfffff0000904ULL
{
__u8 PTPConnCount : 6 ; // Point to point connect. counter
__u8 BrConnCount : 1 ; // Broadcast connection counter
__u8 OnLine : 1 ; // On Line
__u8 ChNr : 6 ; // Channel number
__u8 Res : 2 ; // Reserved
__u8 PayloadHi : 2 ; // Payoad high bits
__u8 OvhdID : 4 ; // Overhead ID
__u8 DataRate : 2 ; // Data Rate
__u8 PayloadLo ; // Payoad low byte
} OPCR ;
#define FIRESAT_SPEED IEEE1394_SPEED_400
static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len)
{ {
...@@ -49,151 +33,139 @@ static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) ...@@ -49,151 +33,139 @@ static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len)
if (mutex_lock_interruptible(&firesat->avc_mutex)) if (mutex_lock_interruptible(&firesat->avc_mutex))
return -EINTR; return -EINTR;
ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, ret = hpsb_node_read(firesat->ud->ne, addr, buf, len);
firesat->nodeentry->generation, addr, buf, len); if (ret < 0)
dev_err(&firesat->ud->device, "CMP: read I/O error\n");
mutex_unlock(&firesat->avc_mutex); mutex_unlock(&firesat->avc_mutex);
return ret; return ret;
} }
static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, static int cmp_lock(struct firesat *firesat, void *data, u64 addr, __be32 arg,
quadlet_t arg, int ext_tcode) int ext_tcode)
{ {
int ret; int ret;
if (mutex_lock_interruptible(&firesat->avc_mutex)) if (mutex_lock_interruptible(&firesat->avc_mutex))
return -EINTR; return -EINTR;
ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, ret = hpsb_node_lock(firesat->ud->ne, addr, ext_tcode, data,
firesat->nodeentry->generation, (__force quadlet_t)arg);
addr, ext_tcode, data, arg); if (ret < 0)
dev_err(&firesat->ud->device, "CMP: lock I/O error\n");
mutex_unlock(&firesat->avc_mutex); mutex_unlock(&firesat->avc_mutex);
return ret; return ret;
} }
//try establishing a point-to-point connection (may be interrupted by a busreset static inline u32 get_opcr(__be32 opcr, u32 mask, u32 shift)
int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel) { {
unsigned int BWU; //bandwidth to allocate return (be32_to_cpu(opcr) >> shift) & mask;
}
static inline void set_opcr(__be32 *opcr, u32 value, u32 mask, u32 shift)
{
*opcr &= ~cpu_to_be32(mask << shift);
*opcr |= cpu_to_be32((value & mask) << shift);
}
quadlet_t old_oPCR,test_oPCR = 0x0; #define get_opcr_online(v) get_opcr((v), 0x1, 31)
u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); #define get_opcr_p2p_connections(v) get_opcr((v), 0x3f, 24)
int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); #define get_opcr_channel(v) get_opcr((v), 0x3f, 16)
/* printk(KERN_INFO "%s: nodeid = %d\n",__func__,firesat->nodeentry->nodeid); */ #define set_opcr_p2p_connections(p, v) set_opcr((p), (v), 0x3f, 24)
#define set_opcr_channel(p, v) set_opcr((p), (v), 0x3f, 16)
#define set_opcr_data_rate(p, v) set_opcr((p), (v), 0x3, 14)
#define set_opcr_overhead_id(p, v) set_opcr((p), (v), 0xf, 10)
if (result < 0) { int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel)
printk("%s: cannot read oPCR\n", __func__); {
return result; __be32 old_opcr, opcr;
} else { u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
/* printk(KERN_INFO "%s: oPCR = %08x\n",__func__,test_oPCR); */ int attempts = 0;
do { int ret;
OPCR *hilf= (OPCR*) &test_oPCR;
ret = cmp_read(firesat, &opcr, opcr_address, 4);
if (!hilf->OnLine) { if (ret < 0)
printk("%s: Output offline; oPCR: %08x\n", __func__, test_oPCR); return ret;
return -EBUSY;
} else { repeat:
quadlet_t new_oPCR; if (!get_opcr_online(opcr)) {
dev_err(&firesat->ud->device, "CMP: output offline\n");
old_oPCR=test_oPCR; return -EBUSY;
if (hilf->PTPConnCount) { }
if (hilf->ChNr != iso_channel) {
printk("%s: Output plug has already connection on channel %u; cannot change it to channel %u\n",__func__,hilf->ChNr,iso_channel); old_opcr = opcr;
return -EBUSY;
} else if (get_opcr_p2p_connections(opcr)) {
printk(KERN_INFO "%s: Overlaying existing connection; connection counter was: %u\n",__func__, hilf->PTPConnCount); if (get_opcr_channel(opcr) != channel) {
BWU=0; //we allocate no bandwidth (is this necessary?) dev_err(&firesat->ud->device,
} else { "CMP: cannot change channel\n");
hilf->ChNr=iso_channel; return -EBUSY;
hilf->DataRate=FIRESAT_SPEED;
hilf->OvhdID=0; //FIXME: that is for worst case -> optimize
BWU=hilf->OvhdID?hilf->OvhdID*32:512;
BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
/* if (allocate_1394_resources(iso_channel,BWU))
{
cout << "Allocation of resources failed\n";
return -2;
}*/
}
hilf->PTPConnCount++;
new_oPCR=test_oPCR;
/* 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); */
result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
if (result < 0) {
printk("%s: cannot compare_swap oPCR\n",__func__);
return result;
}
if ((old_oPCR != test_oPCR) && (!((OPCR*) &old_oPCR)->PTPConnCount))
{
printk("%s: change of oPCR failed -> freeing resources\n",__func__);
// hilf= (OPCR*) &new_oPCR;
// unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
// BWU += (hilf->Payload+3) * (2 << (3-hilf->DataRate));
/* if (deallocate_1394_resources(iso_channel,BWU))
{
cout << "Deallocation of resources failed\n";
return -3;
}*/
}
}
} }
while (old_oPCR != test_oPCR); dev_info(&firesat->ud->device,
"CMP: overlaying existing connection\n");
/* We don't allocate isochronous resources. */
} else {
set_opcr_channel(&opcr, channel);
set_opcr_data_rate(&opcr, IEEE1394_SPEED_400);
/* FIXME: this is for the worst case - optimize */
set_opcr_overhead_id(&opcr, 0);
/* FIXME: allocate isochronous channel and bandwidth at IRM */
} }
set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) + 1);
ret = cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2);
if (ret < 0)
return ret;
if (old_opcr != opcr) {
/*
* FIXME: if old_opcr.P2P_Connections > 0,
* deallocate isochronous channel and bandwidth at IRM
*/
if (++attempts < 6) /* arbitrary limit */
goto repeat;
return -EBUSY;
}
return 0; return 0;
} }
//try breaking a point-to-point connection (may be interrupted by a busreset void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel)
int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel) { {
quadlet_t old_oPCR,test_oPCR; __be32 old_opcr, opcr;
u64 opcr_address = CMP_OUTPUT_PLUG_CONTROL_REG_0 + (plug << 2);
int attempts = 0;
if (cmp_read(firesat, &opcr, opcr_address, 4) < 0)
return;
repeat:
if (!get_opcr_online(opcr) || !get_opcr_p2p_connections(opcr) ||
get_opcr_channel(opcr) != channel) {
dev_err(&firesat->ud->device, "CMP: no connection to break\n");
return;
}
old_opcr = opcr;
set_opcr_p2p_connections(&opcr, get_opcr_p2p_connections(opcr) - 1);
u64 oPCR_address=0xfffff0000904ull+(output_plug << 2); if (cmp_lock(firesat, &opcr, opcr_address, old_opcr, 2) < 0)
int result=cmp_read(firesat, &test_oPCR, oPCR_address, 4); return;
/* printk(KERN_INFO "%s\n",__func__); */ if (old_opcr != opcr) {
/*
* FIXME: if old_opcr.P2P_Connections == 1, i.e. we were last
* owner, deallocate isochronous channel and bandwidth at IRM
*/
if (result < 0) { if (++attempts < 6) /* arbitrary limit */
printk("%s: cannot read oPCR\n", __func__); goto repeat;
return result; }
} else {
do {
OPCR *hilf= (OPCR*) &test_oPCR;
if (!hilf->OnLine || !hilf->PTPConnCount || hilf->ChNr != iso_channel) {
printk("%s: Output plug does not have PtP-connection on that channel; oPCR: %08x\n", __func__, test_oPCR);
return -EINVAL;
} else {
quadlet_t new_oPCR;
old_oPCR=test_oPCR;
hilf->PTPConnCount--;
new_oPCR=test_oPCR;
// printk(KERN_INFO "%s: trying compare_swap...\n", __func__);
result=cmp_lock(firesat, &test_oPCR, oPCR_address, old_oPCR, 2);
if (result < 0) {
printk("%s: cannot compare_swap oPCR\n",__func__);
return result;
}
}
} while (old_oPCR != test_oPCR);
/* hilf = (OPCR*) &old_oPCR;
if (hilf->PTPConnCount == 1) { // if we were the last owner of this connection
cout << "deallocating 1394 resources\n";
unsigned int BWU=hilf->OvhdID?hilf->OvhdID*32:512;
BWU += (hilf->PayloadLo + (hilf->PayloadHi << 8) +3) * (2 << (3-hilf->DataRate));
if (deallocate_1394_resources(iso_channel,BWU))
{
cout << "Deallocation of resources failed\n";
return -3;
}
}*/
}
return 0;
} }
...@@ -3,9 +3,7 @@ ...@@ -3,9 +3,7 @@
struct firesat; struct firesat;
int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int cmp_establish_pp_connection(struct firesat *firesat, int plug, int channel);
int iso_channel); void cmp_break_pp_connection(struct firesat *firesat, int plug, int channel);
int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,
int iso_channel);
#endif /* _CMP_H */ #endif /* _CMP_H */
This diff is collapsed.
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
struct firesat; struct firesat;
int firesat_ca_init(struct firesat *firesat); int firesat_ca_register(struct firesat *firesat);
void firesat_ca_release(struct firesat *firesat); void firesat_ca_release(struct firesat *firesat);
#endif /* _FIREDTV_CI_H */ #endif /* _FIREDTV_CI_H */
...@@ -12,9 +12,11 @@ ...@@ -12,9 +12,11 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include "firesat-rc.h" #include "firesat-rc.h"
#include "firesat.h"
/* fixed table with older keycodes, geared towards MythTV */ /* fixed table with older keycodes, geared towards MythTV */
const static u16 oldtable[] = { const static u16 oldtable[] = {
...@@ -61,7 +63,7 @@ const static u16 oldtable[] = { ...@@ -61,7 +63,7 @@ const static u16 oldtable[] = {
}; };
/* user-modifiable table for a remote as sold in 2008 */ /* user-modifiable table for a remote as sold in 2008 */
static u16 keytable[] = { const static u16 keytable[] = {
/* code from device: 0x0300...0x031f */ /* code from device: 0x0300...0x031f */
...@@ -123,19 +125,24 @@ static u16 keytable[] = { ...@@ -123,19 +125,24 @@ static u16 keytable[] = {
[0x34] = KEY_EXIT, [0x34] = KEY_EXIT,
}; };
static struct input_dev *idev; int firesat_register_rc(struct firesat *firesat, struct device *dev)
int firesat_register_rc(void)
{ {
struct input_dev *idev;
int i, err; int i, err;
idev = input_allocate_device(); idev = input_allocate_device();
if (!idev) if (!idev)
return -ENOMEM; return -ENOMEM;
firesat->remote_ctrl_dev = idev;
idev->name = "FireDTV remote control"; idev->name = "FireDTV remote control";
idev->dev.parent = dev;
idev->evbit[0] = BIT_MASK(EV_KEY); idev->evbit[0] = BIT_MASK(EV_KEY);
idev->keycode = keytable; idev->keycode = kmemdup(keytable, sizeof(keytable), GFP_KERNEL);
if (!idev->keycode) {
err = -ENOMEM;
goto fail;
}
idev->keycodesize = sizeof(keytable[0]); idev->keycodesize = sizeof(keytable[0]);
idev->keycodemax = ARRAY_SIZE(keytable); idev->keycodemax = ARRAY_SIZE(keytable);
...@@ -144,22 +151,31 @@ int firesat_register_rc(void) ...@@ -144,22 +151,31 @@ int firesat_register_rc(void)
err = input_register_device(idev); err = input_register_device(idev);
if (err) if (err)
input_free_device(idev); goto fail_free_keymap;
return 0;
fail_free_keymap:
kfree(idev->keycode);
fail:
input_free_device(idev);
return err; return err;
} }
void firesat_unregister_rc(void) void firesat_unregister_rc(struct firesat *firesat)
{ {
input_unregister_device(idev); kfree(firesat->remote_ctrl_dev->keycode);
input_unregister_device(firesat->remote_ctrl_dev);
} }
void firesat_handle_rc(unsigned int code) void firesat_handle_rc(struct firesat *firesat, unsigned int code)
{ {
u16 *keycode = firesat->remote_ctrl_dev->keycode;
if (code >= 0x0300 && code <= 0x031f) if (code >= 0x0300 && code <= 0x031f)
code = keytable[code - 0x0300]; code = keycode[code - 0x0300];
else if (code >= 0x0340 && code <= 0x0354) else if (code >= 0x0340 && code <= 0x0354)
code = keytable[code - 0x0320]; code = keycode[code - 0x0320];
else if (code >= 0x4501 && code <= 0x451f) else if (code >= 0x4501 && code <= 0x451f)
code = oldtable[code - 0x4501]; code = oldtable[code - 0x4501];
else if (code >= 0x4540 && code <= 0x4542) else if (code >= 0x4540 && code <= 0x4542)
...@@ -170,6 +186,6 @@ void firesat_handle_rc(unsigned int code) ...@@ -170,6 +186,6 @@ void firesat_handle_rc(unsigned int code)
return; return;
} }
input_report_key(idev, code, 1); input_report_key(firesat->remote_ctrl_dev, code, 1);
input_report_key(idev, code, 0); input_report_key(firesat->remote_ctrl_dev, code, 0);
} }
#ifndef _FIREDTV_RC_H #ifndef _FIREDTV_RC_H
#define _FIREDTV_RC_H #define _FIREDTV_RC_H
int firesat_register_rc(void); struct firesat;
void firesat_unregister_rc(void); struct device;
void firesat_handle_rc(unsigned int code);
int firesat_register_rc(struct firesat *firesat, struct device *dev);
void firesat_unregister_rc(struct firesat *firesat);
void firesat_handle_rc(struct firesat *firesat, unsigned int code);
#endif /* _FIREDTV_RC_H */ #endif /* _FIREDTV_RC_H */
...@@ -21,11 +21,11 @@ ...@@ -21,11 +21,11 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <asm/atomic.h>
#include <demux.h> #include <demux.h>
#include <dmxdev.h> #include <dmxdev.h>
#include <dvb_demux.h> #include <dvb_demux.h>
#include <dvb_frontend.h>
#include <dvb_net.h> #include <dvb_net.h>
#include <dvbdev.h> #include <dvbdev.h>
...@@ -127,50 +127,35 @@ enum model_type { ...@@ -127,50 +127,35 @@ enum model_type {
FireSAT_DVB_S2 = 4, FireSAT_DVB_S2 = 4,
}; };
struct hpsb_host; struct input_dev;
struct hpsb_iso; struct hpsb_iso;
struct node_entry; struct unit_directory;
struct firesat { struct firesat {
struct dvb_demux dvb_demux; struct dvb_adapter adapter;
struct dmxdev dmxdev;
/* DVB bits */ struct dvb_demux demux;
struct dvb_adapter *adapter; struct dmx_frontend frontend;
struct dmxdev dmxdev; struct dvb_net dvbnet;
struct dvb_demux demux; struct dvb_frontend fe;
struct dmx_frontend frontend;
struct dvb_net dvbnet; struct dvb_device *cadev;
struct dvb_frontend_info *frontend_info; int ca_last_command;
struct dvb_frontend *fe; int ca_time_interval;
struct dvb_device *cadev; struct mutex avc_mutex;
int ca_last_command; wait_queue_head_t avc_wait;
int ca_time_interval; bool avc_reply_received;
struct work_struct remote_ctrl_work;
struct mutex avc_mutex; struct input_dev *remote_ctrl_dev;
wait_queue_head_t avc_wait;
atomic_t avc_reply_received;
struct work_struct remote_ctrl_work;
struct firesat_channel { struct firesat_channel {
struct firesat *firesat; bool active;
struct dvb_demux_feed *dvbdmxfeed;
int active;
int id;
int pid; int pid;
int type; /* 1 - TS, 2 - Filter */
} channel[16]; } channel[16];
struct mutex demux_mutex; struct mutex demux_mutex;
/* needed by avc_api */
void *respfrm;
int resp_length;
struct hpsb_host *host; struct unit_directory *ud;
u64 guid; /* GUID of this node */
u32 guid_vendor_id; /* Top 24bits of guid */
struct node_entry *nodeentry;
enum model_type type; enum model_type type;
char subunit; char subunit;
...@@ -181,6 +166,10 @@ struct firesat { ...@@ -181,6 +166,10 @@ struct firesat {
struct hpsb_iso *iso_handle; struct hpsb_iso *iso_handle;
struct list_head list; struct list_head list;
/* needed by avc_api */
int resp_length;
u8 respfrm[512];
}; };
struct firewireheader { struct firewireheader {
...@@ -226,11 +215,10 @@ struct device; ...@@ -226,11 +215,10 @@ struct device;
/* firesat_dvb.c */ /* firesat_dvb.c */
int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed);
int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
int firesat_dvbdev_init(struct firesat *firesat, struct device *dev, int firesat_dvbdev_init(struct firesat *firesat, struct device *dev);
struct dvb_frontend *fe);
/* firesat_fe.c */ /* firesat_fe.c */
int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe); void firesat_frontend_init(struct firesat *firesat);
/* firesat_iso.c */ /* firesat_iso.c */
int setup_iso_channel(struct firesat *firesat); int setup_iso_channel(struct firesat *firesat);
......
This diff is collapsed.
...@@ -34,8 +34,8 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) ...@@ -34,8 +34,8 @@ static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat)
return NULL; return NULL;
for (k = 0; k < 16; k++) for (k = 0; k < 16; k++)
if (firesat->channel[k].active == 0) { if (!firesat->channel[k].active) {
firesat->channel[k].active = 1; firesat->channel[k].active = true;
c = &firesat->channel[k]; c = &firesat->channel[k];
break; break;
} }
...@@ -52,7 +52,7 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[] ...@@ -52,7 +52,7 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]
return -EINTR; return -EINTR;
for (k = 0; k < 16; k++) for (k = 0; k < 16; k++)
if (firesat->channel[k].active == 1) if (firesat->channel[k].active)
pid[l++] = firesat->channel[k].pid; pid[l++] = firesat->channel[k].pid;
mutex_unlock(&firesat->demux_mutex); mutex_unlock(&firesat->demux_mutex);
...@@ -68,7 +68,7 @@ static int firesat_channel_release(struct firesat *firesat, ...@@ -68,7 +68,7 @@ static int firesat_channel_release(struct firesat *firesat,
if (mutex_lock_interruptible(&firesat->demux_mutex)) if (mutex_lock_interruptible(&firesat->demux_mutex))
return -EINTR; return -EINTR;
channel->active = 0; channel->active = false;
mutex_unlock(&firesat->demux_mutex); mutex_unlock(&firesat->demux_mutex);
return 0; return 0;
...@@ -81,8 +81,6 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -81,8 +81,6 @@ 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);
switch (dvbdmxfeed->type) { switch (dvbdmxfeed->type) {
case DMX_TYPE_TS: case DMX_TYPE_TS:
case DMX_TYPE_SEC: case DMX_TYPE_SEC:
...@@ -102,7 +100,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -102,7 +100,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
case DMX_TS_PES_OTHER: case DMX_TS_PES_OTHER:
//Dirty fix to keep firesat->channel pid-list up to date //Dirty fix to keep firesat->channel pid-list up to date
for(k=0;k<16;k++){ for(k=0;k<16;k++){
if(firesat->channel[k].active == 0) if (!firesat->channel[k].active)
firesat->channel[k].pid = firesat->channel[k].pid =
dvbdmxfeed->pid; dvbdmxfeed->pid;
break; break;
...@@ -124,11 +122,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -124,11 +122,7 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
} }
dvbdmxfeed->priv = channel; dvbdmxfeed->priv = channel;
channel->dvbdmxfeed = dvbdmxfeed;
channel->pid = dvbdmxfeed->pid; channel->pid = dvbdmxfeed->pid;
channel->type = dvbdmxfeed->type;
channel->firesat = firesat;
if (firesat_channel_collect(firesat, &pidc, pids)) { if (firesat_channel_collect(firesat, &pidc, pids)) {
firesat_channel_release(firesat, channel); firesat_channel_release(firesat, channel);
...@@ -136,16 +130,17 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -136,16 +130,17 @@ int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed)
return -EINTR; return -EINTR;
} }
if(dvbdmxfeed->pid == 8192) { if (dvbdmxfeed->pid == 8192) {
if((k = AVCTuner_GetTS(firesat))) { k = avc_tuner_get_ts(firesat);
if (k) {
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 { k = avc_tuner_set_pids(firesat, pidc, pids);
if((k = AVCTuner_SetPIDs(firesat, pidc, pids))) { if (k) {
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);
...@@ -164,8 +159,6 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -164,8 +159,6 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
int k, l; int k, l;
u16 pids[16]; u16 pids[16];
//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))) {
...@@ -177,7 +170,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -177,7 +170,7 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
return -EINVAL; return -EINVAL;
demux->pids[dvbdmxfeed->pes_type] |= 0x8000; demux->pids[dvbdmxfeed->pes_type] |= 0x8000;
demux->pesfilter[dvbdmxfeed->pes_type] = 0; demux->pesfilter[dvbdmxfeed->pes_type] = NULL;
} }
if (!(dvbdmxfeed->ts_type & TS_DECODER && if (!(dvbdmxfeed->ts_type & TS_DECODER &&
...@@ -191,118 +184,93 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) ...@@ -191,118 +184,93 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
/* list except channel to be removed */ /* list except channel to be removed */
for (k = 0, l = 0; k < 16; k++) for (k = 0, l = 0; k < 16; k++)
if (firesat->channel[k].active == 1) { if (firesat->channel[k].active) {
if (&firesat->channel[k] != c) if (&firesat->channel[k] != c)
pids[l++] = firesat->channel[k].pid; pids[l++] = firesat->channel[k].pid;
else else
firesat->channel[k].active = 0; firesat->channel[k].active = false;
} }
k = AVCTuner_SetPIDs(firesat, l, pids); k = avc_tuner_set_pids(firesat, l, pids);
if (!k) if (!k)
c->active = 0; c->active = false;
mutex_unlock(&firesat->demux_mutex); mutex_unlock(&firesat->demux_mutex);
return k; return k;
} }
int firesat_dvbdev_init(struct firesat *firesat, int firesat_dvbdev_init(struct firesat *firesat, struct device *dev)
struct device *dev,
struct dvb_frontend *fe)
{ {
int result; int err;
firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL);
if (!firesat->adapter) {
printk(KERN_ERR "firedtv: couldn't allocate memory\n");
return -ENOMEM;
}
result = DVB_REGISTER_ADAPTER(firesat->adapter,
firedtv_model_names[firesat->type],
THIS_MODULE, dev, adapter_nr);
if (result < 0) {
printk(KERN_ERR "firedtv: dvb_register_adapter failed\n");
kfree(firesat->adapter);
return result;
}
memset(&firesat->demux, 0, sizeof(struct dvb_demux));
firesat->demux.dmx.capabilities = 0/*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/;
firesat->demux.priv = (void *)firesat;
firesat->demux.filternum = 16;
firesat->demux.feednum = 16;
firesat->demux.start_feed = firesat_start_feed;
firesat->demux.stop_feed = firesat_stop_feed;
firesat->demux.write_to_decoder = NULL;
if ((result = dvb_dmx_init(&firesat->demux)) < 0) { err = DVB_REGISTER_ADAPTER(&firesat->adapter,
printk("%s: dvb_dmx_init failed: error %d\n", __func__, firedtv_model_names[firesat->type],
result); THIS_MODULE, dev, adapter_nr);
if (err)
goto fail_log;
dvb_unregister_adapter(firesat->adapter); /*DMX_TS_FILTERING | DMX_SECTION_FILTERING*/
firesat->demux.dmx.capabilities = 0;
return result; firesat->demux.priv = (void *)firesat;
} firesat->demux.filternum = 16;
firesat->demux.feednum = 16;
firesat->dmxdev.filternum = 16; firesat->demux.start_feed = firesat_start_feed;
firesat->dmxdev.demux = &firesat->demux.dmx; firesat->demux.stop_feed = firesat_stop_feed;
firesat->dmxdev.capabilities = 0; firesat->demux.write_to_decoder = NULL;
if ((result = dvb_dmxdev_init(&firesat->dmxdev, firesat->adapter)) < 0) {
printk("%s: dvb_dmxdev_init failed: error %d\n",
__func__, result);
dvb_dmx_release(&firesat->demux); err = dvb_dmx_init(&firesat->demux);
dvb_unregister_adapter(firesat->adapter); if (err)
goto fail_unreg_adapter;
return result; firesat->dmxdev.filternum = 16;
} firesat->dmxdev.demux = &firesat->demux.dmx;
firesat->dmxdev.capabilities = 0;
firesat->frontend.source = DMX_FRONTEND_0; err = dvb_dmxdev_init(&firesat->dmxdev, &firesat->adapter);
if (err)
goto fail_dmx_release;
if ((result = firesat->demux.dmx.add_frontend(&firesat->demux.dmx, firesat->frontend.source = DMX_FRONTEND_0;
&firesat->frontend)) < 0) {
printk("%s: dvb_dmx_init failed: error %d\n", __func__,
result);
dvb_dmxdev_release(&firesat->dmxdev); err = firesat->demux.dmx.add_frontend(&firesat->demux.dmx,
dvb_dmx_release(&firesat->demux); &firesat->frontend);
dvb_unregister_adapter(firesat->adapter); if (err)
goto fail_dmxdev_release;
return result; err = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx,
} &firesat->frontend);
if (err)
goto fail_rem_frontend;
if ((result = firesat->demux.dmx.connect_frontend(&firesat->demux.dmx, dvb_net_init(&firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx);
&firesat->frontend)) < 0) {
printk("%s: dvb_dmx_init failed: error %d\n", __func__,
result);
firesat->demux.dmx.remove_frontend(&firesat->demux.dmx, &firesat->frontend); firesat_frontend_init(firesat);
dvb_dmxdev_release(&firesat->dmxdev); err = dvb_register_frontend(&firesat->adapter, &firesat->fe);
dvb_dmx_release(&firesat->demux); if (err)
dvb_unregister_adapter(firesat->adapter); goto fail_net_release;
return result; err = firesat_ca_register(firesat);
} if (err)
dev_info(dev, "Conditional Access Module not enabled\n");
dvb_net_init(firesat->adapter, &firesat->dvbnet, &firesat->demux.dmx); return 0;
// fe->ops = firesat_ops;
// fe->dvb = firesat->adapter;
firesat_frontend_attach(firesat, fe);
fe->sec_priv = firesat; //IMPORTANT, functions depend on this!!!
if ((result= dvb_register_frontend(firesat->adapter, fe)) < 0) {
printk("%s: dvb_register_frontend_new failed: error %d\n", __func__, result);
/* ### cleanup */
return result;
}
firesat_ca_init(firesat);
return 0; fail_net_release:
dvb_net_release(&firesat->dvbnet);
firesat->demux.dmx.close(&firesat->demux.dmx);
fail_rem_frontend:
firesat->demux.dmx.remove_frontend(&firesat->demux.dmx,
&firesat->frontend);
fail_dmxdev_release:
dvb_dmxdev_release(&firesat->dmxdev);
fail_dmx_release:
dvb_dmx_release(&firesat->demux);
fail_unreg_adapter:
dvb_unregister_adapter(&firesat->adapter);
fail_log:
dev_err(dev, "DVB initialization failed\n");
return err;
} }
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/string.h>
#include <linux/types.h> #include <linux/types.h>
#include <dvb_frontend.h> #include <dvb_frontend.h>
...@@ -22,22 +23,21 @@ ...@@ -22,22 +23,21 @@
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"); int err;
firesat->isochannel = firesat->adapter->num; //<< 1 | (firesat->subunit & 0x1); // ### ask IRM
// printk("fdi: 2\n"); /* FIXME - allocate free channel at IRM */
result = try_CMPEstablishPPconnection(firesat, firesat->subunit, firesat->isochannel); firesat->isochannel = firesat->adapter.num;
if (result != 0) {
err = cmp_establish_pp_connection(firesat, firesat->subunit,
firesat->isochannel);
if (err) {
printk(KERN_ERR "Could not establish point to point " printk(KERN_ERR "Could not establish point to point "
"connection.\n"); "connection.\n");
return -1; return err;
} }
// printk("fdi: 3\n");
result = setup_iso_channel(firesat); return 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)
...@@ -45,7 +45,7 @@ static int firesat_sleep(struct dvb_frontend *fe) ...@@ -45,7 +45,7 @@ static int firesat_sleep(struct dvb_frontend *fe)
struct firesat *firesat = fe->sec_priv; struct firesat *firesat = fe->sec_priv;
tear_down_iso_channel(firesat); tear_down_iso_channel(firesat);
try_CMPBreakPPconnection(firesat, firesat->subunit, firesat->isochannel); cmp_break_pp_connection(firesat, firesat->subunit, firesat->isochannel);
firesat->isochannel = -1; firesat->isochannel = -1;
return 0; return 0;
} }
...@@ -55,8 +55,8 @@ static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe, ...@@ -55,8 +55,8 @@ static int firesat_diseqc_send_master_cmd(struct dvb_frontend *fe,
{ {
struct firesat *firesat = fe->sec_priv; struct firesat *firesat = fe->sec_priv;
return AVCLNBControl(firesat, LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, return avc_lnb_control(firesat, LNBCONTROL_DONTCARE,
LNBCONTROL_DONTCARE, 1, cmd); LNBCONTROL_DONTCARE, LNBCONTROL_DONTCARE, 1, cmd);
} }
static int firesat_diseqc_send_burst(struct dvb_frontend *fe, static int firesat_diseqc_send_burst(struct dvb_frontend *fe,
...@@ -82,24 +82,19 @@ static int firesat_set_voltage(struct dvb_frontend *fe, ...@@ -82,24 +82,19 @@ static int firesat_set_voltage(struct dvb_frontend *fe,
return 0; return 0;
} }
static int firesat_read_status (struct dvb_frontend *fe, fe_status_t *status) static int firesat_read_status(struct dvb_frontend *fe, fe_status_t *status)
{ {
struct firesat *firesat = fe->sec_priv; struct firesat *firesat = fe->sec_priv;
ANTENNA_INPUT_INFO info; ANTENNA_INPUT_INFO info;
if (AVCTunerStatus(firesat, &info)) if (avc_tuner_status(firesat, &info))
return -EINVAL; return -EINVAL;
if (info.NoRF) { if (info.NoRF)
*status = 0; *status = 0;
} else { else
*status = FE_HAS_SIGNAL | *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC |
FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_LOCK;
FE_HAS_SYNC |
FE_HAS_CARRIER |
FE_HAS_LOCK;
}
return 0; return 0;
} }
...@@ -108,14 +103,11 @@ static int firesat_read_ber(struct dvb_frontend *fe, u32 *ber) ...@@ -108,14 +103,11 @@ 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;
if (AVCTunerStatus(firesat, &info)) if (avc_tuner_status(firesat, &info))
return -EINVAL; return -EINVAL;
*ber = (info.BER[0] << 24) | *ber = info.BER[0] << 24 | info.BER[1] << 16 |
(info.BER[1] << 16) | info.BER[2] << 8 | info.BER[3];
(info.BER[2] << 8) |
info.BER[3];
return 0; return 0;
} }
...@@ -124,11 +116,10 @@ static int firesat_read_signal_strength (struct dvb_frontend *fe, u16 *strength) ...@@ -124,11 +116,10 @@ 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;
if (AVCTunerStatus(firesat, &info)) if (avc_tuner_status(firesat, &info))
return -EINVAL; return -EINVAL;
*strength = info.SignalStrength << 8; *strength = info.SignalStrength << 8;
return 0; return 0;
} }
...@@ -137,14 +128,12 @@ static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr) ...@@ -137,14 +128,12 @@ static int firesat_read_snr(struct dvb_frontend *fe, u16 *snr)
struct firesat *firesat = fe->sec_priv; struct firesat *firesat = fe->sec_priv;
ANTENNA_INPUT_INFO info; ANTENNA_INPUT_INFO info;
if (AVCTunerStatus(firesat, &info)) if (avc_tuner_status(firesat, &info))
return -EINVAL; return -EINVAL;
*snr = (info.CarrierNoiseRatio[0] << 8) + /* C/N[dB] = -10 * log10(snr / 65535) */
info.CarrierNoiseRatio[1]; *snr = (info.CarrierNoiseRatio[0] << 8) + info.CarrierNoiseRatio[1];
*snr *= 257; *snr *= 257;
// C/N[dB] = -10 * log10(snr / 65535)
return 0; return 0;
} }
...@@ -158,10 +147,11 @@ static int firesat_set_frontend(struct dvb_frontend *fe, ...@@ -158,10 +147,11 @@ static int firesat_set_frontend(struct dvb_frontend *fe,
{ {
struct firesat *firesat = fe->sec_priv; struct firesat *firesat = fe->sec_priv;
if (AVCTuner_DSD(firesat, params, NULL) != ACCEPTED) /* FIXME: avc_tuner_dsd never returns ACCEPTED. Check status? */
if (avc_tuner_dsd(firesat, params) != ACCEPTED)
return -EINVAL; return -EINVAL;
else else
return 0; //not sure of this... return 0; /* not sure of this... */
} }
static int firesat_get_frontend(struct dvb_frontend *fe, static int firesat_get_frontend(struct dvb_frontend *fe,
...@@ -170,107 +160,86 @@ static int firesat_get_frontend(struct dvb_frontend *fe, ...@@ -170,107 +160,86 @@ static int firesat_get_frontend(struct dvb_frontend *fe,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static struct dvb_frontend_info firesat_S_frontend_info; void firesat_frontend_init(struct firesat *firesat)
static struct dvb_frontend_info firesat_C_frontend_info; {
static struct dvb_frontend_info firesat_T_frontend_info; struct dvb_frontend_ops *ops = &firesat->fe.ops;
struct dvb_frontend_info *fi = &ops->info;
static struct dvb_frontend_ops firesat_ops = {
.init = firesat_dvb_init, ops->init = firesat_dvb_init;
.sleep = firesat_sleep, ops->sleep = firesat_sleep;
.set_frontend = firesat_set_frontend, ops->set_frontend = firesat_set_frontend;
.get_frontend = firesat_get_frontend, ops->get_frontend = firesat_get_frontend;
.read_status = firesat_read_status, ops->read_status = firesat_read_status;
.read_ber = firesat_read_ber, ops->read_ber = firesat_read_ber;
.read_signal_strength = firesat_read_signal_strength, ops->read_signal_strength = firesat_read_signal_strength;
.read_snr = firesat_read_snr, ops->read_snr = firesat_read_snr;
.read_ucblocks = firesat_read_uncorrected_blocks, ops->read_ucblocks = firesat_read_uncorrected_blocks;
.diseqc_send_master_cmd = firesat_diseqc_send_master_cmd, ops->diseqc_send_master_cmd = firesat_diseqc_send_master_cmd;
.diseqc_send_burst = firesat_diseqc_send_burst, ops->diseqc_send_burst = firesat_diseqc_send_burst;
.set_tone = firesat_set_tone, ops->set_tone = firesat_set_tone;
.set_voltage = firesat_set_voltage, ops->set_voltage = firesat_set_voltage;
};
int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe)
{
switch (firesat->type) { switch (firesat->type) {
case FireSAT_DVB_S: case FireSAT_DVB_S:
firesat->frontend_info = &firesat_S_frontend_info; fi->type = FE_QPSK;
fi->frequency_min = 950000;
fi->frequency_max = 2150000;
fi->frequency_stepsize = 125;
fi->symbol_rate_min = 1000000;
fi->symbol_rate_max = 40000000;
fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK;
break; break;
case FireSAT_DVB_C: case FireSAT_DVB_C:
firesat->frontend_info = &firesat_C_frontend_info; fi->type = FE_QAM;
fi->frequency_min = 47000000;
fi->frequency_max = 866000000;
fi->frequency_stepsize = 62500;
fi->symbol_rate_min = 870000;
fi->symbol_rate_max = 6900000;
fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO;
break; break;
case FireSAT_DVB_T: case FireSAT_DVB_T:
firesat->frontend_info = &firesat_T_frontend_info; fi->type = FE_OFDM;
fi->frequency_min = 49000000;
fi->frequency_max = 861000000;
fi->frequency_stepsize = 62500;
fi->caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_2_3 |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO;
break; break;
default: default:
printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", printk(KERN_ERR "FireDTV: no frontend for model type %d\n",
firesat->type); firesat->type);
firesat->frontend_info = NULL;
} }
fe->ops = firesat_ops; strcpy(fi->name, firedtv_model_names[firesat->type]);
fe->ops.info = *(firesat->frontend_info);
fe->dvb = firesat->adapter;
return 0; firesat->fe.dvb = &firesat->adapter;
firesat->fe.sec_priv = firesat;
} }
static struct dvb_frontend_info firesat_S_frontend_info = {
.name = "FireDTV DVB-S Frontend",
.type = FE_QPSK,
.frequency_min = 950000,
.frequency_max = 2150000,
.frequency_stepsize = 125,
.symbol_rate_min = 1000000,
.symbol_rate_max = 40000000,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_1_2 |
FE_CAN_FEC_2_3 |
FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 |
FE_CAN_FEC_7_8 |
FE_CAN_FEC_AUTO |
FE_CAN_QPSK,
};
static struct dvb_frontend_info firesat_C_frontend_info = {
.name = "FireDTV DVB-C Frontend",
.type = FE_QAM,
.frequency_min = 47000000,
.frequency_max = 866000000,
.frequency_stepsize = 62500,
.symbol_rate_min = 870000,
.symbol_rate_max = 6900000,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_QAM_16 |
FE_CAN_QAM_32 |
FE_CAN_QAM_64 |
FE_CAN_QAM_128 |
FE_CAN_QAM_256 |
FE_CAN_QAM_AUTO,
};
static struct dvb_frontend_info firesat_T_frontend_info = {
.name = "FireDTV DVB-T Frontend",
.type = FE_OFDM,
.frequency_min = 49000000,
.frequency_max = 861000000,
.frequency_stepsize = 62500,
.caps = FE_CAN_INVERSION_AUTO |
FE_CAN_FEC_2_3 |
FE_CAN_TRANSMISSION_MODE_AUTO |
FE_CAN_GUARD_INTERVAL_AUTO |
FE_CAN_HIERARCHY_AUTO,
};
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <dma.h> #include <dma.h>
#include <iso.h> #include <iso.h>
#include <nodemgr.h>
#include "firesat.h" #include "firesat.h"
...@@ -36,7 +37,7 @@ int setup_iso_channel(struct firesat *firesat) ...@@ -36,7 +37,7 @@ int setup_iso_channel(struct firesat *firesat)
{ {
int result; int result;
firesat->iso_handle = firesat->iso_handle =
hpsb_iso_recv_init(firesat->host, hpsb_iso_recv_init(firesat->ud->ne->host,
256 * 200, //data_buf_size, 256 * 200, //data_buf_size,
256, //buf_packets, 256, //buf_packets,
firesat->isochannel, firesat->isochannel,
...@@ -59,7 +60,6 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) ...@@ -59,7 +60,6 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
{ {
unsigned int num; unsigned int num;
unsigned int i; unsigned int i;
/* unsigned int j; */
unsigned int packet; unsigned int packet;
unsigned long flags; unsigned long flags;
struct firesat *firesat = NULL; struct firesat *firesat = NULL;
...@@ -88,12 +88,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso) ...@@ -88,12 +88,7 @@ static void rawiso_activity_cb(struct hpsb_iso *iso)
(188 + sizeof(struct firewireheader)); (188 + sizeof(struct firewireheader));
if (iso->infos[packet].len <= sizeof(struct CIPHeader)) if (iso->infos[packet].len <= sizeof(struct CIPHeader))
continue; // ignore empty packet 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 --) { while (count --) {
if (buf[sizeof(struct firewireheader)] == 0x47) if (buf[sizeof(struct firewireheader)] == 0x47)
dvb_dmx_swfilter_packets(&firesat->demux, dvb_dmx_swfilter_packets(&firesat->demux,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment