summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/budget-av.c249
-rw-r--r--linux/drivers/media/dvb/ttpci-budget/budget.h78
2 files changed, 327 insertions, 0 deletions
diff --git a/linux/drivers/media/dvb/ttpci-budget/budget-av.c b/linux/drivers/media/dvb/ttpci-budget/budget-av.c
new file mode 100644
index 000000000..8e6ed0e76
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci-budget/budget-av.c
@@ -0,0 +1,249 @@
+/*
+ * budget-av.c: driver for the SAA7146 based Budget DVB cards
+ * with analog video in
+ *
+ * Compiled from various sources by Michael Hunold <michael@mihu.de>
+ *
+ * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
+ *
+ * Copyright (C) 1999-2002 Ralph Metzler
+ * & Marcus Metzler for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org/dvb/
+ */
+
+#include "budget.h"
+
+static int budget_debug = 0;
+
+static char *knc1 = "KNC1 DVB-S";
+
+static struct saa7146_sub_info sub_data[] = {
+ {
+ .subvendor = 0x1131,
+ .subdevice = 0x4f56,
+ .name = &knc1,
+ .type = DVB_CARD_KNC1
+ }, {
+ .subvendor = 0xffff,
+ .subdevice = 0xffff,
+ .name = NULL,
+ .type = 0
+ }
+};
+
+/****************************************************************************
+ * INITIALIZATION
+ ****************************************************************************/
+
+static inline void ddelay(int i)
+{
+ current->state=TASK_INTERRUPTIBLE;
+ schedule_timeout((HZ*i)/100);
+}
+
+static inline u8
+i2c_readreg(struct dvb_i2c_bus *i2c, u8 id, u8 reg)
+{
+ u8 mm1[] = {0x00};
+ u8 mm2[] = {0x00};
+ struct i2c_msg msgs[2];
+
+ msgs[0].flags=0;
+ msgs[1].flags=I2C_M_RD;
+ msgs[0].addr=msgs[1].addr=id/2;
+ mm1[0]=reg;
+ msgs[0].len=1; msgs[1].len=1;
+ msgs[0].buf=mm1; msgs[1].buf=mm2;
+ i2c->xfer(i2c, msgs, 2);
+
+ return mm2[0];
+}
+
+static inline int
+i2c_writereg(struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 val)
+{
+ u8 msg[2]={ reg, val };
+ struct i2c_msg msgs;
+
+ msgs.flags=0;
+ msgs.addr=id/2;
+ msgs.len=2;
+ msgs.buf=msg;
+ return i2c->xfer (i2c, &msgs, 1);
+}
+
+static const u8 saa7113_tab[] = {
+ 0x01, 0x08,
+ 0x02, 0xc0,
+ 0x03, 0x33,
+ 0x04, 0x00,
+ 0x05, 0x00,
+ 0x06, 0xeb,
+ 0x07, 0xe0,
+ 0x08, 0x28,
+ 0x09, 0x00,
+ 0x0a, 0x80,
+ 0x0b, 0x47,
+ 0x0c, 0x40,
+ 0x0d, 0x00,
+ 0x0e, 0x01,
+ 0x0f, 0x44,
+
+ 0x10, 0x08,
+ 0x11, 0x0c,
+ 0x12, 0x7b,
+ 0x13, 0x00,
+ 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
+
+ 0x57, 0xff,
+ 0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
+ 0x5b, 0x83, 0x5e, 0x00,
+ 0xff
+};
+
+static int
+init_saa7113(struct budget_s *budget)
+{
+ const u8 *data=saa7113_tab;
+
+ if (i2c_writereg(budget->i2c_bus, 0x4a, 0x01, 0x08)!=1) {
+ DEB_D(("saa7113: not found on KNC card\n"));
+ return -1;
+ }
+ INFO(("saa7113: detected and initializing\n"));
+ while (*data!=0xff) {
+ i2c_writereg(budget->i2c_bus, 0x4a, *data, *(data+1));
+ data+=2;
+ }
+ DEB_D(("saa7113: status=%02x\n", i2c_readreg(budget->i2c_bus, 0x4a, 0x1f)));
+ return 0;
+}
+
+static
+int this_budget_detach(struct saa7146_dev* dev)
+{
+ saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
+ ddelay(20);
+
+ return budget_detach(dev);
+}
+
+static
+int this_budget_attach (struct saa7146_dev* dev, struct saa7146_sub_info *info)
+{
+ struct budget_s *budget = NULL;
+
+ if (budget->card_type->type==DVB_CARD_KNC1) {
+ return -1;
+ }
+
+ if( 0 != budget_attach(dev,info)) {
+ return -1;
+ }
+ budget = (struct budget_s*)dev->ext_priv;
+
+ /* knc1 initialization */
+ saa7146_write(dev, DD1_STREAM_B, 0x04000000);
+ saa7146_write(dev, DD1_INIT, 0x07000600);
+ saa7146_write(dev, MC2,
+ MASK_09 | MASK_25 | MASK_10 | MASK_26);
+
+ //test_knc_ci(av7110);
+
+ saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
+ ddelay(50);
+ if( 0 != init_saa7113(budget)) {
+ this_budget_detach(dev);
+ return -1;
+ }
+
+ /* what is this? since we don't support open()/close()
+ notifications, we simply put this into the release handler... */
+// saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
+ ddelay(20);
+
+ /* fixme: find some sane values here... */
+ saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
+
+ // FIXME: cope with error here!
+ budget_register(budget);
+ printk(KERN_INFO "budget: found budget card w/ video-in.\n");
+}
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+static
+void budget_inc_use(struct saa7146_dev* adap)
+{
+ MOD_INC_USE_COUNT;
+}
+
+static
+void budget_dec_use(struct saa7146_dev* adap)
+{
+ MOD_DEC_USE_COUNT;
+}
+#endif
+
+static
+struct saa7146_extension budget_extension = {
+ .name = "budget dvb /w video in\0",
+ .devices = &sub_data[0],
+ .module = THIS_MODULE,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+ .inc_use = budget_inc_use,
+ .dec_use = budget_dec_use,
+#endif
+ .attach = this_budget_attach,
+ .detach = this_budget_detach,
+ .irq_mask = MASK_07,
+ .irq_func = budget_irq,
+};
+
+
+static
+int __init budget_init(void)
+{
+ DEB_EE((".\n"));
+
+ if (saa7146_register_extension(&budget_extension))
+ return -ENODEV;
+
+ return 0;
+}
+
+
+static
+void __exit budget_exit(void)
+{
+ DEB_EE((".\n"));
+ saa7146_unregister_extension(&budget_extension);
+}
+
+module_init(budget_init);
+module_exit(budget_exit);
+
+MODULE_DESCRIPTION("driver for the SAA7146 based so-called budget PCI DVB cards by "
+ "Siemens, Technotrend, Hauppauge");
+MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(budget_debug,"i");
diff --git a/linux/drivers/media/dvb/ttpci-budget/budget.h b/linux/drivers/media/dvb/ttpci-budget/budget.h
new file mode 100644
index 000000000..939cc375f
--- /dev/null
+++ b/linux/drivers/media/dvb/ttpci-budget/budget.h
@@ -0,0 +1,78 @@
+#ifndef __BUDGET_DVB__
+#define __BUDGET_DVB__
+
+#include "dvb_i2c.h"
+#include "dvb_frontend.h"
+#include "dvbdev.h"
+#include "demux.h"
+#include "dvb_demux.h"
+#include "dmxdev.h"
+#include "dvb_filter.h"
+#include "dvb_net.h"
+#include "saa7146.h"
+
+#if 1
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,51)
+ #define KBUILD_MODNAME budget
+#endif
+#define DEBUG_PROLOG printk("%s: %s(): ",__stringify(KBUILD_MODNAME),__FUNCTION__)
+#define DEB_S(x) if (0!=(budget_debug&0x01)) { DEBUG_PROLOG; printk x; } /* simple debug messages */
+#define DEB_D(x) if (0!=(budget_debug&0x02)) { DEBUG_PROLOG; printk x; } /* more detailed debug messages */
+#define DEB_EE(x) if (0!=(budget_debug&0x04)) { DEBUG_PROLOG; printk x; } /* print enter and exit of functions */
+#else
+#define DEB_S(x)
+#define DEB_D(x)
+#define DEB_EE(x)
+#endif
+
+/* place to store all the necessary device information */
+struct budget_s {
+
+ /* devices */
+ struct dvb_device dvb_dev;
+ dvb_net_t dvb_net;
+
+ struct saa7146_dev *dev;
+
+ struct dvb_i2c_bus *i2c_bus;
+ struct saa7146_sub_info *card_type;
+
+ unsigned char *grabbing;
+ struct saa7146_pgtable pt;
+
+ struct tasklet_struct fidb_tasklet;
+
+ dmxdev_t dmxdev;
+ struct dvb_demux demux;
+ char demux_id[16];
+
+ dmx_frontend_t hw_frontend;
+ dmx_frontend_t mem_frontend;
+
+ int fe_synced;
+ struct semaphore pid_mutex;
+
+ int tsf;
+ u32 ttbp;
+ int feeding;
+
+ int registered;
+
+ struct dvb_adapter *dvb_adapter;
+};
+
+#define TS_WIDTH (4*188)
+#define TS_HEIGHT (1024/4)
+#define TS_BUFLEN (TS_WIDTH*TS_HEIGHT)
+
+#define DVB_CARD_TT_BUDGET 0
+#define DVB_CARD_TT_BUDGET_CI 1
+#define DVB_CARD_KNC1 2
+
+int budget_probe(struct saa7146_dev *, unsigned int subvendor, unsigned int subdevice);
+void budget_irq(struct saa7146_dev *, u32 *isr);
+int budget_attach (struct saa7146_dev* dev, struct saa7146_sub_info *info);
+int budget_detach (struct saa7146_dev *);
+int budget_register(struct budget_s *budget);
+
+#endif