All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 02/17] staging: as102: Fix CodingStyle errors in file as102_drv.c
From: Sylwester Nawrocki @ 2011-10-31 16:24 UTC (permalink / raw)
  To: devel, linux-media
  Cc: Piotr Chmura, Devin Heitmueller, Mauro Carvalho Chehab,
	Sylwester Nawrocki, Stefan Richter, Greg KH
In-Reply-To: <1320078295-3379-1-git-send-email-snjw23@gmail.com>

From: Devin Heitmueller <dheitmueller@kernellabs.com>

Fix Linux kernel coding style (whitespace and indentation) errors
in file as102_drv.c.

Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Piotr Chmura <chmooreck@poczta.onet.pl>
Signed-off-by: Sylwester Nawrocki <snjw23@gmail.com>
---
 drivers/staging/media/as102/as102_drv.c |  100 ++++++++++++++++---------------
 1 files changed, 52 insertions(+), 48 deletions(-)

diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
index c334bff..9e5d81b 100644
--- a/drivers/staging/media/as102/as102_drv.c
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -1,6 +1,7 @@
 /*
  * Abilis Systems Single DVB-T Receiver
  * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
+ * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.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
@@ -36,23 +37,23 @@
 #warning >>> DVB_CORE not defined !!! <<<
 #endif
 
-int debug = 0;
+int debug;
 module_param_named(debug, debug, int, 0644);
 MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
 
-int dual_tuner = 0;
+int dual_tuner;
 module_param_named(dual_tuner, dual_tuner, int, 0644);
-MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner configuration (default: off)");
+MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner config (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;
+static int pid_filtering;
 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;
+static int ts_auto_disable;
 module_param_named(ts_auto_disable, ts_auto_disable, int, 0644);
 MODULE_PARM_DESC(ts_auto_disable, "Stream Auto Enable on FW (default: off)");
 
@@ -65,7 +66,8 @@ 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) {
+static void as102_stop_stream(struct as102_dev_t *dev)
+{
 	struct as102_bus_adapter_t *bus_adap;
 
 	if (dev != NULL)
@@ -80,16 +82,15 @@ static void as102_stop_stream(struct as102_dev_t *dev) {
 		if (mutex_lock_interruptible(&dev->bus_adap.lock))
 			return;
 
-		if (as10x_cmd_stop_streaming(bus_adap) < 0) {
+		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) {
-
+static int as102_start_stream(struct as102_dev_t *dev)
+{
 	struct as102_bus_adapter_t *bus_adap;
 	int ret = -EFAULT;
 
@@ -98,9 +99,8 @@ static int as102_start_stream(struct as102_dev_t *dev) {
 	else
 		return ret;
 
-	if (bus_adap->ops->start_stream != NULL) {
+	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))
@@ -127,25 +127,25 @@ static int as10x_pid_filter(struct as102_dev_t *dev,
 		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;
-		}
+	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);
@@ -154,7 +154,8 @@ static int as10x_pid_filter(struct as102_dev_t *dev,
 	return ret;
 }
 
-static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed) {
+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;
@@ -169,16 +170,16 @@ static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed) {
 				dvbdmxfeed->index, dvbdmxfeed->pid, 1);
 	}
 
-	if (as102_dev->streaming++ == 0) {
+	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) {
+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;
 
@@ -187,9 +188,8 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) {
 	if (mutex_lock_interruptible(&as102_dev->sem))
 		return -ERESTARTSYS;
 
-	if (--as102_dev->streaming == 0) {
+	if (--as102_dev->streaming == 0)
 		as102_stop_stream(as102_dev);
-	}
 
 	if (pid_filtering) {
 		as10x_pid_filter(as102_dev,
@@ -202,7 +202,8 @@ static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed) {
 }
 #endif
 
-int as102_dvb_register(struct as102_dev_t *as102_dev) {
+int as102_dvb_register(struct as102_dev_t *as102_dev)
+{
 	int ret = 0;
 	ENTER();
 
@@ -223,7 +224,7 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) {
 				   );
 	if (ret < 0) {
 		err("%s: dvb_register_adapter() failed (errno = %d)",
-		    __FUNCTION__, ret);
+		    __func__, ret);
 		goto failed;
 	}
 
@@ -240,23 +241,23 @@ int as102_dvb_register(struct as102_dev_t *as102_dev) {
 	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);
+	ret = dvb_dmx_init(&as102_dev->dvb_dmx);
+	if (ret < 0) {
+		err("%s: dvb_dmx_init() failed (errno = %d)", __func__, 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);
+		err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__,
+		    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);
+		    __func__, ret);
 		goto failed;
 	}
 #endif
@@ -283,7 +284,8 @@ failed:
 	return ret;
 }
 
-void as102_dvb_unregister(struct as102_dev_t *as102_dev) {
+void as102_dvb_unregister(struct as102_dev_t *as102_dev)
+{
 	ENTER();
 
 #if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE)
@@ -300,7 +302,8 @@ void as102_dvb_unregister(struct as102_dev_t *as102_dev) {
 	LEAVE();
 }
 
-static int __init as102_driver_init(void) {
+static int __init as102_driver_init(void)
+{
 	int ret = 0;
 
 	ENTER();
@@ -331,7 +334,8 @@ 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) {
+static void __exit as102_driver_exit(void)
+{
 	ENTER();
 	/* deregister this driver with the low level bus subsystem */
 #if defined(CONFIG_AS102_USB)
-- 
1.7.4.1


^ permalink raw reply related

* [Qemu-devel] Problem under OSX Lion: GThread-ERROR **: GThread system may only be initialized once
From: Juan Pineda @ 2011-10-31 16:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori, Andreas Färber
In-Reply-To: <AA6AC32E-94D4-4F8C-9EC4-E12807705D21@logician.com>

The current Qemu master branch crashes under OSX with a GThread error. Commenting out vlc.c line 2188 (call to g_thread_init) allows it to run successfully. I am running OSX Lion. Two caveats:

1) You need to apply Andreas' patch to softfloat.h to fix compile error for uint16
2) You need to compile with gcc-4.2 (non LLVM gcc) and specify --disable-user to successfully compile

See log below.

Thanks!
-Juan



$ ./configure --disable-user --enable-debug --cc=gcc-4.2 --host-cc=gcc-4.2
$ make
$ gdb ./i386-softmmu/qemu-system-i386 
...
GThread-ERROR **: GThread system may only be initialized once.
aborting...

Program received signal SIGABRT, Aborted.
0x00007fff8e50dce2 in __pthread_kill ()
(gdb) bt
#0  0x00007fff8e50dce2 in __pthread_kill ()
#1  0x00007fff94dc17d2 in pthread_kill ()
#2  0x00007fff94db2a7a in abort ()
#3  0x0000000100da28c3 in g_logv ()
#4  0x0000000100da247e in g_log ()
#5  0x0000000100d74333 in g_thread_init ()
#6  0x00000001000e6d8c in qemu_main (argc=3, argv=0x10a896710, envp=0x7fff5fbff120) at /Users/juan/Temp/build/qemu-source_code/vl.c:2188
#7  0x0000000100142e65 in -[QemuCocoaAppController startEmulationWithArgc:argv:] (self=0x1011299d0, _cmd=0x1002818e4, argc=3, argv=0x10a896710) at cocoa.m:798
#8  0x000000010014306a in -[QemuCocoaAppController openPanelDidEnd:returnCode:contextInfo:] (self=0x1011299d0, _cmd=0x1002818aa, sheet=0x10114e450, returnCode=1, contextInfo=0x0) at cocoa.m:822
#9  0x00007fff9551955e in -[NSSavePanel _didEndSheet:returnCode:contextInfo:] ()
#10 0x00007fff952987d7 in -[NSApplication endSheet:returnCode:] ()
#11 0x00007fff94a78a1d in -[NSObject performSelector:withObject:] ()
#12 0x00007fff950e7710 in -[NSApplication sendAction:to:from:] ()
#13 0x00007fff950e7642 in -[NSControl sendAction:to:] ()
#14 0x00007fff950e756d in -[NSCell _sendActionFrom:] ()
#15 0x00007fff950e6a30 in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] ()
#16 0x00007fff951668e0 in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] ()
#17 0x00007fff950e563a in -[NSControl mouseDown:] ()
#18 0x00007fff950b00e0 in -[NSWindow sendEvent:] ()
#19 0x00007fff9504868f in -[NSApplication sendEvent:] ()
#20 0x00007fff94fde682 in -[NSApplication run] ()
#21 0x0000000100144254 in main (argc=1, argv=0x7fff5fbff110) at cocoa.m:945
(gdb) up
#1  0x00007fff94dc17d2 in pthread_kill ()
(gdb) up
#2  0x00007fff94db2a7a in abort ()
(gdb) up
#3  0x0000000100da28c3 in g_logv ()
(gdb) up
#4  0x0000000100da247e in g_log ()
(gdb) up
#5  0x0000000100d74333 in g_thread_init ()
(gdb) up
#6  0x00000001000e6d8c in qemu_main (argc=3, argv=0x10a896710, envp=0x7fff5fbff120) at /Users/juan/Temp/build/qemu-source_code/vl.c:2188
2188	    g_thread_init(NULL);
Current language:  auto; currently c
(gdb) 



On Oct 31, 2011, at 8:32 AM, Juan Pineda wrote:

> Hi Andreas,
> 
> Thanks for your reply. You can verify that my cocoa.m patch works 100% under 0.15.1. That's where I was testing it. The fix is completely independent of the other problems in the OSX build (uint16, GThread, etc.) that have cropped up since 0.15.1, so there should be no problem merging it.
> 
> I will us GDB on that GThread error to find the source code line where it failed and post what I find.
> 
> Thanks!
> -Juan
> 
> 
> 
> On Oct 30, 2011, at 3:45 PM, Andreas Färber wrote:
> 
>> Am 18.10.2011 16:35, schrieb Juan Pineda:
>>>>> What command line do you use? If using the right arguments you
>>>>> shouldn't see a window at all. Are you maybe using -drive instead of
>>>>> -hda and that is not yet handled correctly?
>>> 
>>> The boot volume dialog appears only when a hard disk file is not supplied on the command line. I would think the failure of the dialog to close is not unique to Lion. However in prior OS releases it probably does not present a problem as the main window can be raised above the dialog.
>> 
>> If that were the case I would see it as worth fixing there, too. :)
>> 
>>>>> Apart from this issue, is it working correctly for you?
>> 
>>> However building the main branch (with flags as above) does not work. The build fails with error about redefinition of uint16 in fpu/softfloat.h. If that is fixed the build completes. But trying to run qemu-system-i386 quits:
>>> 
>>>> $ i386-softmmu/qemu-system-i386 -hda ~/Downloads/linux-0.2.img
>>>> 
>>>> GThread-ERROR **: GThread system may only be initialized once.
>>>> aborting...
>>>> Abort trap: 6
>> 
>> That's what I'm seeing, too, so I don't feel comfortable committing this
>> patch now. It compiles file, but it crashes either way with a message
>> similar to the above, so I don't see an improvement (yet).
>> 
>> If you could pinpoint where this error stems from (e.g., single-stepping
>> in gdb) that might help getting it fixed.
>> 
>> Thanks,
>> Andreas
> 

^ permalink raw reply

* [PATCH 01/17] staging: as102: Initial import from Abilis
From: Sylwester Nawrocki @ 2011-10-31 16:24 UTC (permalink / raw)
  To: devel, linux-media
  Cc: Piotr Chmura, Devin Heitmueller, Mauro Carvalho Chehab,
	Sylwester Nawrocki, Stefan Richter, Greg KH, Pierrick Hascoet
In-Reply-To: <1320078295-3379-1-git-send-email-snjw23@gmail.com>

From: Pierrick Hascoet <pierrick.hascoet@abilis.com>

Changes by Devin Heitmueller:

Import the original Abilis Systems as102 driver.  The source is unmodified,
with the only changes I've made so far were that I created a Kconfig and
Makefile so that the code builds in a standard v4l-dvb tree.

This driver requires firmware (which Abilis has provided with redistribution
terms which will allow it to be bundled in the Linux distributions).   The
firmware can be downloaded from here:

http://www.kernellabs.com/firmware/as102/

Thanks to Rainer Miethling from PCTV Systems for working to get the driver
released (for use with the PCTV 74e) and Pierrick Hascoet from Abilis for
authoring the driver.

Changes by Piotr Chmura:
 - moved the driver from media/dvb to staging/media
 - removed Makefile/Kconfig - compilation fails in current tree

[snjw23@gmail.com: edited changelog]
Signed-off-by: Pierrick Hascoet <pierrick.hascoet@abilis.com>
Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com>
Signed-off-by: Piotr Chmura <chmooreck@poczta.onet.pl>
Signed-off-by: Sylwester Nawrocki <snjw23@gmail.com>
---
 drivers/staging/media/as102/Kconfig            |    7 +
 drivers/staging/media/as102/Makefile           |    5 +
 drivers/staging/media/as102/as102_drv.c        |  356 +++++++++++++
 drivers/staging/media/as102/as102_drv.h        |  146 ++++++
 drivers/staging/media/as102/as102_fe.c         |  647 ++++++++++++++++++++++++
 drivers/staging/media/as102/as102_fw.c         |  236 +++++++++
 drivers/staging/media/as102/as102_fw.h         |   42 ++
 drivers/staging/media/as102/as102_usb_drv.c    |  432 ++++++++++++++++
 drivers/staging/media/as102/as102_usb_drv.h    |   54 ++
 drivers/staging/media/as102/as10x_cmd.c        |  478 +++++++++++++++++
 drivers/staging/media/as102/as10x_cmd.h        |  540 ++++++++++++++++++++
 drivers/staging/media/as102/as10x_cmd_cfg.c    |  239 +++++++++
 drivers/staging/media/as102/as10x_cmd_stream.c |  256 ++++++++++
 drivers/staging/media/as102/as10x_handle.h     |   58 +++
 drivers/staging/media/as102/as10x_types.h      |  198 ++++++++
 15 files changed, 3694 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/media/as102/Kconfig
 create mode 100644 drivers/staging/media/as102/Makefile
 create mode 100644 drivers/staging/media/as102/as102_drv.c
 create mode 100644 drivers/staging/media/as102/as102_drv.h
 create mode 100644 drivers/staging/media/as102/as102_fe.c
 create mode 100644 drivers/staging/media/as102/as102_fw.c
 create mode 100644 drivers/staging/media/as102/as102_fw.h
 create mode 100644 drivers/staging/media/as102/as102_usb_drv.c
 create mode 100644 drivers/staging/media/as102/as102_usb_drv.h
 create mode 100644 drivers/staging/media/as102/as10x_cmd.c
 create mode 100644 drivers/staging/media/as102/as10x_cmd.h
 create mode 100644 drivers/staging/media/as102/as10x_cmd_cfg.c
 create mode 100644 drivers/staging/media/as102/as10x_cmd_stream.c
 create mode 100644 drivers/staging/media/as102/as10x_handle.h
 create mode 100644 drivers/staging/media/as102/as10x_types.h

diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig
new file mode 100644
index 0000000..5865029
--- /dev/null
+++ b/drivers/staging/media/as102/Kconfig
@@ -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
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
new file mode 100644
index 0000000..c2334c6
--- /dev/null
+++ b/drivers/staging/media/as102/Makefile
@@ -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
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
new file mode 100644
index 0000000..c334bff
--- /dev/null
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -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: */
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h
new file mode 100644
index 0000000..f50bb9f
--- /dev/null
+++ b/drivers/staging/media/as102/as102_drv.h
@@ -0,0 +1,146 @@
+/*
+ * 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.
+ */
+
+#if defined(CONFIG_AS102_USB)
+#include <linux/usb.h>
+extern struct usb_driver as102_usb_driver;
+#endif
+
+#if defined(CONFIG_AS102_SPI)
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/cdev.h>
+
+extern struct spi_driver as102_spi_driver;
+#endif
+
+#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE)
+#include "dvb_demux.h"
+#include "dvb_frontend.h"
+#include "dmxdev.h"
+#endif
+
+#define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
+#define DRIVER_NAME "as10x_usb"
+
+extern int debug;
+
+#define dprintk(debug, args...) \
+	do { if (debug) {	\
+		printk(KERN_DEBUG "%s: ",__FUNCTION__);	\
+		printk(args);	\
+	} } while (0)
+
+#ifdef TRACE
+#define ENTER()                 printk(">> enter %s\n", __FUNCTION__)
+#define LEAVE()                 printk("<< leave %s\n", __FUNCTION__)
+#else
+#define ENTER()
+#define LEAVE()
+#endif
+
+#define AS102_DEVICE_MAJOR	192
+
+#define AS102_USB_BUF_SIZE	512
+#define MAX_STREAM_URB		32
+
+#include "as10x_cmd.h"
+
+#if defined(CONFIG_AS102_USB)
+#include "as102_usb_drv.h"
+#endif
+
+#if defined(CONFIG_AS102_SPI)
+#include "as10x_spi_drv.h"
+#endif
+
+
+struct as102_bus_adapter_t {
+#if defined(CONFIG_AS102_USB)
+	struct usb_device *usb_dev;
+#elif defined(CONFIG_AS102_SPI)
+	struct spi_device *spi_dev;
+	struct cdev cdev; /* spidev raw device */
+
+	struct timer_list timer;
+	struct completion xfer_done;
+#endif
+	/* bus token lock */
+	struct mutex lock;
+	/* low level interface for bus adapter */
+	union as10x_bus_token_t {
+#if defined(CONFIG_AS102_USB)
+		/* usb token */
+		struct as10x_usb_token_cmd_t usb;
+#endif
+#if defined(CONFIG_AS102_SPI)
+		/* spi token */
+		struct as10x_spi_token_cmd_t spi;
+#endif
+	} token;
+
+	/* token cmd xfer id */
+	uint16_t cmd_xid;
+
+	/* as10x command and response for dvb interface*/
+	struct as10x_cmd_t *cmd, *rsp;
+
+	/* bus adapter private ops callback */
+	struct as102_priv_ops_t *ops;
+};
+
+struct as102_dev_t {
+	struct as102_bus_adapter_t bus_adap;
+	struct list_head device_entry;
+	struct kref kref;
+	unsigned long minor;
+
+#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE)
+	struct dvb_adapter dvb_adap;
+	struct dvb_frontend dvb_fe;
+	struct dvb_demux dvb_dmx;
+	struct dmxdev dvb_dmxdev;
+#endif
+
+	/* demodulator stats */
+	struct as10x_demod_stats demod_stats;
+	/* signal strength */
+	uint16_t signal_strength;
+	/* bit error rate */
+	uint32_t ber;
+
+	/* timer handle to trig ts stream download */
+	struct timer_list timer_handle;
+
+	struct mutex sem;
+	dma_addr_t dma_addr;
+	void *stream;
+	int streaming;
+	struct urb *stream_urb[MAX_STREAM_URB];
+};
+
+int as102_dvb_register(struct as102_dev_t *dev);
+void as102_dvb_unregister(struct as102_dev_t *dev);
+
+#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE)
+int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe);
+int as102_dvb_unregister_fe(struct dvb_frontend *dev);
+#endif
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
new file mode 100644
index 0000000..3e6f497
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fe.c
@@ -0,0 +1,647 @@
+/*
+ * 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/version.h>
+
+#include "as102_drv.h"
+#include "as10x_types.h"
+#include "as10x_cmd.h"
+
+extern int elna_enable;
+
+#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE)
+static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
+					 struct as10x_tps *src);
+
+static void as102_fe_copy_tune_parameters(struct as10x_tune_args *dst,
+					  struct dvb_frontend_parameters *src);
+
+static void as102_fe_release(struct dvb_frontend *fe) {
+	struct as102_dev_t *dev;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return;
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
+	if (mutex_lock_interruptible(&dev->bus_adap.lock))
+		return;
+
+	/* send abilis command: TURN_OFF */
+	as10x_cmd_turn_off(&dev->bus_adap);
+
+	mutex_unlock(&dev->bus_adap.lock);
+#endif
+
+	/* release frontend callback ops */
+	memset(&fe->ops, 0, sizeof(struct dvb_frontend_ops));
+
+	/* flush statistics */
+	memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
+	dev->signal_strength = 0;
+	dev->ber = -1;
+
+	/* reset tuner private data */
+/* 	fe->tuner_priv = NULL; */
+
+	LEAVE();
+}
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
+static int as102_fe_init(struct dvb_frontend *fe) {
+	int ret = 0;
+	struct as102_dev_t *dev;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&dev->bus_adap.lock))
+		return -EBUSY;
+
+	if (elna_enable)
+		ret = as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0);
+
+	/* send abilis command: TURN_ON */
+	ret = as10x_cmd_turn_on(&dev->bus_adap);
+
+	mutex_unlock(&dev->bus_adap.lock);
+
+	LEAVE();
+	return (ret < 0) ? -EINVAL : 0;
+}
+#endif
+
+static int as102_fe_set_frontend(struct dvb_frontend *fe,
+				 struct dvb_frontend_parameters *params) {
+	int ret = 0;
+	struct as102_dev_t *dev;
+	struct as10x_tune_args tune_args = { 0 };
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&dev->bus_adap.lock))
+		return -EBUSY;
+
+	as102_fe_copy_tune_parameters(&tune_args, params);
+
+	/* send abilis command: SET_TUNE */
+	ret =  as10x_cmd_set_tune(&dev->bus_adap, &tune_args);
+	if(ret != 0) {
+		dprintk(debug, "as10x_cmd_set_tune failed. (err = %d)\n", ret);
+	}
+
+	mutex_unlock(&dev->bus_adap.lock);
+
+	LEAVE();
+	return (ret < 0) ? -EINVAL : 0;
+}
+
+static int as102_fe_get_frontend(struct dvb_frontend* fe,
+				 struct dvb_frontend_parameters *p) {
+	int ret = 0;
+	struct as102_dev_t *dev;
+	struct as10x_tps tps = { 0 };
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -EINVAL;
+
+	if (mutex_lock_interruptible(&dev->bus_adap.lock))
+		return -EBUSY;
+
+	/* send abilis command: GET_TPS */
+	ret = as10x_cmd_get_tps(&dev->bus_adap, &tps);
+
+	if (ret == 0)
+		as10x_fe_copy_tps_parameters(p, &tps);
+
+	mutex_unlock(&dev->bus_adap.lock);
+
+	LEAVE();
+	return (ret < 0) ? -EINVAL : 0;
+}
+
+static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
+			struct dvb_frontend_tune_settings *settings) {
+	ENTER();
+
+#if 0
+	dprintk(debug, "step_size    = %d\n", settings->step_size);
+	dprintk(debug, "max_drift    = %d\n", settings->max_drift);
+	dprintk(debug, "min_delay_ms = %d -> %d\n", settings->min_delay_ms, 1000);
+#endif
+
+	settings->min_delay_ms = 1000;
+
+	LEAVE();
+	return 0;
+}
+
+
+static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status) {
+	int ret = 0;
+	struct as102_dev_t *dev;
+	struct as10x_tune_status tstate = { 0 };
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&dev->bus_adap.lock))
+		return -EBUSY;
+
+	/* send abilis command: GET_TUNE_STATUS */
+	ret = as10x_cmd_get_tune_status(&dev->bus_adap, &tstate);
+	if (ret < 0) {
+		dprintk(debug, "as10x_cmd_get_tune_status failed (err = %d)\n", ret);
+		goto out;
+	}
+
+	dev->signal_strength  = tstate.signal_strength;
+	dev->ber  = tstate.BER;
+
+	switch(tstate.tune_state) {
+		case TUNE_STATUS_SIGNAL_DVB_OK:
+			*status = FE_HAS_SIGNAL |
+				  FE_HAS_CARRIER;
+			break;
+		case TUNE_STATUS_STREAM_DETECTED:
+			*status = FE_HAS_SIGNAL  |
+				  FE_HAS_CARRIER |
+				  FE_HAS_SYNC;
+			break;
+		case TUNE_STATUS_STREAM_TUNED:
+			*status = FE_HAS_SIGNAL  |
+				  FE_HAS_CARRIER |
+				  FE_HAS_SYNC	 |
+				  FE_HAS_LOCK;
+			break;
+		default:
+			*status = TUNE_STATUS_NOT_TUNED;
+	}
+
+	dprintk(debug, "tuner status: 0x%02x , strength %d , per: %d , ber: %d\n",
+			tstate.tune_state, tstate.signal_strength,
+			tstate.PER, tstate.BER);
+
+	if (*status & FE_HAS_LOCK) {
+		if (as10x_cmd_get_demod_stats(&dev->bus_adap,
+				(struct as10x_demod_stats *) &dev->demod_stats) < 0) {
+			memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
+			dprintk(debug, "as10x_cmd_get_demod_stats failed (probably not tuned)\n");
+		} else {
+			dprintk(debug, "demod status: fc: 0x%08x , bad fc: 0x%08x , bytes corrected: 0x%08x , MER: 0x%04x\n",
+					dev->demod_stats.frame_count,
+					dev->demod_stats.bad_frame_count,
+					dev->demod_stats.bytes_fixed_by_rs,
+					dev->demod_stats.mer);
+		}
+	} else {
+		memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
+	}
+
+out:
+	mutex_unlock(&dev->bus_adap.lock);
+	LEAVE();
+	return ret;
+}
+
+/*
+ * Note:
+ * - in AS102 SNR=MER
+ *   - the SNR will be returned in linear terms, i.e. not in dB
+ *   - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
+ *   - the accuracy is >2dB for SNR values outside this range
+ */
+static int as102_fe_read_snr(struct dvb_frontend* fe, u16* snr) {
+	struct as102_dev_t *dev;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	*snr = dev->demod_stats.mer;
+
+	LEAVE();
+	return 0;
+}
+
+static int as102_fe_read_ber(struct dvb_frontend* fe, u32* ber) {
+	struct as102_dev_t *dev;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	*ber = dev->ber;
+
+	LEAVE();
+	return 0;
+}
+
+static int as102_fe_read_signal_strength(struct dvb_frontend* fe, u16* strength) {
+	struct as102_dev_t *dev;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	*strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2);
+
+	LEAVE();
+	return 0;
+}
+
+static int as102_fe_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) {
+	struct as102_dev_t *dev;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	if (dev->demod_stats.has_started)
+		*ucblocks = dev->demod_stats.bad_frame_count;
+	else
+		*ucblocks = 0;
+
+	LEAVE();
+	return 0;
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
+static int as102_fe_ts_bus_ctrl(struct dvb_frontend* fe, int acquire) {
+	struct as102_dev_t *dev;
+	int ret;
+
+	ENTER();
+
+	if ((dev = (struct as102_dev_t *) fe->tuner_priv) == NULL)
+		return -ENODEV;
+
+	if (mutex_lock_interruptible(&dev->bus_adap.lock))
+		return -EBUSY;
+
+	if (acquire) {
+		if (elna_enable)
+			as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0);
+
+		ret = as10x_cmd_turn_on(&dev->bus_adap);
+	} else {
+		ret = as10x_cmd_turn_off(&dev->bus_adap);
+	}
+
+	mutex_unlock(&dev->bus_adap.lock);
+
+	LEAVE();
+	return ret;
+}
+#endif
+
+static struct dvb_frontend_ops as102_fe_ops = {
+	.info = {
+		.name			= DEVICE_FULL_NAME,
+		.type			= FE_OFDM,
+		.frequency_min		= 174000000,
+		.frequency_max		= 862000000,
+		.frequency_stepsize	= 166667,
+		.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_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
+			| FE_CAN_QAM_AUTO
+			| FE_CAN_TRANSMISSION_MODE_AUTO
+			| FE_CAN_GUARD_INTERVAL_AUTO
+			| FE_CAN_HIERARCHY_AUTO
+			| FE_CAN_RECOVER
+			| FE_CAN_MUTE_TS
+	},
+
+	.set_frontend		= as102_fe_set_frontend,
+	.get_frontend		= as102_fe_get_frontend,
+	.get_tune_settings	= as102_fe_get_tune_settings,
+
+
+	.read_status		= as102_fe_read_status,
+	.read_snr		= as102_fe_read_snr,
+	.read_ber		= as102_fe_read_ber,
+	.read_signal_strength	= as102_fe_read_signal_strength,
+	.read_ucblocks		= as102_fe_read_ucblocks,
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
+	.ts_bus_ctrl		= as102_fe_ts_bus_ctrl,
+#else
+	.release		= as102_fe_release,
+	.init			= as102_fe_init,
+#endif
+};
+
+int as102_dvb_unregister_fe(struct dvb_frontend *fe) {
+
+	/* unregister frontend */
+	dvb_unregister_frontend(fe);
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19))
+	/* detach frontend */
+	dvb_frontend_detach(fe);
+#endif
+	return 0;
+}
+
+int as102_dvb_register_fe(struct as102_dev_t *as102_dev, struct dvb_frontend *dvb_fe) {
+	int errno;
+	struct dvb_adapter *dvb_adap;
+
+	if(as102_dev == NULL)
+		return -EINVAL;
+
+	/* extract dvb_adapter */
+	dvb_adap = &as102_dev->dvb_adap;
+
+	/* init frontend callback ops */
+	memcpy(&dvb_fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
+
+	/* register dbvb frontend */
+	errno = dvb_register_frontend(dvb_adap, dvb_fe);
+	if(errno == 0)
+		dvb_fe->tuner_priv = as102_dev;
+
+	return errno;
+}
+
+static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
+					 struct as10x_tps *as10x_tps) {
+
+	struct dvb_ofdm_parameters *fe_tps = &dst->u.ofdm;
+
+	/* extract consteallation */
+	switch(as10x_tps->constellation) {
+		case CONST_QPSK:
+			fe_tps->constellation = QPSK;
+			break;
+		case CONST_QAM16:
+			fe_tps->constellation = QAM_16;
+			break;
+		case CONST_QAM64:
+			fe_tps->constellation = QAM_64;
+			break;
+	}
+
+	/* extract hierarchy */
+	switch(as10x_tps->hierarchy) {
+		case HIER_NONE:
+			fe_tps->hierarchy_information = HIERARCHY_NONE;
+			break;
+		case HIER_ALPHA_1:
+			fe_tps->hierarchy_information = HIERARCHY_1;
+			break;
+		case HIER_ALPHA_2:
+			fe_tps->hierarchy_information = HIERARCHY_2;
+			break;
+		case HIER_ALPHA_4:
+			fe_tps->hierarchy_information = HIERARCHY_4;
+			break;
+	}
+
+	/* extract code rate HP */
+	switch(as10x_tps->code_rate_HP) {
+		case CODE_RATE_1_2:
+			fe_tps->code_rate_HP = FEC_1_2;
+			break;
+		case CODE_RATE_2_3:
+			fe_tps->code_rate_HP = FEC_2_3;
+			break;
+		case CODE_RATE_3_4:
+			fe_tps->code_rate_HP = FEC_3_4;
+			break;
+		case CODE_RATE_5_6:
+			fe_tps->code_rate_HP = FEC_5_6;
+			break;
+		case CODE_RATE_7_8:
+			fe_tps->code_rate_HP = FEC_7_8;
+			break;
+	}
+
+	/* extract code rate LP */
+	switch(as10x_tps->code_rate_LP) {
+		case CODE_RATE_1_2:
+			fe_tps->code_rate_LP = FEC_1_2;
+			break;
+		case CODE_RATE_2_3:
+			fe_tps->code_rate_LP = FEC_2_3;
+			break;
+		case CODE_RATE_3_4:
+			fe_tps->code_rate_LP = FEC_3_4;
+			break;
+		case CODE_RATE_5_6:
+			fe_tps->code_rate_LP = FEC_5_6;
+			break;
+		case CODE_RATE_7_8:
+			fe_tps->code_rate_LP = FEC_7_8;
+			break;
+	}
+
+	/* extract guard interval */
+	switch(as10x_tps->guard_interval) {
+		case GUARD_INT_1_32:
+			fe_tps->guard_interval = GUARD_INTERVAL_1_32;
+			break;
+		case GUARD_INT_1_16:
+			fe_tps->guard_interval = GUARD_INTERVAL_1_16;
+			break;
+		case GUARD_INT_1_8:
+			fe_tps->guard_interval = GUARD_INTERVAL_1_8;
+			break;
+		case GUARD_INT_1_4:
+			fe_tps->guard_interval = GUARD_INTERVAL_1_4;
+			break;
+	}
+
+	/* extract transmission mode */
+	switch(as10x_tps->transmission_mode) {
+		case TRANS_MODE_2K:
+			fe_tps->transmission_mode = TRANSMISSION_MODE_2K;
+			break;
+		case TRANS_MODE_8K:
+			fe_tps->transmission_mode = TRANSMISSION_MODE_8K;
+			break;
+	}
+}
+
+static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg) {
+	uint8_t c;
+
+	switch(arg) {
+		case FEC_1_2:
+			c = CODE_RATE_1_2;
+			break;
+		case FEC_2_3:
+			c = CODE_RATE_2_3;
+			break;
+		case FEC_3_4:
+			c = CODE_RATE_3_4;
+			break;
+		case FEC_5_6:
+			c = CODE_RATE_5_6;
+			break;
+		case FEC_7_8:
+			c = CODE_RATE_7_8;
+			break;
+		default:
+			c = CODE_RATE_UNKNOWN;
+			break;
+	}
+
+	return c;
+}
+
+static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args,
+					  struct dvb_frontend_parameters *params) {
+
+	/* set frequency */
+	tune_args->freq = params->frequency / 1000;
+
+	/* fix interleaving_mode */
+	tune_args->interleaving_mode = INTLV_NATIVE;
+
+	switch(params->u.ofdm.bandwidth) {
+		case BANDWIDTH_8_MHZ:
+			tune_args->bandwidth = BW_8_MHZ;
+			break;
+		case BANDWIDTH_7_MHZ:
+			tune_args->bandwidth = BW_7_MHZ;
+			break;
+		case BANDWIDTH_6_MHZ:
+			tune_args->bandwidth = BW_6_MHZ;
+			break;
+		default:
+			tune_args->bandwidth = BW_8_MHZ;
+	}
+
+	switch(params->u.ofdm.guard_interval) {
+		case GUARD_INTERVAL_1_32:
+			tune_args->guard_interval = GUARD_INT_1_32;
+			break;
+		case GUARD_INTERVAL_1_16:
+			tune_args->guard_interval = GUARD_INT_1_16;
+			break;
+		case GUARD_INTERVAL_1_8:
+			tune_args->guard_interval = GUARD_INT_1_8;
+			break;
+		case GUARD_INTERVAL_1_4:
+			tune_args->guard_interval = GUARD_INT_1_4;
+			break;
+		case GUARD_INTERVAL_AUTO:
+		default:
+			tune_args->guard_interval = GUARD_UNKNOWN;
+			break;
+	}
+
+	switch(params->u.ofdm.constellation) {
+		case QPSK:
+			tune_args->constellation = CONST_QPSK;
+			break;
+		case QAM_16:
+			tune_args->constellation = CONST_QAM16;
+			break;
+		case QAM_64:
+			tune_args->constellation = CONST_QAM64;
+			break;
+		default:
+			tune_args->constellation = CONST_UNKNOWN;
+			break;
+	}
+
+	switch(params->u.ofdm.transmission_mode) {
+		case TRANSMISSION_MODE_2K:
+			tune_args->transmission_mode = TRANS_MODE_2K;
+			break;
+		case TRANSMISSION_MODE_8K:
+			tune_args->transmission_mode = TRANS_MODE_8K;
+			break;
+		default:
+			tune_args->transmission_mode = TRANS_MODE_UNKNOWN;
+	}
+
+	switch(params->u.ofdm.hierarchy_information) {
+		case HIERARCHY_NONE:
+			tune_args->hierarchy = HIER_NONE;
+			break;
+		case HIERARCHY_1:
+			tune_args->hierarchy = HIER_ALPHA_1;
+			break;
+		case HIERARCHY_2:
+			tune_args->hierarchy = HIER_ALPHA_2;
+			break;
+		case HIERARCHY_4:
+			tune_args->hierarchy = HIER_ALPHA_4;
+			break;
+		case HIERARCHY_AUTO:
+			tune_args->hierarchy = HIER_UNKNOWN;
+			break;
+	}
+
+	dprintk(debug, "tuner parameters: freq: %d  bw: 0x%02x  gi: 0x%02x\n",
+			params->frequency,
+			tune_args->bandwidth,
+			tune_args->guard_interval);
+
+	/*
+	 * Detect a hierarchy selection
+	 * if HP/LP are both set to FEC_NONE, HP will be selected.
+	 */
+	if ((tune_args->hierarchy != HIER_NONE) &&
+		       ((params->u.ofdm.code_rate_LP == FEC_NONE) ||
+			(params->u.ofdm.code_rate_HP == FEC_NONE))) {
+
+		if (params->u.ofdm.code_rate_LP == FEC_NONE) {
+			tune_args->hier_select = HIER_HIGH_PRIORITY;
+			tune_args->code_rate =
+				as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
+		}
+
+		if (params->u.ofdm.code_rate_HP == FEC_NONE) {
+			tune_args->hier_select = HIER_LOW_PRIORITY;
+			tune_args->code_rate =
+				as102_fe_get_code_rate(params->u.ofdm.code_rate_LP);
+		}
+
+		dprintk(debug, "\thierarchy: 0x%02x  "
+				"selected: %s  code_rate_%s: 0x%02x\n",
+			tune_args->hierarchy,
+			tune_args->hier_select == HIER_HIGH_PRIORITY ? "HP" : "LP",
+			tune_args->hier_select == HIER_HIGH_PRIORITY ? "HP" : "LP",
+			tune_args->code_rate);
+	} else {
+		tune_args->code_rate = as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
+	}
+}
+#endif
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
new file mode 100644
index 0000000..d921a6f
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fw.c
@@ -0,0 +1,236 @@
+/*
+ * 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/ctype.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+
+#include "as102_drv.h"
+#include "as102_fw.h"
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+char as102_st_fw1[] = "as102_data1_st.hex";
+char as102_st_fw2[] = "as102_data2_st.hex";
+char as102_dt_fw1[] = "as102_data1_dt.hex";
+char as102_dt_fw2[] = "as102_data2_dt.hex";
+
+static unsigned char atohx(unsigned char *dst, char *src) {
+	unsigned char value = 0;
+
+	char msb = tolower(*src) - '0';
+	char lsb = tolower(*(src +1)) - '0';
+
+	if (msb > 9 )
+		msb -= 7;
+	if (lsb > 9 )
+		lsb -= 7;
+
+	*dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
+	return value;
+}
+
+/*
+ * Parse INTEL HEX firmware file to extract address and data.
+ */
+static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
+			  unsigned char *data, int *dataLength,
+			  unsigned char *addr_has_changed) {
+
+	int count = 0;
+	unsigned char *src, dst;
+
+	if (*fw_data++ != ':') {
+		printk(KERN_ERR "invalid firmware file\n");
+		return -EFAULT;
+	}
+
+	/* locate end of line */
+	for (src=fw_data; *src != '\n'; src += 2) {
+		atohx(&dst, src);
+		/* parse line to split addr / data */
+		switch (count) {
+			case 0:
+				*dataLength = dst;
+				break;
+			case 1:
+				addr[2] = dst;
+				break;
+			case 2:
+				addr[3] = dst;
+				break;
+			case 3:
+				/* check if data is an address */
+				if (dst == 0x04)
+					*addr_has_changed = 1;
+				else
+					*addr_has_changed = 0;
+				break;
+			case  4:
+			case  5:
+				if (*addr_has_changed) {
+					addr[(count - 4)] = dst;
+				} else {
+					data[(count - 4)] = dst;
+				}
+				break;
+			default:
+				data[(count - 4)] = dst;
+				break;
+		}
+		count++;
+	}
+
+	/* return read value + ':' + '\n' */
+	return ((count * 2) + 2);
+}
+
+static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap,
+				 unsigned char *cmd,
+				 const struct firmware *firmware) {
+
+	struct as10x_fw_pkt_t fw_pkt;
+	int total_read_bytes = 0, errno = 0;
+	unsigned char addr_has_changed = 0;
+
+	ENTER();
+
+	for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
+		int read_bytes = 0, data_len = 0;
+
+		/* parse intel hex line */
+		read_bytes = parse_hex_line(
+				(u8 *) (firmware->data + total_read_bytes),
+				fw_pkt.raw.address,
+				fw_pkt.raw.data,
+				&data_len,
+				&addr_has_changed);
+
+		if (read_bytes <= 0) {
+			goto error;
+		}
+
+		/* detect the end of file */
+		if ((total_read_bytes += read_bytes) == firmware->size) {
+			fw_pkt.u.request[0] = 0x00;
+			fw_pkt.u.request[1] = 0x03;
+
+			/* send EOF command */
+			if ((errno = bus_adap->ops->upload_fw_pkt(bus_adap,(uint8_t *) &fw_pkt, 2, 0)) < 0)
+				goto error;
+		} else {
+			if (!addr_has_changed) {
+				/* prepare command to send */
+				fw_pkt.u.request[0] = 0x00;
+				fw_pkt.u.request[1] = 0x01;
+
+				data_len += sizeof(fw_pkt.u.request);
+				data_len += sizeof(fw_pkt.raw.address);
+
+				/* send cmd to device */
+				if ((errno = bus_adap->ops->upload_fw_pkt(bus_adap, (uint8_t *) &fw_pkt, data_len, 0)) < 0)
+					goto error;
+			}
+		}
+	}
+error:
+	LEAVE();
+	return (errno == 0) ? total_read_bytes : errno;
+}
+
+int as102_fw_upload(struct as102_bus_adapter_t *bus_adap) {
+	int errno = -EFAULT;
+	const struct firmware *firmware;
+	unsigned char *cmd_buf = NULL;
+	char *fw1, *fw2;
+
+#if defined(CONFIG_AS102_USB)
+	struct usb_device *dev = bus_adap->usb_dev;
+#endif
+#if defined(CONFIG_AS102_SPI)
+	struct spi_device *dev = bus_adap->spi_dev;
+#endif
+	ENTER();
+
+	/* select fw file to upload */
+	if (dual_tuner) {
+		fw1 = as102_dt_fw1;
+		fw2 = as102_dt_fw2;
+	} else {
+		fw1 = as102_st_fw1;
+		fw2 = as102_st_fw2;
+	}
+
+#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
+	/* allocate buffer to store firmware upload command and data */
+	if ((cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL)) == NULL) {
+		errno = -ENOMEM;
+		goto error;
+	}
+
+	/* request kernel to locate firmware file: part1 */
+	if ((errno = request_firmware(&firmware, fw1, &dev->dev)) < 0) {
+		printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
+				 DRIVER_NAME, fw1);
+		goto error;
+	}
+
+	/* initiate firmware upload */
+	if ((errno = as102_firmware_upload(bus_adap, cmd_buf, firmware)) < 0) {
+		printk(KERN_ERR "%s: error during firmware upload part1\n",
+				 DRIVER_NAME);
+		goto error;
+	}
+
+	printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
+			 DRIVER_NAME, fw1);
+	release_firmware(firmware);
+
+	/* wait for boot to complete */
+	mdelay(100);
+
+	/* request kernel to locate firmware file: part2 */
+	if ((errno = request_firmware(&firmware, fw2, &dev->dev)) < 0) {
+		printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
+				 DRIVER_NAME, fw2);
+		goto error;
+	}
+
+	/* initiate firmware upload */
+	if ((errno = as102_firmware_upload(bus_adap, cmd_buf, firmware)) < 0) {
+		printk(KERN_ERR "%s: error during firmware upload part2\n",
+				 DRIVER_NAME);
+		goto error;
+	}
+
+	printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
+			DRIVER_NAME, fw2);
+error:
+	/* free data buffer */
+	kfree(cmd_buf);
+	/* release firmware if needed */
+	if (firmware != NULL)
+		release_firmware(firmware);
+#endif
+	LEAVE();
+	return errno;
+}
+#endif
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h
new file mode 100644
index 0000000..27e5347
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fw.h
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+#define MAX_FW_PKT_SIZE	64
+
+extern int dual_tuner;
+
+#pragma pack(1)
+struct as10x_raw_fw_pkt {
+	unsigned char address[4];
+	unsigned char data[MAX_FW_PKT_SIZE - 6];
+};
+
+struct as10x_fw_pkt_t {
+	union {
+		unsigned char request[2];
+		unsigned char length[2];
+	} u;
+	struct as10x_raw_fw_pkt raw;
+};
+#pragma pack()
+
+#ifdef __KERNEL__
+int as102_fw_upload(struct as102_bus_adapter_t *bus_adap);
+#endif
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
new file mode 100644
index 0000000..ee99396
--- /dev/null
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -0,0 +1,432 @@
+/*
+ * 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/slab.h>
+#include <linux/mm.h>
+#include <linux/usb.h>
+
+#include "as102_drv.h"
+#include "as102_usb_drv.h"
+#include "as102_fw.h"
+
+static void as102_usb_disconnect(struct usb_interface *interface);
+static int as102_usb_probe(struct usb_interface *interface,
+			   const struct usb_device_id *id);
+
+static int as102_usb_start_stream(struct as102_dev_t *dev);
+static void as102_usb_stop_stream(struct as102_dev_t *dev);
+
+static int as102_open(struct inode *inode, struct file *file);
+static int as102_release(struct inode *inode, struct file *file);
+
+static struct usb_device_id as102_usb_id_table[] = {
+	{ USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
+	{ USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
+	{ } /* Terminating entry */
+};
+
+struct usb_driver as102_usb_driver = {
+	.name       =  DRIVER_FULL_NAME,
+	.probe      =  as102_usb_probe,
+	.disconnect =  as102_usb_disconnect,
+	.id_table   =  as102_usb_id_table
+};
+
+struct file_operations as102_dev_fops = {
+	.owner   = THIS_MODULE,
+	.open    = as102_open,
+	.release = as102_release,
+};
+
+static struct usb_class_driver as102_usb_class_driver = {
+	.name		= "aton2-%d",
+	.fops		= &as102_dev_fops,
+	.minor_base	= AS102_DEVICE_MAJOR,
+};
+
+static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap,
+			      unsigned char *send_buf, int send_buf_len,
+			      unsigned char *recv_buf, int recv_buf_len) {
+
+	int ret = 0;
+	ENTER();
+
+	if(send_buf != NULL) {
+		ret = usb_control_msg(bus_adap->usb_dev,
+				      usb_sndctrlpipe(bus_adap->usb_dev, 0),
+				      AS102_USB_DEVICE_TX_CTRL_CMD,
+				      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				      bus_adap->cmd_xid, /* value */
+				      0, /* index */
+				      send_buf, send_buf_len,
+				      USB_CTRL_SET_TIMEOUT /* 200 */);
+		if(ret < 0) {
+			dprintk(debug, "usb_control_msg(send) failed, err %i\n",
+					ret);
+			return ret;
+		}
+
+		if(ret != send_buf_len) {
+			dprintk(debug, "only wrote %d of %d bytes\n",
+					ret, send_buf_len);
+			return -1;
+		}
+	}
+
+	if(recv_buf != NULL) {
+#ifdef TRACE
+		dprintk(debug, "want to read: %d bytes\n", recv_buf_len);
+#endif
+		ret = usb_control_msg(bus_adap->usb_dev,
+				      usb_rcvctrlpipe(bus_adap->usb_dev, 0),
+				      AS102_USB_DEVICE_RX_CTRL_CMD,
+				      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				      bus_adap->cmd_xid, /* value */
+				      0, /* index */
+				      recv_buf, recv_buf_len,
+				      USB_CTRL_GET_TIMEOUT /* 200 */);
+		if(ret < 0) {
+			dprintk(debug, "usb_control_msg(recv) failed, err %i\n",
+					ret);
+			return ret;
+		}
+#ifdef TRACE
+		dprintk(debug, "read %d bytes\n", recv_buf_len);
+#endif
+	}
+
+	LEAVE();
+	return ret;
+}
+
+static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap,
+			  unsigned char *send_buf,
+			  int send_buf_len,
+			  int swap32) {
+
+	int ret = 0, actual_len;
+
+	ret = usb_bulk_msg(bus_adap->usb_dev, usb_sndbulkpipe(bus_adap->usb_dev, 1),
+			   send_buf, send_buf_len, &actual_len, 200);
+	if(ret) {
+		dprintk(debug, "usb_bulk_msg(send) failed, err %i\n", ret);
+		return ret;
+	}
+
+	if(actual_len != send_buf_len) {
+		dprintk(debug, "only wrote %d of %d bytes\n",
+				actual_len, send_buf_len);
+		return -1;
+	}
+	return ret ? ret : actual_len;
+}
+
+static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap,
+		   unsigned char *recv_buf, int recv_buf_len) {
+
+	int ret = 0, actual_len;
+
+	if(recv_buf == NULL)
+		return -EINVAL;
+
+	ret = usb_bulk_msg(bus_adap->usb_dev, usb_rcvbulkpipe(bus_adap->usb_dev, 2),
+			   recv_buf, recv_buf_len, &actual_len, 200);
+	if(ret) {
+		dprintk(debug, "usb_bulk_msg(recv) failed, err %i\n", ret);
+		return ret;
+	}
+
+	if(actual_len != recv_buf_len) {
+		dprintk(debug, "only read %d of %d bytes\n",
+				actual_len, recv_buf_len);
+		return -1;
+	}
+	return ret ? ret : actual_len;
+}
+
+struct as102_priv_ops_t as102_priv_ops = {
+	.upload_fw_pkt	= as102_send_ep1,
+	.xfer_cmd	= as102_usb_xfer_cmd,
+	.as102_read_ep2	= as102_read_ep2,
+	.start_stream	= as102_usb_start_stream,
+	.stop_stream	= as102_usb_stop_stream,
+};
+
+static int as102_submit_urb_stream(struct as102_dev_t *dev, struct urb *urb) {
+	int err;
+
+	usb_fill_bulk_urb(urb,
+			  dev->bus_adap.usb_dev,
+			  usb_rcvbulkpipe(dev->bus_adap.usb_dev, 0x2),
+			  urb->transfer_buffer,
+			  AS102_USB_BUF_SIZE,
+			  as102_urb_stream_irq,
+			  dev);
+
+	if ((err = usb_submit_urb(urb, GFP_ATOMIC)))
+		dprintk(debug, "%s: usb_submit_urb failed\n", __FUNCTION__);
+
+	return err;
+}
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18))
+void as102_urb_stream_irq(struct urb *urb, struct pt_regs *regs)
+#else
+void as102_urb_stream_irq(struct urb *urb)
+#endif
+{
+	struct as102_dev_t *as102_dev = urb->context;
+
+	if (urb->actual_length > 0) {
+#if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE)
+		dvb_dmx_swfilter(&as102_dev->dvb_dmx,
+				 urb->transfer_buffer,
+				 urb->actual_length);
+#else
+		/* do nothing ? */
+#endif
+	} else {
+		if(urb->actual_length == 0)
+			memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE);
+	}
+
+	/* is not stopped, re-submit urb */
+	if (as102_dev->streaming)
+		as102_submit_urb_stream(as102_dev, urb);
+}
+
+static void as102_free_usb_stream_buffer(struct as102_dev_t *dev) {
+	int i;
+
+	ENTER();
+
+	for (i = 0; i < MAX_STREAM_URB; i++)
+		usb_free_urb(dev->stream_urb[i]);
+
+	usb_buffer_free(dev->bus_adap.usb_dev,
+			MAX_STREAM_URB * AS102_USB_BUF_SIZE,
+			dev->stream,
+			dev->dma_addr);
+	LEAVE();
+}
+
+static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev) {
+	int i, ret = 0;
+
+	ENTER();
+
+	dev->stream = usb_buffer_alloc(dev->bus_adap.usb_dev,
+				       MAX_STREAM_URB * AS102_USB_BUF_SIZE,
+				       GFP_KERNEL,
+				       &dev->dma_addr);
+	if (!dev->stream) {
+		dprintk(debug, "%s: usb_buffer_alloc failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE);
+
+	/* init urb buffers */
+	for (i = 0; i < MAX_STREAM_URB; i++) {
+		struct urb *urb;
+
+		if (!(urb = usb_alloc_urb(0, GFP_ATOMIC))) {
+			dprintk(debug, "%s: usb_alloc_urb failed\n", __FUNCTION__);
+			as102_free_usb_stream_buffer(dev);
+			return -ENOMEM;
+		}
+
+		urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE);
+		urb->transfer_buffer_length = AS102_USB_BUF_SIZE;
+
+		dev->stream_urb[i] = urb;
+	}
+	LEAVE();
+	return ret;
+}
+
+static void as102_usb_stop_stream(struct as102_dev_t *dev) {
+	int i;
+
+	for (i = 0; i < MAX_STREAM_URB; i++)
+		usb_kill_urb(dev->stream_urb[i]);
+}
+
+static int as102_usb_start_stream(struct as102_dev_t *dev) {
+	int i, ret = 0;
+
+	for (i = 0; i < MAX_STREAM_URB; i++) {
+		if ((ret = as102_submit_urb_stream(dev, dev->stream_urb[i]))) {
+			as102_usb_stop_stream(dev);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+static void as102_usb_release(struct kref *kref) {
+	struct as102_dev_t *as102_dev;
+
+	ENTER();
+
+	as102_dev = container_of(kref, struct as102_dev_t, kref);
+	if (as102_dev != NULL) {
+		usb_put_dev(as102_dev->bus_adap.usb_dev);
+		kfree(as102_dev);
+	}
+
+	LEAVE();
+}
+
+static void as102_usb_disconnect(struct usb_interface *intf) {
+	struct as102_dev_t *as102_dev;
+
+	ENTER();
+
+	/* extract as102_dev_t from usb_device private data */
+	as102_dev = usb_get_intfdata(intf);
+
+	/* unregister dvb layer */
+	as102_dvb_unregister(as102_dev);
+
+	/* free usb buffers */
+	as102_free_usb_stream_buffer(as102_dev);
+
+	usb_set_intfdata(intf, NULL);
+
+	/* usb unregister device */
+	usb_deregister_dev(intf, &as102_usb_class_driver);
+
+	/* decrement usage counter */
+	kref_put(&as102_dev->kref, as102_usb_release);
+
+	printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME);
+
+	LEAVE();
+}
+
+static int as102_usb_probe(struct usb_interface *intf,
+			   const struct usb_device_id *id) {
+	int ret;
+	struct as102_dev_t *as102_dev;
+
+	ENTER();
+
+	if(!(as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL))) {
+		err("%s: kzalloc failed", __FUNCTION__);
+		return -ENOMEM;
+	}
+
+	/* set private callback functions */
+	as102_dev->bus_adap.ops = &as102_priv_ops;
+
+	/* init cmd token for usb bus */
+	as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c;
+	as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r;
+
+	/* init kernel device reference */
+	kref_init(&as102_dev->kref);
+
+	/* store as102 device to usb_device private data */
+	usb_set_intfdata(intf, (void *) as102_dev);
+
+	/* store in as102 device the usb_device pointer */
+	as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf));
+
+	/* we can register the device now, as it is ready */
+	if((ret = usb_register_dev(intf, &as102_usb_class_driver)) < 0) {;
+		/* something prevented us from registering this driver */
+		err("%s: usb_register_dev() failed (errno = %d)",
+		    __FUNCTION__, ret);
+		goto failed;
+	}
+
+	printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME);
+
+	/* request buffer allocation for streaming */
+	if ((ret = as102_alloc_usb_stream_buffer(as102_dev)) != 0)
+		goto failed;
+
+	/* register dvb layer */
+	ret = as102_dvb_register(as102_dev);
+
+	LEAVE();
+	return ret;
+
+failed:
+	usb_set_intfdata(intf, NULL);
+	kfree(as102_dev);
+	return ret;
+}
+
+static int as102_open(struct inode *inode, struct file *file) {
+	int ret = 0, minor = 0;
+	struct usb_interface *intf = NULL;
+	struct as102_dev_t *dev = NULL;
+
+	ENTER();
+
+	/* read minor from inode */
+	minor = iminor(inode);
+
+	/* fetch device from usb interface */
+	if((intf = usb_find_interface(&as102_usb_driver, minor)) == NULL) {
+		printk(KERN_ERR "%s: can't find device for minor %d\n",
+				__FUNCTION__, minor);
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	/* get our device */
+	if((dev = usb_get_intfdata(intf)) == NULL) {
+		ret = -EFAULT;
+		goto exit;
+	}
+
+	/* save our device object in the file's private structure */
+	file->private_data = dev;
+
+	/* increment our usage count for the device */
+	kref_get(&dev->kref);
+
+exit:
+	LEAVE();
+	return ret;
+}
+
+static int as102_release(struct inode *inode, struct file *file) {
+	int ret = 0;
+	struct as102_dev_t *dev = NULL;
+
+	ENTER();
+
+	if((dev = file->private_data) != NULL ) {
+		/* decrement the count on our device */
+		kref_put(&dev->kref, as102_usb_release);
+	}
+
+	LEAVE();
+	return ret;
+}
+
+MODULE_DEVICE_TABLE(usb, as102_usb_id_table);
+
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h
new file mode 100644
index 0000000..abb858e
--- /dev/null
+++ b/drivers/staging/media/as102/as102_usb_drv.h
@@ -0,0 +1,54 @@
+/*
+ * 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/version.h>
+
+#ifndef _AS102_USB_DRV_H_
+#define _AS102_USB_DRV_H_
+
+#define AS102_USB_DEVICE_TX_CTRL_CMD	0xF1
+#define AS102_USB_DEVICE_RX_CTRL_CMD	0xF2
+
+/* define these values to match the supported devices */
+
+/* Abilis system: "TITAN" */
+#define AS102_USB_DEVICE_VENDOR_ID	0x1BA6
+#define AS102_USB_DEVICE_PID_0001	0x0001
+
+/* PCTV Systems: PCTV picoStick (74e) */
+#define DEVICE_FULL_NAME		"PCTV Systems : PCTV picoStick (74e)"
+#define PCTV_74E_USB_VID		0x2013
+#define PCTV_74E_USB_PID		0x0246
+
+extern struct file_operations as102_dev_fops;
+
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18))
+void as102_urb_stream_irq(struct urb *urb, struct pt_regs *regs);
+#else
+void as102_urb_stream_irq(struct urb *urb);
+#endif
+
+
+struct as10x_usb_token_cmd_t {
+	/* token cmd */
+	struct as10x_cmd_t c;
+	/* token response */
+	struct as10x_cmd_t r;
+};
+#endif
+/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
new file mode 100644
index 0000000..cecb809
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd.c
@@ -0,0 +1,478 @@
+/*
+ * 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.
+ */
+
+#if defined(LINUX) && defined(__KERNEL__) /* linux kernel implementation */
+#include <linux/kernel.h>
+#include "as102_drv.h"
+#elif defined(WIN32)
+   #if defined(__BUILDMACHINE__) && (__BUILDMACHINE__ == WinDDK)  /* win32 ddk implementation */
+      #include "wdm.h"
+      #include "Device.h"
+      #include "endian_mgmt.h" /* FIXME */
+   #else /* win32 sdk implementation */
+      #include <windows.h>
+      #include "types.h"
+      #include "util.h"
+      #include "as10x_handle.h"
+      #include "endian_mgmt.h"
+   #endif
+#else /* all other cases */
+   #include <string.h>
+   #include "types.h"
+   #include "util.h"
+   #include "as10x_handle.h"
+   #include "endian_mgmt.h" /* FIXME */
+#endif /* __KERNEL__ */
+
+#include "as10x_types.h"
+#include "as10x_cmd.h"
+
+/**
+   \brief  send turn on command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \return 0 when no error, < 0 in case of error.
+  \callgraph
+*/
+int as10x_cmd_turn_on(as10x_handle_t *phandle)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd,(++phandle->cmd_xid), sizeof(pcmd->body.turn_on.req));
+
+   /* fill command */
+   pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(
+			phandle,
+			(uint8_t *) pcmd,
+			sizeof(pcmd->body.turn_on.req) + HEADER_SIZE,
+			(uint8_t *) prsp,
+			sizeof(prsp->body.turn_on.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send turn off command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_turn_off(as10x_handle_t *phandle)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd,(++phandle->cmd_xid),sizeof(pcmd->body.turn_off.req));
+
+   /* fill command */
+   pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(
+			phandle, (uint8_t *) pcmd,
+			sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
+			 (uint8_t *) prsp,
+			sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send set tune command to AS10x
+   \param  phandle: pointer to AS10x handle
+   \param  ptune:   tune parameters
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+ */
+int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune)
+{
+   int error;
+   struct as10x_cmd_t *preq, *prsp;
+
+   ENTER();
+
+   preq = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(preq,(++phandle->cmd_xid),sizeof(preq->body.set_tune.req));
+
+   /* fill command */
+   preq->body.set_tune.req.proc_id                 = cpu_to_le16(CONTROL_PROC_SETTUNE);
+   preq->body.set_tune.req.args.freq               = cpu_to_le32(ptune->freq);
+   preq->body.set_tune.req.args.bandwidth          = ptune->bandwidth;
+   preq->body.set_tune.req.args.hier_select        = ptune->hier_select;
+   preq->body.set_tune.req.args.constellation      = ptune->constellation;
+   preq->body.set_tune.req.args.hierarchy          = ptune->hierarchy;
+   preq->body.set_tune.req.args.interleaving_mode  = ptune->interleaving_mode;
+   preq->body.set_tune.req.args.code_rate          = ptune->code_rate;
+   preq->body.set_tune.req.args.guard_interval     = ptune->guard_interval;
+   preq->body.set_tune.req.args.transmission_mode  = ptune->transmission_mode;
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(phandle,
+			(uint8_t *) preq,
+			sizeof(preq->body.set_tune.req) + HEADER_SIZE,
+			(uint8_t *) prsp,
+			sizeof(prsp->body.set_tune.rsp) + HEADER_SIZE);
+   } else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send get tune status command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \param  pstatus:   pointer to updated status structure of the current tune
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+ */
+int as10x_cmd_get_tune_status(as10x_handle_t *phandle, struct as10x_tune_status *pstatus)
+{
+   int error;
+   struct as10x_cmd_t  *preq, *prsp;
+
+   ENTER();
+
+   preq = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(preq,(++phandle->cmd_xid),
+		   sizeof(preq->body.get_tune_status.req));
+
+   /* fill command */
+   preq->body.get_tune_status.req.proc_id =
+			cpu_to_le16(CONTROL_PROC_GETTUNESTAT);
+
+   /* send command */
+   if (phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(
+			phandle,
+			(uint8_t *) preq,
+			sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
+			(uint8_t *) prsp,
+			sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if (error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTUNESTAT_RSP);
+   if (error < 0) {
+      goto out;
+   }
+
+   /* Response OK -> get response data */
+   pstatus->tune_state       = prsp->body.get_tune_status.rsp.sts.tune_state;
+   pstatus->signal_strength  =
+		   le16_to_cpu(prsp->body.get_tune_status.rsp.sts.signal_strength);
+   pstatus->PER              = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.PER);
+   pstatus->BER              = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send get TPS command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \param  ptps:      pointer to TPS parameters structure
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+ */
+int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps)
+{
+
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),sizeof(pcmd->body.get_tps.req));
+
+   /* fill command */
+   pcmd->body.get_tune_status.req.proc_id = cpu_to_le16(CONTROL_PROC_GETTPS);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(phandle,
+	       (uint8_t *) pcmd, sizeof(pcmd->body.get_tps.req) + HEADER_SIZE,
+	       (uint8_t *) prsp, sizeof(prsp->body.get_tps.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTPS_RSP);
+   if (error < 0) {
+      goto out;
+   }
+
+   /* Response OK -> get response data */
+   ptps->constellation      = prsp->body.get_tps.rsp.tps.constellation;
+   ptps->hierarchy          = prsp->body.get_tps.rsp.tps.hierarchy;
+   ptps->interleaving_mode  = prsp->body.get_tps.rsp.tps.interleaving_mode;
+   ptps->code_rate_HP       = prsp->body.get_tps.rsp.tps.code_rate_HP;
+   ptps->code_rate_LP       = prsp->body.get_tps.rsp.tps.code_rate_LP;
+   ptps->guard_interval     = prsp->body.get_tps.rsp.tps.guard_interval;
+   ptps->transmission_mode  = prsp->body.get_tps.rsp.tps.transmission_mode;
+   ptps->DVBH_mask_HP       = prsp->body.get_tps.rsp.tps.DVBH_mask_HP;
+   ptps->DVBH_mask_LP       = prsp->body.get_tps.rsp.tps.DVBH_mask_LP;
+   ptps->cell_ID            = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send get demod stats command to AS10x
+   \param  phandle:       pointer to AS10x handle
+   \param  pdemod_stats:  pointer to demod stats parameters structure
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_get_demod_stats(as10x_handle_t  *phandle,
+			      struct as10x_demod_stats *pdemod_stats)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		   sizeof(pcmd->body.get_demod_stats.req));
+
+   /* fill command */
+   pcmd->body.get_demod_stats.req.proc_id =
+      cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(phandle,
+			 (uint8_t *) pcmd,
+			 sizeof(pcmd->body.get_demod_stats.req) + HEADER_SIZE,
+			 (uint8_t *) prsp,
+			 sizeof(prsp->body.get_demod_stats.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp,CONTROL_PROC_GET_DEMOD_STATS_RSP);
+   if (error < 0) {
+      goto out;
+   }
+
+   /* Response OK -> get response data */
+   pdemod_stats->frame_count =
+	   le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.frame_count);
+   pdemod_stats->bad_frame_count =
+	   le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bad_frame_count);
+   pdemod_stats->bytes_fixed_by_rs =
+	   le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs);
+   pdemod_stats->mer =
+	   le16_to_cpu(prsp->body.get_demod_stats.rsp.stats.mer);
+   pdemod_stats->has_started =
+	   prsp->body.get_demod_stats.rsp.stats.has_started;
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send get impulse response command to AS10x
+   \param  phandle:        pointer to AS10x handle
+   \param  is_ready:       pointer to value indicating when impulse
+			   response data is ready
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_get_impulse_resp(as10x_handle_t     *phandle,
+			       uint8_t *is_ready)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		   sizeof(pcmd->body.get_impulse_rsp.req));
+
+   /* fill command */
+   pcmd->body.get_impulse_rsp.req.proc_id =
+      cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(phandle,
+			 (uint8_t *) pcmd,
+			 sizeof(pcmd->body.get_impulse_rsp.req) + HEADER_SIZE,
+			 (uint8_t *) prsp,
+			 sizeof(prsp->body.get_impulse_rsp.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp,CONTROL_PROC_GET_IMPULSE_RESP_RSP);
+   if (error < 0) {
+      goto out;
+   }
+
+   /* Response OK -> get response data */
+   *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
+
+out:
+   LEAVE();
+   return(error);
+}
+
+
+
+/**
+   \brief  build AS10x command header
+   \param  pcmd:     pointer to AS10x command buffer
+   \param  xid:      sequence id of the command
+   \param  cmd_len:  lenght of the command
+   \return -
+   \callgraph
+*/
+void as10x_cmd_build(struct as10x_cmd_t *pcmd,
+		     uint16_t xid, uint16_t cmd_len)
+{
+   pcmd->header.req_id = cpu_to_le16(xid);
+   pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID);
+   pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION);
+   pcmd->header.data_len = cpu_to_le16(cmd_len);
+}
+
+/**
+   \brief  Parse command response
+   \param  pcmd:       pointer to AS10x command buffer
+   \param  cmd_seqid:  sequence id of the command
+   \param  cmd_len:    lenght of the command
+   \return 0 when no error, < 0 in case of error
+   \callgraph
+*/
+int as10x_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
+{
+   int error;
+
+   /* extract command error code */
+   error = prsp->body.common.rsp.error;
+
+   if((error == 0) && (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) {
+      return 0;
+   }
+
+   return AS10X_CMD_ERROR;
+}
+
+
diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h
new file mode 100644
index 0000000..01a7163
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd.h
@@ -0,0 +1,540 @@
+/*
+ * 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.
+ */
+#ifndef _AS10X_CMD_H_
+#define _AS10X_CMD_H_
+
+#ifdef __KERNEL__
+#include <linux/kernel.h>
+#endif
+
+#include "as10x_types.h"
+
+/*********************************/
+/*       MACRO DEFINITIONS       */
+/*********************************/
+#define AS10X_CMD_ERROR -1
+
+#define SERVICE_PROG_ID        0x0002
+#define SERVICE_PROG_VERSION   0x0001
+
+#define HIER_NONE              0x00
+#define HIER_LOW_PRIORITY      0x01
+
+#define HEADER_SIZE (sizeof(struct as10x_cmd_header_t))
+
+/* context request types */
+#define GET_CONTEXT_DATA        1
+#define SET_CONTEXT_DATA        2
+
+/* ODSP suspend modes */
+#define CFG_MODE_ODSP_RESUME  0
+#define CFG_MODE_ODSP_SUSPEND 1
+
+/* Dump memory size */
+#define DUMP_BLOCK_SIZE_MAX   0x20
+
+/*********************************/
+/*     TYPE DEFINITION           */
+/*********************************/
+typedef enum {
+   CONTROL_PROC_TURNON               = 0x0001,
+   CONTROL_PROC_TURNON_RSP           = 0x0100,
+   CONTROL_PROC_SET_REGISTER         = 0x0002,
+   CONTROL_PROC_SET_REGISTER_RSP     = 0x0200,
+   CONTROL_PROC_GET_REGISTER         = 0x0003,
+   CONTROL_PROC_GET_REGISTER_RSP     = 0x0300,
+   CONTROL_PROC_SETTUNE              = 0x000A,
+   CONTROL_PROC_SETTUNE_RSP          = 0x0A00,
+   CONTROL_PROC_GETTUNESTAT          = 0x000B,
+   CONTROL_PROC_GETTUNESTAT_RSP      = 0x0B00,
+   CONTROL_PROC_GETTPS               = 0x000D,
+   CONTROL_PROC_GETTPS_RSP           = 0x0D00,
+   CONTROL_PROC_SETFILTER            = 0x000E,
+   CONTROL_PROC_SETFILTER_RSP        = 0x0E00,
+   CONTROL_PROC_REMOVEFILTER         = 0x000F,
+   CONTROL_PROC_REMOVEFILTER_RSP     = 0x0F00,
+   CONTROL_PROC_GET_IMPULSE_RESP     = 0x0012,
+   CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200,
+   CONTROL_PROC_START_STREAMING      = 0x0013,
+   CONTROL_PROC_START_STREAMING_RSP  = 0x1300,
+   CONTROL_PROC_STOP_STREAMING       = 0x0014,
+   CONTROL_PROC_STOP_STREAMING_RSP   = 0x1400,
+   CONTROL_PROC_GET_DEMOD_STATS      = 0x0015,
+   CONTROL_PROC_GET_DEMOD_STATS_RSP  = 0x1500,
+   CONTROL_PROC_ELNA_CHANGE_MODE     = 0x0016,
+   CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600,
+   CONTROL_PROC_ODSP_CHANGE_MODE     = 0x0017,
+   CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700,
+   CONTROL_PROC_AGC_CHANGE_MODE      = 0x0018,
+   CONTROL_PROC_AGC_CHANGE_MODE_RSP  = 0x1800,
+
+   CONTROL_PROC_CONTEXT              = 0x00FC,
+   CONTROL_PROC_CONTEXT_RSP          = 0xFC00,
+   CONTROL_PROC_DUMP_MEMORY          = 0x00FD,
+   CONTROL_PROC_DUMP_MEMORY_RSP      = 0xFD00,
+   CONTROL_PROC_DUMPLOG_MEMORY       = 0x00FE,
+   CONTROL_PROC_DUMPLOG_MEMORY_RSP   = 0xFE00,
+   CONTROL_PROC_TURNOFF              = 0x00FF,
+   CONTROL_PROC_TURNOFF_RSP          = 0xFF00
+} control_proc;
+
+
+#pragma pack(1)
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} TURN_ON;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t err;
+   } rsp;
+} TURN_OFF;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* tune params */
+      struct as10x_tune_args args;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+   } rsp;
+} SET_TUNE;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+      /* tune status */
+      struct as10x_tune_status sts;
+   } rsp;
+} GET_TUNE_STATUS;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+      /* tps details */
+      struct as10x_tps tps;
+   } rsp;
+} GET_TPS;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t  proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+   } rsp;
+} COMMON;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t  proc_id;
+      /* PID to filter */
+      uint16_t  pid;
+      /* stream type (MPE, PSI/SI or PES )*/
+      uint8_t stream_type;
+      /* PID index in filter table */
+      uint8_t idx;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+      /* Filter id */
+      uint8_t filter_id;
+   } rsp;
+} ADD_PID_FILTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t  proc_id;
+      /* PID to remove */
+      uint16_t  pid;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* response error */
+      uint8_t error;
+   } rsp;
+} DEL_PID_FILTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} START_STREAMING;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} STOP_STREAMING;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* demod stats */
+      struct as10x_demod_stats stats;
+   } rsp;
+} GET_DEMOD_STATS;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* impulse response ready */
+      uint8_t is_ready;
+   } rsp;
+} GET_IMPULSE_RESP;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* value to write (for set context)*/
+      struct as10x_register_value reg_val;
+      /* context tag */
+      uint16_t tag;
+      /* context request type */
+      uint16_t type;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* value read (for get context) */
+      struct as10x_register_value reg_val;
+      /* context request type */
+      uint16_t type;
+      /* error */
+      uint8_t error;
+   } rsp;
+} FW_CONTEXT;
+
+typedef union {
+   /* request */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* register description */
+      struct as10x_register_addr reg_addr;
+      /* register content */
+      struct as10x_register_value reg_val;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} SET_REGISTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* register description */
+      struct as10x_register_addr reg_addr;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* register content */
+      struct as10x_register_value reg_val;
+   } rsp;
+} GET_REGISTER;
+
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* mode */
+      uint8_t mode;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+   } rsp;
+} CFG_CHANGE_MODE;
+
+struct as10x_cmd_header_t {
+   uint16_t req_id;
+   uint16_t prog;
+   uint16_t version;
+   uint16_t data_len;
+};
+
+#define DUMP_BLOCK_SIZE 16
+typedef union {
+   /* request */
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* dump memory type request */
+      uint8_t dump_req;
+      /* register description */
+      struct as10x_register_addr reg_addr;
+      /* nb blocks to read */
+      uint16_t num_blocks;
+   } req;
+   /* response */
+   struct {
+      /* response identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* dump response */
+      uint8_t dump_rsp;
+      /* data */
+      union {
+	 uint8_t  data8[DUMP_BLOCK_SIZE];
+	 uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)];
+	 uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)];
+      } u;
+   } rsp;
+} DUMP_MEMORY;
+
+typedef union {
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* dump memory type request */
+      uint8_t dump_req;
+   } req;
+   struct {
+      /* request identifier */
+      uint16_t proc_id;
+      /* error */
+      uint8_t error;
+      /* dump response */
+      uint8_t dump_rsp;
+      /* dump data */
+      uint8_t data[DUMP_BLOCK_SIZE];
+   } rsp;
+} DUMPLOG_MEMORY;
+
+typedef union {
+   /* request */
+   struct {
+      uint16_t proc_id;
+      uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */];
+   } req;
+   /* response */
+   struct {
+      uint16_t proc_id;
+      uint8_t error;
+      uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */
+		      - 2 /* proc_id */ - 1 /* rc */];
+   } rsp;
+} RAW_DATA;
+
+struct as10x_cmd_t {
+   /* header */
+   struct as10x_cmd_header_t header;
+   /* body */
+   union {
+      TURN_ON           turn_on;
+      TURN_OFF          turn_off;
+      SET_TUNE          set_tune;
+      GET_TUNE_STATUS   get_tune_status;
+      GET_TPS           get_tps;
+      COMMON            common;
+      ADD_PID_FILTER    add_pid_filter;
+      DEL_PID_FILTER    del_pid_filter;
+      START_STREAMING   start_streaming;
+      STOP_STREAMING    stop_streaming;
+      GET_DEMOD_STATS   get_demod_stats;
+      GET_IMPULSE_RESP  get_impulse_rsp;
+      FW_CONTEXT        context;
+      SET_REGISTER      set_register;
+      GET_REGISTER      get_register;
+      CFG_CHANGE_MODE   cfg_change_mode;
+      DUMP_MEMORY       dump_memory;
+      DUMPLOG_MEMORY    dumplog_memory;
+      RAW_DATA          raw_data;
+   } body;
+};
+
+struct as10x_token_cmd_t {
+   /* token cmd */
+   struct as10x_cmd_t c;
+   /* token response */
+   struct as10x_cmd_t r;
+};
+#pragma pack()
+
+
+/**************************/
+/* FUNCTION DECLARATION   */
+/**************************/
+
+void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id,
+		      uint16_t cmd_len);
+int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* as10x cmd */
+int as10x_cmd_turn_on(as10x_handle_t *phandle);
+int as10x_cmd_turn_off(as10x_handle_t *phandle);
+
+int as10x_cmd_set_tune(as10x_handle_t *phandle,
+		       struct as10x_tune_args *ptune);
+
+int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
+			      struct as10x_tune_status *pstatus);
+
+int as10x_cmd_get_tps(as10x_handle_t *phandle,
+		      struct as10x_tps *ptps);
+
+int as10x_cmd_get_demod_stats(as10x_handle_t  *phandle,
+			      struct as10x_demod_stats *pdemod_stats);
+
+int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
+			       uint8_t *is_ready);
+
+/* as10x cmd stream */
+int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
+			     struct as10x_ts_filter *filter);
+int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
+			     uint16_t pid_value);
+
+int as10x_cmd_start_streaming(as10x_handle_t *phandle);
+int as10x_cmd_stop_streaming(as10x_handle_t *phandle);
+
+/* as10x cmd cfg */
+int as10x_cmd_set_context(as10x_handle_t *phandle,
+			  uint16_t tag,
+			  uint32_t value);
+int as10x_cmd_get_context(as10x_handle_t *phandle,
+			  uint16_t tag,
+			  uint32_t *pvalue);
+
+int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode);
+int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id);
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c
new file mode 100644
index 0000000..e3a0f90
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd_cfg.c
@@ -0,0 +1,239 @@
+/**
+
+ \file   as10x_cmd_cfg.c
+
+ \version $Id$
+
+ \author: S. Martinelli
+
+ ----------------------------------------------------------------------------\n
+   (c) Copyright Abilis Systems SARL 2005-2009 All rigths reserved \n
+   www.abilis.com                                                  \n
+ ----------------------------------------------------------------------------\n
+
+ \brief AS10x API, configuration services
+
+	AS10x cmd management: build command buffer, send command through
+	selected port and wait for the response when required.
+
+*/
+
+#if defined(LINUX) && defined(__KERNEL__) /* linux kernel implementation */
+#include <linux/kernel.h>
+#include "as102_drv.h"
+#elif defined(WIN32)
+   #if defined(__BUILDMACHINE__) && (__BUILDMACHINE__ == WinDDK)  /* win32 ddk implementation */
+      #include "wdm.h"
+      #include "Device.h"
+      #include "endian_mgmt.h" /* FIXME */
+   #else /* win32 sdk implementation */
+      #include <windows.h>
+      #include "types.h"
+      #include "util.h"
+      #include "as10x_handle.h"
+      #include "endian_mgmt.h"
+   #endif
+#else /* all other cases */
+   #include <string.h>
+   #include "types.h"
+   #include "util.h"
+   #include "as10x_handle.h"
+   #include "endian_mgmt.h" /* FIXME */
+#endif /* __KERNEL__ */
+
+#include "as10x_types.h"
+#include "as10x_cmd.h"
+
+/***************************/
+/* FUNCTION DEFINITION     */
+/***************************/
+
+/**
+   \brief  send get context command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \param  tag:       context tag
+   \param  pvalue:    pointer where to store context value read
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag,
+			  uint32_t *pvalue)
+{
+   int  error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		    sizeof(pcmd->body.context.req));
+
+   /* fill command */
+   pcmd->body.context.req.proc_id      = cpu_to_le16(CONTROL_PROC_CONTEXT);
+   pcmd->body.context.req.tag          = cpu_to_le16(tag);
+   pcmd->body.context.req.type         = cpu_to_le16(GET_CONTEXT_DATA);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error  = phandle->ops->xfer_cmd(phandle,
+			   (uint8_t *) pcmd,
+			   sizeof(pcmd->body.context.req) + HEADER_SIZE,
+			   (uint8_t *) prsp,
+			   sizeof(prsp->body.context.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response: context command do not follow the common response */
+   /* structure -> specific handling response parse required            */
+   error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
+
+   if(error == 0) {
+     /* Response OK -> get response data */
+      *pvalue = le32_to_cpu(prsp->body.context.rsp.reg_val.u.value32);
+     /* value returned is always a 32-bit value */
+   }
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send set context command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \param  tag:       context tag
+   \param  value:     value to set in context
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag,
+			  uint32_t value)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd,(++phandle->cmd_xid),sizeof(pcmd->body.context.req));
+
+   /* fill command */
+   pcmd->body.context.req.proc_id      = cpu_to_le16(CONTROL_PROC_CONTEXT);
+      /* pcmd->body.context.req.reg_val.mode initialization is not required */
+   pcmd->body.context.req.reg_val.u.value32 = cpu_to_le32(value);
+   pcmd->body.context.req.tag          = cpu_to_le16(tag);
+   pcmd->body.context.req.type         = cpu_to_le16(SET_CONTEXT_DATA);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd){
+      error  = phandle->ops->xfer_cmd(phandle,
+				(uint8_t *) pcmd,
+				sizeof(pcmd->body.context.req) + HEADER_SIZE,
+				(uint8_t *) prsp,
+				sizeof(prsp->body.context.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response: context command do not follow the common response */
+   /* structure -> specific handling response parse required            */
+   error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  send eLNA change mode command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \param  tag:       context tag
+   \param  mode:      mode selected:
+		     - ON    : 0x0 => eLNA always ON
+		     - OFF   : 0x1 => eLNA always OFF
+		     - AUTO  : 0x2 => eLNA follow hysteresis parameters to be
+				      ON or OFF
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		   sizeof(pcmd->body.cfg_change_mode.req));
+
+   /* fill command */
+   pcmd->body.cfg_change_mode.req.proc_id =
+				    cpu_to_le16(CONTROL_PROC_ELNA_CHANGE_MODE);
+   pcmd->body.cfg_change_mode.req.mode    = mode;
+
+   /* send command */
+   if(phandle->ops->xfer_cmd){
+      error  = phandle->ops->xfer_cmd(phandle,
+			 (uint8_t *) pcmd,
+			 sizeof(pcmd->body.cfg_change_mode.req) + HEADER_SIZE,
+			 (uint8_t *) prsp,
+			 sizeof(prsp->body.cfg_change_mode.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  Parse context command response. Since this command does not follow
+	   the common response, a specific parse function is required.
+   \param  prsp:       pointer to AS10x command response buffer
+   \param  proc_id:    id of the command
+   \return 0 when no error, < 0 in case of error.
+	   ABILIS_RC_NOK
+   \callgraph
+*/
+int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id) {
+
+   int err;
+
+   err = prsp->body.context.rsp.error;
+
+   if((err == 0) &&
+      (le16_to_cpu(prsp->body.context.rsp.proc_id) == proc_id)) {
+      return 0;
+   }
+   return AS10X_CMD_ERROR;
+}
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c
new file mode 100644
index 0000000..4dfacf4
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd_stream.c
@@ -0,0 +1,256 @@
+/**
+
+ \file   as10x_cmd_stream.c
+
+ \version $Id$
+
+ \author: S. Martinelli
+
+ ----------------------------------------------------------------------------\n
+   (c) Copyright Abilis Systems SARL 2005-2009 All rigths reserved \n
+   www.abilis.com                                                  \n
+ ----------------------------------------------------------------------------\n
+
+ \brief AS10x CMD, stream services
+
+	AS10x CMD management: build command buffer, send command through
+	selected port and wait for the response when required.
+
+*/
+
+
+#if defined(LINUX) && defined(__KERNEL__) /* linux kernel implementation */
+#include <linux/kernel.h>
+#include "as102_drv.h"
+#elif defined(WIN32)
+    #if defined(DDK) /* win32 ddk implementation */
+	#include "wdm.h"
+	#include "Device.h"
+	#include "endian_mgmt.h" /* FIXME */
+    #else /* win32 sdk implementation */
+	#include <windows.h>
+	#include "types.h"
+	#include "util.h"
+	#include "as10x_handle.h"
+	#include "endian_mgmt.h"
+    #endif
+#else /* all other cases */
+    #include <string.h>
+    #include "types.h"
+    #include "util.h"
+    #include "as10x_handle.h"
+    #include "endian_mgmt.h" /* FIXME */
+#endif /* __KERNEL__ */
+
+#include "as10x_cmd.h"
+
+
+/**
+   \brief  send add filter command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \param  filter:    TSFilter filter for DVB-T
+   \param  pfilter_handle: pointer where to store filter handle
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_add_PID_filter(as10x_handle_t* phandle,
+			     struct as10x_ts_filter *filter) {
+   int    error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		    sizeof(pcmd->body.add_pid_filter.req));
+
+   /* fill command */
+   pcmd->body.add_pid_filter.req.proc_id = cpu_to_le16(CONTROL_PROC_SETFILTER);
+   pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
+   pcmd->body.add_pid_filter.req.stream_type = filter->type;
+
+   if(filter->idx < 16)
+	pcmd->body.add_pid_filter.req.idx = filter->idx;
+   else
+	pcmd->body.add_pid_filter.req.idx = 0xFF;
+
+   /* send command */
+   if(phandle->ops->xfer_cmd) {
+      error = phandle->ops->xfer_cmd(phandle,
+		       (uint8_t *) pcmd,
+		       sizeof(pcmd->body.add_pid_filter.req) + HEADER_SIZE,
+		       (uint8_t *) prsp,
+		       sizeof(prsp->body.add_pid_filter.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
+
+   if(error == 0) {
+     /* Response OK -> get response data */
+     filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
+   }
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief  Send delete filter command to AS10x
+   \param  phandle:       pointer to AS10x handle
+   \param  filter_handle: filter handle
+   \return 0 when no error, < 0 in case of error.
+   \callgraph
+*/
+int as10x_cmd_del_PID_filter(as10x_handle_t* phandle,
+			     uint16_t pid_value)
+{
+
+   int    error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		    sizeof(pcmd->body.del_pid_filter.req));
+
+   /* fill command */
+   pcmd->body.del_pid_filter.req.proc_id = cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
+   pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd){
+      error = phandle->ops->xfer_cmd(phandle,
+		       (uint8_t *) pcmd,
+		       sizeof(pcmd->body.del_pid_filter.req) + HEADER_SIZE,
+		       (uint8_t *) prsp,
+		       sizeof(prsp->body.del_pid_filter.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief Send start streaming command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \return 0 when no error, < 0 in case of error. 
+   \callgraph
+*/
+int as10x_cmd_start_streaming(as10x_handle_t* phandle)
+{
+   int error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		    sizeof(pcmd->body.start_streaming.req));
+
+   /* fill command */
+   pcmd->body.start_streaming.req.proc_id =
+				   cpu_to_le16(CONTROL_PROC_START_STREAMING);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd){
+      error = phandle->ops->xfer_cmd(phandle,
+		       (uint8_t *) pcmd,
+		       sizeof(pcmd->body.start_streaming.req) + HEADER_SIZE,
+		       (uint8_t *) prsp,
+		       sizeof(prsp->body.start_streaming.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+/**
+   \brief Send stop streaming command to AS10x
+   \param  phandle:   pointer to AS10x handle
+   \return 0 when no error, < 0 in case of error. 
+   \callgraph
+*/
+int as10x_cmd_stop_streaming(as10x_handle_t* phandle)
+{
+   int8_t error;
+   struct as10x_cmd_t *pcmd, *prsp;
+
+   ENTER();
+
+   pcmd = phandle->cmd;
+   prsp = phandle->rsp;
+
+   /* prepare command */
+   as10x_cmd_build(pcmd, (++phandle->cmd_xid),
+		    sizeof(pcmd->body.stop_streaming.req));
+
+   /* fill command */
+   pcmd->body.stop_streaming.req.proc_id =
+				   cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
+
+   /* send command */
+   if(phandle->ops->xfer_cmd){
+      error = phandle->ops->xfer_cmd(phandle,
+		       (uint8_t *) pcmd,
+		       sizeof(pcmd->body.stop_streaming.req) + HEADER_SIZE,
+		       (uint8_t *) prsp,
+		       sizeof(prsp->body.stop_streaming.rsp) + HEADER_SIZE);
+   }
+   else{
+      error = AS10X_CMD_ERROR;
+   }
+
+   if(error < 0) {
+      goto out;
+   }
+
+   /* parse response */
+   error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
+
+out:
+   LEAVE();
+   return(error);
+}
+
+
diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h
new file mode 100644
index 0000000..4f01a76
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_handle.h
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+#ifdef __KERNEL__
+struct as102_bus_adapter_t;
+struct as102_dev_t;
+
+#define as10x_handle_t struct as102_bus_adapter_t
+#include "as10x_cmd.h"
+
+/* values for "mode" field */
+#define REGMODE8         8
+#define REGMODE16        16
+#define REGMODE32        32
+
+struct as102_priv_ops_t {
+	int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap,
+			      unsigned char *buf, int buflen, int swap32);
+
+	int (*send_cmd) (struct as102_bus_adapter_t *bus_adap,
+			 unsigned char *buf, int buflen);
+
+	int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap,
+			 unsigned char *send_buf, int send_buf_len,
+			 unsigned char *recv_buf, int recv_buf_len);
+/*
+	int (*pid_filter) (struct as102_bus_adapter_t *bus_adap,
+			   int index, u16 pid, int onoff);
+*/
+	int (*start_stream) (struct as102_dev_t *dev);
+	void (*stop_stream) (struct as102_dev_t *dev);
+
+	int (*reset_target) (struct as102_bus_adapter_t *bus_adap);
+
+	int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode,
+			  uint32_t rd_addr, uint16_t rd_len,
+			  uint32_t wr_addr, uint16_t wr_len);
+
+	int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap,
+			       unsigned char *recv_buf,
+			       int recv_buf_len);
+};
+#endif
diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h
new file mode 100644
index 0000000..3dedb3c
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_types.h
@@ -0,0 +1,198 @@
+/*
+ * 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.
+ */
+#ifndef _AS10X_TYPES_H_
+#define _AS10X_TYPES_H_
+
+#include "as10x_handle.h"
+
+/*********************************/
+/*       MACRO DEFINITIONS       */
+/*********************************/
+
+/* bandwidth constant values */
+#define BW_5_MHZ           0x00
+#define BW_6_MHZ           0x01
+#define BW_7_MHZ           0x02
+#define BW_8_MHZ           0x03
+
+/* hierarchy priority selection values */
+#define HIER_NO_PRIORITY   0x00
+#define HIER_LOW_PRIORITY  0x01
+#define HIER_HIGH_PRIORITY 0x02
+
+/* constellation available values */
+#define CONST_QPSK         0x00
+#define CONST_QAM16        0x01
+#define CONST_QAM64        0x02
+#define CONST_UNKNOWN      0xFF
+
+/* hierarchy available values */
+#define HIER_NONE         0x00
+#define HIER_ALPHA_1      0x01
+#define HIER_ALPHA_2      0x02
+#define HIER_ALPHA_4      0x03
+#define HIER_UNKNOWN      0xFF
+
+/* interleaving available values */
+#define INTLV_NATIVE      0x00
+#define INTLV_IN_DEPTH    0x01
+#define INTLV_UNKNOWN     0xFF
+
+/* code rate available values */
+#define CODE_RATE_1_2     0x00
+#define CODE_RATE_2_3     0x01
+#define CODE_RATE_3_4     0x02
+#define CODE_RATE_5_6     0x03
+#define CODE_RATE_7_8     0x04
+#define CODE_RATE_UNKNOWN 0xFF
+
+/* guard interval available values */
+#define GUARD_INT_1_32    0x00
+#define GUARD_INT_1_16    0x01
+#define GUARD_INT_1_8     0x02
+#define GUARD_INT_1_4     0x03
+#define GUARD_UNKNOWN     0xFF
+
+/* transmission mode available values */
+#define TRANS_MODE_2K      0x00
+#define TRANS_MODE_8K      0x01
+#define TRANS_MODE_4K      0x02
+#define TRANS_MODE_UNKNOWN 0xFF
+
+/* DVBH signalling available values */
+#define TIMESLICING_PRESENT   0x01
+#define MPE_FEC_PRESENT       0x02
+
+/* tune state available */
+#define TUNE_STATUS_NOT_TUNED       0x00
+#define TUNE_STATUS_IDLE            0x01
+#define TUNE_STATUS_LOCKING         0x02
+#define TUNE_STATUS_SIGNAL_DVB_OK   0x03
+#define TUNE_STATUS_STREAM_DETECTED 0x04
+#define TUNE_STATUS_STREAM_TUNED    0x05
+#define TUNE_STATUS_ERROR           0xFF
+
+/* available TS FID filter types */
+#define TS_PID_TYPE_TS       0
+#define TS_PID_TYPE_PSI_SI   1
+#define TS_PID_TYPE_MPE      2
+
+/* number of echos available */
+#define MAX_ECHOS   15
+
+/* Context types */
+#define CONTEXT_LNA                   1010
+#define CONTEXT_ELNA_HYSTERESIS       4003
+#define CONTEXT_ELNA_GAIN             4004
+#define CONTEXT_MER_THRESHOLD         5005
+#define CONTEXT_MER_OFFSET            5006
+#define CONTEXT_IR_STATE              7000
+#define CONTEXT_TSOUT_MSB_FIRST       7004
+#define CONTEXT_TSOUT_FALLING_EDGE    7005
+
+/* Configuration modes */
+#define CFG_MODE_ON     0
+#define CFG_MODE_OFF    1
+#define CFG_MODE_AUTO   2
+
+#pragma pack(1)
+struct as10x_tps {
+   uint8_t constellation;
+   uint8_t hierarchy;
+   uint8_t interleaving_mode;
+   uint8_t code_rate_HP;
+   uint8_t code_rate_LP;
+   uint8_t guard_interval;
+   uint8_t transmission_mode;
+   uint8_t DVBH_mask_HP;
+   uint8_t DVBH_mask_LP;
+   uint16_t cell_ID;
+};
+
+struct as10x_tune_args {
+   /* frequency */
+   uint32_t freq;
+   /* bandwidth */
+   uint8_t bandwidth;
+   /* hierarchy selection */
+   uint8_t hier_select;
+   /* constellation */
+   uint8_t constellation;
+   /* hierarchy */
+   uint8_t hierarchy;
+   /* interleaving mode */
+   uint8_t interleaving_mode;
+   /* code rate */
+   uint8_t code_rate;
+   /* guard interval */
+   uint8_t guard_interval;
+   /* transmission mode */
+   uint8_t transmission_mode;
+};
+
+struct as10x_tune_status {
+   /* tune status */
+   uint8_t tune_state;
+   /* signal strength */
+   int16_t signal_strength;
+   /* packet error rate 10^-4 */
+   uint16_t PER;
+   /* bit error rate 10^-4 */
+   uint16_t BER;
+};
+
+struct as10x_demod_stats {
+   /* frame counter */
+   uint32_t frame_count;
+   /* Bad frame counter */
+   uint32_t bad_frame_count;
+   /* Number of wrong bytes fixed by Reed-Solomon */
+   uint32_t bytes_fixed_by_rs;
+   /* Averaged MER */
+   uint16_t mer;
+   /* statistics calculation state indicator (started or not) */
+   uint8_t has_started;
+};
+
+struct as10x_ts_filter {
+   uint16_t pid;  /** valid PID value 0x00 : 0x2000 */
+   uint8_t  type; /** Red TS_PID_TYPE_<N> values */
+   uint8_t  idx;  /** index in filtering table */
+};
+
+struct as10x_register_value {
+   uint8_t       mode;
+   union {
+      uint8_t    value8;    /* 8 bit value */
+      uint16_t   value16;   /* 16 bit value */
+      uint32_t   value32;   /* 32 bit value */
+   }u;
+};
+
+#pragma pack()
+
+struct as10x_register_addr {
+   /* register addr */
+   uint32_t addr;
+   /* register mode access */
+   uint8_t mode;
+};
+
+
+#endif
-- 
1.7.4.1


^ permalink raw reply related

* [PATCH 00/17] Staging: Abilis Systems AS102 driver
From: Sylwester Nawrocki @ 2011-10-31 16:24 UTC (permalink / raw)
  To: devel, linux-media
  Cc: Piotr Chmura, Devin Heitmueller, Mauro Carvalho Chehab,
	Sylwester Nawrocki, Stefan Richter, Greg KH

Hello,

I have collected most of patches for Abilis Systems AS102 driver
recently submitted by Piotr and I'm resending it as the following
series. There were some issues with some of the previous patches,
due to improper e-mail encoding and some of them refused to apply
properly. Hopefully there is no issues this time, I have also
pushed the patches to a public git, as indicated below.

This change set superseeds all previous as102 patches from Piotr
Chmura, we've agreed to prepare another series addressing the
remaining issues in order to move the driver out of staging.

So this change set is meant as an initial pull to staging/media.
If there are any issues with the patches related to submission
procedure, authorship, etc., please let us know.

The original author dates as in mercurial repository at
http://kernellabs.com/hg/~dheitmueller/v4l-dvb-as102-2/
has been preserved.

The patch set is based of off master branch at
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

It can be pulled from git://gitorious.org/linux-media/media_tree.git

The driver has been tested with PCTV picoStick (74e) DVB-T tuner.

--
Regards,
Sylwester

Devin Heitmueller (9):
  staging: as102: Fix CodingStyle errors in file as102_drv.c
  staging: as102: Fix CodingStyle errors in file as102_fw.c
  staging: as102: Fix CodingStyle errors in file as10x_cmd.c
  staging: as102: Fix CodingStyle errors in file as10x_cmd_stream.c
  staging: as102: Fix CodingStyle errors in file as102_fe.c
  staging: as102: Fix CodingStyle errors in file as102_usb_drv.c
  staging: as102: Fix CodingStyle errors in file as10x_cmd_cfg.c
  staging: as102: Add Elgato EyeTV DTT Deluxe
  staging: as102: Properly handle multiple product names

Pierrick Hascoet (2):
  staging: as102: Initial import from Abilis
  staging: as102: Fix licensing oversight

Piotr Chmura (3):
  staging: as102: Remove non-linux headers inclusion
  staging: as102: Enable compilation
  staging: as102: Add nBox Tuner Dongle support

Sylwester Nawrocki (3):
  staging: as102: Convert the comments to kernel-doc style
  staging: as102: Unconditionally compile code dependent on DVB_CORE
  staging: as102: Remove conditional compilation based on kernel version

 drivers/staging/Kconfig                        |    2 +
 drivers/staging/Makefile                       |    1 +
 drivers/staging/media/as102/Kconfig            |    7 +
 drivers/staging/media/as102/Makefile           |    6 +
 drivers/staging/media/as102/as102_drv.c        |  351 ++++++++++++++
 drivers/staging/media/as102/as102_drv.h        |  141 ++++++
 drivers/staging/media/as102/as102_fe.c         |  603 ++++++++++++++++++++++++
 drivers/staging/media/as102/as102_fw.c         |  251 ++++++++++
 drivers/staging/media/as102/as102_fw.h         |   42 ++
 drivers/staging/media/as102/as102_usb_drv.c    |  478 +++++++++++++++++++
 drivers/staging/media/as102/as102_usb_drv.h    |   59 +++
 drivers/staging/media/as102/as10x_cmd.c        |  452 ++++++++++++++++++
 drivers/staging/media/as102/as10x_cmd.h        |  540 +++++++++++++++++++++
 drivers/staging/media/as102/as10x_cmd_cfg.c    |  215 +++++++++
 drivers/staging/media/as102/as10x_cmd_stream.c |  223 +++++++++
 drivers/staging/media/as102/as10x_handle.h     |   58 +++
 drivers/staging/media/as102/as10x_types.h      |  198 ++++++++
 17 files changed, 3627 insertions(+), 0 deletions(-)
 create mode 100644 drivers/staging/media/as102/Kconfig
 create mode 100644 drivers/staging/media/as102/Makefile
 create mode 100644 drivers/staging/media/as102/as102_drv.c
 create mode 100644 drivers/staging/media/as102/as102_drv.h
 create mode 100644 drivers/staging/media/as102/as102_fe.c
 create mode 100644 drivers/staging/media/as102/as102_fw.c
 create mode 100644 drivers/staging/media/as102/as102_fw.h
 create mode 100644 drivers/staging/media/as102/as102_usb_drv.c
 create mode 100644 drivers/staging/media/as102/as102_usb_drv.h
 create mode 100644 drivers/staging/media/as102/as10x_cmd.c
 create mode 100644 drivers/staging/media/as102/as10x_cmd.h
 create mode 100644 drivers/staging/media/as102/as10x_cmd_cfg.c
 create mode 100644 drivers/staging/media/as102/as10x_cmd_stream.c
 create mode 100644 drivers/staging/media/as102/as10x_handle.h
 create mode 100644 drivers/staging/media/as102/as10x_types.h

--
1.7.4.1

^ permalink raw reply

* git rev-parse --since=1970-01-01 does not work reliably
From: Dmitry V. Levin @ 2011-10-31 16:17 UTC (permalink / raw)
  To: git

Hi,

git rev-parse --since=1970-01-01 (and other git commands that take
date string arguments like --since) may fail when --since=1970-01-01 is
given.  Whether it fails or not depends on current time and timezone data.
For example, "TZ=Europe/Paris git rev-parse --since=1970-01-01" fails two
hours a day (between 00:00 and 02:00 CET), and those who use more eastern
timezones are even less lucky.  In artificial timezones like UTC-24 it
always fails:

$ TZ=UTC-24 git rev-parse --since=1970-01-01
--max-age=18446744073709523490

The problem is that several internal git functions implicitly convert
time_t to unsigned long, so when time_t gets negative, all date string
processing breaks.


-- 
ldv

^ permalink raw reply

* generic I/O
From: Kai Meyer @ 2011-10-31 16:24 UTC (permalink / raw)
  To: kernelnewbies

Are there existing generic block device I/O operations available 
already? I am familiar with constructing and submitting 'struct bio's, 
but what I'd like to do would be greatly simplified if there was an 
existing I/O interface similar to the posix 'read' and 'write' 
functions. If they don't exist, I would probably end up writing 
functions like:
int blk_read(struct block_device *bdev, void *buffer, off_t length);
int blk_write(struct block_device *bdev, void *buffer, off_t length);

Pros and cons to this sort of approach?

-Kai Meyer

^ permalink raw reply

* RE: [PATCH 1/8] clocksource: Convert tcb_clksrc to use clocksource_register_hz/khz
From: Voss, Nikolaus @ 2011-10-31 16:23 UTC (permalink / raw)
  To: 'lkml'; +Cc: 'John Stultz', 'Thomas Gleixner'
In-Reply-To: <1319566096-3222-1-git-send-email-y>

> -----Original Message-----
> From: y@kernel.beaverton.ibm.com [mailto:y@kernel.beaverton.ibm.com]
> Sent: Tuesday, October 25, 2011 8:08 PM
> To: lkml
> Cc: John Stultz; Voss, Nikolaus; Thomas Gleixner
> Subject: [PATCH 1/8] clocksource: Convert tcb_clksrc to use
> clocksource_register_hz/khz
> 
> From: John Stultz <john.stultz@linaro.org>
> 
> Convert tcb_clksrc to use clocksource_register_hz.
> 
> Untested. Help from maintainers would be appreciated.
> 
> CC: Nikolaus Voss <n.voss@weinmann.de>
> CC: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: John Stultz <john.stultz@linaro.org>
> ---
>  drivers/clocksource/tcb_clksrc.c |    4 +---
>  1 files changed, 1 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/clocksource/tcb_clksrc.c
> b/drivers/clocksource/tcb_clksrc.c
> index 79c47e8..55d0f95 100644
> --- a/drivers/clocksource/tcb_clksrc.c
> +++ b/drivers/clocksource/tcb_clksrc.c
> @@ -59,7 +59,6 @@ static struct clocksource clksrc = {
>  	.rating         = 200,
>  	.read           = tc_get_cycles,
>  	.mask           = CLOCKSOURCE_MASK(32),
> -	.shift          = 18,
>  	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
>  };
> 
> @@ -256,7 +255,6 @@ static int __init tcb_clksrc_init(void)
>  		best_divisor_idx = i;
>  	}
> 
> -	clksrc.mult = clocksource_hz2mult(divided_rate, clksrc.shift);
> 
>  	printk(bootinfo, clksrc.name, CONFIG_ATMEL_TCB_CLKSRC_BLOCK,
>  			divided_rate / 1000000,
> @@ -292,7 +290,7 @@ static int __init tcb_clksrc_init(void)
>  	__raw_writel(ATMEL_TC_SYNC, tcaddr + ATMEL_TC_BCR);
> 
>  	/* and away we go! */
> -	clocksource_register(&clksrc);
> +	clocksource_register_hz(&clksrc, divided_rate);
> 
>  	/* channel 2:  periodic and oneshot timer support */
>  	setup_clkevents(tc, clk32k_divisor_idx);
> --
> 1.7.3.2.146.gca209

This works on my G45 system.

Acked-by: Nikolaus Voss <n.voss@weinmann.de>


^ permalink raw reply

* [U-Boot] [PATCH V7 5/5] omap-common: fixes BSS overwriting problem
From: Simon Schwarz @ 2011-10-31 16:23 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1320078187-28423-1-git-send-email-simonschwarzcor@gmail.com>

From: Simon Schwarz <simonschwarzcor@googlemail.com>

spl_nand overwrote BSS section because it reads a whole block everytime. Now
loads the block to spare area and just copy the needed junk to destination.
Whole block read is necessary for ecc check!

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>
---

V2 changes:
nothing

V3 changes:
nothing

V4 changes:
nothing

V5 changes:
nothing

V6 changes:
nothing

V7 changes:
nothing
---
 arch/arm/cpu/armv7/omap-common/spl_nand.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c
index 1b9e171..903255b 100644
--- a/arch/arm/cpu/armv7/omap-common/spl_nand.c
+++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c
@@ -71,7 +71,8 @@ void spl_nand_load_image(void)
 			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
 		spl_parse_image_header(header);
 		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
-			spl_image.size, (void *)spl_image.load_addr);
+			spl_image.size,
+			(void *)spl_image.load_addr - sizeof(header));
 	} else
 #endif
 	{
-- 
1.7.4.1

^ permalink raw reply related

* [U-Boot] [PATCH V7 4/5] devkit8000/spl: init GPMC for dm9000 in SPL
From: Simon Schwarz @ 2011-10-31 16:23 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1320078187-28423-1-git-send-email-simonschwarzcor@gmail.com>

From: Simon Schwarz <simonschwarzcor@googlemail.com>

Linux crashes if the GPMC isn't configured for the dm9000.

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>

---

V2 changes:
nothing

V3 changes:
nothing

V4 changes:
noting

V5 changes:
nothing

V6 changes:
nothing

V7 changes:
FIX multiline comment style
	(http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113500)
---
 arch/arm/include/asm/omap_common.h  |    2 ++
 board/timll/devkit8000/devkit8000.c |   33 +++++++++++++++++++++++++--------
 2 files changed, 27 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index 3f2f004..ab86774 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -78,6 +78,8 @@ u32 omap_boot_mode(void);
 /* SPL common function s*/
 void spl_parse_image_header(const struct image_header *header);
 void omap_rev_string(char *omap_rev_string);
+int spl_uboot_key(void);
+void spl_board_prepare_for_linux(void);
 
 /* NAND SPL functions */
 void spl_nand_load_image(void);
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c
index fee0dff..11c8671 100644
--- a/board/timll/devkit8000/devkit8000.c
+++ b/board/timll/devkit8000/devkit8000.c
@@ -63,6 +63,18 @@ int board_init(void)
 	return 0;
 }
 
+/* Configure GPMC registers for DM9000 */
+static void gpmc_dm9000_config(void)
+{
+	writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1);
+	writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2);
+	writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3);
+	writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4);
+	writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5);
+	writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6);
+	writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7);
+}
+
 /*
  * Routine: misc_init_r
  * Description: Configure board specific parts
@@ -81,14 +93,7 @@ int misc_init_r(void)
 #endif
 
 #ifdef CONFIG_DRIVER_DM9000
-	/* Configure GPMC registers for DM9000 */
-	writel(NET_GPMC_CONFIG1, &gpmc_cfg->cs[6].config1);
-	writel(NET_GPMC_CONFIG2, &gpmc_cfg->cs[6].config2);
-	writel(NET_GPMC_CONFIG3, &gpmc_cfg->cs[6].config3);
-	writel(NET_GPMC_CONFIG4, &gpmc_cfg->cs[6].config4);
-	writel(NET_GPMC_CONFIG5, &gpmc_cfg->cs[6].config5);
-	writel(NET_GPMC_CONFIG6, &gpmc_cfg->cs[6].config6);
-	writel(NET_GPMC_CONFIG7, &gpmc_cfg->cs[6].config7);
+	gpmc_dm9000_config();
 
 	/* Use OMAP DIE_ID as MAC address */
 	if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
@@ -138,3 +143,15 @@ int board_eth_init(bd_t *bis)
 	return dm9000_initialize(bis);
 }
 #endif
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * Do board specific preperation before SPL
+ * Linux boot
+ */
+void spl_board_prepare_for_linux(void)
+{
+	gpmc_dm9000_config();
+}
+
+#endif
-- 
1.7.4.1

^ permalink raw reply related

* [U-Boot] [PATCH V7 3/5] omap-common/spl: Add linux boot to SPL
From: Simon Schwarz @ 2011-10-31 16:23 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1320078187-28423-1-git-send-email-simonschwarzcor@gmail.com>

From: Simon Schwarz <simonschwarzcor@googlemail.com>

This adds Linux booting to the SPL

This depends on CONFIG_MACH_TYPE patch by Igor Grinberg
(http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)

Related CONFIGs:
CONFIG_SPL_OS_BOOT
	Activates/Deactivates the OS booting feature
CONFIG_SPL_OS_BOOT_KEY
	defines the IO-pin number u-boot switch - if pressed u-boot is booted
CONFIG_SYS_NAND_SPL_KERNEL_OFFS
	Offset in NAND of direct boot kernel image to use in SPL
CONFIG_SYS_SPL_ARGS_ADDR
	Address where the kernel boot arguments are expected - this is normaly
	RAM-begin + 0x100

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>
---

V2 changes:
nothing

V3 changes:
nothing

V4 changes:
CHG Using CONFIG_MACH_TYPE now.
DEL CONFIG_SYS_SPL_MACHID
CHG Use CONFIG_MACH_TYPE for machine id config - This makes the patch
	depending on the patch linked above

V5 changes:
FIX compile errors for OMAP4
REBASE u-boot-ti adapted new general gpio interface

V6 changes:
nothing

V7 changes:
FIX multiline comment style
	(http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113501)
---
 arch/arm/cpu/armv7/omap-common/spl.c |   51 ++++++++++++++++++++++++++++++++-
 include/configs/devkit8000.h         |    9 ++++-
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
index d37ca0f..bafddfb 100644
--- a/arch/arm/cpu/armv7/omap-common/spl.c
+++ b/arch/arm/cpu/armv7/omap-common/spl.c
@@ -35,6 +35,7 @@
 #include <i2c.h>
 #include <image.h>
 #include <malloc.h>
+#include <asm/gpio.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -63,6 +64,26 @@ void board_init_f(ulong dummy)
 	relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);
 }
 
+/*
+ * Return the value of the U-boot key
+ *
+ * RETURN
+ * 0 if not pressed
+ * positiv if pressed
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+int spl_uboot_key(void)
+{
+	int val = 0;
+	if (!gpio_request(CONFIG_SPL_OS_BOOT_KEY, "U-Boot key")) {
+		gpio_direction_input(CONFIG_SPL_OS_BOOT_KEY);
+		val = gpio_get_value(CONFIG_SPL_OS_BOOT_KEY);
+		gpio_free(CONFIG_SPL_OS_BOOT_KEY);
+	}
+	return !val;
+}
+#endif
+
 void spl_parse_image_header(const struct image_header *header)
 {
 	u32 header_size = sizeof(struct image_header);
@@ -90,7 +111,26 @@ void spl_parse_image_header(const struct image_header *header)
 	}
 }
 
-static void jump_to_image_no_args(void)
+/*
+ * This function jumps to an image with argument. Normally an FDT or ATAGS
+ * image.
+ * arg: Pointer to paramter image in RAM
+ */
+#ifdef CONFIG_SPL_OS_BOOT
+void jump_to_image_linux(void *arg)
+{
+	debug("Entering kernel arg pointer: 0x%X\n", arg);
+	typedef void (*image_entry_arg_t)(int, int, void *)
+		__attribute__ ((noreturn));
+	image_entry_arg_t image_entry =
+		(image_entry_arg_t) spl_image.entry_point;
+	/* cleanup_before_linux(); */ /*write SPL function for that*/
+	image_entry(0, CONFIG_MACH_TYPE, arg);
+}
+void jump_to_image_linux(void *) __attribute__ ((noreturn));
+#endif
+
+void jump_to_image_no_args(void)
 {
 	typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn));
 	image_entry_noargs_t image_entry =
@@ -99,8 +139,8 @@ static void jump_to_image_no_args(void)
 	debug("image entry point: 0x%X\n", spl_image.entry_point);
 	image_entry();
 }
-
 void jump_to_image_no_args(void) __attribute__ ((noreturn));
+
 void board_init_r(gd_t *id, ulong dummy)
 {
 	u32 boot_device;
@@ -137,6 +177,13 @@ void board_init_r(gd_t *id, ulong dummy)
 		debug("Jumping to U-Boot\n");
 		jump_to_image_no_args();
 		break;
+#ifdef CONFIG_SPL_OS_BOOT
+	case IH_OS_LINUX:
+		debug("Jumping to Linux\n");
+		spl_board_prepare_for_linux();
+		jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR);
+		break;
+#endif
 	default:
 		puts("Unsupported OS image.. Jumping nevertheless..\n");
 		jump_to_image_no_args();
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index f603f55..a848f4d 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -37,7 +37,9 @@
 #define CONFIG_OMAP3430		1	/* which is in a 3430 */
 #define CONFIG_OMAP3_DEVKIT8000	1	/* working with DevKit8000 */
 
-#define	CONFIG_SYS_TEXT_BASE	0x80008000
+#define CONFIG_MACH_TYPE		MACH_TYPE_DEVKIT8000
+
+#define	CONFIG_SYS_TEXT_BASE	0x80100000
 
 #define CONFIG_SDRC	/* The chip has SDRC controller */
 
@@ -333,7 +335,7 @@
 #define CONFIG_SPL_MAX_SIZE		0xB400  /* 45 K */
 #define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK
 
-#define CONFIG_SPL_BSS_START_ADDR	0x80000000 /*CONFIG_SYS_SDRAM_BASE*/
+#define CONFIG_SPL_BSS_START_ADDR	0x80000500 /* leave space for bootargs*/
 #define CONFIG_SPL_BSS_MAX_SIZE		0x80000
 
 /* NAND boot config */
@@ -366,6 +368,9 @@
 #define CONFIG_CMD_SPL_WRITE_SIZE	0x400 /* 1024 byte */
 #define CONFIG_CMD_SPL_NAND_OFS	(CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\
 						0x400000)
+#define CONFIG_SPL_OS_BOOT
+#define CONFIG_SPL_OS_BOOT_KEY	26
+
 #define CONFIG_SYS_NAND_SPL_KERNEL_OFFS	0x280000
 #define CONFIG_SYS_SPL_ARGS_ADDR	(PHYS_SDRAM_1 + 0x100)
 #endif /* __CONFIG_H */
-- 
1.7.4.1

^ permalink raw reply related

* [U-Boot] [PATCH V7 2/5] omap-common: Add NAND SPL linux booting
From: Simon Schwarz @ 2011-10-31 16:23 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1320078187-28423-1-git-send-email-simonschwarzcor@gmail.com>

From: Simon Schwarz <simonschwarzcor@googlemail.com>

This implements booting of Linux from NAND in SPL

Related config parameters:
CONFIG_SYS_NAND_SPL_KERNEL_OFFS
	Offset in NAND of direct boot kernel image to use in SPL
CONFIG_SYS_SPL_ARGS_ADDR
	Address where the kernel boot arguments are expected - this is
	normally RAM-start + 0x100 (on ARM)

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>
---

V2 changes:
nothing

V3 changes:
nothing

V4 changes:
ADD define description to commit message
CHG renaming some defines - renaming SAVEBP SPL

V5 changes:
nothing

V6 changes:
nothing

V7 changes:
nothing
---
 arch/arm/cpu/armv7/omap-common/spl_nand.c |   62 +++++++++++++++++++++-------
 1 files changed, 46 insertions(+), 16 deletions(-)

diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c
index 38d06b1..1b9e171 100644
--- a/arch/arm/cpu/armv7/omap-common/spl_nand.c
+++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c
@@ -24,6 +24,7 @@
 #include <asm/u-boot.h>
 #include <asm/utils.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/io.h>
 #include <nand.h>
 #include <version.h>
 #include <asm/omap_common.h>
@@ -32,6 +33,7 @@
 void spl_nand_load_image(void)
 {
 	struct image_header *header;
+	int *src, *dst;
 	switch (omap_boot_mode()) {
 	case NAND_MODE_HW_ECC:
 		debug("spl: nand - using hw ecc\n");
@@ -45,26 +47,54 @@ void spl_nand_load_image(void)
 
 	/*use CONFIG_SYS_TEXT_BASE as temporary storage area */
 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+#ifdef CONFIG_SPL_OS_BOOT
+	if (!spl_uboot_key()) {
+		/* load parameter image */
+		/* load to temp position since nand_spl_load_image reads
+		 * a whole block which is typically larger than
+		 * CONFIG_CMD_SAVEBP_WRITE_SIZE therefore may overwrite
+		 * following sections like BSS */
+		nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS,
+			CONFIG_CMD_SPL_WRITE_SIZE,
+			(void *)CONFIG_SYS_TEXT_BASE);
+		/* copy to destintion */
+		for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR,
+				src = (int *)CONFIG_SYS_TEXT_BASE;
+				src < (int *)(CONFIG_SYS_TEXT_BASE +
+				CONFIG_CMD_SPL_WRITE_SIZE);
+				src++, dst++) {
+			writel(readl(src), dst);
+		}
 
+		/* load linux */
+		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+		spl_parse_image_header(header);
+		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS,
+			spl_image.size, (void *)spl_image.load_addr);
+	} else
+#endif
+	{
 #ifdef CONFIG_NAND_ENV_DST
-	nand_spl_load_image(CONFIG_ENV_OFFSET,
-		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
-	spl_parse_image_header(header);
-	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
-		(void *)image_load_addr);
+		nand_spl_load_image(CONFIG_ENV_OFFSET,
+			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+		spl_parse_image_header(header);
+		nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
+			(void *)spl_image.load_addr);
 #ifdef CONFIG_ENV_OFFSET_REDUND
-	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
-		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
-	spl_parse_image_header(header);
-	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
-		(void *)image_load_addr);
+		nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
+			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+		spl_parse_image_header(header);
+		nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
+			(void *)spl_image.load_addr);
 #endif
 #endif
-	/* Load u-boot */
-	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
-	spl_parse_image_header(header);
-	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
-		spl_image.size, (void *)spl_image.load_addr);
+		/* Load u-boot */
+		nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+		spl_parse_image_header(header);
+		nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+			spl_image.size, (void *)spl_image.load_addr);
+	}
 	nand_deselect();
 }
-- 
1.7.4.1

^ permalink raw reply related

* [U-Boot] [PATCH V7 1/5] Add cmd_spl command
From: Simon Schwarz @ 2011-10-31 16:23 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1320078187-28423-1-git-send-email-simonschwarzcor@gmail.com>

From: Simon Schwarz <simonschwarzcor@googlemail.com>

This adds a spl command to the u-boot.

Related config:
CONFIG_CMD_CPL
	activate/deactivate the command
CONFIG_CMD_SPL_NAND_OFS
	Offset in NAND to use

Signed-off-by: Simon Schwarz <simonschwarzcor@gmail.com>
---

V2 changes:
CHG corrected bootm call. Now bootm is called with five parameters including
	Address of FDT in RAM. This fixes the hang on savebp fdt call.
ADD debug output of the actual bootm parameter call
CHG help message

V3 changes:
FIX added missing brackets

V4 changes:
CHG Corrected argument number in comments
CHG added check for CONFIG_OF_LIBFDT
CHG squashed the README to this commit
DEL define description from commit message - unused in this patch
CHG renamed to spl now with subcommand export, very different now
ADD New call style with subcommands.
CHG added printf where the image is located
CHG Patched README to reflect changes
CHG parameter count
CHG usage message

V5 changes:
nothing

V6 changes:
nothing

V7 changes:
FIX multiline comment style, cosmetic changes
	(http://article.gmane.org/gmane.comp.boot-loaders.u-boot/113499)
---
 common/Makefile              |    1 +
 common/cmd_spl.c             |  224 ++++++++++++++++++++++++++++++++++++++++++
 doc/README.commands.spl      |   31 ++++++
 include/cmd_spl.h            |   30 ++++++
 include/configs/devkit8000.h |    7 ++
 5 files changed, 293 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_spl.c
 create mode 100644 doc/README.commands.spl
 create mode 100644 include/cmd_spl.h

diff --git a/common/Makefile b/common/Makefile
index 1b672ad..4056e41 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -164,6 +164,7 @@ COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
 endif
 COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o
 COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o
+COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o
 
 # others
 ifdef CONFIG_DDR_SPD
diff --git a/common/cmd_spl.c b/common/cmd_spl.c
new file mode 100644
index 0000000..eb498c6
--- /dev/null
+++ b/common/cmd_spl.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <cmd_spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Calls bootm with the parameters given */
+int call_bootm(int argc, char * const argv[], char *subcommand[])
+{
+	char *bootm_argv[5];
+	char command[] = "do_bootm";
+
+	int i = 0;
+	int ret = 0;
+
+	/* create paramter array */
+	bootm_argv[0] = command;
+	switch (argc) {
+	case 3:
+		bootm_argv[4] = argv[2]; /* fdt addr */
+	case 2:
+		bootm_argv[3] = argv[1]; /* initrd addr */
+	case 1:
+		bootm_argv[2] = argv[0]; /* kernel addr */
+	}
+
+
+	/*
+	 * - do the work -
+	 * exec subcommands of do_bootm to init the images
+	 * data structure
+	 */
+	while (subcommand[i] != '\0') {
+		bootm_argv[1] = subcommand[i];
+		debug("args: %s, %s, %s, %s, %s, %d\n", bootm_argv[0],
+			bootm_argv[1], bootm_argv[2], bootm_argv[3],
+			bootm_argv[4], argc);
+		ret = do_bootm(find_cmd("do_bootm"), 0, argc+2,
+			bootm_argv);
+		debug("Subcommand retcode: %d\n", ret);
+		i++;
+	}
+
+	if (ret) {
+		printf("ERROR prep subcommand failed!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* assemble the bootm paramteres for fdt creation */
+int spl_export_fdt(int argc, char * const argv[])
+{
+#ifdef CONFIG_OF_LIBFDT
+	/* Create subcommand string */
+	char *subcommand[] = {"start",
+	"loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+	"ramdisk",
+#endif
+	"fdt",
+	"cmdline",
+	"bdt",
+	"prep",
+	'\0'};
+
+	/* inspect paramters and execute bootm */
+	argc--;
+	argv++;
+	if (call_bootm(argc, argv, subcommand))
+		return -1;
+
+	printf("Argument image is now in RAM: 0x%p\n",
+		(void *)images.ft_addr);
+	return 0;
+#else
+	printf("Das U-Boot was build without fdt support - aborting\n");
+	return -1;
+#endif
+}
+
+/* assemble the bootm patameters for atags creation */
+int spl_export_atags(int argc, char * const argv[])
+{
+#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
+	defined(CONFIG_CMDLINE_TAG) || \
+	defined(CONFIG_INITRD_TAG) || \
+	defined(CONFIG_SERIAL_TAG) || \
+	defined(CONFIG_REVISION_TAG)
+	/* Create subcommand string */
+	char *subcommand[] = {"start", "loados",
+#ifdef CONFIG_SYS_BOOT_RAMDISK_HIGH
+	"ramdisk",
+#endif
+	"cmdline", "bdt", "prep", '\0'};
+
+	/* inspect parameters and execute bootm */
+	argc--;
+	argv++;
+	if (call_bootm(argc, argv, subcommand))
+		return -1;
+
+	printf("Argument image is now in RAM at: 0x%p\n",
+		(void *)gd->bd->bi_boot_params);
+	return 0;
+#endif
+	printf("Das U-Boot was build without ATAGS support - aborting\n");
+	return -1;
+}
+
+static cmd_tbl_t cmd_spl_export_sub[] = {
+	U_BOOT_CMD_MKENT(fdt, 0, 1, (void *)SPL_EXPORT_FDT, "", ""),
+	U_BOOT_CMD_MKENT(atags, 0, 1, (void *)SPL_EXPORT_ATAGS, "", ""),
+};
+
+int spl_export(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+
+	cmd_tbl_t *c;
+	int cmd;
+
+	if (argc < 2) /* no subcommand */
+		return cmd_usage(cmdtp);
+
+	c = find_cmd_tbl(argv[1], &cmd_spl_export_sub[0],
+		ARRAY_SIZE(cmd_spl_export_sub));
+	if (c) {
+		cmd = (int)c->cmd;
+		switch (cmd) {
+		case SPL_EXPORT_FDT:
+			argc--;
+			argv++;
+			return spl_export_fdt(argc, argv);
+			break;
+		case SPL_EXPORT_ATAGS:
+			argc--;
+			argv++;
+			return spl_export_atags(argc, argv);
+			break;
+		default:
+			/* unrecognized command */
+			return cmd_usage(cmdtp);
+		}
+	} else {
+		/* Unrecognized command */
+		return cmd_usage(cmdtp);
+	}
+
+	return 0;
+}
+
+static cmd_tbl_t cmd_spl_sub[] = {
+	U_BOOT_CMD_MKENT(export, 0, 1, (void *)SPL_EXPORT, "", ""),
+};
+
+int do_spl(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	cmd_tbl_t *c;
+	int cmd;
+
+	if (argc < 2) /* no subcommand */
+		return cmd_usage(cmdtp);
+
+	c = find_cmd_tbl(argv[1], &cmd_spl_sub[0], ARRAY_SIZE(cmd_spl_sub));
+	if (c) {
+		cmd = (int)c->cmd;
+		switch (cmd) {
+		case SPL_EXPORT:
+			argc--;
+			argv++;
+			if (spl_export(cmdtp, flag, argc, argv))
+				printf("Subcommand failed\n");
+			break;
+		default:
+			/* unrecognized command */
+			return cmd_usage(cmdtp);
+		}
+	} else {
+		/* Unrecognized command */
+		return cmd_usage(cmdtp);
+	}
+	return 0;
+}
+
+/*
+ * Arguments:
+ * 1: subcommand
+ * 2: image_type
+ * 3: nand_offset
+ * 4: kernel_addr
+ * 5: initrd_addr
+ * 6: fdt_adr
+ */
+
+U_BOOT_CMD(
+	spl, 6 , 1, do_spl, "SPL configuration",
+	"export <img=atags|fdt> [kernel_addr] [initrd_addr] "
+	"[fdt_addr if <img> = fdt] - export a kernel parameter image\n"
+	"\t initrd_img can be set to \"-\" if fdt_addr without initrd img is"
+	"used");
diff --git a/doc/README.commands.spl b/doc/README.commands.spl
new file mode 100644
index 0000000..818dd53
--- /dev/null
+++ b/doc/README.commands.spl
@@ -0,0 +1,31 @@
+The spl command is used to export a boot parameter image to RAM. Later
+it may implement more functions connected to the SPL.
+
+SUBCOMMAND EXPORT
+To execute the command everything has to be in place as if bootm should be
+used. (kernel image, initrd-image, fdt-image etc.)
+
+export has to subcommands:
+	atags: exports the ATAGS
+	fdt: exports the FDT
+
+Call is:
+spl export <ftd|atags> [kernel_addr] [initrd_addr] [fdt_addr if fdt]
+
+
+TYPICAL CALL
+
+on OMAP3:
+nandecc hw
+nand read 0x82000000 0x280000 0x400000 	/* Read kernel image from NAND*/
+spl export atags 			/* export ATAGS */
+nand erase 0x680000 0x20000		/* erase - one page */
+nand write 0x80000100 0x680000 0x20000	/* write the image - one page */
+
+call with FDT:
+nandecc hw
+nand read 0x82000000 0x280000 0x400000 	/* Read kernel image from NAND*/
+tftpboot 0x80000100 devkit8000.dtb /* Read fdt */
+spl export fdt 0x82000000 - 0x80000100	/* export FDT */
+nand erase 0x680000 0x20000		/* erase - one page */
+nand write <adress shown by spl export> 0x680000 0x20000
diff --git a/include/cmd_spl.h b/include/cmd_spl.h
new file mode 100644
index 0000000..dd3431d
--- /dev/null
+++ b/include/cmd_spl.h
@@ -0,0 +1,30 @@
+/* Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+extern bootm_headers_t images;
+
+enum image_type {FDT, ATAGS};
+
+#define SPL_EXPORT	(0x00000001)
+
+#define SPL_EXPORT_FDT		(0x00000001)
+#define SPL_EXPORT_ATAGS	(0x00000002)
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index 6c51a27..f603f55 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -361,4 +361,11 @@
 #define CONFIG_SYS_SPL_MALLOC_START	0x80108000
 #define CONFIG_SYS_SPL_MALLOC_SIZE	0x100000	/* 1 MB */
 
+/* SPL OS boot options */
+#define CONFIG_CMD_SPL
+#define CONFIG_CMD_SPL_WRITE_SIZE	0x400 /* 1024 byte */
+#define CONFIG_CMD_SPL_NAND_OFS	(CONFIG_SYS_NAND_SPL_KERNEL_OFFS+\
+						0x400000)
+#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS	0x280000
+#define CONFIG_SYS_SPL_ARGS_ADDR	(PHYS_SDRAM_1 + 0x100)
 #endif /* __CONFIG_H */
-- 
1.7.4.1

^ permalink raw reply related

* [U-Boot] [PATCH V7 0/5] SPL Linux boot
From: Simon Schwarz @ 2011-10-31 16:23 UTC (permalink / raw)
  To: u-boot
In-Reply-To: <1317284033-16188-1-git-send-email-simonschwarzcor@gmail.com>

Adds direct Linux boot to SPL. It implements a spl export command to save
ATAGS or FDT to NAND flash. The kernel image has to be in place for this!

Changes in V5:
- Rebased on u-boot-ti
- fixed MAKEALL warnings and errors 
- adapted to general gpio interface
Changes in V6:
- Change old commit message

Changes in V7:
- Correct style and format errors

based on:
- The new SPL layout 
- OMAP3 new SPL layout 
  (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105260)
- CONFIG_MACH_TYPE fix
  (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/105809)
- Prep subcommand patch for arm
  (http://article.gmane.org/gmane.comp.boot-loaders.u-boot/106725)

Related to:
- http://article.gmane.org/gmane.comp.boot-loaders.u-boot/102669

Simon Schwarz (5):
  Add cmd_spl command
  omap-common: Add NAND SPL linux booting
  omap-common/spl: Add linux boot to SPL
  devkit8000/spl: init GPMC for dm9000 in SPL
  omap-common: fixes BSS overwriting problem

 arch/arm/cpu/armv7/omap-common/spl.c      |   51 +++++++-
 arch/arm/cpu/armv7/omap-common/spl_nand.c |   63 ++++++--
 arch/arm/include/asm/omap_common.h        |    2 +
 board/timll/devkit8000/devkit8000.c       |   33 ++++-
 common/Makefile                           |    1 +
 common/cmd_spl.c                          |  224 +++++++++++++++++++++++++++++
 doc/README.commands.spl                   |   31 ++++
 include/cmd_spl.h                         |   30 ++++
 include/configs/devkit8000.h              |   16 ++-
 9 files changed, 423 insertions(+), 28 deletions(-)
 create mode 100644 common/cmd_spl.c
 create mode 100644 doc/README.commands.spl
 create mode 100644 include/cmd_spl.h

-- 
1.7.4.1

^ permalink raw reply

* Re: [lm-sensors] [PATCH 3/3 v2] hwmon: (w83627ehf) Add support for
From: Guenter Roeck @ 2011-10-31 16:22 UTC (permalink / raw)
  To: lm-sensors
In-Reply-To: <20111031170221.14d95aac@endymion.delvare>

On Mon, 2011-10-31 at 12:02 -0400, Jean Delvare wrote:
> This is essentially a stripped down version of the W83627DHG. Noticeable
> difference is that it is still powered with +5V, as older models, even
> though the ADC resolution is 8 mV as newer models have.
> 
> Thanks to Ulf Bruman (Saab Group) for doing all the testing.
> 
> Signed-off-by: Jean Delvare <khali@linux-fr.org>

Acked-by: Guenter Roeck <guenter.roeck@ericsson.com>



_______________________________________________
lm-sensors mailing list
lm-sensors@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/lm-sensors

^ permalink raw reply

* Re: bigalloc and max file size
From: Ted Ts'o @ 2011-10-31 16:22 UTC (permalink / raw)
  To: Andreas Dilger
  Cc: i@coly.li, Andreas Dilger, linux-ext4 development, Alex Zhuravlev,
	Tao Ma, hao.bigrat@gmail.com
In-Reply-To: <422BEB28-76D0-4FD8-B7AE-130C9AAE10C0@dilger.ca>

On Mon, Oct 31, 2011 at 10:08:20AM -0600, Andreas Dilger wrote:
> On 2011-10-31, at 4:22 AM, Theodore Tso <tytso@MIT.EDU> wrote:
> For cluster file systems, such as when you might build Hadoop on top
> > of ext4, there's no real advantage of using RAID arrays as opposed
> > to having single file systems on each disk.  In fact, due to the
> > specd of being able to check multiple disk spindles in parallel,
> > it's advantageous to build cluster file systems on single disk
> > file systems.
> 
> For Lustre at least there are a number of reasons why it uses large
> RAID devices to store the data instead of many small devices: -
> fewer devices that need to be managed. Lustre runs on systems with
> more than 13000 drives, and having to manage connection state for
> that many internal devices is a lot of overhead.

Well, per the discussion on the ext4 call, with Lustre hardware
multiple RAID LUN's get used, so while they might have tens of
petabytes of data, it is still split across a thousand hardware LUN's
or so.  So there is a middle ground between "put all of your 13000
devices on a single hardware RAID LUN", and "use 13000 file systems".
And in that middle ground, it seems surprising that someone would be
bumping into the the 1EB file system limit offered by ext4.

I'm curious why TaoBao is so interested in changing the extent
encoding for bigalloc file systems.  Currently we can support up to 1
EB worth of physical block numbers, and 16TB of logical block numbers.
Are you concerned about bumping into the 1 EB file system limit?  Or
the 16 TB file size limit?  Or something else?

Regards,

						- Ted

^ permalink raw reply

* Re: Various ctrl and event frame work patches (version 2)
From: Hans Verkuil @ 2011-10-31 16:17 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Linux Media Mailing List, Laurent Pinchart
In-Reply-To: <1320074209-23473-1-git-send-email-hdegoede@redhat.com>

Hi Hans!

On Monday, October 31, 2011 16:16:43 Hans de Goede wrote:
> Hi All,
> 
> This patch set obsoletes my previous "add v4l2_subscribed_event_ops" set,
> while working on adding support for ctrl-events to the uvc driver I found
> a few bugs in the event code, which this patchset fixes.

Did you see my comments to patches 3/6, 4/6 and 5/6 in version 1?
Those need to be addressed before I can ack them.

Regards,

	Hans

> Changes since version 1:
> -Added a documentation update (update v4l2-framework.txt) to:
>  "v4l2-event: Add v4l2_subscribed_event_ops"
> 
> Regards,
> 
> Hans
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 

^ permalink raw reply

* [PATCH] fadvise: only initiate writeback for specified range with FADV_DONTNEED
From: Shawn Bohrer @ 2011-10-31 16:16 UTC (permalink / raw)
  To: linux-mm; +Cc: linux-kernel, Shawn Bohrer

Previously POSIX_FADV_DONTNEED would start writeback for the entire file
when the bdi was not write congested.  This negatively impacts
performance if the file contians dirty pages outside of the requested
range.  This change uses __filemap_fdatawrite_range() to only initiate
writeback for the requested range.

Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
---
 mm/fadvise.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/mm/fadvise.c b/mm/fadvise.c
index 8d723c9..469491e 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -117,7 +117,8 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
 		break;
 	case POSIX_FADV_DONTNEED:
 		if (!bdi_write_congested(mapping->backing_dev_info))
-			filemap_flush(mapping);
+			__filemap_fdatawrite_range(mapping, offset, endbyte,
+						   WB_SYNC_NONE);
 
 		/* First and last FULL page! */
 		start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT;
-- 
1.7.6



---------------------------------------------------------------
This email, along with any attachments, is confidential. If you 
believe you received this message in error, please contact the 
sender immediately and delete all copies of the message.  
Thank you.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

^ permalink raw reply related

* [PATCH] fadvise: only initiate writeback for specified range with FADV_DONTNEED
From: Shawn Bohrer @ 2011-10-31 16:16 UTC (permalink / raw)
  To: linux-mm; +Cc: linux-kernel, Shawn Bohrer

Previously POSIX_FADV_DONTNEED would start writeback for the entire file
when the bdi was not write congested.  This negatively impacts
performance if the file contians dirty pages outside of the requested
range.  This change uses __filemap_fdatawrite_range() to only initiate
writeback for the requested range.

Signed-off-by: Shawn Bohrer <sbohrer@rgmadvisors.com>
---
 mm/fadvise.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/mm/fadvise.c b/mm/fadvise.c
index 8d723c9..469491e 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -117,7 +117,8 @@ SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
 		break;
 	case POSIX_FADV_DONTNEED:
 		if (!bdi_write_congested(mapping->backing_dev_info))
-			filemap_flush(mapping);
+			__filemap_fdatawrite_range(mapping, offset, endbyte,
+						   WB_SYNC_NONE);
 
 		/* First and last FULL page! */
 		start_index = (offset+(PAGE_CACHE_SIZE-1)) >> PAGE_CACHE_SHIFT;
-- 
1.7.6



---------------------------------------------------------------
This email, along with any attachments, is confidential. If you 
believe you received this message in error, please contact the 
sender immediately and delete all copies of the message.  
Thank you.


^ permalink raw reply related

* RE: [PATCH v2 3/3] staging: nvec: add device tree support
From: Stephen Warren @ 2011-10-31 16:16 UTC (permalink / raw)
  To: Marc Dietrich
  Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Olof Johansson, Colin Cross,
	devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X@public.gmane.org,
	Julian Andres Klode
In-Reply-To: <2542173.LWlOZpfLLJ@ax5200p>

Marc Dietrich wrote at Sunday, October 30, 2011 2:58 PM:
> On Friday 28 October 2011 09:56:41 you wrote:
> > Marc Dietrich wrote at Friday, October 28, 2011 5:02 AM:
> > > Am Donnerstag, 27. Oktober 2011, 12:17:25 schrieb Stephen Warren:
> > > > Marc Dietrich wrote at Wednesday, October 26, 2011 1:59 PM:
> > > > > This adds device tree support to the nvec driver. By using this
> > > > > method it is no longer necessary to specify platform data
> > > > > through a board file.
> >
> > ...
> >
> > > > > +/* Match table for of_platform binding */
> > > > > +static const struct of_device_id nvidia_nvec_of_match[]
> > > > > __devinitconst = { +	{ .compatible = "nvidia,nvec", },
...
> > I'd like to call this "nvidia,nvec-1.0" to version this compatible
> > property; that's the specification version in the latest document that
> > I saw. While we do seemed to have abandoned this approach, I want to
> > make sure this is extensible if someone suddenly decides to go back to
> > it and creates a 2.0 in the future. Does that seem reasonable?
> 
> mmh, I can't see why we should add it now. There is no V2 I can see in my
> limited view. If your company plans to expand the protocol you can either
> enhance our driver or create a new one (nvec2), which can add a nvidia,nvec-2
> compatibility property (we can also change ours to nvidia,nvec-1 at the same
> time, but that's not required).

We can't rename anything in DT once we've started using it; if we release
a new kernel that changes (rather than just adds to) the compatible values
it supports, that'd cause old DT files to cease to operate against the new
kernel.

I suppose nvidia,nvec is fine. We can always add nvidia,nvec2 if we do
rev the protocol, and have the existing unnumbered value implicitly be
version 1.

> > That said, there are apparently some OEMs who did change the protocol
> > and do something slightly different. I'm trying to confirm whether PAZ00
> > was one of them. I guess not if PAZ00 works with the standard driver that
> > you linked to.
> 
> There are so called OEM commands which we will move to a board specific nvec
> file (e.g. nvec_paz00.c). We haven't got the chance to test it on other boards
> using it yet (e.g. toshiba folio, advent vega, ...). The tablets are mostly
> using it for power control and maybe also leds/switches. I don't think any
> other board uses keyboard / mouse functions.

It sounded like some OEMS had used a completely different protocol rather
than just making use of the OEM commands. Still, it isn't entirely clear
whether that's true yet. I don't think it impacts this driver/board, so
we can just ignore this for now.

-- 
nvpublic

^ permalink raw reply

* Re: Need some help about the build xen.efi
From: Konrad Rzeszutek Wilk @ 2011-10-31 16:15 UTC (permalink / raw)
  To: liang tang; +Cc: xen-devel@lists.xensource.com, Jan Beulich
In-Reply-To: <4EAEAC4B.4000004@oracle.com>

On Mon, Oct 31, 2011 at 10:10:19PM +0800, liang tang wrote:
> Hi,Jan
> I have download xen unstable tree which include your efi patch,and
> try to build xen.efi ,but there only have xen.gz ,don't have xen.efi
> .I find the file xen\arch\x86\efi\disable have report some error :
> ld don't  support -m i386pep.  my gcc version is 4.6.1.
> if modify the i386pep to elf_x86_64 ,the build can continue ,and

Right, but that is not correct. The i386pep defines what type of executable
the binary will be. You do not want an x86_64 ELF, you want an i386
Portable Executable Program (I think that is what PEP stands for).

Google should have some details on how build/install an cross compiler for
i386pep.

> report other error --subsystem=10 and
> --image-base=0xffff82c480000000 unrecognized.
> do you have any suggestion about that?  thank you very much!
> 
> the detail is follow.
> ld: unrecognized option '--image-base=0xffff82c480000000'
> 
> In the xen/arch/x86/efi/disabled
> ld: unrecognized emulation mode: i386pep
> Supported emulations: elf_x86_64 elf32_x86_64 elf_i386 i386linux elf_l1om
> 
> liang.
> 

> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply

* Re: [PATCH] tracing: fix event_subsystem ref counting
From: Steven Rostedt @ 2011-10-31 16:14 UTC (permalink / raw)
  To: Ilya Dryomov; +Cc: linux-kernel
In-Reply-To: <1320052062-7846-1-git-send-email-idryomov@gmail.com>

On Mon, 2011-10-31 at 11:07 +0200, Ilya Dryomov wrote:
> Fix a bug introduced by e9dbfae5, which prevents event_subsystem from
> ever being released.
> 
> Ref_count was added to keep track of subsystem users, not for counting
> events.  Subsystem is created with ref_count = 1, so there is no need to
> increment it for every event, we have nr_events for that.  Fix this by
> touching ref_count only when we actually have a new user -
> subsystem_open().

Good catch, I'll pull this in.

Thanks!

-- Steve

> 
> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
> ---
>  kernel/trace/trace_events.c |    1 -
>  1 files changed, 0 insertions(+), 1 deletions(-)
> 
> diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
> index 581876f..c212a7f 100644
> --- a/kernel/trace/trace_events.c
> +++ b/kernel/trace/trace_events.c
> @@ -1078,7 +1078,6 @@ event_subsystem_dir(const char *name, struct dentry *d_events)
>  	/* First see if we did not already create this dir */
>  	list_for_each_entry(system, &event_subsystems, list) {
>  		if (strcmp(system->name, name) == 0) {
> -			__get_system(system);
>  			system->nr_events++;
>  			return system->entry;
>  		}



^ permalink raw reply

* [PATCH] i2c-gpio.c: correct logic of pdata->scl_is_open_drain
From: Voss, Nikolaus @ 2011-10-31 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

If pdata->scl_is_open_drain was set, the driver used push-pull output
for SCL, not open-drain output.

Signed-off-by: Nikolaus Voss <n.voss@weinmann.de>
---
 drivers/i2c/busses/i2c-gpio.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index a651779..b161335 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -104,7 +104,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_request_scl;
 
-	if (pdata->sda_is_open_drain) {
+	if (!pdata->sda_is_open_drain) {
 		gpio_direction_output(pdata->sda_pin, 1);
 		bit_data->setsda = i2c_gpio_setsda_val;
 	} else {
@@ -112,7 +112,7 @@ static int __devinit i2c_gpio_probe(struct platform_device *pdev)
 		bit_data->setsda = i2c_gpio_setsda_dir;
 	}
 
-	if (pdata->scl_is_open_drain || pdata->scl_is_output_only) {
+	if (!pdata->scl_is_open_drain || pdata->scl_is_output_only) {
 		gpio_direction_output(pdata->scl_pin, 1);
 		bit_data->setscl = i2c_gpio_setscl_val;
 	} else {
-- 
1.7.4.1

^ permalink raw reply related

* [Qemu-devel] [PATCH 1/2] net: socket backend passes junk size to getsockname(), fix
From: Markus Armbruster @ 2011-10-31 16:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori
In-Reply-To: <1320077498-692-1-git-send-email-armbru@redhat.com>

net_socket_fd_init_dgram() passes an uninitialized address length to
getsockname().  I guess this happens to work as long as the junk value
is at least sizeof(sockaddr_in).

Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 net/socket.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index e9ef128..eb3e0d6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -260,6 +260,7 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
      */
 
     if (is_connected) {
+        saddr_len = sizeof(saddr);
 	if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {
 	    /* must be bound */
 	    if (saddr.sin_addr.s_addr==0) {
-- 
1.7.6.4

^ permalink raw reply related

* [Qemu-devel] [PATCH 2/2] net: socket backend shows junk in "info network", fix
From: Markus Armbruster @ 2011-10-31 16:11 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori
In-Reply-To: <1320077498-692-1-git-send-email-armbru@redhat.com>

net_socket_fd_init_dgram() prints uninitialized saddr into
nc->info_str.

Spotted by Coverity.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 net/socket.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/net/socket.c b/net/socket.c
index eb3e0d6..42bbae4 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -288,10 +288,15 @@ static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan,
 
     nc = qemu_new_net_client(&net_dgram_socket_info, vlan, NULL, model, name);
 
-    snprintf(nc->info_str, sizeof(nc->info_str),
-	    "socket: fd=%d (%s mcast=%s:%d)",
-	    fd, is_connected ? "cloned" : "",
-	    inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
+    if (is_connected) {
+        snprintf(nc->info_str, sizeof(nc->info_str),
+                 "socket: fd=%d (cloned mcast=%s:%d)",
+                 fd, inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
+    } else {
+        snprintf(nc->info_str, sizeof(nc->info_str),
+                 "socket: fd=%d",
+                 fd);
+    }
 
     s = DO_UPCAST(NetSocketState, nc, nc);
 
-- 
1.7.6.4

^ permalink raw reply related

* Re: [PATCH 5/5] distro_tracking_fields: updates for sudo, mtools, grep, and openssh
From: Koen Kooi @ 2011-10-31 16:05 UTC (permalink / raw)
  To: Patches and discussions about the oe-core layer; +Cc: Paul Eggleton
In-Reply-To: <4EAEC2CE.400@intel.com>

[-- Attachment #1: Type: text/plain, Size: 1100 bytes --]


Op 31 okt. 2011, om 16:46 heeft Saul Wold het volgende geschreven:

> On 10/31/2011 02:08 AM, Paul Eggleton wrote:
>> On Wednesday 26 October 2011 21:37:39 Saul Wold wrote:
>>>> -RECIPE_TIME_BETWEEN_LAST_TWO_RELEASES_pn-sudo = "1 month"
>>>> -RECIPE_LATEST_RELEASE_DATE_pn-sudo = "2011/05/16"
>>>> +RECIPE_TIME_BETWEEN_LAST_TWO_RELEASES_pn-sudo = "2 months"
>>>> +RECIPE_LATEST_RELEASE_DATE_pn-sudo = "2011/10/21"
>>> 
>>> These date formats should be MMM DD, YYYY also, for all the data listed
>>> below also.
>> 
>> I'd been meaning to ask this before - is there a good reason for not being
>> consistent and using the same format for all date fields in this file?
>> 
> Maybe I am missing your comment, is that what I not suggested in my comment above?  All date formats in the distro_tracking_fields should be in the MMM DD, YYY format.

Can we please use a format that makes sense for non-americans as well? E.g. YYYY/MM/DD or DD/MM/YYYY or plain ISO (2011-10-31T17:04:31+01:00) without the hours? Anything that doesn't put days in between months and year.

regards,

KOen

[-- Attachment #2: Message signed with OpenPGP using GPGMail --]
[-- Type: application/pgp-signature, Size: 169 bytes --]

^ permalink raw reply


This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.