summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb
diff options
context:
space:
mode:
authorHolger Waechtler <devnull@localhost>2003-11-20 03:54:10 +0000
committerHolger Waechtler <devnull@localhost>2003-11-20 03:54:10 +0000
commit16df2e090a7bbd03359880991777c52fed1874c9 (patch)
treef54633609c50aad85b8c704de64b71a68a0e0475 /linux/drivers/media/dvb
parent03efc557ef5c42cb4e6259997665e6ccc4b29ead (diff)
downloadmediapointer-dvb-s2-16df2e090a7bbd03359880991777c52fed1874c9.tar.gz
mediapointer-dvb-s2-16df2e090a7bbd03359880991777c52fed1874c9.tar.bz2
firmware loader implementation contributed by Martin Stubbs
Diffstat (limited to 'linux/drivers/media/dvb')
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig16
-rw-r--r--linux/drivers/media/dvb/frontends/sp887x.c100
2 files changed, 106 insertions, 10 deletions
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index dd20a8aab..e9dc80540 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -155,3 +155,19 @@ config DVB_TDA1004X_FIRMWARE_FILE
wget http://www.technotrend.de/new/215/TTweb_215a_budget_20_05_2003.zip
unzip -j TTweb_215a_budget_20_05_2003.zip Software/Oem/PCI/App/ttlcdacc.dll
mv ttlcdacc.dll /etc/dvb/tda1004x.bin
+
+config DVB_SP887X_FIRMWARE_FILE
+ string "Full pathname of sp887x firmware file"
+ depends on DVB_SP887X
+ default "/etc/dvb/sc_main.mc"
+ help
+ This driver needs a copy of the Avermedia firmware. The version tested
+ is part of the Avermedia DVB-T 1.3.26.3 Application. This can be downloaded
+ from the Avermedia web site.
+ If the software is installed in Windows the file will be in the
+ /Program Files/AVerTV DVB-T/ directory and is called sc_main.mc.
+ Alternatively it can "extracted" from the install cab files but this will have
+ to be done in windows as I don't know of a linux version of extract.exe.
+ Copy this file to /etc/dvb/sc_main.mc. With this version of the file the first
+ 10 bytes are discarded and the next 0x4000 loaded. This may change in future
+ versions. \ No newline at end of file
diff --git a/linux/drivers/media/dvb/frontends/sp887x.c b/linux/drivers/media/dvb/frontends/sp887x.c
index a19281995..b25c3ff2f 100644
--- a/linux/drivers/media/dvb/frontends/sp887x.c
+++ b/linux/drivers/media/dvb/frontends/sp887x.c
@@ -1,11 +1,39 @@
+/*
+ Driver for the Microtune 7202D Frontend
+*/
+
+/*
+ This driver needs a copy of the Avermedia firmware. The version tested
+ is part of the Avermedia DVB-T 1.3.26.3 Application. If the software is
+ installed in Windows the file will be in the /Program Files/AVerTV DVB-T/
+ directory and is called sc_main.mc. Alternatively it can "extracted" from
+ the install cab files. Copy this file to /etc/dvb/sc_main.mc.
+ With this version of the file the first 10 bytes are discarded and the
+ next 0x4000 loaded. This may change in future versions.
+ */
+#define __KERNEL_SYSCALLS__
+#include <linux/kernel.h>
+#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+#include <linux/fcntl.h>
+#include <linux/errno.h>
#include <linux/i2c.h>
+
#include "dvb_frontend.h"
#include "dvb_functions.h"
+#ifndef DVB_SP887X_FIRMWARE_FILE
+#define DVB_SP887X_FIRMWARE_FILE "/etc/dvb/sc_main.mc"
+#endif
+
+static char *sp887x_firmware = DVB_SP887X_FIRMWARE_FILE;
#if 0
#define dprintk(x...) printk(x)
@@ -39,7 +67,7 @@ struct dvb_frontend_info sp887x_info = {
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER
};
-
+static int errno;
static
int i2c_writebytes (struct dvb_frontend *fe, u8 addr, u8 *buf, u8 len)
@@ -75,7 +103,7 @@ int sp887x_writereg (struct dvb_frontend *fe, u16 reg, u16 data)
/**
* in case of soft reset we ignore ACK errors...
*/
- if (!(reg == 0xf1a && data == 0x000 &&
+ if (!(reg == 0xf1a && data == 0x000 &&
(ret == -EREMOTEIO || ret == -EFAULT)))
{
printk("%s: writereg error "
@@ -112,8 +140,9 @@ u16 sp887x_readreg (struct dvb_frontend *fe, u16 reg)
static
void sp887x_microcontroller_stop (struct dvb_frontend *fe)
{
+ dprintk("%s\n", __FUNCTION__);
sp887x_writereg(fe, 0xf08, 0x000);
- sp887x_writereg(fe, 0xf09, 0x000);
+ sp887x_writereg(fe, 0xf09, 0x000);
/* microcontroller STOP */
sp887x_writereg(fe, 0xf00, 0x000);
@@ -123,8 +152,9 @@ void sp887x_microcontroller_stop (struct dvb_frontend *fe)
static
void sp887x_microcontroller_start (struct dvb_frontend *fe)
{
+ dprintk("%s\n", __FUNCTION__);
sp887x_writereg(fe, 0xf08, 0x000);
- sp887x_writereg(fe, 0xf09, 0x000);
+ sp887x_writereg(fe, 0xf09, 0x000);
/* microcontroller START */
sp887x_writereg(fe, 0xf00, 0x001);
@@ -135,6 +165,7 @@ static
void sp887x_setup_agc (struct dvb_frontend *fe)
{
/* setup AGC parameters */
+ dprintk("%s\n", __FUNCTION__);
sp887x_writereg(fe, 0x33c, 0x054);
sp887x_writereg(fe, 0x33b, 0x04c);
sp887x_writereg(fe, 0x328, 0x000);
@@ -152,8 +183,6 @@ void sp887x_setup_agc (struct dvb_frontend *fe)
}
-#include "sp887x_firm.h"
-
#define BLOCKSIZE 30
/**
@@ -163,13 +192,61 @@ static
int sp887x_initial_setup (struct dvb_frontend *fe)
{
u8 buf [BLOCKSIZE+2];
+ unsigned char *firmware = NULL;
int i;
+ int fd;
+ int filesize;
+ int fw_size;
+
+ dprintk("%s\n", __FUNCTION__);
/* soft reset */
sp887x_writereg(fe, 0xf1a, 0x000);
sp887x_microcontroller_stop (fe);
+ mm_segment_t fs = get_fs();
+
+ // Load the firmware
+ set_fs(get_ds());
+ fd = open(sp887x_firmware, 0, 0);
+ if (fd < 0) {
+ printk(KERN_WARNING "%s: Unable to open firmware %s\n", __FUNCTION__,
+ sp887x_firmware);
+ return -EIO;
+ }
+ filesize = lseek(fd, 0L, 2);
+ if (filesize <= 0) {
+ printk(KERN_WARNING "%s: Firmware %s is empty\n", __FUNCTION__,
+ sp887x_firmware);
+ sys_close(fd);
+ return -EIO;
+ }
+
+ fw_size = 0x4000;
+
+ // allocate buffer for it
+ firmware = vmalloc(fw_size);
+ if (firmware == NULL) {
+ printk(KERN_WARNING "%s: Out of memory loading firmware\n",
+ __FUNCTION__);
+ sys_close(fd);
+ return -EIO;
+ }
+
+ // read it!
+ // read the first 16384 bytes from the file
+ // ignore the first 10 bytes
+ lseek(fd, 10, 0);
+ if (read(fd, firmware, fw_size) != fw_size) {
+ printk(KERN_WARNING "%s: Failed to read firmware\n", __FUNCTION__);
+ vfree(firmware);
+ sys_close(fd);
+ return -EIO;
+ }
+ sys_close(fd);
+ set_fs(fs);
+
printk ("%s: firmware upload... ", __FUNCTION__);
/* setup write pointer to -1 (end of memory) */
@@ -179,12 +256,12 @@ int sp887x_initial_setup (struct dvb_frontend *fe)
/* dummy write (wrap around to start of memory) */
sp887x_writereg(fe, 0x8f0a, 0x0000);
- for (i=0; i<sizeof(sp887x_firm); i+=BLOCKSIZE) {
+ for (i=0; i<fw_size; i+=BLOCKSIZE) {
int c = BLOCKSIZE;
int err;
- if (i+c > sizeof(sp887x_firm))
- c = sizeof(sp887x_firm) - i;
+ if (i+c > fw_size)
+ c = fw_size - i;
/* bit 0x8000 in address is set to enable 13bit mode */
/* bit 0x4000 enables multibyte read/write transfers */
@@ -192,15 +269,18 @@ int sp887x_initial_setup (struct dvb_frontend *fe)
buf[0] = 0xcf;
buf[1] = 0x0a;
- memcpy(&buf[2], &sp887x_firm[i], c);
+ memcpy(&buf[2], firmware + i, c);
if ((err = i2c_writebytes (fe, 0x70, buf, c+2)) < 0) {
printk ("failed.\n");
printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
+ vfree(firmware);
return err;
}
}
+ vfree(firmware);
+
/* don't write RS bytes between packets */
sp887x_writereg(fe, 0xc13, 0x001);