diff options
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/dvb/ttpci-budget/budget-av.c | 249 | ||||
-rw-r--r-- | linux/drivers/media/dvb/ttpci-budget/budget.h | 78 |
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 |