From: Johannes Stezenbach <js@linuxtv.org>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org
Subject: [DVB patch 28/48] support pcHDTV HD2000
Date: Tue, 22 Mar 2005 02:24:01 +0100 [thread overview]
Message-ID: <20050322013458.128528000@abc> (raw)
In-Reply-To: 20050322013427.919515000@abc
[-- Attachment #1: dvb-pchdtv-hd2000.patch --]
[-- Type: text/plain, Size: 27327 bytes --]
o DVB support for the pcHDTV HD2000 card, submitted by Rusty Scott
o remove bttv dependency from frontend (Kenneth Aafloy)
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
bt8xx/Kconfig | 4
bt8xx/dvb-bt8xx.c | 72 +++++
bt8xx/dvb-bt8xx.h | 1
frontends/Kconfig | 7
frontends/Makefile | 1
frontends/or51132.c | 6
frontends/or51211.c | 631 ++++++++++++++++++++++++++++++++++++++++++++++++++++
frontends/or51211.h | 44 +++
8 files changed, 761 insertions(+), 5 deletions(-)
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/bt8xx/Kconfig
===================================================================
--- linux-2.6.12-rc1-mm1.orig/drivers/media/dvb/bt8xx/Kconfig 2005-03-21 23:27:57.000000000 +0100
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/bt8xx/Kconfig 2005-03-22 00:18:23.000000000 +0100
@@ -5,9 +5,11 @@ config DVB_BT8XX
select DVB_SP887X
select DVB_NXT6000
select DVB_CX24110
+ select DVB_OR51211
help
Support for PCI cards based on the Bt8xx PCI bridge. Examples are
- the Nebula cards, the Pinnacle PCTV cards and Twinhan DST cards.
+ the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and
+ pcHDTV HD2000 cards.
Since these cards have no MPEG decoder onboard, they transmit
only compressed MPEG data over the PCI bus, so you need
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/bt8xx/dvb-bt8xx.c
===================================================================
--- linux-2.6.12-rc1-mm1.orig/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2005-03-21 23:27:57.000000000 +0100
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/bt8xx/dvb-bt8xx.c 2005-03-22 00:18:23.000000000 +0100
@@ -133,7 +133,7 @@ static int thomson_dtt7579_demod_init(st
static u8 mt352_reset [] = { 0x50, 0x80 };
static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 };
static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0x20 };
- static u8 mt352_gpp_ctl_cfg [] = { 0x75, 0x33 };
+ static u8 mt352_gpp_ctl_cfg [] = { 0x8C, 0x33 };
static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 };
mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config));
@@ -369,6 +369,63 @@ static struct dst_config dst_config = {
};
+static int or51211_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
+{
+ struct dvb_bt8xx_card* bt = (struct dvb_bt8xx_card*) fe->dvb->priv;
+
+ return request_firmware(fw, name, &bt->bt->dev->dev);
+}
+
+static void or51211_setmode(struct dvb_frontend * fe, int mode)
+{
+ struct dvb_bt8xx_card *bt = fe->dvb->priv;
+ bttv_write_gpio(bt->bttv_nr, 0x0002, mode); /* Reset */
+ msleep(20);
+}
+
+static void or51211_reset(struct dvb_frontend * fe)
+{
+ struct dvb_bt8xx_card *bt = fe->dvb->priv;
+
+ /* RESET DEVICE
+ * reset is controled by GPIO-0
+ * when set to 0 causes reset and when to 1 for normal op
+ * must remain reset for 128 clock cycles on a 50Mhz clock
+ * also PRM1 PRM2 & PRM4 are controled by GPIO-1,GPIO-2 & GPIO-4
+ * We assume that the reset has be held low long enough or we
+ * have been reset by a power on. When the driver is unloaded
+ * reset set to 0 so if reloaded we have been reset.
+ */
+ /* reset & PRM1,2&4 are outputs */
+ int ret = bttv_gpio_enable(bt->bttv_nr, 0x001F, 0x001F);
+ if (ret != 0) {
+ printk(KERN_WARNING "or51211: Init Error - Can't Reset DVR "
+ "(%i)\n", ret);
+ }
+ bttv_write_gpio(bt->bttv_nr, 0x001F, 0x0000); /* Reset */
+ msleep(20);
+ /* Now set for normal operation */
+ bttv_write_gpio(bt->bttv_nr, 0x0001F, 0x0001);
+ /* wait for operation to begin */
+ msleep(500);
+}
+
+static void or51211_sleep(struct dvb_frontend * fe)
+{
+ struct dvb_bt8xx_card *bt = fe->dvb->priv;
+ bttv_write_gpio(bt->bttv_nr, 0x0001, 0x0000);
+}
+
+static struct or51211_config or51211_config = {
+
+ .demod_address = 0x15,
+ .request_firmware = or51211_request_firmware,
+ .setmode = or51211_setmode,
+ .reset = or51211_reset,
+ .sleep = or51211_sleep,
+};
+
+
static int vp3021_alps_tded4_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *) fe->dvb->priv;
@@ -458,6 +515,13 @@ static void frontend_init(struct dvb_bt8
break;
}
break;
+
+ case BTTV_PC_HDTV:
+ card->fe = or51211_attach(&or51211_config, card->i2c_adapter);
+ if (card->fe != NULL) {
+ break;
+ }
+ break;
}
if (card->fe == NULL) {
@@ -637,6 +701,12 @@ static int dvb_bt8xx_probe(struct device
* RISC+FIFO ENABLE */
break;
+ case BTTV_PC_HDTV:
+ card->gpio_mode = 0x0100EC7B;
+ card->op_sync_orin = 0;
+ card->irq_err_ignore = 0;
+ break;
+
default:
printk(KERN_WARNING "dvb_bt8xx: Unknown bttv card type: %d.\n",
sub->core->type);
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/bt8xx/dvb-bt8xx.h
===================================================================
--- linux-2.6.12-rc1-mm1.orig/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2005-03-21 23:27:57.000000000 +0100
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/bt8xx/dvb-bt8xx.h 2005-03-22 00:18:23.000000000 +0100
@@ -34,6 +34,7 @@
#include "dst.h"
#include "nxt6000.h"
#include "cx24110.h"
+#include "or51211.h"
struct dvb_bt8xx_card {
struct semaphore lock;
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/Kconfig
===================================================================
--- linux-2.6.12-rc1-mm1.orig/drivers/media/dvb/frontends/Kconfig 2005-03-22 00:15:24.000000000 +0100
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/Kconfig 2005-03-22 00:18:23.000000000 +0100
@@ -162,4 +162,11 @@ config DVB_OR51132
tristate "OR51132 based (pcHDTV)"
depends on DVB_CORE
+config DVB_OR51211
+ tristate "or51211 based (pcHDTV HD2000 card)"
+ depends on DVB_CORE
+ select FW_LOADER
+ help
+ An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
+
endmenu
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/Makefile
===================================================================
--- linux-2.6.12-rc1-mm1.orig/drivers/media/dvb/frontends/Makefile 2005-03-21 23:27:57.000000000 +0100
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/Makefile 2005-03-22 00:18:23.000000000 +0100
@@ -26,4 +26,5 @@ obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
obj-$(CONFIG_DVB_NXT2002) += nxt2002.o
+obj-$(CONFIG_DVB_OR51211) += or51211.o
obj-$(CONFIG_DVB_OR51132) += or51132.o
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/or51211.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/or51211.c 2005-03-22 00:18:23.000000000 +0100
@@ -0,0 +1,631 @@
+/*
+ * Support for OR51211 (pcHDTV HD-2000) - VSB
+ *
+ * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
+ *
+ * Based on code from Jack Kelliher (kelliher@xmission.com)
+ * Copyright (C) 2002 & pcHDTV, inc.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+*/
+
+/*
+ * This driver needs external firmware. Please use the command
+ * "<kerneldir>/Documentation/dvb/get_dvb_firmware or51211" to
+ * download/extract it, and then copy it to /usr/lib/hotplug/firmware.
+ */
+#define OR51211_DEFAULT_FIRMWARE "dvb-fe-or51211.fw"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <asm/byteorder.h>
+
+#include "dvb_frontend.h"
+#include "or51211.h"
+
+static int debug;
+#define dprintk(args...) \
+ do { \
+ if (debug) printk(KERN_DEBUG "or51211: " args); \
+ } while (0)
+
+static u8 run_buf[] = {0x7f,0x01};
+static u8 cmd_buf[] = {0x04,0x01,0x50,0x80,0x06}; // ATSC
+
+struct or51211_state {
+
+ struct i2c_adapter* i2c;
+ struct dvb_frontend_ops ops;
+
+ /* Configuration settings */
+ const struct or51211_config* config;
+
+ struct dvb_frontend frontend;
+ struct bt878* bt;
+
+ /* Demodulator private data */
+ u8 initialized:1;
+
+ /* Tuner private data */
+ u32 current_frequency;
+};
+
+static int i2c_writebytes (struct or51211_state* state, u8 reg, u8 *buf,
+ int len)
+{
+ int err;
+ struct i2c_msg msg;
+ msg.addr = reg;
+ msg.flags = 0;
+ msg.len = len;
+ msg.buf = buf;
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "or51211: i2c_writebytes error "
+ "(addr %02x, err == %i)\n", reg, err);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static u8 i2c_readbytes (struct or51211_state* state, u8 reg, u8* buf, int len)
+{
+ int err;
+ struct i2c_msg msg;
+ msg.addr = reg;
+ msg.flags = I2C_M_RD;
+ msg.len = len;
+ msg.buf = buf;
+
+ if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
+ printk(KERN_WARNING "or51211: i2c_readbytes error "
+ "(addr %02x, err == %i)\n", reg, err);
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int or51211_load_firmware (struct dvb_frontend* fe,
+ const struct firmware *fw)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ u8 tudata[585];
+ int i;
+
+ dprintk("Firmware is %d bytes\n",fw->size);
+
+ /* Get eprom data */
+ tudata[0] = 17;
+ if (i2c_writebytes(state,0x50,tudata,1)) {
+ printk(KERN_WARNING "or51211:load_firmware error eprom addr\n");
+ return -1;
+ }
+ if (i2c_readbytes(state,0x50,&tudata[145],192)) {
+ printk(KERN_WARNING "or51211: load_firmware error eprom\n");
+ return -1;
+ }
+
+ /* Create firmware buffer */
+ for (i = 0; i < 145; i++)
+ tudata[i] = fw->data[i];
+
+ for (i = 0; i < 248; i++)
+ tudata[i+337] = fw->data[145+i];
+
+ state->config->reset(fe);
+
+ if (i2c_writebytes(state,state->config->demod_address,tudata,585)) {
+ printk(KERN_WARNING "or51211: load_firmware error 1\n");
+ return -1;
+ }
+ msleep(1);
+
+ if (i2c_writebytes(state,state->config->demod_address,
+ &fw->data[393],8125)) {
+ printk(KERN_WARNING "or51211: load_firmware error 2\n");
+ return -1;
+ }
+ msleep(1);
+
+ if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+ printk(KERN_WARNING "or51211: load_firmware error 3\n");
+ return -1;
+ }
+
+ /* Wait at least 5 msec */
+ msleep(10);
+ if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+ printk(KERN_WARNING "or51211: load_firmware error 4\n");
+ return -1;
+ }
+ msleep(10);
+
+ printk("or51211: Done.\n");
+ return 0;
+};
+
+static int or51211_setmode(struct dvb_frontend* fe, int mode)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ u8 rec_buf[14];
+
+ state->config->setmode(fe, mode);
+
+ if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+ printk(KERN_WARNING "or51211: setmode error 1\n");
+ return -1;
+ }
+
+ /* Wait at least 5 msec */
+ msleep(10);
+ if (i2c_writebytes(state,state->config->demod_address,run_buf,2)) {
+ printk(KERN_WARNING "or51211: setmode error 2\n");
+ return -1;
+ }
+
+ msleep(10);
+
+ /* Set operation mode in Receiver 1 register;
+ * type 1:
+ * data 0x50h Automatic sets receiver channel conditions
+ * Automatic NTSC rejection filter
+ * Enable MPEG serial data output
+ * MPEG2tr
+ * High tuner phase noise
+ * normal +/-150kHz Carrier acquisition range
+ */
+ if (i2c_writebytes(state,state->config->demod_address,cmd_buf,3)) {
+ printk(KERN_WARNING "or51211: setmode error 3\n");
+ return -1;
+ }
+
+ rec_buf[0] = 0x04;
+ rec_buf[1] = 0x00;
+ rec_buf[2] = 0x03;
+ rec_buf[3] = 0x00;
+ msleep(20);
+ if (i2c_writebytes(state,state->config->demod_address,rec_buf,3)) {
+ printk(KERN_WARNING "or51211: setmode error 5\n");
+ }
+ msleep(3);
+ if (i2c_readbytes(state,state->config->demod_address,&rec_buf[10],2)) {
+ printk(KERN_WARNING "or51211: setmode error 6");
+ return -1;
+ }
+ dprintk("setmode rec status %02x %02x\n",rec_buf[10],rec_buf[11]);
+
+ return 0;
+}
+
+static int or51211_set_parameters(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ u32 freq = 0;
+ u16 tunerfreq = 0;
+ u8 buf[4];
+
+ /* Change only if we are actually changing the channel */
+ if (state->current_frequency != param->frequency) {
+ freq = 44000 + (param->frequency/1000);
+ tunerfreq = freq * 16/1000;
+
+ dprintk("set_parameters frequency = %d (tunerfreq = %d)\n",
+ param->frequency,tunerfreq);
+
+ buf[0] = (tunerfreq >> 8) & 0x7F;
+ buf[1] = (tunerfreq & 0xFF);
+ buf[2] = 0x8E;
+
+ if (param->frequency < 157250000) {
+ buf[3] = 0xA0;
+ dprintk("set_parameters VHF low range\n");
+ } else if (param->frequency < 454000000) {
+ buf[3] = 0x90;
+ dprintk("set_parameters VHF high range\n");
+ } else {
+ buf[3] = 0x30;
+ dprintk("set_parameters UHF range\n");
+ }
+ dprintk("set_parameters tuner bytes: 0x%02x 0x%02x "
+ "0x%02x 0x%02x\n",buf[0],buf[1],buf[2],buf[3]);
+
+ if (i2c_writebytes(state,0xC2>>1,buf,4))
+ printk(KERN_WARNING "or51211:set_parameters error "
+ "writing to tuner\n");
+
+ /* Set to ATSC mode */
+ or51211_setmode(fe,0);
+
+ /* Update current frequency */
+ state->current_frequency = param->frequency;
+ }
+ return 0;
+}
+
+static int or51211_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ unsigned char rec_buf[2];
+ unsigned char snd_buf[] = {0x04,0x00,0x03,0x00};
+ *status = 0;
+
+ /* Receiver Status */
+ if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
+ printk(KERN_WARNING "or51132: read_status write error\n");
+ return -1;
+ }
+ msleep(3);
+ if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
+ printk(KERN_WARNING "or51132: read_status read error\n");
+ return -1;
+ }
+ dprintk("read_status %x %x\n",rec_buf[0],rec_buf[1]);
+
+ if (rec_buf[0] & 0x01) { /* Receiver Lock */
+ *status |= FE_HAS_SIGNAL;
+ *status |= FE_HAS_CARRIER;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_SYNC;
+ *status |= FE_HAS_LOCK;
+ }
+ return 0;
+}
+
+/* log10-1 table at .5 increments from 1 to 100.5 */
+static unsigned int i100x20log10[] = {
+ 0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
+ 1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
+ 2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
+ 2408, 2434, 2460, 2486, 2510, 2534, 2557, 2580, 2602, 2623,
+ 2644, 2664, 2684, 2704, 2723, 2742, 2760, 2778, 2795, 2813,
+ 2829, 2846, 2862, 2878, 2894, 2909, 2924, 2939, 2954, 2968,
+ 2982, 2996, 3010, 3023, 3037, 3050, 3062, 3075, 3088, 3100,
+ 3112, 3124, 3136, 3148, 3159, 3170, 3182, 3193, 3204, 3214,
+ 3225, 3236, 3246, 3256, 3266, 3276, 3286, 3296, 3306, 3316,
+ 3325, 3334, 3344, 3353, 3362, 3371, 3380, 3389, 3397, 3406,
+ 3415, 3423, 3432, 3440, 3448, 3456, 3464, 3472, 3480, 3488,
+ 3496, 3504, 3511, 3519, 3526, 3534, 3541, 3549, 3556, 3563,
+ 3570, 3577, 3584, 3591, 3598, 3605, 3612, 3619, 3625, 3632,
+ 3639, 3645, 3652, 3658, 3665, 3671, 3677, 3683, 3690, 3696,
+ 3702, 3708, 3714, 3720, 3726, 3732, 3738, 3744, 3750, 3755,
+ 3761, 3767, 3772, 3778, 3784, 3789, 3795, 3800, 3806, 3811,
+ 3816, 3822, 3827, 3832, 3838, 3843, 3848, 3853, 3858, 3863,
+ 3868, 3874, 3879, 3884, 3888, 3893, 3898, 3903, 3908, 3913,
+ 3918, 3922, 3927, 3932, 3936, 3941, 3946, 3950, 3955, 3960,
+ 3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
+};
+
+static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
+
+static unsigned int i20Log10(unsigned short val)
+{
+ unsigned int rntval = 100;
+ unsigned int tmp = val;
+ unsigned int exp = 1;
+
+ while(tmp > 100) {tmp /= 100; exp++;}
+
+ val = (2 * val)/denom[exp];
+ if (exp > 1) rntval = 2000*exp;
+
+ rntval += i100x20log10[val];
+ return rntval;
+}
+
+static int or51211_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ u8 rec_buf[2];
+ u8 snd_buf[4];
+ u8 snr_equ;
+
+ /* SNR after Equalizer */
+ snd_buf[0] = 0x04;
+ snd_buf[1] = 0x00;
+ snd_buf[2] = 0x04;
+ snd_buf[3] = 0x00;
+
+ if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
+ printk(KERN_WARNING "or51211: read_status write error\n");
+ return -1;
+ }
+ msleep(3);
+ if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
+ printk(KERN_WARNING "or51211: read_status read error\n");
+ return -1;
+ }
+ snr_equ = rec_buf[0] & 0xff;
+
+ /* The value reported back from the frontend will be FFFF=100% 0000=0% */
+ *strength = (((5334 - i20Log10(snr_equ))/3+5)*65535)/1000;
+
+ dprintk("read_signal_strength %i\n",*strength);
+
+ return 0;
+}
+
+static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ u8 rec_buf[2];
+ u8 snd_buf[4];
+
+ /* SNR after Equalizer */
+ snd_buf[0] = 0x04;
+ snd_buf[1] = 0x00;
+ snd_buf[2] = 0x04;
+ snd_buf[3] = 0x00;
+
+ if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
+ printk(KERN_WARNING "or51211: read_status write error\n");
+ return -1;
+ }
+ msleep(3);
+ if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
+ printk(KERN_WARNING "or51211: read_status read error\n");
+ return -1;
+ }
+ *snr = rec_buf[0] & 0xff;
+
+ dprintk("read_snr %i\n",*snr);
+
+ return 0;
+}
+
+static int or51211_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+ *ber = -ENOSYS;
+ return 0;
+}
+
+static int or51211_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+ *ucblocks = -ENOSYS;
+ return 0;
+}
+
+static int or51211_sleep(struct dvb_frontend* fe)
+{
+ return 0;
+}
+
+static int or51211_init(struct dvb_frontend* fe)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ const struct or51211_config* config = state->config;
+ const struct firmware* fw;
+ unsigned char get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00};
+ unsigned char rec_buf[14];
+ int ret,i;
+
+ if (!state->initialized) {
+ /* Request the firmware, this will block until it uploads */
+ printk(KERN_INFO "or51211: Waiting for firmware upload "
+ "(%s)...\n", OR51211_DEFAULT_FIRMWARE);
+ ret = config->request_firmware(fe, &fw,
+ OR51211_DEFAULT_FIRMWARE);
+ printk(KERN_INFO "or51211:Got Hotplug firmware\n");
+ if (ret) {
+ printk(KERN_WARNING "or51211: No firmware uploaded "
+ "(timeout or file not found?)\n");
+ return ret;
+ }
+
+ ret = or51211_load_firmware(fe, fw);
+ if (ret) {
+ printk(KERN_WARNING "or51211: Writing firmware to "
+ "device failed!\n");
+ release_firmware(fw);
+ return ret;
+ }
+ printk(KERN_INFO "or51211: Firmware upload complete.\n");
+
+ /* Set operation mode in Receiver 1 register;
+ * type 1:
+ * data 0x50h Automatic sets receiver channel conditions
+ * Automatic NTSC rejection filter
+ * Enable MPEG serial data output
+ * MPEG2tr
+ * High tuner phase noise
+ * normal +/-150kHz Carrier acquisition range
+ */
+ if (i2c_writebytes(state,state->config->demod_address,
+ cmd_buf,3)) {
+ printk(KERN_WARNING "or51211: Load DVR Error 5\n");
+ return -1;
+ }
+
+ /* Read back ucode version to besure we loaded correctly */
+ /* and are really up and running */
+ rec_buf[0] = 0x04;
+ rec_buf[1] = 0x00;
+ rec_buf[2] = 0x03;
+ rec_buf[3] = 0x00;
+ msleep(30);
+ if (i2c_writebytes(state,state->config->demod_address,
+ rec_buf,3)) {
+ printk(KERN_WARNING "or51211: Load DVR Error A\n");
+ return -1;
+ }
+ msleep(3);
+ if (i2c_readbytes(state,state->config->demod_address,
+ &rec_buf[10],2)) {
+ printk(KERN_WARNING "or51211: Load DVR Error B\n");
+ return -1;
+ }
+
+ rec_buf[0] = 0x04;
+ rec_buf[1] = 0x00;
+ rec_buf[2] = 0x01;
+ rec_buf[3] = 0x00;
+ msleep(20);
+ if (i2c_writebytes(state,state->config->demod_address,
+ rec_buf,3)) {
+ printk(KERN_WARNING "or51211: Load DVR Error C\n");
+ return -1;
+ }
+ msleep(3);
+ if (i2c_readbytes(state,state->config->demod_address,
+ &rec_buf[12],2)) {
+ printk(KERN_WARNING "or51211: Load DVR Error D\n");
+ return -1;
+ }
+
+ for (i = 0; i < 8; i++)
+ rec_buf[i]=0xed;
+
+ for (i = 0; i < 5; i++) {
+ msleep(30);
+ get_ver_buf[4] = i+1;
+ if (i2c_writebytes(state,state->config->demod_address,
+ get_ver_buf,5)) {
+ printk(KERN_WARNING "or51211:Load DVR Error 6"
+ " - %d\n",i);
+ return -1;
+ }
+ msleep(3);
+
+ if (i2c_readbytes(state,state->config->demod_address,
+ &rec_buf[i*2],2)) {
+ printk(KERN_WARNING "or51211:Load DVR Error 7"
+ " - %d\n",i);
+ return -1;
+ }
+ /* If we didn't receive the right index, try again */
+ if ((int)rec_buf[i*2+1]!=i+1){
+ i--;
+ }
+ }
+ dprintk("read_fwbits %x %x %x %x %x %x %x %x %x %x\n",
+ rec_buf[0], rec_buf[1], rec_buf[2], rec_buf[3],
+ rec_buf[4], rec_buf[5], rec_buf[6], rec_buf[7],
+ rec_buf[8], rec_buf[9]);
+
+ printk(KERN_INFO "or51211: ver TU%02x%02x%02x VSB mode %02x"
+ " Status %02x\n",
+ rec_buf[2], rec_buf[4],rec_buf[6],
+ rec_buf[12],rec_buf[10]);
+
+ rec_buf[0] = 0x04;
+ rec_buf[1] = 0x00;
+ rec_buf[2] = 0x03;
+ rec_buf[3] = 0x00;
+ msleep(20);
+ if (i2c_writebytes(state,state->config->demod_address,
+ rec_buf,3)) {
+ printk(KERN_WARNING "or51211: Load DVR Error 8\n");
+ return -1;
+ }
+ msleep(20);
+ if (i2c_readbytes(state,state->config->demod_address,
+ &rec_buf[8],2)) {
+ printk(KERN_WARNING "or51211: Load DVR Error 9\n");
+ return -1;
+ }
+ state->initialized = 1;
+ }
+
+ return 0;
+}
+
+static int or51211_get_tune_settings(struct dvb_frontend* fe,
+ struct dvb_frontend_tune_settings* fesettings)
+{
+ fesettings->min_delay_ms = 500;
+ fesettings->step_size = 0;
+ fesettings->max_drift = 0;
+ return 0;
+}
+
+static void or51211_release(struct dvb_frontend* fe)
+{
+ struct or51211_state* state = fe->demodulator_priv;
+ state->config->sleep(fe);
+ kfree(state);
+}
+
+static struct dvb_frontend_ops or51211_ops;
+
+struct dvb_frontend* or51211_attach(const struct or51211_config* config,
+ struct i2c_adapter* i2c)
+{
+ struct or51211_state* state = NULL;
+
+ /* Allocate memory for the internal state */
+ state = kmalloc(sizeof(struct or51211_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* Setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ memcpy(&state->ops, &or51211_ops, sizeof(struct dvb_frontend_ops));
+ state->initialized = 0;
+ state->current_frequency = 0;
+
+ /* Create dvb_frontend */
+ state->frontend.ops = &state->ops;
+ state->frontend.demodulator_priv = state;
+ return &state->frontend;
+
+error:
+ if (state) kfree(state);
+ return NULL;
+}
+
+static struct dvb_frontend_ops or51211_ops = {
+
+ .info = {
+ .name = "Oren OR51211 VSB Frontend",
+ .type = FE_ATSC,
+ .frequency_min = 44000000,
+ .frequency_max = 958000000,
+ .frequency_stepsize = 166666,
+ .caps = 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_8VSB
+ },
+
+ .release = or51211_release,
+
+ .init = or51211_init,
+ .sleep = or51211_sleep,
+
+ .set_frontend = or51211_set_parameters,
+ .get_tune_settings = or51211_get_tune_settings,
+
+ .read_status = or51211_read_status,
+ .read_ber = or51211_read_ber,
+ .read_signal_strength = or51211_read_signal_strength,
+ .read_snr = or51211_read_snr,
+ .read_ucblocks = or51211_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("Oren OR51211 VSB [pcHDTV HD-2000] Demodulator Driver");
+MODULE_AUTHOR("Kirk Lapray");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(or51211_attach);
+
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/or51211.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/or51211.h 2005-03-22 00:18:23.000000000 +0100
@@ -0,0 +1,44 @@
+/*
+ * Support for OR51211 (pcHDTV HD-2000) - VSB
+ *
+ * Copyright (C) 2005 Kirk Lapray <kirk_lapray@bigfoot.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 OR51211_H
+#define OR51211_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct or51211_config
+{
+ /* The demodulator's i2c address */
+ u8 demod_address;
+
+ /* Request firmware for device */
+ int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
+ void (*setmode)(struct dvb_frontend * fe, int mode);
+ void (*reset)(struct dvb_frontend * fe);
+ void (*sleep)(struct dvb_frontend * fe);
+};
+
+extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
+ struct i2c_adapter* i2c);
+
+#endif // OR51211_H
+
Index: linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/or51132.c
===================================================================
--- linux-2.6.12-rc1-mm1.orig/drivers/media/dvb/frontends/or51132.c 2005-03-21 23:27:57.000000000 +0100
+++ linux-2.6.12-rc1-mm1/drivers/media/dvb/frontends/or51132.c 2005-03-22 00:18:23.000000000 +0100
@@ -422,7 +422,7 @@ static int or51132_read_status(struct dv
}
/* log10-1 table at .5 increments from 1 to 100.5 */
-unsigned int i100x20log10[] = {
+static unsigned int i100x20log10[] = {
0, 352, 602, 795, 954, 1088, 1204, 1306, 1397, 1480,
1556, 1625, 1690, 1750, 1806, 1858, 1908, 1955, 2000, 2042,
2082, 2121, 2158, 2193, 2227, 2260, 2292, 2322, 2352, 2380,
@@ -445,9 +445,9 @@ unsigned int i100x20log10[] = {
3964, 3969, 3973, 3978, 3982, 3986, 3991, 3995, 4000, 4004,
};
-unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
+static unsigned int denom[] = {1,1,100,1000,10000,100000,1000000,10000000,100000000};
-unsigned int i20Log10(unsigned short val)
+static unsigned int i20Log10(unsigned short val)
{
unsigned int rntval = 100;
unsigned int tmp = val;
--
next prev parent reply other threads:[~2005-03-22 1:47 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-03-22 1:23 [DVB patch 00/48] DVB updates for 2.6.12-rc1-mm1 Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 01/48] clarify firmware upload messages Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 02/48] dibcom: frontend fixes Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 03/48] dibusb: misc. fixes Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 04/48] skystar2: remove duplicate pci_release_region() Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 05/48] mt352: Pinnacle 300i comments Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 06/48] support Activy Budget card Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 07/48] skystar2: update email address Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 08/48] ves1x93: invert_pwm fix Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 09/48] dibusb readme update Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 10/48] dibusb: support Hauppauge WinTV NOVA-T USB2 Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 11/48] nxt2002: QAM64/256 support Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 12/48] get_dvb_firmware: new unshield version Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 13/48] dib3000: corrected device naming Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 14/48] dibusb: debug changes Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 15/48] dibusb: increased the number of urbs for usb1.1 devices Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 16/48] ttusb_dec: use alternative interface to save bandwidth Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 17/48] l64781: email address fix Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 18/48] skystar2: fix MAC address reading Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 19/48] support KWorld/ADSTech Instant DVB-T USB2.0 Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 20/48] cleanups, make stuff static Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 21/48] refactor sw pid filter to drop redundant code Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 22/48] nxt2002: fix max frequency Johannes Stezenbach
2005-03-22 2:43 ` Gene Heskett
2005-03-22 1:23 ` [DVB patch 23/48] ttusb-budget: s/usb_unlink_urb/usb_kill_urb/ Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 24/48] av7110: fix Oops when av7110_ir_init() failed Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 25/48] saa7146: static initialization Johannes Stezenbach
2005-03-22 1:23 ` [DVB patch 26/48] av7110: error handling during attach Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 27/48] corrected links to firmware files Johannes Stezenbach
2005-03-22 1:24 ` Johannes Stezenbach [this message]
2005-03-22 1:24 ` [DVB patch 29/48] dibusb: support nova-t usb ir Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 30/48] OREN or51211, or51132_qam and or51132_vsb firmware download info Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 31/48] ttusb_dec: IR support Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 32/48] dibusb: pll fix Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 33/48] tda10021: fix continuity errors Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 34/48] saa7146: remove duplicate setgpio Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 35/48] fix CAMs on Typhoon DVB-S Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 36/48] frontends: kfree() cleanup Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 37/48] clear up confusion between ids and adapters Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 38/48] dibusb: remove useless ifdef Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 39/48] support for Technotrend PCI DVB-T Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 40/48] dibusb: HanfTek UMT-010 fixes Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 41/48] vfree() checking cleanups Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 42/48] convert from pci_module_init to pci_register_driver Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 43/48] dibusb: support dtt200u (Yakumo/Typhoon/Hama) USB2.0 device Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 44/48] sparse warnings on one-bit bitfields Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 45/48] support Nova-S rev 2.2 Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 46/48] ttusb_dec: cleanup Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 47/48] gcc 2.95 compile fixes Johannes Stezenbach
2005-03-22 1:24 ` [DVB patch 48/48] mt352: cleanups Johannes Stezenbach
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050322013458.128528000@abc \
--to=js@linuxtv.org \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.