diff options
Diffstat (limited to 'drivers/media/dvb/firesat')
-rw-r--r-- | drivers/media/dvb/firesat/Kconfig | 13 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/Makefile | 4 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/avc_api.c | 121 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/avc_api.h | 115 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/cmp.c | 99 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/cmp.h | 14 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat-ci.c | 16 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat-ci.h | 8 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat-rc.c | 147 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat-rc.h | 13 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat.h | 78 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_1394.c | 164 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_dvb.c | 147 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_fe.c | 41 | ||||
-rw-r--r-- | drivers/media/dvb/firesat/firesat_iso.c | 12 |
15 files changed, 467 insertions, 525 deletions
diff --git a/drivers/media/dvb/firesat/Kconfig b/drivers/media/dvb/firesat/Kconfig index 93f8de5..03d25ad 100644 --- a/drivers/media/dvb/firesat/Kconfig +++ b/drivers/media/dvb/firesat/Kconfig @@ -1,11 +1,12 @@ -config DVB_FIRESAT - tristate "FireSAT devices" +config DVB_FIREDTV + tristate "FireDTV (FireWire attached DVB receivers)" depends on DVB_CORE && IEEE1394 && INPUT help - Support for external IEEE1394 adapters designed by Digital Everywhere and - produced by El Gato, shipped under the brand name 'FireDTV/FloppyDTV'. + Support for DVB receivers from Digital Everywhere, known as FireDTV + and FloppyDTV, which are connected via IEEE 1394 (FireWire). - These devices don't have a MPEG decoder built in, so you need + These devices don't have an MPEG decoder built in, so you need an external software decoder to watch TV. - Say Y if you own such a device and want to use it. + To compile this driver as a module, say M here: the module will be + called firedtv. diff --git a/drivers/media/dvb/firesat/Makefile b/drivers/media/dvb/firesat/Makefile index be7701b..9e49edc 100644 --- a/drivers/media/dvb/firesat/Makefile +++ b/drivers/media/dvb/firesat/Makefile @@ -1,4 +1,4 @@ -firesat-objs := firesat_1394.o \ +firedtv-objs := firesat_1394.o \ firesat_dvb.o \ firesat_fe.o \ firesat_iso.o \ @@ -7,7 +7,7 @@ firesat-objs := firesat_1394.o \ firesat-rc.o \ firesat-ci.o -obj-$(CONFIG_DVB_FIRESAT) += firesat.o +obj-$(CONFIG_DVB_FIREDTV) += firedtv.o EXTRA_CFLAGS := -Idrivers/ieee1394 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core diff --git a/drivers/media/dvb/firesat/avc_api.c b/drivers/media/dvb/firesat/avc_api.c index 3c8e7e3..6337f9f 100644 --- a/drivers/media/dvb/firesat/avc_api.c +++ b/drivers/media/dvb/firesat/avc_api.c @@ -1,9 +1,9 @@ /* - * FireSAT AVC driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com> - * Copyright (c) 2008 Ben Backx <ben@bbackx.com> - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.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 * modify it under the terms of the GNU General Public License as @@ -11,13 +11,20 @@ * the License, or (at your option) any later version. */ -#include "firesat.h" +#include <linux/crc32.h> +#include <linux/delay.h> +#include <linux/kernel.h> +#include <linux/moduleparam.h> +#include <linux/mutex.h> +#include <linux/wait.h> +#include <linux/workqueue.h> +#include <asm/atomic.h> + #include <ieee1394_transactions.h> #include <nodemgr.h> -#include <asm/byteorder.h> -#include <linux/delay.h> -#include <linux/crc32.h> + #include "avc_api.h" +#include "firesat.h" #include "firesat-rc.h" #define RESPONSE_REGISTER 0xFFFFF0000D00ULL @@ -28,8 +35,6 @@ static unsigned int avc_comm_debug = 0; module_param(avc_comm_debug, int, 0644); MODULE_PARM_DESC(avc_comm_debug, "debug logging level [0..2] of AV/C communication, default is 0 (no)"); -static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal); - /* Frees an allocated packet */ static void avc_free_packet(struct hpsb_packet *packet) { @@ -232,67 +237,39 @@ static int __AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, return 0; } -int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) { +int AVCWrite(struct firesat*firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm) +{ int ret; - if(down_interruptible(&firesat->avc_sem)) + + if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; ret = __AVCWrite(firesat, CmdFrm, RspFrm); - up(&firesat->avc_sem); + mutex_unlock(&firesat->avc_mutex); return ret; } -static void do_schedule_remotecontrol(unsigned long ignored); -DECLARE_TASKLET(schedule_remotecontrol, do_schedule_remotecontrol, 0); - -static void do_schedule_remotecontrol(unsigned long ignored) { - struct firesat *firesat; - unsigned long flags; - - spin_lock_irqsave(&firesat_list_lock, flags); - list_for_each_entry(firesat,&firesat_list,list) { - if(atomic_read(&firesat->reschedule_remotecontrol) == 1) { - if(down_trylock(&firesat->avc_sem)) - tasklet_schedule(&schedule_remotecontrol); - else { - if(__AVCRegisterRemoteControl(firesat, 1) == 0) - atomic_set(&firesat->reschedule_remotecontrol, 0); - else - tasklet_schedule(&schedule_remotecontrol); - - up(&firesat->avc_sem); - } +int AVCRecv(struct firesat *firesat, u8 *data, size_t length) +{ + AVCRspFrm *RspFrm = (AVCRspFrm *)data; + + if (length >= 8 && + RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && + RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && + RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2 && + RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { + if (RspFrm->resp == CHANGED) { + firesat_handle_rc(RspFrm->operand[4] << 8 | + RspFrm->operand[5]); + schedule_work(&firesat->remote_ctrl_work); + } else if (RspFrm->resp != INTERIM) { + printk(KERN_INFO "firedtv: remote control result = " + "%d\n", RspFrm->resp); } - } - spin_unlock_irqrestore(&firesat_list_lock, flags); -} - -int AVCRecv(struct firesat *firesat, u8 *data, size_t length) { -// printk(KERN_INFO "%s\n",__func__); - - // remote control handling - -#if 0 - AVCRspFrm *RspFrm = (AVCRspFrm*)data; - - if(/*RspFrm->length >= 8 && ###*/ - ((RspFrm->operand[0] == SFE_VENDOR_DE_COMPANYID_0 && - RspFrm->operand[1] == SFE_VENDOR_DE_COMPANYID_1 && - RspFrm->operand[2] == SFE_VENDOR_DE_COMPANYID_2)) && - RspFrm->operand[3] == SFE_VENDOR_OPCODE_REGISTER_REMOTE_CONTROL) { - if(RspFrm->resp == CHANGED) { -// printk(KERN_INFO "%s: code = %02x %02x\n",__func__,RspFrm->operand[4],RspFrm->operand[5]); - firesat_got_remotecontrolcode((((u16)RspFrm->operand[4]) << 8) | ((u16)RspFrm->operand[5])); - - // schedule - atomic_set(&firesat->reschedule_remotecontrol, 1); - tasklet_schedule(&schedule_remotecontrol); - } else if(RspFrm->resp != INTERIM) - printk(KERN_INFO "%s: remote control result = %d\n",__func__, RspFrm->resp); return 0; } -#endif + if(atomic_read(&firesat->avc_reply_received) == 1) { printk(KERN_ERR "%s: received out-of-order AVC response, " "ignored\n",__func__); @@ -718,7 +695,8 @@ int AVCTuner_GetTS(struct firesat *firesat){ return 0; } -int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *transport) { +int AVCIdentifySubunit(struct firesat *firesat) +{ AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -752,8 +730,6 @@ int AVCIdentifySubunit(struct firesat *firesat, unsigned char *systemId, int *tr printk(KERN_ERR "%s: Invalid response length\n", __func__); return -EINVAL; } - if(systemId) - *systemId = RspFrm.operand[7]; return 0; } @@ -901,7 +877,7 @@ int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount) return 0; } -static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal) +int AVCRegisterRemoteControl(struct firesat *firesat) { AVCCmdFrm CmdFrm; @@ -922,19 +898,16 @@ static int __AVCRegisterRemoteControl(struct firesat*firesat, int internal) CmdFrm.length = 8; - if(internal) { - if(__AVCWrite(firesat,&CmdFrm,NULL) < 0) - return -EIO; - } else - if(AVCWrite(firesat,&CmdFrm,NULL) < 0) - return -EIO; - - return 0; + return AVCWrite(firesat, &CmdFrm, NULL); } -int AVCRegisterRemoteControl(struct firesat*firesat) +void avc_remote_ctrl_work(struct work_struct *work) { - return __AVCRegisterRemoteControl(firesat, 0); + struct firesat *firesat = + container_of(work, struct firesat, remote_ctrl_work); + + /* Should it be rescheduled in failure cases? */ + AVCRegisterRemoteControl(firesat); } int AVCTuner_Host2Ca(struct firesat *firesat) diff --git a/drivers/media/dvb/firesat/avc_api.h b/drivers/media/dvb/firesat/avc_api.h index 0416656..66f419a 100644 --- a/drivers/media/dvb/firesat/avc_api.h +++ b/drivers/media/dvb/firesat/avc_api.h @@ -1,32 +1,25 @@ -/*************************************************************************** - avc_api.h - description - ------------------- - begin : Wed May 1 2000 - copyright : (C) 2000 by Manfred Weihs - copyright : (C) 2003 by Philipp Gutgsell - copyright : (C) 2008 by Henrik Kurelid (henrik@kurelid.se) - email : 0014guph@edu.fh-kaernten.ac.at - ***************************************************************************/ - -/*************************************************************************** - * * - * 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. * - * * - ***************************************************************************/ - /* - This is based on code written by Peter Halwachs, - Thomas Groiss and Andreas Monitzer. -*/ - - -#ifndef __AVC_API_H__ -#define __AVC_API_H__ - -#include <linux/dvb/frontend.h> + * AV/C API + * + * Copyright (C) 2000 Manfred Weihs + * Copyright (C) 2003 Philipp Gutgsell <0014guph@edu.fh-kaernten.ac.at> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * Copyright (C) 2008 Ben Backx <ben@bbackx.com> + * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se> + * + * This is based on code written by Peter Halwachs, Thomas Groiss and + * Andreas Monitzer. + * + * 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 _AVC_API_H +#define _AVC_API_H + +#include <linux/types.h> /************************************************************* Constants from EN510221 @@ -416,34 +409,38 @@ typedef struct #define LNBCONTROL_DONTCARE 0xff - -extern int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, AVCRspFrm *RspFrm); -extern int AVCRecv(struct firesat *firesat, u8 *data, size_t length); - -extern int AVCTuner_DSIT(struct firesat *firesat, - int Source_Plug, - struct dvb_frontend_parameters *params, - __u8 *status); - -extern int AVCTunerStatus(struct firesat *firesat, ANTENNA_INPUT_INFO *antenna_input_info); -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_GetTS(struct firesat *firesat); - -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 AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); -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 - +struct dvb_diseqc_master_cmd; +struct dvb_frontend_parameters; +struct firesat; + +int AVCWrite(struct firesat *firesat, const AVCCmdFrm *CmdFrm, + AVCRspFrm *RspFrm); +int AVCRecv(struct firesat *firesat, u8 *data, size_t length); + +int AVCTuner_DSIT(struct firesat *firesat, int Source_Plug, + struct dvb_frontend_parameters *params, __u8 *status); + +int AVCTunerStatus(struct firesat *firesat, + ANTENNA_INPUT_INFO *antenna_input_info); +int AVCTuner_DSD(struct firesat *firesat, + struct dvb_frontend_parameters *params, __u8 *status); +int AVCTuner_SetPIDs(struct firesat *firesat, unsigned char pidc, u16 pid[]); +int AVCTuner_GetTS(struct firesat *firesat); + +int AVCIdentifySubunit(struct firesat *firesat); +int AVCLNBControl(struct firesat *firesat, char voltage, char burst, + char conttone, char nrdiseq, + struct dvb_diseqc_master_cmd *diseqcmd); +int AVCSubUnitInfo(struct firesat *firesat, char *subunitcount); +void avc_remote_ctrl_work(struct work_struct *work); +int AVCRegisterRemoteControl(struct firesat *firesat); +int AVCTuner_Host2Ca(struct firesat *firesat); +int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); +int avc_ca_info(struct firesat *firesat, char *app_info, int *length); +int avc_ca_reset(struct firesat *firesat); +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_enter_menu(struct firesat *firesat); +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); + +#endif /* _AVC_API_H */ diff --git a/drivers/media/dvb/firesat/cmp.c b/drivers/media/dvb/firesat/cmp.c index a1291caa..d1bafba 100644 --- a/drivers/media/dvb/firesat/cmp.c +++ b/drivers/media/dvb/firesat/cmp.c @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * 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 @@ -10,15 +10,19 @@ * the License, or (at your option) any later version. */ -#include "cmp.h" -#include <ieee1394.h> -#include <nodemgr.h> -#include <highlevel.h> -#include <ohci1394.h> +#include <linux/kernel.h> +#include <linux/mutex.h> +#include <linux/types.h> + #include <hosts.h> +#include <ieee1394.h> #include <ieee1394_core.h> #include <ieee1394_transactions.h> +#include <nodemgr.h> + #include "avc_api.h" +#include "cmp.h" +#include "firesat.h" typedef struct _OPCR { @@ -38,63 +42,33 @@ typedef struct _OPCR #define FIRESAT_SPEED IEEE1394_SPEED_400 -/* hpsb_lock is being removed from the kernel-source, - * therefor we define our own 'firesat_hpsb_lock'*/ - -int send_packet_and_wait(struct hpsb_packet *packet); - -int firesat_hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, - u64 addr, int extcode, quadlet_t * data, quadlet_t arg) { - - struct hpsb_packet *packet; - int retval = 0; - - BUG_ON(in_interrupt()); // We can't be called in an interrupt, yet - - packet = hpsb_make_lockpacket(host, node, addr, extcode, data, arg); - if (!packet) - return -ENOMEM; - - packet->generation = generation; - retval = send_packet_and_wait(packet); - if (retval < 0) - goto hpsb_lock_fail; - - retval = hpsb_packet_success(packet); - - if (retval == 0) { - *data = packet->data[0]; - } - - hpsb_lock_fail: - hpsb_free_tlabel(packet); - hpsb_free_packet(packet); - - return retval; -} - - -static int cmp_read(struct firesat *firesat, void *buffer, u64 addr, size_t length) { +static int cmp_read(struct firesat *firesat, void *buf, u64 addr, size_t len) +{ int ret; - if(down_interruptible(&firesat->avc_sem)) + + if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation, - addr, buffer, length); + ret = hpsb_read(firesat->host, firesat->nodeentry->nodeid, + firesat->nodeentry->generation, addr, buf, len); - up(&firesat->avc_sem); + mutex_unlock(&firesat->avc_mutex); return ret; } -static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, quadlet_t arg, int ext_tcode) { +static int cmp_lock(struct firesat *firesat, quadlet_t *data, u64 addr, + quadlet_t arg, int ext_tcode) +{ int ret; - if(down_interruptible(&firesat->avc_sem)) + + if (mutex_lock_interruptible(&firesat->avc_mutex)) return -EINTR; - ret = firesat_hpsb_lock(firesat->host, firesat->nodeentry->nodeid, firesat->nodeentry->generation, - addr, ext_tcode, data, arg); + ret = hpsb_lock(firesat->host, firesat->nodeentry->nodeid, + firesat->nodeentry->generation, + addr, ext_tcode, data, arg); - up(&firesat->avc_sem); + mutex_unlock(&firesat->avc_mutex); return ret; } @@ -223,20 +197,3 @@ int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_ch } return 0; } - -static void complete_packet(void *data) { - complete((struct completion *) data); -} - -int send_packet_and_wait(struct hpsb_packet *packet) { - struct completion done; - int retval; - - init_completion(&done); - hpsb_set_packet_complete_task(packet, complete_packet, &done); - retval = hpsb_send_packet(packet); - if (retval == 0) - wait_for_completion(&done); - - return retval; -} diff --git a/drivers/media/dvb/firesat/cmp.h b/drivers/media/dvb/firesat/cmp.h index d43fbc2..600d578 100644 --- a/drivers/media/dvb/firesat/cmp.h +++ b/drivers/media/dvb/firesat/cmp.h @@ -1,9 +1,11 @@ -#ifndef __FIRESAT__CMP_H_ -#define __FIRESAT__CMP_H_ +#ifndef _CMP_H +#define _CMP_H -#include "firesat.h" +struct firesat; -extern int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, int iso_channel); -extern int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug,int iso_channel); +int try_CMPEstablishPPconnection(struct firesat *firesat, int output_plug, + int iso_channel); +int try_CMPBreakPPconnection(struct firesat *firesat, int output_plug, + int iso_channel); -#endif +#endif /* _CMP_H */ diff --git a/drivers/media/dvb/firesat/firesat-ci.c b/drivers/media/dvb/firesat/firesat-ci.c index 821048d..3ef25cc 100644 --- a/drivers/media/dvb/firesat/firesat-ci.c +++ b/drivers/media/dvb/firesat/firesat-ci.c @@ -1,7 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * 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 @@ -9,13 +10,16 @@ * the License, or (at your option) any later version. */ -#include "firesat-ci.h" -#include "firesat.h" -#include "avc_api.h" - #include <linux/dvb/ca.h> +#include <linux/fs.h> +#include <linux/module.h> + #include <dvbdev.h> +#include "avc_api.h" +#include "firesat.h" +#include "firesat-ci.h" + 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)"); diff --git a/drivers/media/dvb/firesat/firesat-ci.h b/drivers/media/dvb/firesat/firesat-ci.h index dafe3f0..04fe406 100644 --- a/drivers/media/dvb/firesat/firesat-ci.h +++ b/drivers/media/dvb/firesat/firesat-ci.h @@ -1,9 +1,9 @@ -#ifndef __FIRESAT_CA_H -#define __FIRESAT_CA_H +#ifndef _FIREDTV_CI_H +#define _FIREDTV_CI_H -#include "firesat.h" +struct firesat; int firesat_ca_init(struct firesat *firesat); void firesat_ca_release(struct firesat *firesat); -#endif +#endif /* _FIREDTV_CI_H */ diff --git a/drivers/media/dvb/firesat/firesat-rc.c b/drivers/media/dvb/firesat/firesat-rc.c index e300b81..d3e08f9 100644 --- a/drivers/media/dvb/firesat/firesat-rc.c +++ b/drivers/media/dvb/firesat/firesat-rc.c @@ -1,9 +1,26 @@ -#include "firesat.h" -#include "firesat-rc.h" +/* + * FireDTV driver (formerly known as FireSAT) + * + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * + * 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/bitops.h> #include <linux/input.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include "firesat-rc.h" + +/* fixed table with older keycodes, geared towards MythTV */ +const static u16 oldtable[] = { + + /* code from device: 0x4501...0x451f */ -static u16 firesat_irtable[] = { KEY_ESC, KEY_F9, KEY_1, @@ -35,50 +52,124 @@ static u16 firesat_irtable[] = { KEY_RIGHT, KEY_P, KEY_M, + + /* code from device: 0x4540...0x4542 */ + KEY_R, KEY_V, KEY_C, - 0 }; -static struct input_dev firesat_idev; +/* user-modifiable table for a remote as sold in 2008 */ +static u16 keytable[] = { + + /* code from device: 0x0300...0x031f */ + + [0x00] = KEY_POWER, + [0x01] = KEY_SLEEP, + [0x02] = KEY_STOP, + [0x03] = KEY_OK, + [0x04] = KEY_RIGHT, + [0x05] = KEY_1, + [0x06] = KEY_2, + [0x07] = KEY_3, + [0x08] = KEY_LEFT, + [0x09] = KEY_4, + [0x0a] = KEY_5, + [0x0b] = KEY_6, + [0x0c] = KEY_UP, + [0x0d] = KEY_7, + [0x0e] = KEY_8, + [0x0f] = KEY_9, + [0x10] = KEY_DOWN, + [0x11] = KEY_TITLE, /* "OSD" - fixme */ + [0x12] = KEY_0, + [0x13] = KEY_F20, /* "16:9" - fixme */ + [0x14] = KEY_SCREEN, /* "FULL" - fixme */ + [0x15] = KEY_MUTE, + [0x16] = KEY_SUBTITLE, + [0x17] = KEY_RECORD, + [0x18] = KEY_TEXT, + [0x19] = KEY_AUDIO, + [0x1a] = KEY_RED, + [0x1b] = KEY_PREVIOUS, + [0x1c] = KEY_REWIND, + [0x1d] = KEY_PLAYPAUSE, + [0x1e] = KEY_NEXT, + [0x1f] = KEY_VOLUMEUP, + + /* code from device: 0x0340...0x0354 */ + + [0x20] = KEY_CHANNELUP, + [0x21] = KEY_F21, /* "4:3" - fixme */ + [0x22] = KEY_TV, + [0x23] = KEY_DVD, + [0x24] = KEY_VCR, + [0x25] = KEY_AUX, + [0x26] = KEY_GREEN, + [0x27] = KEY_YELLOW, + [0x28] = KEY_BLUE, + [0x29] = KEY_CHANNEL, /* "CH.LIST" */ + [0x2a] = KEY_VENDOR, /* "CI" - fixme */ + [0x2b] = KEY_VOLUMEDOWN, + [0x2c] = KEY_CHANNELDOWN, + [0x2d] = KEY_LAST, + [0x2e] = KEY_INFO, + [0x2f] = KEY_FORWARD, + [0x30] = KEY_LIST, + [0x31] = KEY_FAVORITES, + [0x32] = KEY_MENU, + [0x33] = KEY_EPG, + [0x34] = KEY_EXIT, +}; + +static struct input_dev *idev; int firesat_register_rc(void) { - int index; + int i, err; + + idev = input_allocate_device(); + if (!idev) + return -ENOMEM; - memset(&firesat_idev, 0, sizeof(firesat_idev)); + idev->name = "FireDTV remote control"; + idev->evbit[0] = BIT_MASK(EV_KEY); + idev->keycode = keytable; + idev->keycodesize = sizeof(keytable[0]); + idev->keycodemax = ARRAY_SIZE(keytable); - firesat_idev.evbit[0] = BIT(EV_KEY); + for (i = 0; i < ARRAY_SIZE(keytable); i++) + set_bit(keytable[i], idev->keybit); - for (index = 0; firesat_irtable[index] != 0; index++) - set_bit(firesat_irtable[index], firesat_idev.keybit); + err = input_register_device(idev); + if (err) + input_free_device(idev); - return input_register_device(&firesat_idev); + return err; } -int firesat_unregister_rc(void) +void firesat_unregister_rc(void) { - input_unregister_device(&firesat_idev); - return 0; + input_unregister_device(idev); } -int firesat_got_remotecontrolcode(u16 code) +void firesat_handle_rc(unsigned int code) { - u16 keycode; - - if (code > 0x4500 && code < 0x4520) - keycode = firesat_irtable[code - 0x4501]; - else if (code > 0x453f && code < 0x4543) - keycode = firesat_irtable[code - 0x4521]; + if (code >= 0x0300 && code <= 0x031f) + code = keytable[code - 0x0300]; + else if (code >= 0x0340 && code <= 0x0354) + code = keytable[code - 0x0320]; + else if (code >= 0x4501 && code <= 0x451f) + code = oldtable[code - 0x4501]; + else if (code >= 0x4540 && code <= 0x4542) + code = oldtable[code - 0x4521]; else { - printk(KERN_DEBUG "%s: invalid key code 0x%04x\n", __func__, - code); - return -EINVAL; + printk(KERN_DEBUG "firedtv: invalid key code 0x%04x " + "from remote control\n", code); + return; } - input_report_key(&firesat_idev, keycode, 1); - input_report_key(&firesat_idev, keycode, 0); - - return 0; + input_report_key(idev, code, 1); + input_report_key(idev, code, 0); } diff --git a/drivers/media/dvb/firesat/firesat-rc.h b/drivers/media/dvb/firesat/firesat-rc.h index e89a806..81f4fde 100644 --- a/drivers/media/dvb/firesat/firesat-rc.h +++ b/drivers/media/dvb/firesat/firesat-rc.h @@ -1,9 +1,8 @@ -#ifndef __FIRESAT_LIRC_H -#define __FIRESAT_LIRC_H +#ifndef _FIREDTV_RC_H +#define _FIREDTV_RC_H -extern int firesat_register_rc(void); -extern int firesat_unregister_rc(void); -extern int firesat_got_remotecontrolcode(u16 code); - -#endif +int firesat_register_rc(void); +void firesat_unregister_rc(void); +void firesat_handle_rc(unsigned int code); +#endif /* _FIREDTV_RC_H */ diff --git a/drivers/media/dvb/firesat/firesat.h b/drivers/media/dvb/firesat/firesat.h index f0bac24..5f0de88 100644 --- a/drivers/media/dvb/firesat/firesat.h +++ b/drivers/media/dvb/firesat/firesat.h @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * 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 @@ -10,22 +10,26 @@ * the License, or (at your option) any later version. */ -#ifndef __FIRESAT_H -#define __FIRESAT_H +#ifndef _FIREDTV_H +#define _FIREDTV_H -#include "dvb_frontend.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_net.h" - -#include <linux/version.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 25) -#include <linux/semaphore.h> -#endif -#include <linux/dvb/frontend.h> #include <linux/dvb/dmx.h> -#include <iso.h> +#include <linux/dvb/frontend.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/spinlock_types.h> +#include <linux/types.h> +#include <linux/wait.h> +#include <linux/workqueue.h> +#include <asm/atomic.h> + +#include <demux.h> +#include <dmxdev.h> +#include <dvb_demux.h> +#include <dvb_net.h> +#include <dvbdev.h> +#include <linux/version.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 @@ -116,15 +120,19 @@ enum model_type { - FireSAT_DVB_S = 1, - FireSAT_DVB_C = 2, - FireSAT_DVB_T = 3, - FireSAT_DVB_S2 = 4 + FireSAT_UNKNOWN = 0, + FireSAT_DVB_S = 1, + FireSAT_DVB_C = 2, + FireSAT_DVB_T = 3, + FireSAT_DVB_S2 = 4, }; +struct hpsb_host; +struct hpsb_iso; +struct node_entry; + struct firesat { struct dvb_demux dvb_demux; - char *model_name; /* DVB bits */ struct dvb_adapter *adapter; @@ -139,11 +147,10 @@ struct firesat { int ca_last_command; int ca_time_interval; - struct semaphore avc_sem; + struct mutex avc_mutex; wait_queue_head_t avc_wait; atomic_t avc_reply_received; - - atomic_t reschedule_remotecontrol; + struct work_struct remote_ctrl_work; struct firesat_channel { struct firesat *firesat; @@ -154,7 +161,7 @@ struct firesat { int pid; int type; /* 1 - TS, 2 - Filter */ } channel[16]; - struct semaphore demux_sem; + struct mutex demux_mutex; /* needed by avc_api */ void *respfrm; @@ -210,22 +217,23 @@ struct CIPHeader { }; }; +extern const char *firedtv_model_names[]; extern struct list_head firesat_list; extern spinlock_t firesat_list_lock; +struct device; + /* firesat_dvb.c */ -extern int firesat_start_feed(struct dvb_demux_feed *dvbdmxfeed); -extern int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed); -extern int firesat_dvbdev_init(struct firesat *firesat, - struct device *dev, - struct dvb_frontend *fe); +int firesat_start_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, + struct dvb_frontend *fe); /* firesat_fe.c */ -extern int firesat_frontend_attach(struct firesat *firesat, - struct dvb_frontend *fe); +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); +int setup_iso_channel(struct firesat *firesat); +void tear_down_iso_channel(struct firesat *firesat); -#endif +#endif /* _FIREDTV_H */ diff --git a/drivers/media/dvb/firesat/firesat_1394.c b/drivers/media/dvb/firesat/firesat_1394.c index b19e594..a13fbe6 100644 --- a/drivers/media/dvb/firesat/firesat_1394.c +++ b/drivers/media/dvb/firesat/firesat_1394.c @@ -1,9 +1,9 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) 2004 Andreas Monitzer <andy@monitzer.com> - * Copyright (c) 2007-2008 Ben Backx <ben@bbackx.com> - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.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 * modify it under the terms of the GNU General Public License as @@ -11,26 +11,34 @@ * the License, or (at your option) any later version. */ -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/time.h> +#include <linux/device.h> #include <linux/errno.h> -#include <linux/interrupt.h> -#include <ieee1394_hotplug.h> -#include <nodemgr.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/spinlock.h> +#include <linux/string.h> +#include <linux/types.h> +#include <asm/atomic.h> + +#include <dmxdev.h> +#include <dvb_demux.h> +#include <dvb_frontend.h> +#include <dvbdev.h> + +#include <csr1212.h> #include <highlevel.h> -#include <ohci1394.h> #include <hosts.h> -#include <dvbdev.h> +#include <ieee1394_hotplug.h> +#include <nodemgr.h> -#include "firesat.h" #include "avc_api.h" #include "cmp.h" -#include "firesat-rc.h" +#include "firesat.h" #include "firesat-ci.h" +#include "firesat-rc.h" #define FIRESAT_Vendor_ID 0x001287 @@ -75,52 +83,6 @@ MODULE_DEVICE_TABLE(ieee1394, firesat_id_table); LIST_HEAD(firesat_list); spinlock_t firesat_list_lock = SPIN_LOCK_UNLOCKED; -static void firesat_add_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 fcp_request(struct hpsb_host *host, - int nodeid, - int direction, - int cts, - u8 *data, - size_t length); - -static struct hpsb_highlevel firesat_highlevel = { - .name = "FireSAT", - .add_host = firesat_add_host, - .remove_host = firesat_remove_host, - .host_reset = firesat_host_reset, - .fcp_request = fcp_request, -}; - -static void firesat_add_host (struct hpsb_host *host) -{ - struct ti_ohci *ohci = (struct ti_ohci *)host->hostdata; - - /* We only work with the OHCI-1394 driver */ - if (strcmp(host->driver->name, OHCI1394_DRIVER_NAME)) - return; - - if (!hpsb_create_hostinfo(&firesat_highlevel, host, 0)) { - printk(KERN_ERR "Cannot allocate hostinfo\n"); - return; - } - - hpsb_set_hostinfo(&firesat_highlevel, host, ohci); - hpsb_set_hostinfo_key(&firesat_highlevel, host, ohci->host->id); -} - -static void firesat_remove_host (struct hpsb_host *host) -{ - -} - -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); -} - static void fcp_request(struct hpsb_host *host, int nodeid, int direction, @@ -156,6 +118,14 @@ static void fcp_request(struct hpsb_host *host, printk("%s: received invalid fcp request, ignored\n", __func__); } +const char *firedtv_model_names[] = { + [FireSAT_UNKNOWN] = "unknown type", + [FireSAT_DVB_S] = "FireDTV S/CI", + [FireSAT_DVB_C] = "FireDTV C/CI", + [FireSAT_DVB_T] = "FireDTV T/CI", + [FireSAT_DVB_S2] = "FireDTV S2 ", +}; + static int firesat_probe(struct device *dev) { struct unit_directory *ud = container_of(dev, struct unit_directory, device); @@ -165,6 +135,7 @@ static int firesat_probe(struct device *dev) unsigned char subunitcount = 0xff, subunit; struct firesat **firesats = kmalloc(sizeof (void*) * 2,GFP_KERNEL); int kv_len; + int i; char *kv_buf; if (!firesats) { @@ -207,11 +178,11 @@ static int firesat_probe(struct device *dev) return -ENOMEM; } - sema_init(&firesat->avc_sem, 1); + mutex_init(&firesat->avc_mutex); init_waitqueue_head(&firesat->avc_wait); atomic_set(&firesat->avc_reply_received, 1); - sema_init(&firesat->demux_sem, 1); - atomic_set(&firesat->reschedule_remotecontrol, 0); + mutex_init(&firesat->demux_mutex); + INIT_WORK(&firesat->remote_ctrl_work, avc_remote_ctrl_work); spin_lock_irqsave(&firesat_list_lock, flags); INIT_LIST_HEAD(&firesat->list); @@ -244,23 +215,13 @@ static int firesat_probe(struct device *dev) while ((kv_buf + kv_len - 1) == '\0') kv_len--; kv_buf[kv_len++] = '\0'; - /* Determining the device model */ - if (strcmp(kv_buf, "FireDTV S/CI") == 0) { - printk(KERN_INFO "%s: found DVB/S\n", __func__); - firesat->type = 1; - } else if (strcmp(kv_buf, "FireDTV C/CI") == 0) { - printk(KERN_INFO "%s: found DVB/C\n", __func__); - firesat->type = 2; - } else if (strcmp(kv_buf, "FireDTV T/CI") == 0) { - printk(KERN_INFO "%s: found DVB/T\n", __func__); - firesat->type = 3; - } else if (strcmp(kv_buf, "FireDTV S2 ") == 0) { - printk(KERN_INFO "%s: found DVB/S2\n", __func__); - firesat->type = 4; - } + for (i = ARRAY_SIZE(firedtv_model_names); --i;) + if (strcmp(kv_buf, firedtv_model_names[i]) == 0) + break; + firesat->type = i; kfree(kv_buf); - if (AVCIdentifySubunit(firesat, NULL, (int*)&firesat->type)) { + if (AVCIdentifySubunit(firesat)) { printk("%s: cannot identify subunit %d\n", __func__, subunit); spin_lock_irqsave(&firesat_list_lock, flags); list_del(&firesat->list); @@ -270,14 +231,14 @@ static int firesat_probe(struct device *dev) } // ---- + /* FIXME: check for error return */ firesat_dvbdev_init(firesat, dev, fe); // ---- firesats[subunit] = firesat; } // loop for all tuners - //beta ;-) Disable remote control stuff to avoid crashing - //if(firesats[0]) - // AVCRegisterRemoteControl(firesats[0]); + if (firesats[0]) + AVCRegisterRemoteControl(firesats[0]); return 0; } @@ -306,6 +267,8 @@ static int firesat_remove(struct device *dev) list_del(&firesats[k]->list); spin_unlock_irqrestore(&firesat_list_lock, flags); + cancel_work_sync(&firesats[k]->remote_ctrl_work); + kfree(firesats[k]->fe); kfree(firesats[k]->adapter); kfree(firesats[k]->respfrm); @@ -339,7 +302,7 @@ static int firesat_update(struct unit_directory *ud) static struct hpsb_protocol_driver firesat_driver = { - .name = "FireSAT", + .name = "firedtv", .id_table = firesat_id_table, .update = firesat_update, @@ -352,32 +315,41 @@ static struct hpsb_protocol_driver firesat_driver = { }, }; +static struct hpsb_highlevel firesat_highlevel = { + .name = "firedtv", + .fcp_request = fcp_request, +}; + static int __init firesat_init(void) { int ret; - printk(KERN_INFO "FireSAT loaded\n"); hpsb_register_highlevel(&firesat_highlevel); ret = hpsb_register_protocol(&firesat_driver); if (ret) { - printk(KERN_ERR "FireSAT: failed to register protocol\n"); - hpsb_unregister_highlevel(&firesat_highlevel); - return ret; + printk(KERN_ERR "firedtv: failed to register protocol\n"); + goto fail; } - //Crash in this function, just disable RC for the time being... - //Don't forget to uncomment in firesat_exit and firesat_probe when you enable this. - /*if((ret=firesat_register_rc())) - printk("%s: firesat_register_rc return error code %d (ignored)\n", __func__, ret);*/ + ret = firesat_register_rc(); + if (ret) { + printk(KERN_ERR "firedtv: failed to register input device\n"); + goto fail_rc; + } return 0; +fail_rc: + hpsb_unregister_protocol(&firesat_driver); +fail: + hpsb_unregister_highlevel(&firesat_highlevel); + return ret; } static void __exit firesat_exit(void) { + firesat_unregister_rc(); hpsb_unregister_protocol(&firesat_driver); hpsb_unregister_highlevel(&firesat_highlevel); - printk(KERN_INFO "FireSAT quit\n"); } module_init(firesat_init); @@ -385,6 +357,6 @@ module_exit(firesat_exit); MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>"); MODULE_AUTHOR("Ben Backx <ben@bbackx.com>"); -MODULE_DESCRIPTION("FireSAT DVB Driver"); +MODULE_DESCRIPTION("FireDTV DVB Driver"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("FireSAT DVB"); +MODULE_SUPPORTED_DEVICE("FireDTV DVB"); diff --git a/drivers/media/dvb/firesat/firesat_dvb.c b/drivers/media/dvb/firesat/firesat_dvb.c index 9e87402..e944cee 100644 --- a/drivers/media/dvb/firesat/firesat_dvb.c +++ b/drivers/media/dvb/firesat/firesat_dvb.c @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * 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 @@ -10,64 +10,52 @@ * the License, or (at your option) any later version. */ -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/time.h> #include <linux/errno.h> -#include <linux/interrupt.h> -#include <ieee1394_hotplug.h> -#include <nodemgr.h> -#include <highlevel.h> -#include <ohci1394.h> -#include <hosts.h> +#include <linux/kernel.h> +#include <linux/mutex.h> +#include <linux/types.h> + +#include <dvb_demux.h> +#include <dvb_frontend.h> #include <dvbdev.h> -#include "firesat.h" #include "avc_api.h" -#include "cmp.h" -#include "firesat-rc.h" +#include "firesat.h" #include "firesat-ci.h" DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); static struct firesat_channel *firesat_channel_allocate(struct firesat *firesat) { + struct firesat_channel *c = NULL; int k; - //printk(KERN_INFO "%s\n", __func__); - - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return NULL; - 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); - + for (k = 0; k < 16; k++) if (firesat->channel[k].active == 0) { firesat->channel[k].active = 1; - up(&firesat->demux_sem); - return &firesat->channel[k]; + c = &firesat->channel[k]; + break; } - } - up(&firesat->demux_sem); - return NULL; // no more channels available + mutex_unlock(&firesat->demux_mutex); + return c; } static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[]) { int k, l = 0; - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; for (k = 0; k < 16; k++) if (firesat->channel[k].active == 1) pid[l++] = firesat->channel[k].pid; - up(&firesat->demux_sem); + mutex_unlock(&firesat->demux_mutex); *pidc = l; @@ -77,12 +65,12 @@ static int firesat_channel_collect(struct firesat *firesat, int *pidc, u16 pid[] static int firesat_channel_release(struct firesat *firesat, struct firesat_channel *channel) { - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; channel->active = 0; - up(&firesat->demux_sem); + mutex_unlock(&firesat->demux_mutex); return 0; } @@ -172,7 +160,8 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { struct dvb_demux *demux = dvbdmxfeed->demux; struct firesat *firesat = (struct firesat*)demux->priv; - int k, l = 0; + struct firesat_channel *c = dvbdmxfeed->priv; + int k, l; u16 pids[16]; //printk(KERN_INFO "%s (pid %u)\n", __func__, dvbdmxfeed->pid); @@ -197,30 +186,24 @@ int firesat_stop_feed(struct dvb_demux_feed *dvbdmxfeed) return 0; } - if (down_interruptible(&firesat->demux_sem)) + if (mutex_lock_interruptible(&firesat->demux_mutex)) return -EINTR; - - // list except channel to be removed - for (k = 0; k < 16; k++) + /* list except channel to be removed */ + for (k = 0, l = 0; k < 16; k++) if (firesat->channel[k].active == 1) { - if (&firesat->channel[k] != - (struct firesat_channel *)dvbdmxfeed->priv) + if (&firesat->channel[k] != c) pids[l++] = firesat->channel[k].pid; else firesat->channel[k].active = 0; } - if ((k = AVCTuner_SetPIDs(firesat, l, pids))) { - up(&firesat->demux_sem); - return k; - } + k = AVCTuner_SetPIDs(firesat, l, pids); + if (!k) + c->active = 0; - ((struct firesat_channel *)dvbdmxfeed->priv)->active = 0; - - up(&firesat->demux_sem); - - return 0; + mutex_unlock(&firesat->demux_mutex); + return k; } int firesat_dvbdev_init(struct firesat *firesat, @@ -229,60 +212,20 @@ int firesat_dvbdev_init(struct firesat *firesat, { int result; -#if 0 - switch (firesat->type) { - case FireSAT_DVB_S: - firesat->model_name = "FireSAT DVB-S"; - firesat->frontend_info = &firesat_S_frontend_info; - break; - case FireSAT_DVB_C: - firesat->model_name = "FireSAT DVB-C"; - firesat->frontend_info = &firesat_C_frontend_info; - break; - case FireSAT_DVB_T: - firesat->model_name = "FireSAT DVB-T"; - firesat->frontend_info = &firesat_T_frontend_info; - break; - default: - printk("%s: unknown model type 0x%x on subunit %d!\n", - __func__, firesat->type,subunit); - firesat->model_name = "Unknown"; - firesat->frontend_info = NULL; - } -#endif -/* // ------- CRAP ----------- - if (!firesat->frontend_info) { - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); - kfree(firesat); - continue; - } -*/ - //initialising firesat->adapter before calling dvb_register_adapter - if (!(firesat->adapter = kmalloc(sizeof (struct dvb_adapter), GFP_KERNEL))) { - printk("%s: couldn't allocate memory.\n", __func__); - kfree(firesat->adapter); - kfree(firesat); - return -ENOMEM; - } - - if ((result = DVB_REGISTER_ADAPTER(firesat->adapter, - firesat->model_name, - THIS_MODULE, - dev, adapter_nr)) < 0) { - - printk("%s: dvb_register_adapter failed: error %d\n", __func__, result); -#if 0 - /* ### cleanup */ - spin_lock_irqsave(&firesat_list_lock, flags); - list_del(&firesat->list); - spin_unlock_irqrestore(&firesat_list_lock, flags); -#endif - kfree(firesat); + firesat->adapter = kmalloc(sizeof(*firesat->adapter), GFP_KERNEL); + if (!firesat->adapter) { + printk(KERN_ERR "firedtv: couldn't allocate memory\n"); + return -ENOMEM; + } - return result; - } + 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*/; diff --git a/drivers/media/dvb/firesat/firesat_fe.c b/drivers/media/dvb/firesat/firesat_fe.c index 1c86c3e..ec614ea 100644 --- a/drivers/media/dvb/firesat/firesat_fe.c +++ b/drivers/media/dvb/firesat/firesat_fe.c @@ -1,8 +1,8 @@ /* - * FireSAT DVB driver + * FireDTV driver (formerly known as FireSAT) * - * Copyright (c) ? - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com> + * 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 @@ -10,26 +10,15 @@ * the License, or (at your option) any later version. */ -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/wait.h> -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/time.h> #include <linux/errno.h> -#include <linux/interrupt.h> -#include <ieee1394_hotplug.h> -#include <nodemgr.h> -#include <highlevel.h> -#include <ohci1394.h> -#include <hosts.h> -#include <dvbdev.h> +#include <linux/kernel.h> +#include <linux/types.h> + +#include <dvb_frontend.h> -#include "firesat.h" #include "avc_api.h" #include "cmp.h" -#include "firesat-rc.h" -#include "firesat-ci.h" +#include "firesat.h" static int firesat_dvb_init(struct dvb_frontend *fe) { @@ -209,21 +198,17 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) { switch (firesat->type) { case FireSAT_DVB_S: - firesat->model_name = "FireSAT DVB-S"; firesat->frontend_info = &firesat_S_frontend_info; break; case FireSAT_DVB_C: - firesat->model_name = "FireSAT DVB-C"; firesat->frontend_info = &firesat_C_frontend_info; break; case FireSAT_DVB_T: - firesat->model_name = "FireSAT DVB-T"; firesat->frontend_info = &firesat_T_frontend_info; break; default: - printk("%s: unknown model type 0x%x !\n", - __func__, firesat->type); - firesat->model_name = "Unknown"; + printk(KERN_ERR "firedtv: no frontend for model type 0x%x\n", + firesat->type); firesat->frontend_info = NULL; } fe->ops = firesat_ops; @@ -235,7 +220,7 @@ int firesat_frontend_attach(struct firesat *firesat, struct dvb_frontend *fe) static struct dvb_frontend_info firesat_S_frontend_info = { - .name = "FireSAT DVB-S Frontend", + .name = "FireDTV DVB-S Frontend", .type = FE_QPSK, .frequency_min = 950000, @@ -256,7 +241,7 @@ static struct dvb_frontend_info firesat_S_frontend_info = { static struct dvb_frontend_info firesat_C_frontend_info = { - .name = "FireSAT DVB-C Frontend", + .name = "FireDTV DVB-C Frontend", .type = FE_QAM, .frequency_min = 47000000, @@ -276,7 +261,7 @@ static struct dvb_frontend_info firesat_C_frontend_info = { static struct dvb_frontend_info firesat_T_frontend_info = { - .name = "FireSAT DVB-T Frontend", + .name = "FireDTV DVB-T Frontend", .type = FE_OFDM, .frequency_min = 49000000, diff --git a/drivers/media/dvb/firesat/firesat_iso.c b/drivers/media/dvb/firesat/firesat_iso.c index 15e23cf..bc94afe 100644 --- a/drivers/media/dvb/firesat/firesat_iso.c +++ b/drivers/media/dvb/firesat/firesat_iso.c @@ -1,7 +1,7 @@ /* * FireSAT DVB driver * - * Copyright (c) 2008 Henrik Kurelid <henrik@kurelid.se> + * 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 @@ -9,6 +9,16 @@ * the License, or (at your option) any later version. */ +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/spinlock.h> + +#include <dvb_demux.h> + +#include <dma.h> +#include <iso.h> + #include "firesat.h" static void rawiso_activity_cb(struct hpsb_iso *iso); |