-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 273596 b: refs/heads/master c: 41b44e0 h: refs/heads/master v: v3
- Loading branch information
Pierrick Hascoet
authored and
Mauro Carvalho Chehab
committed
Nov 3, 2011
1 parent
5c31eef
commit 181a9c1
Showing
16 changed files
with
3,695 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 539b469518b45c0b5915bec3e258e21e03667084 | ||
refs/heads/master: 41b44e0418112e694f9b7beb8088efbb8c9c0053 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
config DVB_AS102 | ||
tristate "Abilis AS102 DVB receiver" | ||
depends on DVB_CORE && USB && I2C && INPUT | ||
help | ||
Choose Y or M here if you have a device containing an AS102 | ||
|
||
To compile this driver as a module, choose M here |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o as102_fe.o as102_usb_drv.o as10x_cmd_cfg.o | ||
|
||
obj-$(CONFIG_DVB_AS102) += dvb-as102.o | ||
|
||
EXTRA_CFLAGS += -DLINUX -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,356 @@ | ||
/* | ||
* Abilis Systems Single DVB-T Receiver | ||
* Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.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, or (at your option) | ||
* any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
*/ | ||
#include <linux/kernel.h> | ||
#include <linux/errno.h> | ||
#include <linux/init.h> | ||
#include <linux/slab.h> | ||
#include <linux/module.h> | ||
#include <linux/mm.h> | ||
#include <linux/kref.h> | ||
#include <asm/uaccess.h> | ||
#include <linux/usb.h> | ||
|
||
/* header file for Usb device driver*/ | ||
#include "as102_drv.h" | ||
#include "as102_fw.h" | ||
|
||
#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE) | ||
#include "dvbdev.h" | ||
#else | ||
#warning >>> DVB_CORE not defined !!! <<< | ||
#endif | ||
|
||
int debug = 0; | ||
module_param_named(debug, debug, int, 0644); | ||
MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)"); | ||
|
||
int dual_tuner = 0; | ||
module_param_named(dual_tuner, dual_tuner, int, 0644); | ||
MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner configuration (default: off)"); | ||
|
||
static int fw_upload = 1; | ||
module_param_named(fw_upload, fw_upload, int, 0644); | ||
MODULE_PARM_DESC(fw_upload, "Turn on/off default FW upload (default: on)"); | ||
|
||
static int pid_filtering = 0; | ||
module_param_named(pid_filtering, pid_filtering, int, 0644); | ||
MODULE_PARM_DESC(pid_filtering, "Activate HW PID filtering (default: off)"); | ||
|
||
static int ts_auto_disable = 0; | ||
module_param_named(ts_auto_disable, ts_auto_disable, int, 0644); | ||
MODULE_PARM_DESC(ts_auto_disable, "Stream Auto Enable on FW (default: off)"); | ||
|
||
int elna_enable = 1; | ||
module_param_named(elna_enable, elna_enable, int, 0644); | ||
MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)"); | ||
|
||
#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR | ||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
#endif | ||
|
||
#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE) | ||
static void as102_stop_stream(struct as102_dev_t *dev) { | ||
struct as102_bus_adapter_t *bus_adap; | ||
|
||
if (dev != NULL) | ||
bus_adap = &dev->bus_adap; | ||
else | ||
return; | ||
|
||
if (bus_adap->ops->stop_stream != NULL) | ||
bus_adap->ops->stop_stream(dev); | ||
|
||
if (ts_auto_disable) { | ||
if (mutex_lock_interruptible(&dev->bus_adap.lock)) | ||
return; | ||
|
||
if (as10x_cmd_stop_streaming(bus_adap) < 0) { | ||
dprintk(debug, "as10x_cmd_stop_streaming failed\n"); | ||
} | ||
|
||
mutex_unlock(&dev->bus_adap.lock); | ||
} | ||
} | ||
|
||
static int as102_start_stream(struct as102_dev_t *dev) { | ||
|
||
struct as102_bus_adapter_t *bus_adap; | ||
int ret = -EFAULT; | ||
|
||
if (dev != NULL) | ||
bus_adap = &dev->bus_adap; | ||
else | ||
return ret; | ||
|
||
if (bus_adap->ops->start_stream != NULL) { | ||
ret = bus_adap->ops->start_stream(dev); | ||
} | ||
|
||
if (ts_auto_disable) { | ||
if (mutex_lock_interruptible(&dev->bus_adap.lock)) | ||
return -EFAULT; | ||
|
||
ret = as10x_cmd_start_streaming(bus_adap); | ||
|
||
mutex_unlock(&dev->bus_adap.lock); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
static int as10x_pid_filter(struct as102_dev_t *dev, | ||
int index, u16 pid, int onoff) { | ||
|
||
struct as102_bus_adapter_t *bus_adap = &dev->bus_adap; | ||
int ret = -EFAULT; | ||
|
||
ENTER(); | ||
|
||
if (mutex_lock_interruptible(&dev->bus_adap.lock)) { | ||
dprintk(debug, "mutex_lock_interruptible(lock) failed !\n"); | ||
return -EBUSY; | ||
} | ||
|
||
switch(onoff) { | ||
case 0: | ||
ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid); | ||
dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n", | ||
index, pid, ret); | ||
break; | ||
case 1: | ||
{ | ||
struct as10x_ts_filter filter; | ||
|
||
filter.type = TS_PID_TYPE_TS; | ||
filter.idx = 0xFF; | ||
filter.pid = pid; | ||
|
||
ret = as10x_cmd_add_PID_filter(bus_adap, &filter); | ||
dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n", | ||
index, filter.idx, filter.pid, ret); | ||
break; | ||
} | ||
} | ||
|
||
mutex_unlock(&dev->bus_adap.lock); | ||
|
||
LEAVE(); | ||
return ret; | ||
} | ||
|
||
static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed) { | ||
int ret = 0; | ||
struct dvb_demux *demux = dvbdmxfeed->demux; | ||
struct as102_dev_t *as102_dev = demux->priv; | ||
|
||
ENTER(); | ||
|
||
if (mutex_lock_interruptible(&as102_dev->sem)) | ||
return -ERESTARTSYS; | ||
|
||
if (pid_filtering) { | ||
as10x_pid_filter(as102_dev, | ||
dvbdmxfeed->index, dvbdmxfeed->pid, 1); | ||
} | ||
|
||
if (as102_dev->streaming++ == 0) { | ||
ret = as102_start_stream(as102_dev); | ||
} | ||
|
||
mutex_unlock(&as102_dev->sem); | ||
LEAVE(); | ||
return ret; | ||
} | ||
|
||
static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) { | ||
struct dvb_demux *demux = dvbdmxfeed->demux; | ||
struct as102_dev_t *as102_dev = demux->priv; | ||
|
||
ENTER(); | ||
|
||
if (mutex_lock_interruptible(&as102_dev->sem)) | ||
return -ERESTARTSYS; | ||
|
||
if (--as102_dev->streaming == 0) { | ||
as102_stop_stream(as102_dev); | ||
} | ||
|
||
if (pid_filtering) { | ||
as10x_pid_filter(as102_dev, | ||
dvbdmxfeed->index, dvbdmxfeed->pid, 0); | ||
} | ||
|
||
mutex_unlock(&as102_dev->sem); | ||
LEAVE(); | ||
return 0; | ||
} | ||
#endif | ||
|
||
int as102_dvb_register(struct as102_dev_t *as102_dev) { | ||
int ret = 0; | ||
ENTER(); | ||
|
||
#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE) | ||
ret = dvb_register_adapter(&as102_dev->dvb_adap, | ||
DEVICE_FULL_NAME, | ||
THIS_MODULE, | ||
#if defined(CONFIG_AS102_USB) | ||
&as102_dev->bus_adap.usb_dev->dev | ||
#elif defined(CONFIG_AS102_SPI) | ||
&as102_dev->bus_adap.spi_dev->dev | ||
#else | ||
#error >>> dvb_register_adapter <<< | ||
#endif | ||
#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR | ||
, adapter_nr | ||
#endif | ||
); | ||
if (ret < 0) { | ||
err("%s: dvb_register_adapter() failed (errno = %d)", | ||
__FUNCTION__, ret); | ||
goto failed; | ||
} | ||
|
||
as102_dev->dvb_dmx.priv = as102_dev; | ||
as102_dev->dvb_dmx.filternum = pid_filtering ? 16 : 256; | ||
as102_dev->dvb_dmx.feednum = 256; | ||
as102_dev->dvb_dmx.start_feed = as102_dvb_dmx_start_feed; | ||
as102_dev->dvb_dmx.stop_feed = as102_dvb_dmx_stop_feed; | ||
|
||
as102_dev->dvb_dmx.dmx.capabilities = DMX_TS_FILTERING | | ||
DMX_SECTION_FILTERING; | ||
|
||
as102_dev->dvb_dmxdev.filternum = as102_dev->dvb_dmx.filternum; | ||
as102_dev->dvb_dmxdev.demux = &as102_dev->dvb_dmx.dmx; | ||
as102_dev->dvb_dmxdev.capabilities = 0; | ||
|
||
if ((ret = dvb_dmx_init(&as102_dev->dvb_dmx)) < 0) { | ||
err("%s: dvb_dmx_init() failed (errno = %d)", | ||
__FUNCTION__, ret); | ||
goto failed; | ||
} | ||
|
||
ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap); | ||
if (ret < 0) { | ||
err("%s: dvb_dmxdev_init() failed (errno = %d)", | ||
__FUNCTION__, ret); | ||
goto failed; | ||
} | ||
|
||
ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe); | ||
if (ret < 0) { | ||
err("%s: as102_dvb_register_frontend() failed (errno = %d)", | ||
__FUNCTION__, ret); | ||
goto failed; | ||
} | ||
#endif | ||
|
||
/* init bus mutex for token locking */ | ||
mutex_init(&as102_dev->bus_adap.lock); | ||
|
||
/* init start / stop stream mutex */ | ||
mutex_init(&as102_dev->sem); | ||
|
||
#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) | ||
/* | ||
* try to load as102 firmware. If firmware upload failed, we'll be | ||
* able to upload it later. | ||
*/ | ||
if (fw_upload) | ||
try_then_request_module(as102_fw_upload(&as102_dev->bus_adap), | ||
"firmware_class"); | ||
#endif | ||
|
||
failed: | ||
LEAVE(); | ||
/* FIXME: free dvb_XXX */ | ||
return ret; | ||
} | ||
|
||
void as102_dvb_unregister(struct as102_dev_t *as102_dev) { | ||
ENTER(); | ||
|
||
#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE) | ||
/* unregister as102 frontend */ | ||
as102_dvb_unregister_fe(&as102_dev->dvb_fe); | ||
|
||
/* unregister demux device */ | ||
dvb_dmxdev_release(&as102_dev->dvb_dmxdev); | ||
dvb_dmx_release(&as102_dev->dvb_dmx); | ||
|
||
/* unregister dvb adapter */ | ||
dvb_unregister_adapter(&as102_dev->dvb_adap); | ||
#endif | ||
LEAVE(); | ||
} | ||
|
||
static int __init as102_driver_init(void) { | ||
int ret = 0; | ||
|
||
ENTER(); | ||
|
||
/* register this driver with the low level subsystem */ | ||
#if defined(CONFIG_AS102_USB) | ||
ret = usb_register(&as102_usb_driver); | ||
if (ret) | ||
err("usb_register failed (ret = %d)", ret); | ||
#endif | ||
#if defined(CONFIG_AS102_SPI) | ||
ret = spi_register_driver(&as102_spi_driver); | ||
if (ret) | ||
printk(KERN_ERR "spi_register failed (ret = %d)", ret); | ||
#endif | ||
|
||
LEAVE(); | ||
return ret; | ||
} | ||
|
||
/* | ||
* Mandatory function : Adds a special section to the module indicating | ||
* where initialisation function is defined | ||
*/ | ||
module_init(as102_driver_init); | ||
|
||
/** | ||
* \brief as102 driver exit point. This function is called when device has | ||
* to be removed. | ||
*/ | ||
static void __exit as102_driver_exit(void) { | ||
ENTER(); | ||
/* deregister this driver with the low level bus subsystem */ | ||
#if defined(CONFIG_AS102_USB) | ||
usb_deregister(&as102_usb_driver); | ||
#endif | ||
#if defined(CONFIG_AS102_SPI) | ||
spi_unregister_driver(&as102_spi_driver); | ||
#endif | ||
LEAVE(); | ||
} | ||
|
||
/* | ||
* required function for unload: Adds a special section to the module | ||
* indicating where unload function is defined | ||
*/ | ||
module_exit(as102_driver_exit); | ||
/* modinfo details */ | ||
MODULE_DESCRIPTION(DRIVER_FULL_NAME); | ||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>"); | ||
|
||
/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */ |
Oops, something went wrong.