#include <linux/smp_lock.h>
#include <linux/kernel.h>
-#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/vmalloc.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
-#include <linux/i2c.h>
#include <asm/system.h>
#include <asm/semaphore.h>
#include <linux/dvb/frontend.h>
+#include "dvb_i2c.h"
#include "dvb_frontend.h"
+#include "dvb_functions.h"
+
+
+ #define DEBUG_VARIABLE av7110_debug
#include "ttpci-eeprom.h"
#include "av7110.h"
#include "av7110_ca.h"
#include "av7110_ipack.h"
-int av7110_debug;
-
-static int vidmode=CVBS_RGB_OUT;
-static int pids_off;
-static int adac=DVB_ADAC_TI;
-static int hw_sections;
-static int rgb_on;
-static int volume = 255;
-
-module_param_named(debug, av7110_debug, int, 0644);
-MODULE_PARM_DESC(debug, "debug level (bitmask, default 0)");
-module_param(vidmode, int, 0444);
-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_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
-module_param(adac, int, 0444);
-MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
-module_param(hw_sections, int, 0444);
-MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
-module_param(rgb_on, int, 0444);
-MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
- " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
-module_param(volume, int, 0444);
-MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
static void restart_feeds(struct av7110 *av7110);
-static int av7110_num = 0;
-
-#define FE_FUNC_OVERRIDE(fe_func, av7110_copy, av7110_func) \
-{\
- if (fe_func != NULL) { \
- av7110_copy = fe_func; \
- fe_func = av7110_func; \
- } \
-}
-
-
-static void init_av7110_av(struct av7110 *av7110)
-{
- struct saa7146_dev *dev=av7110->dev;
-
- /* set internal volume control to maximum */
- av7110->adac_type = DVB_ADAC_TI;
- av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
-
- av7710_set_video_mode(av7110, vidmode);
-
- /* handle different card types */
- /* remaining inits according to card and frontend type */
- av7110->analog_tuner_flags = 0;
- av7110->current_input = 0;
- if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
- printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n",
- av7110->dvb_adapter->num);
- av7110->adac_type = DVB_ADAC_CRYSTAL;
- i2c_writereg(av7110, 0x20, 0x01, 0xd2);
- i2c_writereg(av7110, 0x20, 0x02, 0x49);
- i2c_writereg(av7110, 0x20, 0x03, 0x00);
- i2c_writereg(av7110, 0x20, 0x04, 0x00);
+int av7110_debug = 0;
- /**
- * some special handling for the Siemens DVB-C cards...
- */
- } else if (0 == av7110_init_analog_module(av7110)) {
- /* done. */
- }
- else if (dev->pci->subsystem_vendor == 0x110a) {
- printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n",
- av7110->dvb_adapter->num);
- av7110->adac_type = DVB_ADAC_NONE;
- }
- else {
- av7110->adac_type = adac;
- printk("dvb-ttpci: adac type set to %d @ card %d\n",
- av7110->dvb_adapter->num, av7110->adac_type);
- }
+static int vidmode=CVBS_RGB_OUT;
+static int pids_off;
+static int adac=DVB_ADAC_TI;
+static int hw_sections = 0;
+static int rgb_on = 0;
- if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
- // switch DVB SCART on
- av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
- av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
- 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, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
- }
- }
+int av7110_num = 0;
- av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
- av7110_setup_irc_config(av7110, 0);
-}
static void recover_arm(struct av7110 *av7110)
{
- dprintk(4, "%p\n",av7110);
+ DEB_EE(("av7110: %p\n",av7110));
av7110_bootarm(av7110);
- msleep(100);
+ dvb_delay(100);
restart_feeds(av7110);
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
}
static void arm_error(struct av7110 *av7110)
{
- dprintk(4, "%p\n",av7110);
+ DEB_EE(("av7110: %p\n",av7110));
av7110->arm_errors++;
av7110->arm_ready=0;
static int arm_thread(void *data)
{
struct av7110 *av7110 = data;
+ unsigned long timeout;
u16 newloops = 0;
- int timeout;
- dprintk(4, "%p\n",av7110);
+ DEB_EE(("av7110: %p\n",av7110));
- lock_kernel ();
- daemonize ("arm_mon");
- sigfillset (¤t->blocked);
- unlock_kernel ();
-
+ dvb_kernel_thread_setup ("arm_mon");
av7110->arm_thread = current;
- for (;;) {
- timeout = wait_event_interruptible_timeout(av7110->arm_wait,
- av7110->arm_rmmod, 5 * HZ);
- if (-ERESTARTSYS == timeout || av7110->arm_rmmod) {
+ while (1) {
+ timeout = wait_event_interruptible_timeout(av7110->arm_wait,0 != av7110->arm_rmmod, 5*HZ);
+ if (-ERESTARTSYS == timeout || 0 != av7110->arm_rmmod) {
/* got signal or told to quit*/
break;
}
up(&av7110->dcomlock);
if (newloops==av7110->arm_loops) {
- printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n",
+ printk(KERN_ERR "av7110%d: ARM crashed!\n",
av7110->dvb_adapter->num);
arm_error(av7110);
- av7710_set_video_mode(av7110, vidmode);
-
- init_av7110_av(av7110);
if (down_interruptible(&av7110->dcomlock))
break;
{
static struct av7110 *last;
- dprintk(4, "%p\n",av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if (!av7110)
av7110 = last;
void av7110_register_irc_handler(void (*func)(u32))
{
- dprintk(4, "registering %p\n", func);
+ DEB_EE(("registering %p\n", func));
irc_handler = func;
}
void av7110_unregister_irc_handler(void (*func)(u32))
{
- dprintk(4, "unregistering %p\n", func);
+ DEB_EE(("unregistering %p\n", func));
irc_handler = NULL;
}
-static void run_handlers(unsigned long ircom)
+void run_handlers(unsigned long ircom)
{
if (irc_handler != NULL)
(*irc_handler)((u32) ircom);
}
-static DECLARE_TASKLET(irtask, run_handlers, 0);
+DECLARE_TASKLET(irtask,run_handlers,0);
-static void IR_handle(struct av7110 *av7110, u32 ircom)
+void IR_handle(struct av7110 *av7110, u32 ircom)
{
- dprintk(4, "ircommand = %08x\n", ircom);
+ DEB_S(("av7110: ircommand = %08x\n", ircom));
irtask.data = (unsigned long) ircom;
tasklet_schedule(&irtask);
}
* IRQ handling
****************************************************************************/
-static int DvbDmxFilterCallback(u8 *buffer1, size_t buffer1_len,
+static inline int DvbDmxFilterCallback(u8 * buffer1, size_t buffer1_len,
u8 * buffer2, size_t buffer2_len,
struct dvb_demux_filter *dvbdmxfilter,
enum dmx_success success,
struct av7110 *av7110)
{
+ DEB_INT(("av7110: %p\n",av7110));
+
if (!dvbdmxfilter->feed->demux->dmx.frontend)
return 0;
if (dvbdmxfilter->feed->demux->dmx.frontend->source==DMX_MEMORY_FE)
int type=av7110->debitype;
int handle=(type>>8)&0x1f;
-// dprintk(4, "%p\n",av7110);
+// DEB_EE(("av7110: %p\n",av7110));
print_time("debi");
- SAA7146_IER_DISABLE(av7110->dev, MASK_19);
- SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
+ saa7146_write(av7110->dev, IER,
+ saa7146_read(av7110->dev, IER) & ~MASK_19 );
+ saa7146_write(av7110->dev, ISR, MASK_19 );
if (type==-1) {
printk("DEBI irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
u32 rxbuf, txbuf;
int len;
+ //printk("GPIO0 irq\n");
+
if (av7110->debitype !=-1)
- printk("dvb-ttpci: GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
+ printk("GPIO0 irq oops @ %ld, psr:0x%08x, ssr:0x%08x\n",
jiffies, saa7146_read(av7110->dev, PSR),
saa7146_read(av7110->dev, SSR));
ARM_ClearIrq(av7110);
- SAA7146_IER_DISABLE(av7110->dev, MASK_19);
- SAA7146_ISR_CLEAR(av7110->dev, MASK_19);
+ saa7146_write(av7110->dev, IER,
+ saa7146_read(av7110->dev, IER) & ~MASK_19 );
+ saa7146_write(av7110->dev, ISR, MASK_19 );
av7110->debitype = irdebi(av7110, DEBINOSWAP, IRQ_STATE, 0, 2);
av7110->debilen = irdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, 0, 2);
txbuf=irdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
len = (av7110->debilen + 3) & ~3;
-// dprintk(8, "GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen);
+// DEB_D(("GPIO0 irq %d %d\n", av7110->debitype, av7110->debilen));
print_time("gpio");
-// dprintk(8, "GPIO0 irq %02x\n", av7110->debitype&0xff);
+// DEB_D(("GPIO0 irq %02x\n", av7110->debitype&0xff));
switch (av7110->debitype&0xff) {
case DATA_TS_PLAY:
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
av7110->video_size.h = h_ar & 0xfff;
- dprintk(8, "GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
+ DEB_D(("GPIO0 irq: DATA_MPEG_VIDEO_EVENT: w/h/ar = %u/%u/%u\n",
av7110->video_size.w,
av7110->video_size.h,
- av7110->video_size.aspect_ratio);
+ av7110->video_size.aspect_ratio));
event.type = VIDEO_EVENT_SIZE_CHANGED;
event.u.size.w = av7110->video_size.w;
wake_up(&cibuf->queue);
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
- saa7146_wait_for_debi_done(av7110->dev, 0);
+ saa7146_wait_for_debi_done(av7110->dev);
saa7146_write(av7110->dev, IER,
saa7146_read(av7110->dev, IER) | MASK_19 );
if (len < 5)
iwdebi(av7110, DEBINOSWAP, TX_BUFF, 0, 2);
break;
}
- dprintk(8, "GPIO0 PES_PLAY len=%04x\n", len);
+ DEB_D(("GPIO0 PES_PLAY len=%04x\n", len));
iwdebi(av7110, DEBINOSWAP, TX_LEN, len, 2);
iwdebi(av7110, DEBINOSWAP, IRQ_STATE_EXT, len, 2);
- saa7146_wait_for_debi_done(av7110->dev, 0);
+ saa7146_wait_for_debi_done(av7110->dev);
saa7146_write(av7110->dev, IER,
saa7146_read(av7110->dev, IER) | MASK_19 );
memcpy(av7110->debi_virt, av7110->bmpbuf+av7110->bmpp, len);
av7110->bmpp+=len;
av7110->bmplen-=len;
- saa7146_wait_for_debi_done(av7110->dev, 0);
+ saa7146_wait_for_debi_done(av7110->dev);
saa7146_write(av7110->dev, IER,
saa7146_read(av7110->dev, IER) | MASK_19 );
if (len < 5)
case DATA_TS_RECORD:
case DATA_PES_RECORD:
- saa7146_wait_for_debi_done(av7110->dev, 0);
+ saa7146_wait_for_debi_done(av7110->dev);
saa7146_write(av7110->dev, IER,
saa7146_read(av7110->dev, IER) | MASK_19);
irdebi(av7110, DEBISWAB, DPRAM_BASE+rxbuf, 0, len);
return;
case DATA_DEBUG_MESSAGE:
- saa7146_wait_for_debi_done(av7110->dev, 0);
+ saa7146_wait_for_debi_done(av7110->dev);
if (!len || len>0xff) {
iwdebi(av7110, DEBINOSWAP, RX_BUFF, 0, 2);
break;
break;
default:
- printk("dvb-ttpci: gpioirq unknown type=%d len=%d\n",
+ printk("gpioirq unknown type=%d len=%d\n",
av7110->debitype, av7110->debilen);
break;
}
struct dvb_device *dvbdev = (struct dvb_device *) file->private_data;
struct av7110 *av7110 = (struct av7110 *) dvbdev->priv;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n", av7110));
if (cmd == OSD_SEND_CMD)
return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
- if (cmd == OSD_GET_CAPABILITY)
- return av7110_osd_capability(av7110, (osd_cap_t *) parg);
return -EINVAL;
}
static inline int SetPIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n", av7110));
if (vpid == 0x1fff || apid == 0x1fff ||
ttpid == 0x1fff || subpid == 0x1fff || pcrpid == 0x1fff) {
void ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid,
u16 subpid, u16 pcrpid)
{
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n", av7110));
if (down_interruptible(&av7110->pid_mutex))
return;
// u16 mode=0x0320;
u16 mode=0xb96a;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if (dvbdmxfilter->type == DMX_TYPE_SEC) {
if (hw_sections) {
buf[3] = mode;
ret = av7110_fw_request(av7110, buf, 20, &handle, 1);
- if (ret != 0 || handle >= 32) {
- printk("dvb-ttpci: %s error buf %04x %04x %04x %04x "
- "ret %x handle %04x\n",
- __FUNCTION__, buf[0], buf[1], buf[2], buf[3],
- ret, handle);
- dvbdmxfilter->hw_handle = 0xffff;
- return -1;
+ if (ret < 0) {
+ printk("StartHWFilter error\n");
+ return ret;
}
av7110->handle2filter[handle] = dvbdmxfilter;
int ret;
u16 handle;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n", av7110));
handle = dvbdmxfilter->hw_handle;
- if (handle >= 32) {
- printk("%s tried to stop invalid filter %04x, filter type = %x\n",
- __FUNCTION__, handle, dvbdmxfilter->type);
+ if (handle > 32) {
+ DEB_S(("dvb: StopHWFilter tried to stop invalid filter %d.\n",
+ handle));
+ DEB_S(("dvb: filter type = %d\n", dvbdmxfilter->type));
return 0;
}
buf[1] = 1;
buf[2] = handle;
ret = av7110_fw_request(av7110, buf, 3, answ, 2);
- if (ret != 0 || answ[1] != handle) {
- printk("dvb-ttpci: %s error cmd %04x %04x %04x ret %x "
- "resp %04x %04x pid %d\n",
- __FUNCTION__, buf[0], buf[1], buf[2], ret,
- answ[0], answ[1], dvbdmxfilter->feed->pid);
+ if (ret)
+ printk("StopHWFilter error\n");
+
+ if (answ[1] != handle) {
+ DEB_S(("dvb: filter %d shutdown error :%d\n", handle, answ[1]));
ret = -1;
}
return ret;
u16 *pid = dvbdmx->pids, npids[5];
int i;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
npids[0] = npids[1] = npids[2] = npids[3] = npids[4] = 0xffff;
i = dvbdmxfeed->pes_type;
u16 *pid = dvbdmx->pids, npids[5];
int i;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n", av7110));
if (dvbdmxfeed->pes_type <= 1) {
av7110_av_stop(av7110, dvbdmxfeed->pes_type ? RP_VIDEO : RP_AUDIO);
static int av7110_start_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
- struct av7110 *av7110 = demux->priv;
+ struct av7110 *av7110 = (struct av7110 *) demux->priv;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n", av7110));
if (!demux->dmx.frontend)
return -EINVAL;
static int av7110_stop_feed(struct dvb_demux_feed *feed)
{
struct dvb_demux *demux = feed->demux;
- struct av7110 *av7110 = demux->priv;
+ struct av7110 *av7110 = (struct av7110 *) demux->priv;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if (feed->type == DMX_TYPE_TS) {
if (feed->ts_type & TS_DECODER) {
int mode;
int i;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
mode = av7110->playing;
av7110->playing = 0;
BUG();
av7110 = (struct av7110 *) dvbdemux->priv;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if (num != 0)
return -EINVAL;
printk(KERN_ERR "%s: av7110_fw_request error\n", __FUNCTION__);
return -EIO;
}
- dprintk(2, "fwstc = %04hx %04hx %04hx %04hx\n",
- fwstc[0], fwstc[1], fwstc[2], fwstc[3]);
+ DEB_EE(("av7110: fwstc = %04hx %04hx %04hx %04hx\n",
+ fwstc[0], fwstc[1], fwstc[2], fwstc[3]));
*stc = (((uint64_t) ((fwstc[3] & 0x8000) >> 15)) << 32) |
(((uint64_t) fwstc[1]) << 16) | ((uint64_t) fwstc[0]);
*base = 1;
- dprintk(4, "stc = %lu\n", (unsigned long)*stc);
+ DEB_EE(("av7110: stc = %lu\n", (unsigned long)*stc));
return 0;
}
* SEC device file operations
******************************************************************************/
-
-static int av7110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+static int av7110_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
+ struct av7110 *av7110 = fe->before_after_data;
+
+ DEB_EE(("av7110: %p\n", av7110));
- switch (tone) {
+ switch (cmd) {
+ case FE_SET_TONE:
+ switch ((fe_sec_tone_mode_t) arg) {
case SEC_TONE_ON:
Set22K(av7110, 1);
break;
case SEC_TONE_OFF:
Set22K(av7110, 0);
break;
-
default:
return -EINVAL;
+};
+ break;
+
+ case FE_DISEQC_SEND_MASTER_CMD:
+ {
+ struct dvb_diseqc_master_cmd *cmd = arg;
+ av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
+ break;
}
+ case FE_DISEQC_SEND_BURST:
+ av7110_diseqc_send(av7110, 0, NULL, (unsigned long) arg);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+};
+
return 0;
}
-static int av7110_diseqc_send_master_cmd(struct dvb_frontend* fe,
- struct dvb_diseqc_master_cmd* cmd)
+
+static void av7110_before_after_tune (fe_status_t s, void *data)
{
- struct av7110* av7110 = fe->dvb->priv;
+ struct av7110 *av7110 = data;
- av7110_diseqc_send(av7110, cmd->msg_len, cmd->msg, -1);
+ DEB_EE(("av7110: %p\n",av7110));
- return 0;
-}
+ av7110->fe_synced = (s & FE_HAS_LOCK) ? 1 : 0;
-static int av7110_diseqc_send_burst(struct dvb_frontend* fe,
- fe_sec_mini_cmd_t minicmd)
-{
- struct av7110* av7110 = fe->dvb->priv;
+ if (av7110->playing)
+ return;
- av7110_diseqc_send(av7110, 0, NULL, minicmd);
+ if (down_interruptible(&av7110->pid_mutex))
+ return;
- return 0;
+ if (av7110->fe_synced) {
+ SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
+ av7110->pids[DMX_PES_AUDIO],
+ av7110->pids[DMX_PES_TELETEXT], 0,
+ av7110->pids[DMX_PES_PCR]);
+ av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
+ } else {
+ SetPIDs(av7110, 0, 0, 0, 0, 0);
+ av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, FlushTSQueue, 0);
+ }
+
+ up(&av7110->pid_mutex);
}
int ret, i;
struct dvb_demux *dvbdemux=&av7110->demux;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if (av7110->registered)
return -1;
av7110->registered=1;
+ dvb_add_frontend_notifier (av7110->dvb_adapter,
+ av7110_before_after_tune, av7110);
+
+ /**
+ * init DiSEqC stuff
+ */
+ dvb_add_frontend_ioctls (av7110->dvb_adapter,
+ av7110_diseqc_ioctl, NULL, av7110);
+
dvbdemux->priv = (void *) av7110;
for (i=0; i<32; i++)
{
struct dvb_demux *dvbdemux=&av7110->demux;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if (!av7110->registered)
return;
dvb_dmxdev_release(&av7110->dmxdev);
dvb_dmx_release(&av7110->demux);
- if (av7110->fe != NULL)
- dvb_unregister_frontend(av7110->fe);
+ dvb_remove_frontend_notifier (av7110->dvb_adapter,
+ av7110_before_after_tune);
+
+ dvb_remove_frontend_ioctls (av7110->dvb_adapter,
+ av7110_diseqc_ioctl, NULL);
+
dvb_unregister_device(av7110->osd_dev);
av7110_av_unregister(av7110);
av7110_ca_unregister(av7110);
int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
{
u8 msg[2] = { reg, val };
+ struct dvb_i2c_bus *i2c = av7110->i2c_bus;
struct i2c_msg msgs;
msgs.flags = 0;
msgs.addr = id / 2;
msgs.len = 2;
msgs.buf = msg;
- return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
+ return i2c->xfer(i2c, &msgs, 1);
}
-#if 0
u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
{
+ struct dvb_i2c_bus *i2c = av7110->i2c_bus;
u8 mm1[] = {0x00};
u8 mm2[] = {0x00};
struct i2c_msg msgs[2];
mm1[0] = reg;
msgs[0].len = 1; msgs[1].len = 1;
msgs[0].buf = mm1; msgs[1].buf = mm2;
- i2c_transfer(&av7110->i2c_adap, msgs, 2);
+ i2c->xfer(i2c, msgs, 2);
return mm2[0];
}
-#endif
+
+static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
+{
+ struct saa7146_dev *dev = i2c->data;
+ return saa7146_i2c_transfer(dev, msgs, num, 6);
+}
/****************************************************************************
* INITIALIZATION
/* request the av7110 firmware, this will block until someone uploads it */
ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
if (ret) {
- if (ret == -ENOENT) {
- printk(KERN_ERR "dvb-ttpci: could not load firmware,"
- " file not found: dvb-ttpci-01.fw\n");
- printk(KERN_ERR "dvb-ttpci: usually this should be in"
- " /usr/lib/hotplug/firmware\n");
- printk(KERN_ERR "dvb-ttpci: and can be downloaded here"
- " http://www.linuxtv.org/download/dvb/firmware/\n");
- } else
- printk(KERN_ERR "dvb-ttpci: cannot request firmware"
- " (error %i)\n", ret);
+ printk("dvb-ttpci: cannot request firmware!\n");
return -EINVAL;
}
-
if (fw->size <= 200000) {
printk("dvb-ttpci: this firmware is way too small.\n");
- release_firmware(fw);
return -EINVAL;
}
-
/* check if the firmware is available */
av7110->bin_fw = (unsigned char*) vmalloc(fw->size);
if (NULL == av7110->bin_fw) {
- dprintk(1, "out of memory\n");
- release_firmware(fw);
+ DEB_D(("out of memory\n"));
return -ENOMEM;
}
-
memcpy(av7110->bin_fw, fw->data, fw->size);
av7110->size_fw = fw->size;
if ((ret = check_firmware(av7110)))
vfree(av7110->bin_fw);
-
- release_firmware(fw);
return ret;
}
#endif
-
-static int alps_bsrv2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
- u8 pwr = 0;
- u8 buf[4];
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) };
- u32 div = (params->frequency + 479500) / 125;
-
- if (params->frequency > 2000000) pwr = 3;
- else if (params->frequency > 1800000) pwr = 2;
- else if (params->frequency > 1600000) pwr = 1;
- else if (params->frequency > 1200000) pwr = 0;
- else if (params->frequency >= 1100000) pwr = 1;
- else pwr = 2;
-
- buf[0] = (div >> 8) & 0x7f;
- buf[1] = div & 0xff;
- buf[2] = ((div & 0x18000) >> 10) | 0x95;
- buf[3] = (pwr << 6) | 0x30;
-
- // NOTE: since we're using a prescaler of 2, we set the
- // divisor frequency to 62.5kHz and divide by 125 above
-
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static struct ves1x93_config alps_bsrv2_config = {
- .demod_address = 0x08,
- .xin = 90100000UL,
- .invert_pwm = 0,
- .pll_set = alps_bsrv2_pll_set,
-};
-
-
-static u8 alps_bsru6_inittab[] = {
- 0x01, 0x15,
- 0x02, 0x30,
- 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 av7110* av7110 = (struct av7110*) fe->dvb->priv;
- int ret;
- u8 data[4];
- u32 div;
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
- if ((params->frequency < 950000) || (params->frequency > 2150000))
- return -EINVAL;
-
- div = (params->frequency + (125 - 1)) / 125; // round correctly
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
- data[3] = 0xC4;
-
- if (params->frequency > 1530000) data[3] = 0xc0;
-
- ret = i2c_transfer (&av7110->i2c_adap, &msg, 1);
- if (ret != 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 alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- struct av7110* av7110 = fe->dvb->priv;
- u32 div;
- u8 data[4];
- struct i2c_msg msg = { .addr = 0x62, .flags = 0, .buf = data, .len = sizeof(data) };
-
- div = (params->frequency + 35937500 + 31250) / 62500;
-
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0x85 | ((div >> 10) & 0x60);
- data[3] = (params->frequency < 174000000 ? 0x88 : params->frequency < 470000000 ? 0x84 : 0x81);
-
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static struct ves1820_config alps_tdbe2_config = {
- .demod_address = 0x09,
- .xin = 57840000UL,
- .invert = 1,
- .selagc = VES1820_SELAGC_SIGNAMPERR,
- .pll_set = alps_tdbe2_pll_set,
-};
-
-
-
-
-static int grundig_29504_451_pll_set(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params)
-{
- struct av7110* av7110 = fe->dvb->priv;
- u32 div;
- u8 data[4];
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
- div = params->frequency / 125;
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0x8e;
- data[3] = 0x00;
-
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static struct tda8083_config grundig_29504_451_config = {
- .demod_address = 0x68,
- .pll_set = grundig_29504_451_pll_set,
-};
-
-
-
-static int philips_cd1516_pll_set(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params)
-{
- struct av7110* av7110 = fe->dvb->priv;
- u32 div;
- u32 f = params->frequency;
- u8 data[4];
- struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) };
-
- div = (f + 36125000 + 31250) / 62500;
-
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0x8e;
- data[3] = (f < 174000000 ? 0xa1 : f < 470000000 ? 0x92 : 0x34);
-
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static struct ves1820_config philips_cd1516_config = {
- .demod_address = 0x09,
- .xin = 57840000UL,
- .invert = 1,
- .selagc = VES1820_SELAGC_SIGNAMPERR,
- .pll_set = philips_cd1516_pll_set,
-};
-
-
-
-static int alps_tdlb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- struct av7110* av7110 = fe->dvb->priv;
- u32 div, pwr;
- u8 data[4];
- struct i2c_msg msg = { .addr = 0x60, .flags = 0, .buf = data, .len = sizeof(data) };
-
- div = (params->frequency + 36200000) / 166666;
-
- if (params->frequency <= 782000000)
- pwr = 1;
- else
- pwr = 2;
-
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0x85;
- data[3] = pwr << 6;
-
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1)
- return -EIO;
- return 0;
-}
-
-static int alps_tdlb7_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name)
-{
- struct av7110* av7110 = (struct av7110*) fe->dvb->priv;
-
- return request_firmware(fw, name, &av7110->dev->pci->dev);
-}
-
-static struct sp8870_config alps_tdlb7_config = {
-
- .demod_address = 0x71,
- .pll_set = alps_tdlb7_pll_set,
- .request_firmware = alps_tdlb7_request_firmware,
-};
-
-
-
-static int nexusca_stv0297_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
-{
- struct av7110* av7110 = fe->dvb->priv;
- u32 div;
- u8 data[4];
- 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 };
- int i;
-
- div = (params->frequency + 36150000 + 31250) / 62500;
-
- data[0] = (div >> 8) & 0x7f;
- data[1] = div & 0xff;
- data[2] = 0xce;
-
- if (params->frequency < 45000000)
- return -EINVAL;
- else if (params->frequency < 137000000)
- data[3] = 0x01;
- else if (params->frequency < 403000000)
- data[3] = 0x02;
- else if (params->frequency < 860000000)
- data[3] = 0x04;
- else
- return -EINVAL;
-
- stv0297_enable_plli2c(fe);
- if (i2c_transfer (&av7110->i2c_adap, &msg, 1) != 1) {
- printk("nexusca: pll transfer failed!\n");
- return -EIO;
- }
-
- // wait for PLL lock
- for(i=0; i< 20; i++) {
-
- stv0297_enable_plli2c(fe);
- if (i2c_transfer (&av7110->i2c_adap, &readmsg, 1) == 1)
- if (data[0] & 0x40) break;
- msleep(10);
- }
-
- return 0;
-}
-
-static struct stv0297_config nexusca_stv0297_config = {
-
- .demod_address = 0x1C,
- .pll_set = nexusca_stv0297_pll_set,
-};
-
-
-static void av7110_fe_lock_fix(struct av7110* av7110, fe_status_t status)
-{
- int synced = (status & FE_HAS_LOCK) ? 1 : 0;
-
- av7110->fe_status = status;
-
- if (av7110->fe_synced == synced)
- return;
-
- av7110->fe_synced = synced;
-
- if (av7110->playing)
- return;
-
- if (down_interruptible(&av7110->pid_mutex))
- return;
-
- if (av7110->fe_synced) {
- SetPIDs(av7110, av7110->pids[DMX_PES_VIDEO],
- av7110->pids[DMX_PES_AUDIO],
- av7110->pids[DMX_PES_TELETEXT], 0,
- av7110->pids[DMX_PES_PCR]);
- av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, Scan, 0);
- } else {
- SetPIDs(av7110, 0, 0, 0, 0, 0);
- av7110_fw_cmd(av7110, COMTYPE_PID_FILTER, FlushTSQueue, 0);
- av7110_wait_msgstate(av7110, GPMQBusy);
- }
-
- 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)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_init(fe);
-}
-
-static int av7110_fe_read_status(struct dvb_frontend* fe, fe_status_t* status)
-{
- struct av7110* av7110 = fe->dvb->priv;
- int ret;
-
- /* call the real implementation */
- ret = av7110->fe_read_status(fe, status);
- if (ret)
- return ret;
-
- if (((*status ^ av7110->fe_status) & FE_HAS_LOCK) && (*status & FE_HAS_LOCK)) {
- av7110_fe_lock_fix(av7110, *status);
- }
-
- return 0;
-}
-
-static int av7110_fe_diseqc_reset_overload(struct dvb_frontend* fe)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- 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)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_diseqc_send_master_cmd(fe, cmd);
-}
-
-static int av7110_fe_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_diseqc_send_burst(fe, minicmd);
-}
-
-static int av7110_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_set_tone(fe, tone);
-}
-
-static int av7110_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_set_voltage(fe, voltage);
-}
-
-static int av7110_fe_dishnetwork_send_legacy_command(struct dvb_frontend* fe, unsigned int cmd)
-{
- struct av7110* av7110 = fe->dvb->priv;
-
- av7110_fe_lock_fix(av7110, 0);
- return av7110->fe_dishnetwork_send_legacy_command(fe, cmd);
-}
-
-static u8 read_pwm(struct av7110* av7110)
-{
- u8 b = 0xff;
- u8 pwm;
- struct i2c_msg msg[] = { { .addr = 0x50,.flags = 0,.buf = &b,.len = 1 },
- { .addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1} };
-
- if ((i2c_transfer(&av7110->i2c_adap, msg, 2) != 2) || (pwm == 0xff))
- pwm = 0x48;
-
- return pwm;
-}
-
-static void frontend_init(struct av7110 *av7110)
-{
- if (av7110->dev->pci->subsystem_vendor == 0x110a) {
- switch(av7110->dev->pci->subsystem_device) {
- case 0x0000: // Fujitsu/Siemens DVB-Cable (ves1820/Philips CD1516(??))
- av7110->fe = ves1820_attach(&philips_cd1516_config,
- &av7110->i2c_adap, read_pwm(av7110));
- break;
- }
-
- } else if (av7110->dev->pci->subsystem_vendor == 0x13c2) {
- switch(av7110->dev->pci->subsystem_device) {
- case 0x0000: // Hauppauge/TT WinTV DVB-S rev1.X
- case 0x0003: // Hauppauge/TT WinTV Nexus-S Rev 2.X
- case 0x1002: // Hauppauge/TT WinTV DVB-S rev1.3SE
-
- // try the ALPS BSRV2 first of all
- av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap);
- if (av7110->fe) {
- av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
- av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
- av7110->fe->ops->set_tone = av7110_set_tone;
- break;
- }
-
- // try the ALPS BSRU6 now
- av7110->fe = stv0299_attach(&alps_bsru6_config, &av7110->i2c_adap);
- if (av7110->fe) {
- av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
- av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
- av7110->fe->ops->set_tone = av7110_set_tone;
- break;
- }
-
- // Try the grundig 29504-451
- av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap);
- if (av7110->fe) {
- av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd;
- av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst;
- av7110->fe->ops->set_tone = av7110_set_tone;
- 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;
-
- case 0x0001: // Hauppauge/TT Nexus-T premium rev1.X
-
- // ALPS TDLB7
- av7110->fe = sp8870_attach(&alps_tdlb7_config, &av7110->i2c_adap);
- break;
-
- case 0x0002: // Hauppauge/TT DVB-C premium rev2.X
-
- av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110));
- break;
-
- case 0x000A: // Hauppauge/TT Nexus-CA rev1.X
-
- av7110->fe = stv0297_attach(&nexusca_stv0297_config, &av7110->i2c_adap, 0x7b);
- 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 */
- av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
- break;
- }
- }
- }
-
- if (av7110->fe == NULL) {
- printk("dvb-ttpci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
- av7110->dev->pci->vendor,
- av7110->dev->pci->device,
- av7110->dev->pci->subsystem_vendor,
- av7110->dev->pci->subsystem_device);
- } else {
- FE_FUNC_OVERRIDE(av7110->fe->ops->init, av7110->fe_init, av7110_fe_init);
- FE_FUNC_OVERRIDE(av7110->fe->ops->read_status, av7110->fe_read_status, av7110_fe_read_status);
- FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_reset_overload, av7110->fe_diseqc_reset_overload, av7110_fe_diseqc_reset_overload);
- FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_master_cmd, av7110->fe_diseqc_send_master_cmd, av7110_fe_diseqc_send_master_cmd);
- FE_FUNC_OVERRIDE(av7110->fe->ops->diseqc_send_burst, av7110->fe_diseqc_send_burst, av7110_fe_diseqc_send_burst);
- 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->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)) {
- printk("av7110: Frontend registration failed!\n");
- if (av7110->fe->ops->release)
- av7110->fe->ops->release(av7110->fe);
- av7110->fe = NULL;
- }
- }
-}
-
static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
{
struct av7110 *av7110 = NULL;
int ret = 0;
- dprintk(4, "dev: %p\n", dev);
+ DEB_EE(("dev: %p\n", dev));
/* prepare the av7110 device struct */
if (!(av7110 = kmalloc (sizeof (struct av7110), GFP_KERNEL))) {
- dprintk(1, "out of memory\n");
+ printk ("%s: out of memory!\n", __FUNCTION__);
return -ENOMEM;
}
-
+ DEB_EE(("av7110: %p\n", av7110));
memset(av7110, 0, sizeof(struct av7110));
av7110->card_name = (char*)pci_ext->ext_priv;
- av7110->dev = dev;
+ av7110->dev=(struct saa7146_dev *)dev;
dev->ext_priv = av7110;
if ((ret = get_firmware(av7110))) {
get recognized before the main driver is fully loaded */
saa7146_write(dev, GPIO_CTRL, 0x500000);
-#ifdef I2C_ADAP_CLASS_TV_DIGITAL
- av7110->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
-#else
- av7110->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
-#endif
- strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
+ saa7146_i2c_adapter_prepare(dev, NULL, 0, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
- saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
+ av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev,
+ av7110->dvb_adapter, 0);
- if (i2c_add_adapter(&av7110->i2c_adap) < 0) {
+ if (!av7110->i2c_bus) {
dvb_unregister_adapter (av7110->dvb_adapter);
kfree(av7110);
return -ENOMEM;
}
- ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac);
+ ttpci_eeprom_parse_mac(av7110->i2c_bus);
saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
saa7146_write(dev, BCS_CTRL, 0x80400040);
/* locks for data transfers from/to AV7110 */
spin_lock_init (&av7110->debilock);
sema_init(&av7110->dcomlock, 1);
+ av7110->debilock=SPIN_LOCK_UNLOCKED;
av7110->debitype=-1;
/* default OSD window */
av7110->osdwin=1;
- sema_init(&av7110->osd_sema, 1);
/* ARM "watchdog" */
init_waitqueue_head(&av7110->arm_wait);
}
if (FW_VERSION(av7110->arm_app)<0x2501)
- printk ("dvb-ttpci: Warning, firmware version 0x%04x is too old. "
+ printk ("av7110: Warning, firmware version 0x%04x is too old. "
"System might be unstable!\n", FW_VERSION(av7110->arm_app));
if (kernel_thread(arm_thread, (void *) av7110, 0) < 0) {
- printk("dvb-ttpci: failed to start arm_mon kernel thread @ card %d\n",
+ printk(KERN_ERR "av7110(%d): faile to start arm_mon kernel thread\n",
av7110->dvb_adapter->num);
goto err2;
}
- /* set initial volume in mixer struct */
- av7110->mixer.volume_left = volume;
- av7110->mixer.volume_right = volume;
+ /* set internal volume control to maximum */
+ av7110->adac_type = DVB_ADAC_TI;
+ av7110_set_volume(av7110, 0xff, 0xff);
+
+ av7710_set_video_mode(av7110, vidmode);
+
+ /* handle different card types */
+ /* remaining inits according to card and frontend type */
+ av7110->has_analog_tuner = 0;
+ av7110->current_input = 0;
+ if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) {
+ printk ("av7110(%d): Crystal audio DAC detected\n",
+ av7110->dvb_adapter->num);
+ av7110->adac_type = DVB_ADAC_CRYSTAL;
+ i2c_writereg(av7110, 0x20, 0x01, 0xd2);
+ i2c_writereg(av7110, 0x20, 0x02, 0x49);
+ i2c_writereg(av7110, 0x20, 0x03, 0x00);
+ i2c_writereg(av7110, 0x20, 0x04, 0x00);
- init_av7110_av(av7110);
+ /**
+ * some special handling for the Siemens DVB-C cards...
+ */
+ } else if (0 == av7110_init_analog_module(av7110)) {
+ /* done. */
+ }
+ else if (dev->pci->subsystem_vendor == 0x110a) {
+ printk("av7110(%d): DVB-C w/o analog module detected\n",
+ av7110->dvb_adapter->num);
+ av7110->adac_type = DVB_ADAC_NONE;
+ }
+ else {
+ av7110->adac_type = adac;
+ printk("av7110(%d): adac type set to %d\n",
+ av7110->dvb_adapter->num, av7110->adac_type);
+ }
+ if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
+ // switch DVB SCART on
+ av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
+ av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
+ if (rgb_on)
+ saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
+ //saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
+ }
+
+ av7110_set_volume(av7110, 0xff, 0xff);
+
+ av7110_setup_irc_config (av7110, 0);
av7110_register(av7110);
/* special case DVB-C: these cards have an analog tuner
if (ret)
goto err3;
- av7110->dvb_adapter->priv = av7110;
- frontend_init(av7110);
-
- printk(KERN_INFO "dvb-ttpci: found av7110-%d.\n", av7110_num);
+ printk(KERN_INFO "av7110: found av7110-%d.\n",av7110_num);
av7110->device_initialized = 1;
av7110_num++;
return 0;
av7110->arm_rmmod = 1;
wake_up_interruptible(&av7110->arm_wait);
while (av7110->arm_thread)
- msleep(1);
+ dvb_delay(1);
err2:
av7110_ca_exit(av7110);
av7110_av_exit(av7110);
err:
- i2c_del_adapter(&av7110->i2c_adap);
+ dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter,
+ av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
static int av7110_detach (struct saa7146_dev* saa)
{
struct av7110 *av7110 = (struct av7110*)saa->ext_priv;
- dprintk(4, "%p\n", av7110);
+ DEB_EE(("av7110: %p\n",av7110));
if( 0 == av7110->device_initialized ) {
return 0;
wake_up_interruptible(&av7110->arm_wait);
while (av7110->arm_thread)
- msleep(1);
+ dvb_delay(1);
dvb_unregister(av7110);
- SAA7146_IER_DISABLE(saa, MASK_19 | MASK_03);
- SAA7146_ISR_CLEAR(saa, MASK_19 | MASK_03);
+ IER_DISABLE(saa, (MASK_19 | MASK_03));
+// saa7146_write (av7110->dev, IER,
+// saa7146_read(av7110->dev, IER) & ~(MASK_19 | MASK_03));
+
+ saa7146_write(av7110->dev, ISR,(MASK_19 | MASK_03));
av7110_ca_exit(av7110);
av7110_av_exit(av7110);
pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
av7110->debi_bus);
- i2c_del_adapter(&av7110->i2c_adap);
-
+ dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter);
av7110_num--;
static void av7110_irq(struct saa7146_dev* dev, u32 *isr)
{
- struct av7110 *av7110 = dev->ext_priv;
+ struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
+
+// DEB_INT(("dev: %p, av7110: %p\n",dev,av7110));
if (*isr & MASK_19)
tasklet_schedule (&av7110->debi_tasklet);
.ext_priv = x_name, \
.ext = &av7110_extension }
-MAKE_AV7110_INFO(tts_1_X, "Technotrend/Hauppauge WinTV DVB-S rev1.X");
-MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X");
-MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X");
-MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X");
-MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X");
-MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV Nexus-S rev1.3");
-MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C");
+MAKE_AV7110_INFO(fs_1_5, "Siemens cable card PCI rev1.5");
+MAKE_AV7110_INFO(fs_1_3, "Siemens/Technotrend/Hauppauge PCI rev1.3");
+MAKE_AV7110_INFO(tt_1_6, "Technotrend/Hauppauge PCI rev1.3 or 1.6");
+MAKE_AV7110_INFO(tt_2_1, "Technotrend/Hauppauge PCI rev2.1");
+MAKE_AV7110_INFO(tt_t, "Technotrend/Hauppauge PCI DVB-T");
+MAKE_AV7110_INFO(unkwn0, "Technotrend/Hauppauge PCI rev?(unknown0)?");
+MAKE_AV7110_INFO(unkwn1, "Technotrend/Hauppauge PCI rev?(unknown1)?");
+MAKE_AV7110_INFO(unkwn2, "Technotrend/Hauppauge PCI rev?(unknown2)?");
+MAKE_AV7110_INFO(nexus, "Technotrend/Hauppauge Nexus PCI DVB-S");
+MAKE_AV7110_INFO(dvboc11,"Octal/Technotrend DVB-C for iTV");
static struct pci_device_id pci_tbl[] = {
- MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000),
- MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001),
- MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002),
- MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003),
- MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002),
- MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000),
- MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a),
-
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0006), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-S v????
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0008), UNDEFINED CARD */ // TT/Hauppauge WinTV DVB-T v????
-/* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v????
-
+ MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0xffff),
+ MAKE_EXTENSION_PCI(fs_1_5, 0x110a, 0x0000),
+ MAKE_EXTENSION_PCI(fs_1_3, 0x13c2, 0x0000),
+ MAKE_EXTENSION_PCI(unkwn0, 0x13c2, 0x1002),
+ MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0001),
+ MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0002),
+ MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0003),
+ MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x0004),
+ MAKE_EXTENSION_PCI(tt_1_6, 0x13c2, 0x0006),
+ MAKE_EXTENSION_PCI(tt_t, 0x13c2, 0x0008),
+ MAKE_EXTENSION_PCI(tt_2_1, 0x13c2, 0x1102),
+ MAKE_EXTENSION_PCI(unkwn1, 0xffc2, 0x0000),
+ MAKE_EXTENSION_PCI(unkwn2, 0x00a1, 0x00a1),
+ MAKE_EXTENSION_PCI(nexus, 0x00a1, 0xa1a0),
+ MAKE_EXTENSION_PCI(dvboc11,0x13c2, 0x000a),
{
.vendor = 0,
}
MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
MODULE_LICENSE("GPL");
+MODULE_PARM(av7110_debug,"i");
+MODULE_PARM(vidmode,"i");
+MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
+MODULE_PARM(pids_off,"i");
+MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
+MODULE_PARM(adac,"i");
+MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
+MODULE_PARM(hw_sections, "i");
+MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
+MODULE_PARM(rgb_on, "i");
+MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
+ " signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");