Commit eb97de0b authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] dvb: av7110 driver update

- av7110: fixed av7110_before_after_tune()/av7110_fe_lock_fix(): firmware >=
  261d: wait for empty message queue, firmware <= 261c: wait 50ms

- av7110: add __user and __iomem annotations, remove some unnecessary cast
  (patch by C.Y.M)

- av7110: __av7110_send_fw_cmd(): added some sanity checks suggested by
  Werner Fin

- av7110: added support for full-featured DVB-C cards: 13c2:0000 Siemens
  DVB-C (full-length card) VES1820/Philips CD1516 and 13c2:0003 Haupauge DVB-C
  2.1 VES1820/ALPS TDBE2

- av7110: follow saa7146 changes, remove superflous casts, and other misc. 
  minor cleanups

- av7110: Fixed race condition between driver and av7110 while accessing the
  COMMAND register in DPRAM.  See
  http://www.linuxtv.org/mailinglists/vdr/2004/01-2004/msg00331.html

- budget: various cleanups by Adrian bunk 
Signed-off-by: default avatarMichael Hunold <hunold@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0e8a0d01
...@@ -77,7 +77,7 @@ static int rgb_on; ...@@ -77,7 +77,7 @@ static int rgb_on;
static int volume = 255; static int volume = 255;
module_param_named(debug, av7110_debug, int, 0644); module_param_named(debug, av7110_debug, int, 0644);
MODULE_PARM_DESC(av7110_debug, "Turn on/off debugging (default:off)."); MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
module_param(vidmode, int, 0444); module_param(vidmode, int, 0444);
MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC"); MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
module_param(pids_off, int, 0444); module_param(pids_off, int, 0444);
...@@ -117,7 +117,7 @@ static void init_av7110_av(struct av7110 *av7110) ...@@ -117,7 +117,7 @@ static void init_av7110_av(struct av7110 *av7110)
/* handle different card types */ /* handle different card types */
/* remaining inits according to card and frontend type */ /* remaining inits according to card and frontend type */
av7110->has_analog_tuner = 0; av7110->analog_tuner_flags = 0;
av7110->current_input = 0; av7110->current_input = 0;
if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
...@@ -149,10 +149,12 @@ static void init_av7110_av(struct av7110 *av7110) ...@@ -149,10 +149,12 @@ static void init_av7110_av(struct av7110 *av7110)
// switch DVB SCART on // switch DVB SCART on
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0); av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1); av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
if (rgb_on) if (rgb_on &&
(av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16 saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
//saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8 //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
} }
}
av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right); av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
av7110_setup_irc_config(av7110, 0); av7110_setup_irc_config(av7110, 0);
...@@ -192,9 +194,10 @@ static int arm_thread(void *data) ...@@ -192,9 +194,10 @@ static int arm_thread(void *data)
av7110->arm_thread = current; av7110->arm_thread = current;
while (1) { for (;;) {
timeout = wait_event_interruptible_timeout(av7110->arm_wait,0 != av7110->arm_rmmod, 5*HZ); timeout = wait_event_interruptible_timeout(av7110->arm_wait,
if (-ERESTARTSYS == timeout || 0 != av7110->arm_rmmod) { av7110->arm_rmmod, 5 * HZ);
if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
/* got signal or told to quit*/ /* got signal or told to quit*/
break; break;
} }
...@@ -287,7 +290,7 @@ static void IR_handle(struct av7110 *av7110, u32 ircom) ...@@ -287,7 +290,7 @@ static void IR_handle(struct av7110 *av7110, u32 ircom)
* IRQ handling * IRQ handling
****************************************************************************/ ****************************************************************************/
static inline int DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len, static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
u8 * buffer2, size_t buffer2_len, u8 * buffer2, size_t buffer2_len,
struct dvb_demux_filter *dvbdmxfilter, struct dvb_demux_filter *dvbdmxfilter,
enum dmx_success success, enum dmx_success success,
...@@ -355,9 +358,8 @@ static void debiirq (unsigned long data) ...@@ -355,9 +358,8 @@ static void debiirq (unsigned long data)
// dprintk(4, "%p\n",av7110); // dprintk(4, "%p\n",av7110);
print_time("debi"); print_time("debi");
saa7146_write(av7110->dev, IER, SAA7146_IER_DISABLE(av7110->dev, MASK_19);
saa7146_read(av7110->dev, IER) & ~MASK_19 ); SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
saa7146_write(av7110->dev, ISR, MASK_19 );
if (type==-1) { if (type==-1) {
printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n", printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
...@@ -493,9 +495,8 @@ static void gpioirq (unsigned long data) ...@@ -493,9 +495,8 @@ static void gpioirq (unsigned long data)
ARM_ClearIrq(av7110); ARM_ClearIrq(av7110);
saa7146_write(av7110->dev, IER, SAA7146_IER_DISABLE(av7110->dev, MASK_19);
saa7146_read(av7110->dev, IER) & ~MASK_19 ); SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
saa7146_write(av7110->dev, ISR, MASK_19 );
av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2); av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2); av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
...@@ -822,9 +823,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -822,9 +823,13 @@ static int StartHWFilter(struct dvb_demux_filter *dvbdmxfilter)
buf[3] = mode; buf[3] = mode;
ret = av7110_fw_request(av7110, buf, 20, &handle, 1); ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
if (ret < 0) { if (ret != 0 || handle >= 32) {
dprintk(1, "StartHWFilter error\n"); printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
return ret; "ret %x handle %04x\n",
__FUNCTION__, buf[0], buf[1], buf[2], buf[3],
ret, handle);
dvbdmxfilter->hw_handle = 0xffff;
return -1;
} }
av7110->handle2filter[handle] = dvbdmxfilter; av7110->handle2filter[handle] = dvbdmxfilter;
...@@ -844,8 +849,9 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -844,8 +849,9 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
handle = dvbdmxfilter->hw_handle; handle = dvbdmxfilter->hw_handle;
if (handle > 32) { if (handle >= 32) {
dprintk(1, "StopHWFilter tried to stop invalid filter %d, filter type = %d\n", handle, dvbdmxfilter->type); printk("%s tried to stop invalid filter %04x, filter type = %x\n",
__FUNCTION__, handle, dvbdmxfilter->type);
return 0; return 0;
} }
...@@ -855,11 +861,11 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter) ...@@ -855,11 +861,11 @@ static int StopHWFilter(struct dvb_demux_filter *dvbdmxfilter)
buf[1] = 1; buf[1] = 1;
buf[2] = handle; buf[2] = handle;
ret = av7110_fw_request(av7110, buf, 3, answ, 2); ret = av7110_fw_request(av7110, buf, 3, answ, 2);
if (ret) if (ret != 0 || answ[1] != handle) {
dprintk(1, "StopHWFilter error\n"); printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
"resp %04x %04x pid %d\n",
if (answ[1] != handle) { __FUNCTION__, buf[0], buf[1], buf[2], ret,
dprintk(2, "filter %d shutdown error :%d\n", handle, answ[1]); answ[0], answ[1], dvbdmxfilter->feed->pid);
ret = -1; ret = -1;
} }
return ret; return ret;
...@@ -937,7 +943,7 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed) ...@@ -937,7 +943,7 @@ static void dvb_feed_stop_pid(struct dvb_demux_feed *dvbdmxfeed)
static int av7110_start_feed(struct dvb_demux_feed *feed) static int av7110_start_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = (struct av7110 *) demux->priv; struct av7110 *av7110 = demux->priv;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -995,7 +1001,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed) ...@@ -995,7 +1001,7 @@ static int av7110_start_feed(struct dvb_demux_feed *feed)
static int av7110_stop_feed(struct dvb_demux_feed *feed) static int av7110_stop_feed(struct dvb_demux_feed *feed)
{ {
struct dvb_demux *demux = feed->demux; struct dvb_demux *demux = feed->demux;
struct av7110 *av7110 = (struct av7110 *) demux->priv; struct av7110 *av7110 = demux->priv;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -1119,18 +1125,20 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) ...@@ -1119,18 +1125,20 @@ static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
return 0; return 0;
} }
static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd* cmd)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1); av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
return 0; return 0;
} }
static int av7110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
fe_sec_mini_cmd_t minicmd)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_diseqc_send(av7110, 0, NULL, minicmd); av7110_diseqc_send(av7110, 0, NULL, minicmd);
...@@ -1223,7 +1231,8 @@ static void dvb_unregister(struct av7110 *av7110) ...@@ -1223,7 +1231,8 @@ static void dvb_unregister(struct av7110 *av7110)
dvb_dmxdev_release(&av7110->dmxdev); dvb_dmxdev_release(&av7110->dmxdev);
dvb_dmx_release(&av7110->demux); dvb_dmx_release(&av7110->demux);
if (av7110->fe != NULL) dvb_unregister_frontend(av7110->fe); if (av7110->fe != NULL)
dvb_unregister_frontend(av7110->fe);
dvb_unregister_device(av7110->osd_dev); dvb_unregister_device(av7110->osd_dev);
av7110_av_unregister(av7110); av7110_av_unregister(av7110);
av7110_ca_unregister(av7110); av7110_ca_unregister(av7110);
...@@ -1519,7 +1528,7 @@ static struct stv0299_config alps_bsru6_config = { ...@@ -1519,7 +1528,7 @@ static struct stv0299_config alps_bsru6_config = {
static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u32 div; u32 div;
u8 data[4]; u8 data[4];
struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) }; struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
...@@ -1547,9 +1556,10 @@ static struct ves1820_config alps_tdbe2_config = { ...@@ -1547,9 +1556,10 @@ static struct ves1820_config alps_tdbe2_config = {
static int grundig_29504_451_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u32 div; u32 div;
u8 data[4]; u8 data[4];
struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
...@@ -1572,9 +1582,10 @@ static struct tda8083_config grundig_29504_451_config = { ...@@ -1572,9 +1582,10 @@ static struct tda8083_config grundig_29504_451_config = {
static int philips_cd1516_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) static int philips_cd1516_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u32 div; u32 div;
u32 f = params->frequency; u32 f = params->frequency;
u8 data[4]; u8 data[4];
...@@ -1604,7 +1615,7 @@ static struct ves1820_config philips_cd1516_config = { ...@@ -1604,7 +1615,7 @@ static struct ves1820_config philips_cd1516_config = {
static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u32 div, pwr; u32 div, pwr;
u8 data[4]; u8 data[4];
struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) }; struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
...@@ -1644,19 +1655,18 @@ static struct sp8870_config alps_tdlb7_config = { ...@@ -1644,19 +1655,18 @@ static struct sp8870_config alps_tdlb7_config = {
static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
u32 div; u32 div;
u8 data[4]; u8 data[4];
struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) }; struct i2c_msg msg = { .addr = 0x63, .flags = 0, .buf = data, .len = sizeof(data) };
struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 }; struct i2c_msg readmsg = { .addr = 0x63, .flags = I2C_M_RD, .buf = data, .len = 1 };
int i; int i;
// this calculation does not match the TDA6405TS datasheet!
div = (params->frequency + 36150000 + 31250) / 62500; div = (params->frequency + 36150000 + 31250) / 62500;
data[0] = (div >> 8) & 0x7f; data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff; data[1] = div & 0xff;
data[2] = 0xce; // this value does not match the TDA6405TS datasheet! data[2] = 0xce;
if (params->frequency < 45000000) if (params->frequency < 45000000)
return -EINVAL; return -EINVAL;
...@@ -1696,9 +1706,14 @@ static struct stv0297_config nexusca_stv0297_config = { ...@@ -1696,9 +1706,14 @@ static struct stv0297_config nexusca_stv0297_config = {
static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
{ {
msleep (50); int synced = (status & FE_HAS_LOCK) ? 1 : 0;
av7110->fe_status = status;
av7110->fe_synced = (status & FE_HAS_LOCK) ? 1 : 0; if (av7110->fe_synced == synced)
return;
av7110->fe_synced = synced;
if (av7110->playing) if (av7110->playing)
return; return;
...@@ -1714,16 +1729,23 @@ static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status) ...@@ -1714,16 +1729,23 @@ static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0); av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
} else { } else {
SetPIDs(av7110, 0, 0, 0, 0, 0); SetPIDs(av7110, 0, 0, 0, 0, 0);
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, FlushTSQueue, 0); av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
av7110_wait_msgstate(av7110, GPMQBusy);
} }
av7110->fe_status = status;
up(&av7110->pid_mutex); up(&av7110->pid_mutex);
} }
static int av7110_fe_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
{
struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0);
return av7110->fe_set_frontend(fe, params);
}
static int av7110_fe_init(struct dvb_frontend* fe) static int av7110_fe_init(struct dvb_frontend* fe)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_init(fe); return av7110->fe_init(fe);
...@@ -1731,7 +1753,7 @@ static int av7110_fe_init(struct dvb_frontend* fe) ...@@ -1731,7 +1753,7 @@ static int av7110_fe_init(struct dvb_frontend* fe)
static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
int ret; int ret;
/* call the real implementation */ /* call the real implementation */
...@@ -1748,15 +1770,16 @@ static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status) ...@@ -1748,15 +1770,16 @@ static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe) static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_diseqc_reset_overload(fe); return av7110->fe_diseqc_reset_overload(fe);
} }
static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe,
struct dvb_diseqc_master_cmd* cmd)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_diseqc_send_master_cmd(fe, cmd); return av7110->fe_diseqc_send_master_cmd(fe, cmd);
...@@ -1764,7 +1787,7 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_ ...@@ -1764,7 +1787,7 @@ static int av7110_fe_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_
static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_diseqc_send_burst(fe, minicmd); return av7110->fe_diseqc_send_burst(fe, minicmd);
...@@ -1772,7 +1795,7 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_ ...@@ -1772,7 +1795,7 @@ static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_
static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_set_tone(fe, tone); return av7110->fe_set_tone(fe, tone);
...@@ -1780,7 +1803,7 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) ...@@ -1780,7 +1803,7 @@ static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_set_voltage(fe, voltage); return av7110->fe_set_voltage(fe, voltage);
...@@ -1788,7 +1811,7 @@ static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t volta ...@@ -1788,7 +1811,7 @@ static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t volta
static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd) static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
{ {
struct av7110* av7110 = (struct av7110*) fe->dvb->priv; struct av7110* av7110 = fe->dvb->priv;
av7110_fe_lock_fix(av7110, 0); av7110_fe_lock_fix(av7110, 0);
return av7110->fe_dishnetwork_send_legacy_command(fe, cmd); return av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
...@@ -1812,9 +1835,8 @@ static void frontend_init(struct av7110 *av7110) ...@@ -1812,9 +1835,8 @@ static void frontend_init(struct av7110 *av7110)
if (av7110->dev->pci->subsystem_vendor == 0x110a) { if (av7110->dev->pci->subsystem_vendor == 0x110a) {
switch(av7110->dev->pci->subsystem_device) { switch(av7110->dev->pci->subsystem_device) {
case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??)) case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap, read_pwm(av7110)); av7110->fe = ves1820_attach(&philips_cd1516_config,
if (av7110->fe) &av7110->i2c_adap, read_pwm(av7110));
break;
break; break;
} }
...@@ -1850,27 +1872,41 @@ static void frontend_init(struct av7110 *av7110) ...@@ -1850,27 +1872,41 @@ static void frontend_init(struct av7110 *av7110)
av7110->fe->ops->set_tone = av7110_set_tone; av7110->fe->ops->set_tone = av7110_set_tone;
break; break;
} }
/* Try DVB-C cards */
switch(av7110->dev->pci->subsystem_device) {
case 0x0000:
/* Siemens DVB-C (full-length card) VES1820/Philips CD1516 */
av7110->fe = ves1820_attach(&philips_cd1516_config, &av7110->i2c_adap,
read_pwm(av7110));
break;
case 0x0003:
/* Haupauge DVB-C 2.1 VES1820/ALPS TDBE2 */
av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap,
read_pwm(av7110));
break;
}
break; break;
case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
// ALPS TDLB7 // ALPS TDLB7
av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap); av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
if (av7110->fe)
break;
break; break;
case 0x0002: // Hauppauge/TT DVB-C premium rev2.X case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
if (av7110->fe)
break;
break; break;
case 0x000A: // Hauppauge/TT Nexus-CA rev1.X case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b); av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
if (av7110->fe) { if (av7110->fe) {
/* set TDA9819 into DVB mode */
saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
/* tuner on this needs a slower i2c bus speed */ /* tuner on this needs a slower i2c bus speed */
av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
break; break;
...@@ -1893,6 +1929,8 @@ static void frontend_init(struct av7110 *av7110) ...@@ -1893,6 +1929,8 @@ static void frontend_init(struct av7110 *av7110)
FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone); FE_FUNC_OVERRIDE(av7110->fe->ops->set_tone, av7110->fe_set_tone, av7110_fe_set_tone);
FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;) FE_FUNC_OVERRIDE(av7110->fe->ops->set_voltage, av7110->fe_set_voltage, av7110_fe_set_voltage;)
FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command);
FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend);
if (dvb_register_frontend(av7110->dvb_adapter, av7110->fe)) { if (dvb_register_frontend(av7110->dvb_adapter, av7110->fe)) {
printk("av7110: Frontend registration failed!\n"); printk("av7110: Frontend registration failed!\n");
if (av7110->fe->ops->release) if (av7110->fe->ops->release)
...@@ -1969,7 +2007,6 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d ...@@ -1969,7 +2007,6 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
/* locks for data transfers from/to AV7110 */ /* locks for data transfers from/to AV7110 */
spin_lock_init (&av7110->debilock); spin_lock_init (&av7110->debilock);
sema_init(&av7110->dcomlock, 1); sema_init(&av7110->dcomlock, 1);
av7110->debilock=SPIN_LOCK_UNLOCKED;
av7110->debitype=-1; av7110->debitype=-1;
/* default OSD window */ /* default OSD window */
...@@ -2086,11 +2123,8 @@ static int av7110_detach (struct saa7146_dev* saa) ...@@ -2086,11 +2123,8 @@ static int av7110_detach (struct saa7146_dev* saa)
dvb_unregister(av7110); dvb_unregister(av7110);
IER_DISABLE(saa, (MASK_19 | MASK_03)); SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
// saa7146_write (av7110->dev, IER, SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03));
saa7146_write(av7110->dev, ISR,(MASK_19 | MASK_03));
av7110_ca_exit(av7110); av7110_ca_exit(av7110);
av7110_av_exit(av7110); av7110_av_exit(av7110);
...@@ -2117,7 +2151,7 @@ static int av7110_detach (struct saa7146_dev* saa) ...@@ -2117,7 +2151,7 @@ static int av7110_detach (struct saa7146_dev* saa)
static void av7110_irq(struct saa7146_dev* dev, u32 *isr) static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
{ {
struct av7110 *av7110 = (struct av7110*)dev->ext_priv; struct av7110 *av7110 = dev->ext_priv;
if (*isr & MASK_19) if (*isr & MASK_19)
tasklet_schedule (&av7110->debi_tasklet); tasklet_schedule (&av7110->debi_tasklet);
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include <media/saa7146_vv.h> #include <media/saa7146_vv.h>
#define ANALOG_TUNER_VES1820 1
#define ANALOG_TUNER_STV0297 2
#define ANALOG_TUNER_VBI 0x100
extern int av7110_debug; extern int av7110_debug;
#define dprintk(level,args...) \ #define dprintk(level,args...) \
...@@ -82,7 +87,7 @@ struct av7110 { ...@@ -82,7 +87,7 @@ struct av7110 {
char *card_name; char *card_name;
/* support for analog module of dvb-c */ /* support for analog module of dvb-c */
int has_analog_tuner; int analog_tuner_flags;
int current_input; int current_input;
u32 current_freq; u32 current_freq;
...@@ -122,8 +127,8 @@ struct av7110 { ...@@ -122,8 +127,8 @@ struct av7110 {
spinlock_t debilock; spinlock_t debilock;
struct semaphore dcomlock; struct semaphore dcomlock;
int debitype; volatile int debitype;
int debilen; volatile int debilen;
/* Recording and playback flags */ /* Recording and playback flags */
...@@ -235,6 +240,7 @@ struct av7110 { ...@@ -235,6 +240,7 @@ struct av7110 {
int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone); int (*fe_set_tone)(struct dvb_frontend* fe, fe_sec_tone_mode_t tone);
int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage); int (*fe_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);
int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd); int (*fe_dishnetwork_send_legacy_command)(struct dvb_frontend* fe, unsigned int cmd);
int (*fe_set_frontend)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params);
}; };
......
...@@ -110,16 +110,16 @@ void av7110_reset_arm(struct av7110 *av7110) ...@@ -110,16 +110,16 @@ void av7110_reset_arm(struct av7110 *av7110)
saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO);
/* Disable DEBI and GPIO irq */ /* Disable DEBI and GPIO irq */
IER_DISABLE(av7110->dev, (MASK_19 | MASK_03)); SAA7146_IER_DISABLE(av7110->dev, MASK_19 | MASK_03);
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI); saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
msleep(30); /* the firmware needs some time to initialize */ msleep(30); /* the firmware needs some time to initialize */
ARM_ResetMailBox(av7110); ARM_ResetMailBox(av7110);
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
IER_ENABLE(av7110->dev, MASK_03); SAA7146_IER_ENABLE(av7110->dev, MASK_03);
av7110->arm_ready = 1; av7110->arm_ready = 1;
dprintk(1, "reset ARM\n"); dprintk(1, "reset ARM\n");
...@@ -223,8 +223,8 @@ int av7110_bootarm(struct av7110 *av7110) ...@@ -223,8 +223,8 @@ int av7110_bootarm(struct av7110 *av7110)
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO); saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTLO);
/* Disable DEBI and GPIO irq */ /* Disable DEBI and GPIO irq */
IER_DISABLE(av7110->dev, MASK_03 | MASK_19); SAA7146_IER_DISABLE(av7110->dev, MASK_03 | MASK_19);
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
/* enable DEBI */ /* enable DEBI */
saa7146_write(av7110->dev, MC1, 0x08800880); saa7146_write(av7110->dev, MC1, 0x08800880);
...@@ -280,8 +280,8 @@ int av7110_bootarm(struct av7110 *av7110) ...@@ -280,8 +280,8 @@ int av7110_bootarm(struct av7110 *av7110)
//ARM_ClearIrq(av7110); //ARM_ClearIrq(av7110);
ARM_ResetMailBox(av7110); ARM_ResetMailBox(av7110);
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); SAA7146_ISR_CLEAR(av7110->dev, MASK_19 | MASK_03);
IER_ENABLE(av7110->dev, MASK_03); SAA7146_IER_ENABLE(av7110->dev, MASK_03);
av7110->arm_errors = 0; av7110->arm_errors = 0;
av7110->arm_ready = 1; av7110->arm_ready = 1;
...@@ -293,13 +293,44 @@ int av7110_bootarm(struct av7110 *av7110) ...@@ -293,13 +293,44 @@ int av7110_bootarm(struct av7110 *av7110)
* DEBI command polling * DEBI command polling
****************************************************************************/ ****************************************************************************/
int av7110_wait_msgstate(struct av7110 *av7110, u16 flags)
{
unsigned long start;
u32 stat;
if (FW_VERSION(av7110->arm_app) <= 0x261c) {
/* not supported by old firmware */
msleep(50);
return 0;
}
/* new firmware */
start = jiffies;
for (;;) {
if (down_interruptible(&av7110->dcomlock))
return -ERESTARTSYS;
stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
up(&av7110->dcomlock);
if ((stat & flags) == 0) {
break;
}
if (time_after(jiffies, start + ARM_WAIT_FREE)) {
printk(KERN_ERR "%s: timeout waiting for MSGSTATE %04x\n",
__FUNCTION__, stat & flags);
return -1;
}
msleep(1);
}
return 0;
}
int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
{ {
int i; int i;
unsigned long start; unsigned long start;
#ifdef COM_DEBUG char *type = NULL;
u16 flags[2] = {0, 0};
u32 stat; u32 stat;
#endif
// dprintk(4, "%p\n", av7110); // dprintk(4, "%p\n", av7110);
...@@ -330,14 +361,45 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) ...@@ -330,14 +361,45 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
} }
#endif #endif
switch ((buf[0] >> 8) & 0xff) {
case COMTYPE_PIDFILTER:
case COMTYPE_ENCODER:
case COMTYPE_REC_PLAY:
case COMTYPE_MPEGDECODER:
type = "MSG";
flags[0] = GPMQOver;
flags[1] = GPMQFull;
break;
case COMTYPE_OSD:
type = "OSD";
flags[0] = OSDQOver;
flags[1] = OSDQFull;
break;
default:
break;
}
if (type != NULL) {
/* non-immediate COMMAND type */
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull) { for (;;) {
msleep(1); stat = rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2);
if (time_after(jiffies, start + ARM_WAIT_OSD)) { if (stat & flags[0]) {
printk(KERN_ERR "dvb-ttpci: %s(): timeout waiting for !OSDQFull\n", __FUNCTION__); printk(KERN_ERR "%s: %s QUEUE overflow\n",
__FUNCTION__, type);
return -1;
}
if ((stat & flags[1]) == 0)
break;
if (time_after(jiffies, start + ARM_WAIT_FREE)) {
printk(KERN_ERR "%s: timeout waiting on busy %s QUEUE\n",
__FUNCTION__, type);
return -1; return -1;
} }
msleep(1);
}
} }
for (i = 2; i < length; i++) for (i = 2; i < length; i++)
wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2); wdebi(av7110, DEBINOSWAP, COMMAND + 2 * i, (u32) buf[i], 2);
...@@ -972,7 +1034,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) ...@@ -972,7 +1034,7 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
goto out; goto out;
} else { } else {
int i, len = dc->x0-dc->color+1; int i, len = dc->x0-dc->color+1;
u8 __user *colors = dc->data; u8 __user *colors = (u8 *)dc->data;
u8 r, g, b, blend; u8 r, g, b, blend;
for (i = 0; i<len; i++) { for (i = 0; i<len; i++) {
......
...@@ -65,6 +65,9 @@ enum av7110_video_output_mode ...@@ -65,6 +65,9 @@ enum av7110_video_output_mode
#define HPQOver 0x0008 #define HPQOver 0x0008
#define OSDQFull 0x0010 /* OSD Queue Full */ #define OSDQFull 0x0010 /* OSD Queue Full */
#define OSDQOver 0x0020 #define OSDQOver 0x0020
#define GPMQBusy 0x0040 /* Queue not empty, FW >= 261d */
#define HPQBusy 0x0080
#define OSDQBusy 0x0100
/* hw section filter flags */ /* hw section filter flags */
#define SECTION_EIT 0x01 #define SECTION_EIT 0x01
...@@ -368,6 +371,7 @@ extern int av7110_firmversion(struct av7110 *av7110); ...@@ -368,6 +371,7 @@ extern int av7110_firmversion(struct av7110 *av7110);
#define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000) #define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000)
#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF) #define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF)
extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags);
extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...); extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
extern int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length); extern int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
extern int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length); extern int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length);
......
...@@ -92,10 +92,8 @@ static struct v4l2_input inputs[2] = { ...@@ -92,10 +92,8 @@ static struct v4l2_input inputs[2] = {
} }
}; };
/* for Siemens DVB-C analog module: (taken from ves1820.c) */ static int ves1820_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
{ {
u8 addr = 0x09;
u8 buf[] = { 0x00, reg, data }; u8 buf[] = { 0x00, reg, data };
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 }; struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
...@@ -106,6 +104,17 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data) ...@@ -106,6 +104,17 @@ static int ves1820_writereg(struct saa7146_dev *dev, u8 reg, u8 data)
return 0; return 0;
} }
static int stv0297_writereg(struct saa7146_dev *dev, u8 addr, u8 reg, u8 data)
{
u8 buf [] = { reg, data };
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 2 };
if (1 != saa7146_i2c_transfer(dev, &msg, 1, 1))
return -1;
return 0;
}
static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
{ {
struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 }; struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = data, .len = 4 };
...@@ -117,12 +126,7 @@ static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4]) ...@@ -117,12 +126,7 @@ static int tuner_write(struct saa7146_dev *dev, u8 addr, u8 data [4])
return 0; return 0;
} }
static int ves1820_set_tv_freq(struct saa7146_dev *dev, u32 freq)
/**
* set up the downconverter frequency divisor for a
* reference clock comparision frequency of 62.5 kHz.
*/
static int tuner_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{ {
u32 div; u32 div;
u8 config; u8 config;
...@@ -151,6 +155,34 @@ static int tuner_set_tv_freq(struct saa7146_dev *dev, u32 freq) ...@@ -151,6 +155,34 @@ static int tuner_set_tv_freq(struct saa7146_dev *dev, u32 freq)
return tuner_write(dev, 0x61, buf); return tuner_write(dev, 0x61, buf);
} }
static int stv0297_set_tv_freq(struct saa7146_dev *dev, u32 freq)
{
u32 div;
u8 data[4];
div = (freq + 38900000 + 31250) / 62500;
data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff;
data[2] = 0xce;
if (freq < 45000000)
return -EINVAL;
else if (freq < 137000000)
data[3] = 0x01;
else if (freq < 403000000)
data[3] = 0x02;
else if (freq < 860000000)
data[3] = 0x04;
else
return -EINVAL;
stv0297_writereg(dev, 0x1C, 0x87, 0x78);
stv0297_writereg(dev, 0x1C, 0x86, 0xc8);
return tuner_write(dev, 0x63, data);
}
static struct saa7146_standard analog_standard[]; static struct saa7146_standard analog_standard[];
static struct saa7146_standard dvb_standard[]; static struct saa7146_standard dvb_standard[];
...@@ -168,7 +200,6 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) ...@@ -168,7 +200,6 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
struct saa7146_vv *vv = dev->vv_data; struct saa7146_vv *vv = dev->vv_data;
struct av7110 *av7110 = (struct av7110*)dev->ext_priv; struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
u16 adswitch; u16 adswitch;
u8 band = 0;
int source, sync, err; int source, sync, err;
dprintk(4, "%p\n", av7110); dprintk(4, "%p\n", av7110);
...@@ -184,7 +215,6 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) ...@@ -184,7 +215,6 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
if (0 != av7110->current_input) { if (0 != av7110->current_input) {
adswitch = 1; adswitch = 1;
band = 0x60; /* analog band */
source = SAA7146_HPS_SOURCE_PORT_B; source = SAA7146_HPS_SOURCE_PORT_B;
sync = SAA7146_HPS_SYNC_PORT_B; sync = SAA7146_HPS_SYNC_PORT_B;
memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2); memcpy(standard, analog_standard, sizeof(struct saa7146_standard) * 2);
...@@ -195,9 +225,16 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) ...@@ -195,9 +225,16 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
if (ves1820_writereg(dev, 0x09, 0x0f, 0x60))
dprintk(1, "setting band in demodulator failed.\n");
} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9198 pin30(VIF)
}
} else { } else {
adswitch = 0; adswitch = 0;
band = 0x20; /* digital band */
source = SAA7146_HPS_SOURCE_PORT_A; source = SAA7146_HPS_SOURCE_PORT_A;
sync = SAA7146_HPS_SYNC_PORT_A; sync = SAA7146_HPS_SYNC_PORT_A;
memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2); memcpy(standard, dvb_standard, sizeof(struct saa7146_standard) * 2);
...@@ -208,15 +245,20 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) ...@@ -208,15 +245,20 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono msp_writereg(av7110, MSP_WR_DSP, 0x000e, 0x3000); // FM matrix, mono
msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x7f00); // SCART 1 volume
if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
if (ves1820_writereg(dev, 0x09, 0x0f, 0x20))
dprintk(1, "setting band in demodulator failed.\n");
} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
}
} }
/* hmm, this does not do anything!? */ /* hmm, this does not do anything!? */
if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch)) if (av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, adswitch))
dprintk(1, "ADSwitch error\n"); dprintk(1, "ADSwitch error\n");
if (ves1820_writereg(dev, 0x0f, band))
dprintk(1, "setting band in demodulator failed.\n");
saa7146_set_hps_source_and_sync(dev, source, sync); saa7146_set_hps_source_and_sync(dev, source, sync);
if (vv->ov_suspend != NULL) { if (vv->ov_suspend != NULL) {
...@@ -242,7 +284,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -242,7 +284,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index); dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
if (!av7110->has_analog_tuner || t->index != 0) if (!av7110->analog_tuner_flags || t->index != 0)
return -EINVAL; return -EINVAL;
memset(t, 0, sizeof(*t)); memset(t, 0, sizeof(*t));
...@@ -285,7 +327,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -285,7 +327,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
u16 fm_matrix, src; u16 fm_matrix, src;
dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index); dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
if (!av7110->has_analog_tuner || av7110->current_input != 1) if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL; return -EINVAL;
switch (t->audmode) { switch (t->audmode) {
...@@ -322,7 +364,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -322,7 +364,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency); dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
if (!av7110->has_analog_tuner || av7110->current_input != 1) if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL; return -EINVAL;
memset(f, 0, sizeof(*f)); memset(f, 0, sizeof(*f));
...@@ -336,7 +378,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -336,7 +378,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency); dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
if (!av7110->has_analog_tuner || av7110->current_input != 1) if (!av7110->analog_tuner_flags || av7110->current_input != 1)
return -EINVAL; return -EINVAL;
if (V4L2_TUNER_ANALOG_TV != f->type) if (V4L2_TUNER_ANALOG_TV != f->type)
...@@ -346,7 +388,11 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -346,7 +388,11 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0); msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
/* tune in desired frequency */ /* tune in desired frequency */
tuner_set_tv_freq(dev, f->frequency); if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
ves1820_set_tv_freq(dev, f->frequency);
} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
stv0297_set_tv_freq(dev, f->frequency);
}
av7110->current_freq = f->frequency; av7110->current_freq = f->frequency;
msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
...@@ -361,7 +407,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -361,7 +407,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index); dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
if (av7110->has_analog_tuner ) { if (av7110->analog_tuner_flags) {
if (i->index < 0 || i->index >= 2) if (i->index < 0 || i->index >= 2)
return -EINVAL; return -EINVAL;
} else { } else {
...@@ -386,7 +432,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -386,7 +432,7 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
dprintk(2, "VIDIOC_S_INPUT: %d\n", input); dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
if (!av7110->has_analog_tuner ) if (!av7110->analog_tuner_flags)
return 0; return 0;
if (input < 0 || input >= 2) if (input < 0 || input >= 2)
...@@ -528,7 +574,27 @@ int av7110_init_analog_module(struct av7110 *av7110) ...@@ -528,7 +574,27 @@ int av7110_init_analog_module(struct av7110 *av7110)
INFO(("saa7113 not accessible.\n")); INFO(("saa7113 not accessible.\n"));
} else { } else {
u8 *i = saa7113_init_regs; u8 *i = saa7113_init_regs;
av7110->has_analog_tuner = 1;
if ((av7110->dev->pci->subsystem_vendor == 0x110a) && (av7110->dev->pci->subsystem_device == 0x0000)) {
/* Fujitsu/Siemens DVB-Cable */
av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
} else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x0002)) {
/* Hauppauge/TT DVB-C premium */
av7110->analog_tuner_flags |= ANALOG_TUNER_VES1820;
} else if ((av7110->dev->pci->subsystem_vendor == 0x13c2) && (av7110->dev->pci->subsystem_device == 0x000A)) {
/* Hauppauge/TT DVB-C premium */
av7110->analog_tuner_flags |= ANALOG_TUNER_STV0297;
}
/* setup for DVB by default */
if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20))
dprintk(1, "setting band in demodulator failed.\n");
} else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTHI); // TDA9198 pin9(STD)
saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9198 pin30(VIF)
}
/* init the saa7113 */ /* init the saa7113 */
while (*i != 0xff) { while (*i != 0xff) {
if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) { if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) {
...@@ -579,7 +645,7 @@ int av7110_init_v4l(struct av7110 *av7110) ...@@ -579,7 +645,7 @@ int av7110_init_v4l(struct av7110 *av7110)
/* special case DVB-C: these cards have an analog tuner /* special case DVB-C: these cards have an analog tuner
plus need some special handling, so we have separate plus need some special handling, so we have separate
saa7146_ext_vv data for these... */ saa7146_ext_vv data for these... */
if (av7110->has_analog_tuner) if (av7110->analog_tuner_flags)
ret = saa7146_vv_init(dev, &av7110_vv_data_c); ret = saa7146_vv_init(dev, &av7110_vv_data_c);
else else
ret = saa7146_vv_init(dev, &av7110_vv_data_st); ret = saa7146_vv_init(dev, &av7110_vv_data_st);
...@@ -594,12 +660,12 @@ int av7110_init_v4l(struct av7110 *av7110) ...@@ -594,12 +660,12 @@ int av7110_init_v4l(struct av7110 *av7110)
saa7146_vv_release(dev); saa7146_vv_release(dev);
return -ENODEV; return -ENODEV;
} }
if (av7110->has_analog_tuner) { if (av7110->analog_tuner_flags) {
if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
ERR(("cannot register vbi v4l2 device. skipping.\n")); ERR(("cannot register vbi v4l2 device. skipping.\n"));
} else } else {
/* we use this to remember that this dvb-c card can do vbi */ av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
av7110->has_analog_tuner = 2; }
} }
return 0; return 0;
} }
...@@ -607,7 +673,7 @@ int av7110_init_v4l(struct av7110 *av7110) ...@@ -607,7 +673,7 @@ int av7110_init_v4l(struct av7110 *av7110)
int av7110_exit_v4l(struct av7110 *av7110) int av7110_exit_v4l(struct av7110 *av7110)
{ {
saa7146_unregister_device(&av7110->v4l_dev, av7110->dev); saa7146_unregister_device(&av7110->v4l_dev, av7110->dev);
if (2 == av7110->has_analog_tuner) if (av7110->analog_tuner_flags & ANALOG_TUNER_VBI)
saa7146_unregister_device(&av7110->vbi_dev, av7110->dev); saa7146_unregister_device(&av7110->vbi_dev, av7110->dev);
return 0; return 0;
} }
......
...@@ -563,23 +563,13 @@ static int philips_tu1216_pll_init(struct dvb_frontend *fe) ...@@ -563,23 +563,13 @@ static int philips_tu1216_pll_init(struct dvb_frontend *fe)
{ {
struct budget *budget = (struct budget *) fe->dvb->priv; struct budget *budget = (struct budget *) fe->dvb->priv;
static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab }; static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 }; struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len =
sizeof(tu1216_init) };
// setup PLL configuration // setup PLL configuration
if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
return -EIO; return -EIO;
msleep(1); msleep(1);
// disable the mc44BC374c (do not check for errors)
tuner_msg.addr = 0x65;
tuner_msg.buf = disable_mc44BC374c;
tuner_msg.len = sizeof(disable_mc44BC374c);
if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1) {
i2c_transfer(&budget->i2c_adap, &tuner_msg, 1);
}
return 0; return 0;
} }
...@@ -593,7 +583,7 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p ...@@ -593,7 +583,7 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
u8 band, cp, filter; u8 band, cp, filter;
// determine charge pump // determine charge pump
tuner_frequency = params->frequency + 36130000; tuner_frequency = params->frequency + 36166000;
if (tuner_frequency < 87000000) if (tuner_frequency < 87000000)
return -EINVAL; return -EINVAL;
else if (tuner_frequency < 130000000) else if (tuner_frequency < 130000000)
...@@ -620,7 +610,7 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p ...@@ -620,7 +610,7 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
// determine band // determine band
if (params->frequency < 49000000) if (params->frequency < 49000000)
return -EINVAL; return -EINVAL;
else if (params->frequency < 159000000) else if (params->frequency < 161000000)
band = 1; band = 1;
else if (params->frequency < 444000000) else if (params->frequency < 444000000)
band = 2; band = 2;
...@@ -632,17 +622,14 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p ...@@ -632,17 +622,14 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
// setup PLL filter // setup PLL filter
switch (params->u.ofdm.bandwidth) { switch (params->u.ofdm.bandwidth) {
case BANDWIDTH_6_MHZ: case BANDWIDTH_6_MHZ:
tda1004x_write_byte(fe, 0x0C, 0);
filter = 0; filter = 0;
break; break;
case BANDWIDTH_7_MHZ: case BANDWIDTH_7_MHZ:
tda1004x_write_byte(fe, 0x0C, 0);
filter = 0; filter = 0;
break; break;
case BANDWIDTH_8_MHZ: case BANDWIDTH_8_MHZ:
tda1004x_write_byte(fe, 0x0C, 0xFF);
filter = 1; filter = 1;
break; break;
...@@ -651,11 +638,11 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p ...@@ -651,11 +638,11 @@ static int philips_tu1216_pll_set(struct dvb_frontend *fe, struct dvb_frontend_p
} }
// calculate divisor // calculate divisor
// ((36130000+((1000000/6)/2)) + Finput)/(1000000/6) // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000; tuner_frequency = (((params->frequency / 1000) * 6) + 217496) / 1000;
// setup tuner buffer // setup tuner buffer
tuner_buf[0] = tuner_frequency >> 8; tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
tuner_buf[1] = tuner_frequency & 0xff; tuner_buf[1] = tuner_frequency & 0xff;
tuner_buf[2] = 0xca; tuner_buf[2] = 0xca;
tuner_buf[3] = (cp << 5) | (filter << 3) | band; tuner_buf[3] = (cp << 5) | (filter << 3) | band;
...@@ -679,6 +666,7 @@ struct tda1004x_config philips_tu1216_config = { ...@@ -679,6 +666,7 @@ struct tda1004x_config philips_tu1216_config = {
.demod_address = 0x8, .demod_address = 0x8,
.invert = 1, .invert = 1,
.invert_oclk = 1,
.pll_init = philips_tu1216_pll_init, .pll_init = philips_tu1216_pll_init,
.pll_set = philips_tu1216_pll_set, .pll_set = philips_tu1216_pll_set,
.request_firmware = philips_tu1216_request_firmware, .request_firmware = philips_tu1216_request_firmware,
......
...@@ -844,6 +844,7 @@ static struct tda1004x_config philips_tdm1316l_config = { ...@@ -844,6 +844,7 @@ static struct tda1004x_config philips_tdm1316l_config = {
.demod_address = 0x8, .demod_address = 0x8,
.invert = 0, .invert = 0,
.invert_oclk = 0,
.pll_init = philips_tdm1316l_pll_init, .pll_init = philips_tdm1316l_pll_init,
.pll_set = philips_tdm1316l_pll_set, .pll_set = philips_tdm1316l_pll_set,
.request_firmware = philips_tdm1316l_request_firmware, .request_firmware = philips_tdm1316l_request_firmware,
......
...@@ -56,7 +56,7 @@ static int stop_ts_capture(struct budget *budget) ...@@ -56,7 +56,7 @@ static int stop_ts_capture(struct budget *budget)
return budget->feeding; return budget->feeding;
saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off saa7146_write(budget->dev, MC1, MASK_20); // DMA3 off
IER_DISABLE(budget->dev, MASK_10); SAA7146_IER_DISABLE(budget->dev, MASK_10);
return 0; return 0;
} }
...@@ -124,7 +124,7 @@ static int start_ts_capture (struct budget *budget) ...@@ -124,7 +124,7 @@ static int start_ts_capture (struct budget *budget)
saa7146_write(dev, MC2, (MASK_04 | MASK_20)); saa7146_write(dev, MC2, (MASK_04 | MASK_20));
saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on saa7146_write(dev, MC1, (MASK_04 | MASK_20)); // DMA3 on
IER_ENABLE(budget->dev, MASK_10); // VPE SAA7146_IER_ENABLE(budget->dev, MASK_10); // VPE
return ++budget->feeding; return ++budget->feeding;
} }
......
...@@ -3,6 +3,8 @@ config DVB_TTUSB_BUDGET ...@@ -3,6 +3,8 @@ config DVB_TTUSB_BUDGET
depends on DVB_CORE && USB depends on DVB_CORE && USB
select DVB_CX22700 select DVB_CX22700
select DVB_TDA1004X select DVB_TDA1004X
select DVB_TDA8083
select DVB_STV0299
help help
Support for external USB adapters designed by Technotrend and Support for external USB adapters designed by Technotrend and
produced by Hauppauge, shipped under the brand name 'Nova-USB'. produced by Hauppauge, shipped under the brand name 'Nova-USB'.
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#include "dvb_net.h" #include "dvb_net.h"
#include "cx22700.h" #include "cx22700.h"
#include "tda1004x.h" #include "tda1004x.h"
#include "stv0299.h"
#include "tda8083.h"
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
#include <linux/dvb/dmx.h> #include <linux/dvb/dmx.h>
...@@ -489,7 +491,6 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe, ...@@ -489,7 +491,6 @@ static int ttusb_send_diseqc(struct dvb_frontend* fe,
} }
#endif #endif
#if 0
static int ttusb_update_lnb(struct ttusb *ttusb) static int ttusb_update_lnb(struct ttusb *ttusb)
{ {
u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1, u8 b[] = { 0xaa, ++ttusb->c, 0x16, 5, /*power: */ 1,
...@@ -524,7 +525,6 @@ static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) ...@@ -524,7 +525,6 @@ static int ttusb_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
return ttusb_update_lnb(ttusb); return ttusb_update_lnb(ttusb);
} }
#endif #endif
#endif
#if 0 #if 0
...@@ -1177,7 +1177,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend ...@@ -1177,7 +1177,8 @@ static int philips_tdm1316l_pll_set(struct dvb_frontend* fe, struct dvb_frontend
tuner_buf[2] = 0xca; tuner_buf[2] = 0xca;
tuner_buf[3] = (cp << 5) | (filter << 3) | band; tuner_buf[3] = (cp << 5) | (filter << 3) | band;
if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1) return -EIO; if (i2c_transfer(&ttusb->i2c_adap, &tuner_msg, 1) != 1)
return -EIO;
msleep(1); msleep(1);
return 0; return 0;
...@@ -1194,24 +1195,187 @@ static struct tda1004x_config philips_tdm1316l_config = { ...@@ -1194,24 +1195,187 @@ static struct tda1004x_config philips_tdm1316l_config = {
.demod_address = 0x8, .demod_address = 0x8,
.invert = 1, .invert = 1,
.invert_oclk = 0,
.pll_init = philips_tdm1316l_pll_init, .pll_init = philips_tdm1316l_pll_init,
.pll_set = philips_tdm1316l_pll_set, .pll_set = philips_tdm1316l_pll_set,
.request_firmware = philips_tdm1316l_request_firmware, .request_firmware = philips_tdm1316l_request_firmware,
}; };
static u8 alps_bsru6_inittab[] = {
0x01, 0x15,
0x02, 0x00,
0x03, 0x00,
0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
0x06, 0x40, /* DAC not used, set to high impendance mode */
0x07, 0x00, /* DAC LSB */
0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
0x09, 0x00, /* FIFO */
0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
0x10, 0x3f, // AGC2 0x3d
0x11, 0x84,
0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on
0x15, 0xc9, // lock detector threshold
0x16, 0x00,
0x17, 0x00,
0x18, 0x00,
0x19, 0x00,
0x1a, 0x00,
0x1f, 0x50,
0x20, 0x00,
0x21, 0x00,
0x22, 0x00,
0x23, 0x00,
0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
0x29, 0x1e, // 1/2 threshold
0x2a, 0x14, // 2/3 threshold
0x2b, 0x0f, // 3/4 threshold
0x2c, 0x09, // 5/6 threshold
0x2d, 0x05, // 7/8 threshold
0x2e, 0x01,
0x31, 0x1f, // test all FECs
0x32, 0x19, // viterbi and synchro search
0x33, 0xfc, // rs control
0x34, 0x93, // error control
0x0f, 0x52,
0xff, 0xff
};
static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
{
u8 aclk = 0;
u8 bclk = 0;
if (srate < 1500000) {
aclk = 0xb7;
bclk = 0x47;
} else if (srate < 3000000) {
aclk = 0xb7;
bclk = 0x4b;
} else if (srate < 7000000) {
aclk = 0xb7;
bclk = 0x4f;
} else if (srate < 14000000) {
aclk = 0xb7;
bclk = 0x53;
} else if (srate < 30000000) {
aclk = 0xb6;
bclk = 0x53;
} else if (srate < 45000000) {
aclk = 0xb4;
bclk = 0x51;
}
stv0299_writereg(fe, 0x13, aclk);
stv0299_writereg(fe, 0x14, bclk);
stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
return 0;
}
static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
u8 buf[4];
u32 div;
struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
if ((params->frequency < 950000) || (params->frequency > 2150000))
return -EINVAL;
div = (params->frequency + (125 - 1)) / 125; // round correctly
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
buf[3] = 0xC4;
if (params->frequency > 1530000)
buf[3] = 0xc0;
if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
return -EIO;
return 0;
}
static struct stv0299_config alps_bsru6_config = {
.demod_address = 0x68,
.inittab = alps_bsru6_inittab,
.mclk = 88000000UL,
.invert = 1,
.enhanced_tuning = 0,
.skip_reinit = 0,
.lock_output = STV0229_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
.min_delay_ms = 100,
.set_symbol_rate = alps_bsru6_set_symbol_rate,
.pll_set = alps_bsru6_pll_set,
};
static int ttusb_novas_grundig_29504_491_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
{
struct ttusb* ttusb = (struct ttusb*) fe->dvb->priv;
u8 buf[4];
u32 div;
struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
div = params->frequency / 125;
buf[0] = (div >> 8) & 0x7f;
buf[1] = div & 0xff;
buf[2] = 0x8e;
buf[3] = 0x00;
if (i2c_transfer(&ttusb->i2c_adap, &msg, 1) != 1)
return -EIO;
return 0;
}
static struct tda8083_config ttusb_novas_grundig_29504_491_config = {
.demod_address = 0x68,
.pll_set = ttusb_novas_grundig_29504_491_pll_set,
};
static void frontend_init(struct ttusb* ttusb) static void frontend_init(struct ttusb* ttusb)
{ {
switch(ttusb->dev->descriptor.idProduct) { switch(ttusb->dev->descriptor.idProduct) {
case 0x1003: // Hauppauge/TT Nova-USB-S budget (stv0299/ALPS BSRU6(tsa5059)
// try the ALPS BSRU6 first
ttusb->fe = stv0299_attach(&alps_bsru6_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops->set_voltage = ttusb_set_voltage;
break;
}
// Grundig 29504-491
ttusb->fe = tda8083_attach(&ttusb_novas_grundig_29504_491_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) {
ttusb->fe->ops->set_voltage = ttusb_set_voltage;
break;
}
break;
case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??)) case 0x1005: // Hauppauge/TT Nova-USB-t budget (tda10046/Philips td1316(tda6651tt) OR cx22700/ALPS TDMB7(??))
// try the ALPS TDMB7 first // try the ALPS TDMB7 first
ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap); ttusb->fe = cx22700_attach(&alps_tdmb7_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) break; if (ttusb->fe != NULL)
break;
// Philips td1316 // Philips td1316
ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap); ttusb->fe = tda10046_attach(&philips_tdm1316l_config, &ttusb->i2c_adap);
if (ttusb->fe != NULL) break; if (ttusb->fe != NULL)
break;
break; break;
} }
...@@ -1382,7 +1546,7 @@ static void ttusb_disconnect(struct usb_interface *intf) ...@@ -1382,7 +1546,7 @@ static void ttusb_disconnect(struct usb_interface *intf)
} }
static struct usb_device_id ttusb_table[] = { static struct usb_device_id ttusb_table[] = {
/* {USB_DEVICE(0xb48, 0x1003)},UNDEFINED HARDWARE - mail linuxtv.org list */ {USB_DEVICE(0xb48, 0x1003)},
/* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */ /* {USB_DEVICE(0xb48, 0x1004)},UNDEFINED HARDWARE - mail linuxtv.org list*/ /* to be confirmed ???? */
{USB_DEVICE(0xb48, 0x1005)}, {USB_DEVICE(0xb48, 0x1005)},
{} {}
......
...@@ -62,7 +62,7 @@ typedef enum fe_caps { ...@@ -62,7 +62,7 @@ typedef enum fe_caps {
FE_CAN_HIERARCHY_AUTO = 0x100000, FE_CAN_HIERARCHY_AUTO = 0x100000,
FE_CAN_8VSB = 0x200000, FE_CAN_8VSB = 0x200000,
FE_CAN_16VSB = 0x400000, FE_CAN_16VSB = 0x400000,
FE_NEEDS_BENDING = 0x20000000, // frontend requires frequency bending FE_NEEDS_BENDING = 0x20000000, // not supported anymore, don't use (frontend requires frequency bending)
FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically
FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output
} fe_caps_t; } fe_caps_t;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment