Commit 0d3430ba authored by Gerd Knorr's avatar Gerd Knorr Committed by Linus Torvalds

[PATCH] saa7134 update

Major saa7134 driver update.  Changes:
 * add a bunch of new cards.
 * add dvb card support (Pinnacle 300i only for now ...).
 * update empress encoder card support,
   use the new v4l2 mpeg API for the settings.
Signed-off-by: default avatarGerd Knorr <kraxel@bytesex.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 32ecb127
...@@ -249,7 +249,9 @@ config VIDEO_SAA7134 ...@@ -249,7 +249,9 @@ config VIDEO_SAA7134
config VIDEO_SAA7134_DVB config VIDEO_SAA7134_DVB
tristate "DVB Support for saa7134 based TV cards" tristate "DVB Support for saa7134 based TV cards"
depends on VIDEO_SAA7134 && DVB_CORE && BROKEN depends on VIDEO_SAA7134 && DVB_CORE
select VIDEO_BUF_DVB
select DVB_MT352
---help--- ---help---
This adds support for DVB cards based on the This adds support for DVB cards based on the
Philips saa7134 chip. Philips saa7134 chip.
......
...@@ -8,3 +8,4 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o ...@@ -8,3 +8,4 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o
EXTRA_CFLAGS += -I$(src)/.. EXTRA_CFLAGS += -I$(src)/..
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends
This diff is collapsed.
This diff is collapsed.
/* /*
* $Id: saa7134-core.c,v 1.15 2004/11/07 14:44:59 kraxel Exp $ * $Id: saa7134-core.c,v 1.28 2005/02/22 09:56:29 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* driver core * driver core
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/kmod.h> #include <linux/kmod.h>
...@@ -88,7 +89,7 @@ MODULE_PARM_DESC(card, "card type"); ...@@ -88,7 +89,7 @@ MODULE_PARM_DESC(card, "card type");
static DECLARE_MUTEX(devlist_lock); static DECLARE_MUTEX(devlist_lock);
LIST_HEAD(saa7134_devlist); LIST_HEAD(saa7134_devlist);
static LIST_HEAD(mops_list); static LIST_HEAD(mops_list);
unsigned int saa7134_devcount; static unsigned int saa7134_devcount;
#define dprintk(fmt, arg...) if (core_debug) \ #define dprintk(fmt, arg...) if (core_debug) \
printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg) printk(KERN_DEBUG "%s/core: " fmt, dev->name , ## arg)
...@@ -620,7 +621,7 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -620,7 +621,7 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
dump_statusregs(dev); dump_statusregs(dev);
#endif #endif
if (report & SAA7134_IRQ_REPORT_INTL) if (report & SAA7134_IRQ_REPORT_RDCAP /* _INTL */)
saa7134_irq_video_intl(dev); saa7134_irq_video_intl(dev);
if ((report & SAA7134_IRQ_REPORT_DONE_RA0) && if ((report & SAA7134_IRQ_REPORT_DONE_RA0) &&
...@@ -642,8 +643,8 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -642,8 +643,8 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
SAA7134_IRQ_REPORT_GPIO18)) && SAA7134_IRQ_REPORT_GPIO18)) &&
dev->remote) dev->remote)
saa7134_input_irq(dev); saa7134_input_irq(dev);
}
};
if (10 == loop) { if (10 == loop) {
print_irqstatus(dev,loop,report,status); print_irqstatus(dev,loop,report,status);
if (report & SAA7134_IRQ_REPORT_PE) { if (report & SAA7134_IRQ_REPORT_PE) {
...@@ -651,6 +652,13 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs) ...@@ -651,6 +652,13 @@ static irqreturn_t saa7134_irq(int irq, void *dev_id, struct pt_regs *regs)
printk(KERN_WARNING "%s/irq: looping -- " printk(KERN_WARNING "%s/irq: looping -- "
"clearing PE (parity error!) enable bit\n",dev->name); "clearing PE (parity error!) enable bit\n",dev->name);
saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE); saa_clearl(SAA7134_IRQ2,SAA7134_IRQ2_INTE_PE);
} else if (report & (SAA7134_IRQ_REPORT_GPIO16 |
SAA7134_IRQ_REPORT_GPIO18)) {
/* disable gpio IRQs */
printk(KERN_WARNING "%s/irq: looping -- "
"clearing GPIO enable bits\n",dev->name);
saa_clearl(SAA7134_IRQ2, (SAA7134_IRQ2_INTE_GPIO16 |
SAA7134_IRQ2_INTE_GPIO18));
} else { } else {
/* disable all irqs */ /* disable all irqs */
printk(KERN_WARNING "%s/irq: looping -- " printk(KERN_WARNING "%s/irq: looping -- "
...@@ -725,20 +733,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev) ...@@ -725,20 +733,7 @@ static int saa7134_hwinit2(struct saa7134_dev *dev)
/* enable IRQ's */ /* enable IRQ's */
saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ1, 0);
saa_writel(SAA7134_IRQ2, saa_writel(SAA7134_IRQ2, dev->irq2_mask);
SAA7134_IRQ2_INTE_GPIO18 |
SAA7134_IRQ2_INTE_GPIO18A |
SAA7134_IRQ2_INTE_GPIO16 |
SAA7134_IRQ2_INTE_SC2 |
SAA7134_IRQ2_INTE_SC1 |
SAA7134_IRQ2_INTE_SC0 |
/* SAA7134_IRQ2_INTE_DEC5 | FIXME: TRIG_ERR ??? */
SAA7134_IRQ2_INTE_DEC3 |
SAA7134_IRQ2_INTE_DEC2 |
/* SAA7134_IRQ2_INTE_DEC1 | */
SAA7134_IRQ2_INTE_DEC0 |
SAA7134_IRQ2_INTE_PE |
SAA7134_IRQ2_INTE_AR);
return 0; return 0;
} }
...@@ -959,6 +954,13 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, ...@@ -959,6 +954,13 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
} }
/* initialize hardware #1 */ /* initialize hardware #1 */
dev->irq2_mask =
SAA7134_IRQ2_INTE_DEC3 |
SAA7134_IRQ2_INTE_DEC2 |
SAA7134_IRQ2_INTE_DEC1 |
SAA7134_IRQ2_INTE_DEC0 |
SAA7134_IRQ2_INTE_PE |
SAA7134_IRQ2_INTE_AR;
saa7134_board_init1(dev); saa7134_board_init1(dev);
saa7134_hwinit1(dev); saa7134_hwinit1(dev);
...@@ -1060,6 +1062,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, ...@@ -1060,6 +1062,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
} }
list_add_tail(&dev->devlist,&saa7134_devlist); list_add_tail(&dev->devlist,&saa7134_devlist);
up(&devlist_lock); up(&devlist_lock);
/* check for signal */
saa7134_irq_video_intl(dev);
return 0; return 0;
fail5: fail5:
...@@ -1207,6 +1212,8 @@ static int saa7134_init(void) ...@@ -1207,6 +1212,8 @@ static int saa7134_init(void)
static void saa7134_fini(void) static void saa7134_fini(void)
{ {
if (pending_registered)
unregister_module_notifier(&pending_notifier);
pci_unregister_driver(&saa7134_pci_driver); pci_unregister_driver(&saa7134_pci_driver);
} }
......
/* /*
* $Id: saa7134-dvb.c,v 1.4 2004/11/07 14:44:59 kraxel Exp $ * $Id: saa7134-dvb.c,v 1.12 2005/02/18 12:28:29 kraxel Exp $
* *
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
* *
...@@ -30,35 +30,211 @@ ...@@ -30,35 +30,211 @@
#include "saa7134-reg.h" #include "saa7134-reg.h"
#include "saa7134.h" #include "saa7134.h"
#include "dvb-pll.h"
#include "mt352.h"
#include "mt352_priv.h" /* FIXME */
#include "tda1004x.h"
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static unsigned int antenna_pwr = 0;
module_param(antenna_pwr, int, 0444);
MODULE_PARM_DESC(antenna_pwr,"enable antenna power (Pinnacle 300i)");
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
static int dvb_init(struct saa7134_dev *dev) static int pinnacle_antenna_pwr(struct saa7134_dev *dev, int on)
{ {
printk("%s: %s\n",dev->name,__FUNCTION__); u32 ok;
if (!on) {
saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
return 0;
}
saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 26));
saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
udelay(10);
saa_setl(SAA7134_GPIO_GPMODE0 >> 2, (1 << 28));
saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
udelay(10);
saa_setl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 28));
udelay(10);
ok = saa_readl(SAA7134_GPIO_GPSTATUS0) & (1 << 27);
printk("%s: %s %s\n", dev->name, __FUNCTION__,
ok ? "on" : "off");
if (!ok)
saa_clearl(SAA7134_GPIO_GPSTATUS0 >> 2, (1 << 26));
return ok;
}
static int mt352_pinnacle_init(struct dvb_frontend* fe)
{
static u8 clock_config [] = { CLOCK_CTL, 0x3d, 0x28 };
static u8 reset [] = { RESET, 0x80 };
static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0xa0 };
static u8 capt_range_cfg[] = { CAPT_RANGE, 0x31 };
static u8 fsm_ctl_cfg[] = { 0x7b, 0x04 };
static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x0f };
static u8 scan_ctl_cfg [] = { SCAN_CTL, 0x0d };
static u8 irq_cfg [] = { INTERRUPT_EN_0, 0x00, 0x00, 0x00, 0x00 };
struct saa7134_dev *dev= fe->dvb->priv;
printk("%s: %s called\n",dev->name,__FUNCTION__);
mt352_write(fe, clock_config, sizeof(clock_config));
udelay(200);
mt352_write(fe, reset, sizeof(reset));
mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
mt352_write(fe, agc_cfg, sizeof(agc_cfg));
mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
mt352_write(fe, fsm_ctl_cfg, sizeof(fsm_ctl_cfg));
mt352_write(fe, scan_ctl_cfg, sizeof(scan_ctl_cfg));
mt352_write(fe, irq_cfg, sizeof(irq_cfg));
return 0;
}
static int mt352_pinnacle_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params,
u8* pllbuf)
{
static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
static int off = TDA9887_PRESENT | TDA9887_PORT2_ACTIVE;
struct saa7134_dev *dev = fe->dvb->priv;
struct v4l2_frequency f;
/* set frequency (mt2050) */
f.tuner = 0;
f.type = V4L2_TUNER_DIGITAL_TV;
f.frequency = params->frequency / 1000 * 16 / 1000;
saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&off);
pinnacle_antenna_pwr(dev, antenna_pwr);
/* mt352 setup */
mt352_pinnacle_init(fe);
pllbuf[0] = 0xc2;
pllbuf[1] = 0x00;
pllbuf[2] = 0x00;
pllbuf[3] = 0x80;
pllbuf[4] = 0x00;
return 0;
}
static struct mt352_config pinnacle_300i = {
.demod_address = 0x3c >> 1,
.adc_clock = 20333,
.if2 = 36150,
.no_tuner = 1,
.demod_init = mt352_pinnacle_init,
.pll_set = mt352_pinnacle_pll_set,
};
/* ------------------------------------------------------------------ */
static int medion_cardbus_init(struct dvb_frontend* fe)
{
/* anything to do here ??? */
return 0;
}
static int medion_cardbus_pll_set(struct dvb_frontend* fe,
struct dvb_frontend_parameters* params)
{
struct saa7134_dev *dev = fe->dvb->priv;
struct v4l2_frequency f;
/*
* this instructs tuner.o to set the frequency, the call will
* end up in tuner_command(), VIDIOC_S_FREQUENCY switch.
* tda9887.o will see that as well.
*/
f.tuner = 0;
f.type = V4L2_TUNER_DIGITAL_TV;
f.frequency = params->frequency / 1000 * 16 / 1000;
saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
return 0;
}
static int fe_request_firmware(struct dvb_frontend* fe,
const struct firmware **fw, char* name)
{
struct saa7134_dev *dev = fe->dvb->priv;
return request_firmware(fw, name, &dev->pci->dev);
}
struct tda1004x_config medion_cardbus = {
.demod_address = 0x08, /* not sure this is correct */
.invert = 0,
.invert_oclk = 0,
.pll_init = medion_cardbus_init,
.pll_set = medion_cardbus_pll_set,
.request_firmware = fe_request_firmware,
};
/* ------------------------------------------------------------------ */
static int dvb_init(struct saa7134_dev *dev)
{
/* init struct videobuf_dvb */ /* init struct videobuf_dvb */
dev->ts.nr_bufs = 32;
dev->ts.nr_packets = 32*4;
dev->dvb.name = dev->name; dev->dvb.name = dev->name;
videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops, videobuf_queue_init(&dev->dvb.dvbq, &saa7134_ts_qops,
dev->pci, &dev->slock, dev->pci, &dev->slock,
V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_TOP, V4L2_FIELD_ALTERNATE,
sizeof(struct saa7134_buf), sizeof(struct saa7134_buf),
dev); dev);
/* TODO: init frontend */ switch (dev->board) {
if (NULL == dev->dvb.frontend) case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
printk("%s: pinnacle 300i dvb setup\n",dev->name);
dev->dvb.frontend = mt352_attach(&pinnacle_300i,
&dev->i2c_adap);
break;
case SAA7134_BOARD_MD7134:
dev->dvb.frontend = tda10046_attach(&medion_cardbus,
&dev->i2c_adap);
if (NULL == dev->dvb.frontend)
printk("%s: Hmm, looks like this is the old MD7134 "
"version without DVB-T support\n",dev->name);
break;
default:
printk("%s: Huh? unknown DVB card?\n",dev->name);
break;
}
if (NULL == dev->dvb.frontend) {
printk("%s: frontend initialization failed\n",dev->name);
return -1; return -1;
}
/* register everything else */ /* register everything else */
return videobuf_dvb_register(&dev->dvb); return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
} }
static int dvb_fini(struct saa7134_dev *dev) static int dvb_fini(struct saa7134_dev *dev)
{ {
static int on = TDA9887_PRESENT | TDA9887_PORT2_INACTIVE;
printk("%s: %s\n",dev->name,__FUNCTION__); printk("%s: %s\n",dev->name,__FUNCTION__);
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_300I_DVBT_PAL:
/* otherwise we don't detect the tuner on next insmod */
saa7134_i2c_call_clients(dev,TDA9887_SET_CONFIG,&on);
break;
};
videobuf_dvb_unregister(&dev->dvb); videobuf_dvb_unregister(&dev->dvb);
return 0; return 0;
} }
...@@ -86,6 +262,5 @@ module_exit(dvb_unregister); ...@@ -86,6 +262,5 @@ module_exit(dvb_unregister);
/* /*
* Local variables: * Local variables:
* c-basic-offset: 8 * c-basic-offset: 8
* compile-command: "make DVB=1"
* End: * End:
*/ */
/* /*
* $Id: saa7134-empress.c,v 1.3 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-empress.c,v 1.10 2005/02/03 10:24:33 kraxel Exp $
* *
* (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
* *
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -50,16 +51,21 @@ MODULE_PARM_DESC(debug,"enable debug messages"); ...@@ -50,16 +51,21 @@ MODULE_PARM_DESC(debug,"enable debug messages");
static void ts_reset_encoder(struct saa7134_dev* dev) static void ts_reset_encoder(struct saa7134_dev* dev)
{ {
if (!dev->empress_started)
return;
saa_writeb(SAA7134_SPECIAL_MODE, 0x00); saa_writeb(SAA7134_SPECIAL_MODE, 0x00);
msleep(10); msleep(10);
saa_writeb(SAA7134_SPECIAL_MODE, 0x01); saa_writeb(SAA7134_SPECIAL_MODE, 0x01);
msleep(100); msleep(100);
dev->empress_started = 0;
} }
static int ts_init_encoder(struct saa7134_dev* dev, void* arg) static int ts_init_encoder(struct saa7134_dev* dev)
{ {
ts_reset_encoder(dev); ts_reset_encoder(dev);
saa7134_i2c_call_clients(dev, MPEG_SETPARAMS, arg); saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, NULL);
dev->empress_started = 1;
return 0; return 0;
} }
...@@ -81,18 +87,19 @@ static int ts_open(struct inode *inode, struct file *file) ...@@ -81,18 +87,19 @@ static int ts_open(struct inode *inode, struct file *file)
return -ENODEV; return -ENODEV;
dprintk("open minor=%d\n",minor); dprintk("open minor=%d\n",minor);
down(&dev->empress_tsq.lock);
err = -EBUSY; err = -EBUSY;
if (dev->empress_users) if (down_trylock(&dev->empress_tsq.lock))
goto done; goto done;
if (dev->empress_users)
goto done_up;
dev->empress_users++; dev->empress_users++;
file->private_data = dev; file->private_data = dev;
ts_init_encoder(dev, NULL);
err = 0; err = 0;
done: done_up:
up(&dev->empress_tsq.lock); up(&dev->empress_tsq.lock);
done:
return err; return err;
} }
...@@ -105,6 +112,7 @@ static int ts_release(struct inode *inode, struct file *file) ...@@ -105,6 +112,7 @@ static int ts_release(struct inode *inode, struct file *file)
down(&dev->empress_tsq.lock); down(&dev->empress_tsq.lock);
if (dev->empress_tsq.reading) if (dev->empress_tsq.reading)
videobuf_read_stop(&dev->empress_tsq); videobuf_read_stop(&dev->empress_tsq);
videobuf_mmap_free(&dev->empress_tsq);
dev->empress_users--; dev->empress_users--;
/* stop the encoder */ /* stop the encoder */
...@@ -119,6 +127,9 @@ ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos) ...@@ -119,6 +127,9 @@ ts_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{ {
struct saa7134_dev *dev = file->private_data; struct saa7134_dev *dev = file->private_data;
if (!dev->empress_started)
ts_init_encoder(dev);
return videobuf_read_stream(&dev->empress_tsq, return videobuf_read_stream(&dev->empress_tsq,
data, count, ppos, 0, data, count, ppos, 0,
file->f_flags & O_NONBLOCK); file->f_flags & O_NONBLOCK);
...@@ -281,8 +292,13 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, ...@@ -281,8 +292,13 @@ static int ts_do_ioctl(struct inode *inode, struct file *file,
case VIDIOC_S_CTRL: case VIDIOC_S_CTRL:
return saa7134_common_ioctl(dev, cmd, arg); return saa7134_common_ioctl(dev, cmd, arg);
case MPEG_SETPARAMS: case VIDIOC_S_MPEGCOMP:
return ts_init_encoder(dev, arg); saa7134_i2c_call_clients(dev, VIDIOC_S_MPEGCOMP, arg);
ts_init_encoder(dev);
return 0;
case VIDIOC_G_MPEGCOMP:
saa7134_i2c_call_clients(dev, VIDIOC_G_MPEGCOMP, arg);
return 0;
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
...@@ -320,6 +336,26 @@ static struct video_device saa7134_empress_template = ...@@ -320,6 +336,26 @@ static struct video_device saa7134_empress_template =
.minor = -1, .minor = -1,
}; };
static void empress_signal_update(void* data)
{
struct saa7134_dev* dev = (struct saa7134_dev*) data;
if (dev->nosignal) {
dprintk("no video signal\n");
ts_reset_encoder(dev);
} else {
dprintk("video signal acquired\n");
if (dev->empress_users)
ts_init_encoder(dev);
}
}
static void empress_signal_change(struct saa7134_dev *dev)
{
schedule_work(&dev->empress_workqueue);
}
static int empress_init(struct saa7134_dev *dev) static int empress_init(struct saa7134_dev *dev)
{ {
int err; int err;
...@@ -335,6 +371,8 @@ static int empress_init(struct saa7134_dev *dev) ...@@ -335,6 +371,8 @@ static int empress_init(struct saa7134_dev *dev)
"%s empress (%s)", dev->name, "%s empress (%s)", dev->name,
saa7134_boards[dev->board].name); saa7134_boards[dev->board].name);
INIT_WORK(&dev->empress_workqueue, empress_signal_update, (void*) dev);
err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER,
empress_nr[dev->nr]); empress_nr[dev->nr]);
if (err < 0) { if (err < 0) {
...@@ -353,6 +391,8 @@ static int empress_init(struct saa7134_dev *dev) ...@@ -353,6 +391,8 @@ static int empress_init(struct saa7134_dev *dev)
V4L2_FIELD_ALTERNATE, V4L2_FIELD_ALTERNATE,
sizeof(struct saa7134_buf), sizeof(struct saa7134_buf),
dev); dev);
empress_signal_update(dev);
return 0; return 0;
} }
...@@ -362,6 +402,7 @@ static int empress_fini(struct saa7134_dev *dev) ...@@ -362,6 +402,7 @@ static int empress_fini(struct saa7134_dev *dev)
if (NULL == dev->empress_dev) if (NULL == dev->empress_dev)
return 0; return 0;
flush_scheduled_work();
video_unregister_device(dev->empress_dev); video_unregister_device(dev->empress_dev);
dev->empress_dev = NULL; dev->empress_dev = NULL;
return 0; return 0;
...@@ -371,6 +412,7 @@ static struct saa7134_mpeg_ops empress_ops = { ...@@ -371,6 +412,7 @@ static struct saa7134_mpeg_ops empress_ops = {
.type = SAA7134_MPEG_EMPRESS, .type = SAA7134_MPEG_EMPRESS,
.init = empress_init, .init = empress_init,
.fini = empress_fini, .fini = empress_fini,
.signal_change = empress_signal_change,
}; };
static int __init empress_register(void) static int __init empress_register(void)
......
/* /*
* $Id: saa7134-i2c.c,v 1.7 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-i2c.c,v 1.10 2005/01/24 17:37:23 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* i2c interface support * i2c interface support
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -205,7 +206,8 @@ static inline int i2c_send_byte(struct saa7134_dev *dev, ...@@ -205,7 +206,8 @@ static inline int i2c_send_byte(struct saa7134_dev *dev,
dword &= 0x0f; dword &= 0x0f;
dword |= (attr << 6); dword |= (attr << 6);
dword |= ((__u32)data << 8); dword |= ((__u32)data << 8);
dword |= 0x00 << 16; dword |= 0x00 << 16; /* 100 kHz */
// dword |= 0x40 << 16; /* 400 kHz */
dword |= 0xf0 << 24; dword |= 0xf0 << 24;
saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword); saa_writel(SAA7134_I2C_ATTR_STATUS >> 2, dword);
#endif #endif
...@@ -248,13 +250,24 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -248,13 +250,24 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
if (!i2c_reset(dev)) if (!i2c_reset(dev))
return -EIO; return -EIO;
d2printk("start xfer\n");
d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name); d1printk(KERN_DEBUG "%s: i2c xfer:",dev->name);
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) { if (!(msgs[i].flags & I2C_M_NOSTART) || 0 == i) {
/* send address */ /* send address */
d2printk("send address\n");
addr = msgs[i].addr << 1; addr = msgs[i].addr << 1;
if (msgs[i].flags & I2C_M_RD) if (msgs[i].flags & I2C_M_RD)
addr |= 1; addr |= 1;
if (i > 0 && msgs[i].flags & I2C_M_RD) {
/* workaround for a saa7134 i2c bug
* needed to talk to the mt352 demux
* thanks to pinnacle for the hint */
int quirk = 0xfd;
d1printk(" [%02x quirk]",quirk);
i2c_send_byte(dev,START,quirk);
i2c_recv_byte(dev);
}
d1printk(" < %02x", addr); d1printk(" < %02x", addr);
rc = i2c_send_byte(dev,START,addr); rc = i2c_send_byte(dev,START,addr);
if (rc < 0) if (rc < 0)
...@@ -262,6 +275,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -262,6 +275,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
} }
if (msgs[i].flags & I2C_M_RD) { if (msgs[i].flags & I2C_M_RD) {
/* read bytes */ /* read bytes */
d2printk("read bytes\n");
for (byte = 0; byte < msgs[i].len; byte++) { for (byte = 0; byte < msgs[i].len; byte++) {
d1printk(" ="); d1printk(" =");
rc = i2c_recv_byte(dev); rc = i2c_recv_byte(dev);
...@@ -272,6 +286,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -272,6 +286,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
} }
} else { } else {
/* write bytes */ /* write bytes */
d2printk("write bytes\n");
for (byte = 0; byte < msgs[i].len; byte++) { for (byte = 0; byte < msgs[i].len; byte++) {
data = msgs[i].buf[byte]; data = msgs[i].buf[byte];
d1printk(" %02x", data); d1printk(" %02x", data);
...@@ -281,6 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap, ...@@ -281,6 +296,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
} }
} }
} }
d2printk("xfer done\n");
d1printk(" >"); d1printk(" >");
i2c_set_attr(dev,STOP); i2c_set_attr(dev,STOP);
rc = -EIO; rc = -EIO;
...@@ -313,18 +329,6 @@ static u32 functionality(struct i2c_adapter *adap) ...@@ -313,18 +329,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL; return I2C_FUNC_SMBUS_EMUL;
} }
#ifndef I2C_PEC
static void inc_use(struct i2c_adapter *adap)
{
MOD_INC_USE_COUNT;
}
static void dec_use(struct i2c_adapter *adap)
{
MOD_DEC_USE_COUNT;
}
#endif
static int attach_inform(struct i2c_client *client) static int attach_inform(struct i2c_client *client)
{ {
struct saa7134_dev *dev = client->adapter->algo_data; struct saa7134_dev *dev = client->adapter->algo_data;
...@@ -345,12 +349,7 @@ static struct i2c_algorithm saa7134_algo = { ...@@ -345,12 +349,7 @@ static struct i2c_algorithm saa7134_algo = {
}; };
static struct i2c_adapter saa7134_adap_template = { static struct i2c_adapter saa7134_adap_template = {
#ifdef I2C_PEC
.owner = THIS_MODULE, .owner = THIS_MODULE,
#else
.inc_use = inc_use,
.dec_use = dec_use,
#endif
#ifdef I2C_CLASS_TV_ANALOG #ifdef I2C_CLASS_TV_ANALOG
.class = I2C_CLASS_TV_ANALOG, .class = I2C_CLASS_TV_ANALOG,
#endif #endif
......
/* /*
* $Id: saa7134-input.c,v 1.12 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-input.c,v 1.16 2004/12/10 12:33:39 kraxel Exp $
* *
* handle saa7134 IR remotes via linux kernel input layer. * handle saa7134 IR remotes via linux kernel input layer.
* *
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -258,6 +259,55 @@ static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = { ...@@ -258,6 +259,55 @@ static IR_KEYTAB_TYPE md2819_codes[IR_KEYTAB_SIZE] = {
[ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE- [ 17 ] = KEY_CHANNELDOWN, // CHANNEL/PAGE-
[ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+ [ 49 ] = KEY_CHANNELUP // CHANNEL/PAGE+
}; };
static IR_KEYTAB_TYPE videomate_tv_pvr_codes[IR_KEYTAB_SIZE] = {
[ 20 ] = KEY_MUTE,
[ 36 ] = KEY_ZOOM,
[ 1 ] = KEY_DVD,
[ 35 ] = KEY_RADIO,
[ 0 ] = KEY_TV,
[ 10 ] = KEY_REWIND,
[ 8 ] = KEY_PLAYPAUSE,
[ 15 ] = KEY_FORWARD,
[ 2 ] = KEY_PREVIOUS,
[ 7 ] = KEY_STOP,
[ 6 ] = KEY_NEXT,
[ 12 ] = KEY_UP,
[ 14 ] = KEY_DOWN,
[ 11 ] = KEY_LEFT,
[ 13 ] = KEY_RIGHT,
[ 17 ] = KEY_OK,
[ 3 ] = KEY_MENU,
[ 9 ] = KEY_SETUP,
[ 5 ] = KEY_VIDEO,
[ 34 ] = KEY_CHANNEL,
[ 18 ] = KEY_VOLUMEUP,
[ 21 ] = KEY_VOLUMEDOWN,
[ 16 ] = KEY_CHANNELUP,
[ 19 ] = KEY_CHANNELDOWN,
[ 4 ] = KEY_RECORD,
[ 22 ] = KEY_KP1,
[ 23 ] = KEY_KP2,
[ 24 ] = KEY_KP3,
[ 25 ] = KEY_KP4,
[ 26 ] = KEY_KP5,
[ 27 ] = KEY_KP6,
[ 28 ] = KEY_KP7,
[ 29 ] = KEY_KP8,
[ 30 ] = KEY_KP9,
[ 31 ] = KEY_KP0,
[ 32 ] = KEY_LANGUAGE,
[ 33 ] = KEY_SLEEP,
};
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
static int build_key(struct saa7134_dev *dev) static int build_key(struct saa7134_dev *dev)
...@@ -335,6 +385,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -335,6 +385,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
break; break;
case SAA7134_BOARD_CINERGY400: case SAA7134_BOARD_CINERGY400:
case SAA7134_BOARD_CINERGY600: case SAA7134_BOARD_CINERGY600:
case SAA7134_BOARD_CINERGY600_MK3:
ir_codes = cinergy_codes; ir_codes = cinergy_codes;
mask_keycode = 0x00003f; mask_keycode = 0x00003f;
mask_keyup = 0x040000; mask_keyup = 0x040000;
...@@ -353,6 +404,7 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -353,6 +404,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
polling = 50; // ms polling = 50; // ms
break; break;
case SAA7134_BOARD_MD2819: case SAA7134_BOARD_MD2819:
case SAA7134_BOARD_AVERMEDIA_305:
case SAA7134_BOARD_AVERMEDIA_307: case SAA7134_BOARD_AVERMEDIA_307:
ir_codes = md2819_codes; ir_codes = md2819_codes;
mask_keycode = 0x0007C8; mask_keycode = 0x0007C8;
...@@ -362,6 +414,12 @@ int saa7134_input_init1(struct saa7134_dev *dev) ...@@ -362,6 +414,12 @@ int saa7134_input_init1(struct saa7134_dev *dev)
saa_setb(SAA7134_GPIO_GPMODE0, 0x4); saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4); saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
break; break;
case SAA7134_BOARD_VIDEOMATE_TV_PVR:
ir_codes = videomate_tv_pvr_codes;
mask_keycode = 0x00003F;
mask_keyup = 0x400000;
polling = 50; // ms
break;
} }
if (NULL == ir_codes) { if (NULL == ir_codes) {
printk("%s: Oops: IR config error [card=%d]\n", printk("%s: Oops: IR config error [card=%d]\n",
......
/* /*
* $Id: saa7134-oss.c,v 1.11 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-oss.c,v 1.13 2004/12/10 12:33:39 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* oss dsp interface * oss dsp interface
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/soundcard.h> #include <linux/soundcard.h>
...@@ -543,6 +544,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev) ...@@ -543,6 +544,7 @@ mixer_recsrc_7134(struct saa7134_dev *dev)
break; break;
case LINE1: case LINE1:
case LINE2: case LINE2:
case LINE2_LEFT:
analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08; analog_io = (LINE1 == dev->oss.input) ? 0x00 : 0x08;
rate = (32000 == dev->oss.rate) ? 0x01 : 0x03; rate = (32000 == dev->oss.rate) ? 0x01 : 0x03;
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io); saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, analog_io);
...@@ -566,6 +568,7 @@ mixer_recsrc_7133(struct saa7134_dev *dev) ...@@ -566,6 +568,7 @@ mixer_recsrc_7133(struct saa7134_dev *dev)
value = 0xbbbb32; /* AUX1 */ value = 0xbbbb32; /* AUX1 */
break; break;
case LINE2: case LINE2:
case LINE2_LEFT:
value = 0xbbbb54; /* AUX2 */ value = 0xbbbb54; /* AUX2 */
break; break;
} }
...@@ -608,6 +611,7 @@ mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level) ...@@ -608,6 +611,7 @@ mixer_level(struct saa7134_dev *dev, enum saa7134_audio_in src, int level)
(100 == level) ? 0x00 : 0x10); (100 == level) ? 0x00 : 0x10);
break; break;
case LINE2: case LINE2:
case LINE2_LEFT:
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20, saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x20,
(100 == level) ? 0x00 : 0x20); (100 == level) ? 0x00 : 0x20);
break; break;
......
/* /*
* $Id: saa7134-ts.c,v 1.12 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-ts.c,v 1.14 2005/02/03 10:24:33 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* video4linux video interface * video4linux video interface
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -220,10 +221,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status) ...@@ -220,10 +221,10 @@ void saa7134_irq_ts_done(struct saa7134_dev *dev, unsigned long status)
if (dev->ts_q.curr) { if (dev->ts_q.curr) {
field = dev->ts_q.curr->vb.field; field = dev->ts_q.curr->vb.field;
if (field == V4L2_FIELD_TOP) { if (field == V4L2_FIELD_TOP) {
if ((status & 0x100000) != 0x100000) if ((status & 0x100000) != 0x000000)
goto done; goto done;
} else { } else {
if ((status & 0x100000) != 0x000000) if ((status & 0x100000) != 0x100000)
goto done; goto done;
} }
saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE); saa7134_buffer_finish(dev,&dev->ts_q,STATE_DONE);
......
/* /*
* $Id: saa7134-tvaudio.c,v 1.17 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-tvaudio.c,v 1.22 2005/01/07 13:11:19 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* tv audio decoder (fm stereo, nicam, ...) * tv audio decoder (fm stereo, nicam, ...)
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -237,13 +238,14 @@ static void mute_input_7134(struct saa7134_dev *dev) ...@@ -237,13 +238,14 @@ static void mute_input_7134(struct saa7134_dev *dev)
if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device) if (PCI_DEVICE_ID_PHILIPS_SAA7134 == dev->pci->device)
/* 7134 mute */ /* 7134 mute */
saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xff : 0xbb); saa_writeb(SAA7134_AUDIO_MUTE_CTRL, mute ? 0xbf : 0xbb);
/* switch internal audio mux */ /* switch internal audio mux */
switch (in->amux) { switch (in->amux) {
case TV: ausel=0xc0; ics=0x00; ocs=0x02; break; case TV: ausel=0xc0; ics=0x00; ocs=0x02; break;
case LINE1: ausel=0x80; ics=0x00; ocs=0x00; break; case LINE1: ausel=0x80; ics=0x00; ocs=0x00; break;
case LINE2: ausel=0x80; ics=0x08; ocs=0x01; break; case LINE2: ausel=0x80; ics=0x08; ocs=0x01; break;
case LINE2_LEFT: ausel=0x80; ics=0x08; ocs=0x05; break;
} }
saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel); saa_andorb(SAA7134_AUDIO_FORMAT_CTRL, 0xc0, ausel);
saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics); saa_andorb(SAA7134_ANALOG_IO_SELECT, 0x08, ics);
...@@ -437,15 +439,16 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au ...@@ -437,15 +439,16 @@ static int tvaudio_getstereo(struct saa7134_dev *dev, struct saa7134_tvaudio *au
nicam = saa_readb(SAA7134_NICAM_STATUS); nicam = saa_readb(SAA7134_NICAM_STATUS);
dprintk("getstereo: nicam=0x%x\n",nicam); dprintk("getstereo: nicam=0x%x\n",nicam);
switch (nicam & 0x0b) { switch (nicam & 0x0b) {
case 0x08:
retval = V4L2_TUNER_SUB_MONO;
break;
case 0x09: case 0x09:
retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; retval = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
break; break;
case 0x0a: case 0x0a:
retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; retval = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
break; break;
case 0x08:
default:
retval = V4L2_TUNER_SUB_MONO;
break;
} }
break; break;
} }
...@@ -748,9 +751,16 @@ static int mute_input_7133(struct saa7134_dev *dev) ...@@ -748,9 +751,16 @@ static int mute_input_7133(struct saa7134_dev *dev)
int mask; int mask;
switch (dev->input->amux) { switch (dev->input->amux) {
case TV: reg = 0x02; break; case TV:
case LINE1: reg = 0x00; break; reg = 0x02;
case LINE2: reg = 0x01; break; break;
case LINE1:
reg = 0x00;
break;
case LINE2:
case LINE2_LEFT:
reg = 0x01;
break;
} }
if (dev->ctl_mute) if (dev->ctl_mute)
reg = 0x07; reg = 0x07;
...@@ -869,6 +879,21 @@ static int tvaudio_thread_ddep(void *data) ...@@ -869,6 +879,21 @@ static int tvaudio_thread_ddep(void *data)
/* ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ */
/* common stuff + external entry points */ /* common stuff + external entry points */
static void saa7134_enable_i2s(struct saa7134_dev *dev)
{
int i2s_format;
if (!card_is_empress(dev))
return;
i2s_format = (dev->input->amux == TV) ? 0x00 : 0x01;
/* enable I2S audio output for the mpeg encoder */
saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2s_format);
saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
}
int saa7134_tvaudio_rx2mode(u32 rx) int saa7134_tvaudio_rx2mode(u32 rx)
{ {
u32 mode; u32 mode;
...@@ -911,6 +936,7 @@ void saa7134_tvaudio_setinput(struct saa7134_dev *dev, ...@@ -911,6 +936,7 @@ void saa7134_tvaudio_setinput(struct saa7134_dev *dev,
mute_input_7133(dev); mute_input_7133(dev);
break; break;
} }
saa7134_enable_i2s(dev);
} }
void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level) void saa7134_tvaudio_setvolume(struct saa7134_dev *dev, int level)
...@@ -946,18 +972,6 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) ...@@ -946,18 +972,6 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
DECLARE_MUTEX_LOCKED(sem); DECLARE_MUTEX_LOCKED(sem);
int (*my_thread)(void *data) = NULL; int (*my_thread)(void *data) = NULL;
/* enable I2S audio output */
if (card_is_empress(dev)) {
int i2sform = (48000 == dev->oss.rate)
? 0x01 : 0x00;
/* enable I2S output */
saa_writeb(SAA7134_I2S_OUTPUT_SELECT, 0x80);
saa_writeb(SAA7134_I2S_OUTPUT_FORMAT, i2sform);
saa_writeb(SAA7134_I2S_OUTPUT_LEVEL, 0x0F);
saa_writeb(SAA7134_I2S_AUDIO_OUTPUT, 0x01);
}
switch (dev->pci->device) { switch (dev->pci->device) {
case PCI_DEVICE_ID_PHILIPS_SAA7134: case PCI_DEVICE_ID_PHILIPS_SAA7134:
my_thread = tvaudio_thread; my_thread = tvaudio_thread;
...@@ -977,9 +991,10 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev) ...@@ -977,9 +991,10 @@ int saa7134_tvaudio_init2(struct saa7134_dev *dev)
if (dev->thread.pid < 0) if (dev->thread.pid < 0)
printk(KERN_WARNING "%s: kernel_thread() failed\n", printk(KERN_WARNING "%s: kernel_thread() failed\n",
dev->name); dev->name);
wake_up_interruptible(&dev->thread.wq); saa7134_tvaudio_do_scan(dev);
} }
saa7134_enable_i2s(dev);
return 0; return 0;
} }
......
/* /*
* $Id: saa7134-vbi.c,v 1.5 2004/11/07 13:17:15 kraxel Exp $ * $Id: saa7134-vbi.c,v 1.6 2004/12/10 12:33:39 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* video4linux video interface * video4linux video interface
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
......
/* /*
* $Id: saa7134-video.c,v 1.19 2004/11/07 14:44:59 kraxel Exp $ * $Id: saa7134-video.c,v 1.28 2005/02/15 15:59:35 kraxel Exp $
* *
* device driver for philips saa7134 based TV cards * device driver for philips saa7134 based TV cards
* video4linux video interface * video4linux video interface
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -267,6 +268,24 @@ static struct saa7134_tvnorm tvnorms[] = { ...@@ -267,6 +268,24 @@ static struct saa7134_tvnorm tvnorms[] = {
.chroma_ctrl2 = 0x06, .chroma_ctrl2 = 0x06,
.vgate_misc = 0x1c, .vgate_misc = 0x1c,
},{
.name = "PAL-60",
.id = V4L2_STD_PAL_60,
.h_start = 0,
.h_stop = 719,
.video_v_start = 22,
.video_v_stop = 22+239,
.vbi_v_start = 10, /* FIXME */
.vbi_v_stop = 21, /* FIXME */
.src_timing = 1,
.sync_control = 0x18,
.luma_control = 0x40,
.chroma_ctrl1 = 0x81,
.chroma_gain = 0x2a,
.chroma_ctrl2 = 0x06,
.vgate_misc = 0x1c,
} }
}; };
#define TVNORMS ARRAY_SIZE(tvnorms) #define TVNORMS ARRAY_SIZE(tvnorms)
...@@ -443,11 +462,10 @@ void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits) ...@@ -443,11 +462,10 @@ void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
{ {
int luma_control,sync_control,mux,nosignal; int luma_control,sync_control,mux;
dprintk("set tv norm = %s\n",norm->name); dprintk("set tv norm = %s\n",norm->name);
dev->tvnorm = norm; dev->tvnorm = norm;
nosignal = (0 == (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03));
mux = card_in(dev,dev->ctl_input).vmux; mux = card_in(dev,dev->ctl_input).vmux;
luma_control = norm->luma_control; luma_control = norm->luma_control;
...@@ -455,7 +473,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm) ...@@ -455,7 +473,7 @@ static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
if (mux > 5) if (mux > 5)
luma_control |= 0x80; /* svideo */ luma_control |= 0x80; /* svideo */
if (noninterlaced || nosignal) if (noninterlaced || dev->nosignal)
sync_control |= 0x20; sync_control |= 0x20;
/* setup cropping */ /* setup cropping */
...@@ -1359,6 +1377,9 @@ static int video_release(struct inode *inode, struct file *file) ...@@ -1359,6 +1377,9 @@ static int video_release(struct inode *inode, struct file *file)
res_free(dev,fh,RESOURCE_VBI); res_free(dev,fh,RESOURCE_VBI);
} }
/* free stuff */
videobuf_mmap_free(&fh->cap);
videobuf_mmap_free(&fh->vbi);
saa7134_pgtable_free(dev->pci,&fh->pt_cap); saa7134_pgtable_free(dev->pci,&fh->pt_cap);
saa7134_pgtable_free(dev->pci,&fh->pt_vbi); saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
...@@ -1472,6 +1493,7 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh, ...@@ -1472,6 +1493,7 @@ static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
f->fmt.pix.width = maxw; f->fmt.pix.width = maxw;
if (f->fmt.pix.height > maxh) if (f->fmt.pix.height > maxh)
f->fmt.pix.height = maxh; f->fmt.pix.height = maxh;
f->fmt.pix.width &= ~0x03;
f->fmt.pix.bytesperline = f->fmt.pix.bytesperline =
(f->fmt.pix.width * fmt->depth) >> 3; (f->fmt.pix.width * fmt->depth) >> 3;
f->fmt.pix.sizeimage = f->fmt.pix.sizeimage =
...@@ -2267,7 +2289,7 @@ int saa7134_video_init1(struct saa7134_dev *dev) ...@@ -2267,7 +2289,7 @@ int saa7134_video_init1(struct saa7134_dev *dev)
dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value; dev->ctl_hue = ctrl_by_id(V4L2_CID_HUE)->default_value;
dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value; dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value; dev->ctl_volume = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
dev->ctl_mute = ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value; dev->ctl_mute = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value;
dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value; dev->ctl_invert = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value;
dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value; dev->ctl_automute = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value;
...@@ -2317,24 +2339,31 @@ int saa7134_video_fini(struct saa7134_dev *dev) ...@@ -2317,24 +2339,31 @@ int saa7134_video_fini(struct saa7134_dev *dev)
void saa7134_irq_video_intl(struct saa7134_dev *dev) void saa7134_irq_video_intl(struct saa7134_dev *dev)
{ {
static const char *st[] = { static const char *st[] = {
"no signal", "found NTSC", "found PAL", "found SECAM" }; "(no signal)", "NTSC", "PAL", "SECAM" };
int norm; u32 st1,st2;
norm = saa_readb(SAA7134_STATUS_VIDEO1) & 0x03; st1 = saa_readb(SAA7134_STATUS_VIDEO1);
dprintk("DCSDT: %s\n",st[norm]); st2 = saa_readb(SAA7134_STATUS_VIDEO2);
dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
if (0 != norm) { (st1 & 0x40) ? "not locked" : "locked",
/* wake up tvaudio audio carrier scan thread */ (st2 & 0x40) ? "no" : "yes",
saa7134_tvaudio_do_scan(dev); st[st1 & 0x03]);
if (!noninterlaced) dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
saa_clearb(SAA7134_SYNC_CTRL, 0x20);
} else { if (dev->nosignal) {
/* no video signal -> mute audio */ /* no video signal -> mute audio */
if (dev->ctl_automute) if (dev->ctl_automute)
dev->automute = 1; dev->automute = 1;
saa7134_tvaudio_setmute(dev); saa7134_tvaudio_setmute(dev);
saa_setb(SAA7134_SYNC_CTRL, 0x20); saa_setb(SAA7134_SYNC_CTRL, 0x20);
} else {
/* wake up tvaudio audio carrier scan thread */
saa7134_tvaudio_do_scan(dev);
if (!noninterlaced)
saa_clearb(SAA7134_SYNC_CTRL, 0x20);
} }
if (dev->mops && dev->mops->signal_change)
dev->mops->signal_change(dev);
} }
void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status) void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
......
/* /*
* $Id: saa7134.h,v 1.27 2004/11/04 11:03:52 kraxel Exp $ * $Id: saa7134.h,v 1.38 2005/03/07 12:01:51 kraxel Exp $
* *
* v4l2 device driver for philips saa7134 based TV cards * v4l2 device driver for philips saa7134 based TV cards
* *
...@@ -64,6 +64,7 @@ enum saa7134_audio_in { ...@@ -64,6 +64,7 @@ enum saa7134_audio_in {
TV = 1, TV = 1,
LINE1 = 2, LINE1 = 2,
LINE2 = 3, LINE2 = 3,
LINE2_LEFT,
}; };
enum saa7134_video_out { enum saa7134_video_out {
...@@ -156,11 +157,11 @@ struct saa7134_format { ...@@ -156,11 +157,11 @@ struct saa7134_format {
#define SAA7134_BOARD_AVACSSMARTTV 32 #define SAA7134_BOARD_AVACSSMARTTV 32
#define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33 #define SAA7134_BOARD_AVERMEDIA_DVD_EZMAKER 33
#define SAA7134_BOARD_NOVAC_PRIMETV7133 34 #define SAA7134_BOARD_NOVAC_PRIMETV7133 34
#define SAA7134_BOARD_AVERMEDIA_305 35 #define SAA7134_BOARD_AVERMEDIA_STUDIO_305 35
#define SAA7133_BOARD_UPMOST_PURPLE_TV 36 #define SAA7133_BOARD_UPMOST_PURPLE_TV 36
#define SAA7134_BOARD_ITEMS_MTV005 37 #define SAA7134_BOARD_ITEMS_MTV005 37
#define SAA7134_BOARD_CINERGY200 38 #define SAA7134_BOARD_CINERGY200 38
#define SAA7134_BOARD_FLYTVPLATINUM 39 #define SAA7134_BOARD_FLYTVPLATINUM_MINI 39
#define SAA7134_BOARD_VIDEOMATE_TV_PVR 40 #define SAA7134_BOARD_VIDEOMATE_TV_PVR 40
#define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS 41 #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUS 41
#define SAA7134_BOARD_SABRENT_SBTTVFM 42 #define SAA7134_BOARD_SABRENT_SBTTVFM 42
...@@ -169,6 +170,14 @@ struct saa7134_format { ...@@ -169,6 +170,14 @@ struct saa7134_format {
#define SAA7134_BOARD_AVERMEDIA_307 45 #define SAA7134_BOARD_AVERMEDIA_307 45
#define SAA7134_BOARD_AVERMEDIA_CARDBUS 46 #define SAA7134_BOARD_AVERMEDIA_CARDBUS 46
#define SAA7134_BOARD_CINERGY400_CARDBUS 47 #define SAA7134_BOARD_CINERGY400_CARDBUS 47
#define SAA7134_BOARD_CINERGY600_MK3 48
#define SAA7134_BOARD_VIDEOMATE_GOLD_PLUS 49
#define SAA7134_BOARD_PINNACLE_300I_DVBT_PAL 50
#define SAA7134_BOARD_PROVIDEO_PV952 51
#define SAA7134_BOARD_AVERMEDIA_305 52
#define SAA7135_BOARD_ASUSTeK_TVFM7135 53
#define SAA7134_BOARD_FLYTVPLATINUM_FM 54
#define SAA7134_BOARD_FLYDVBTDUO 55
#define SAA7134_MAXBOARDS 8 #define SAA7134_MAXBOARDS 8
#define SAA7134_INPUT_MAX 8 #define SAA7134_INPUT_MAX 8
...@@ -355,6 +364,7 @@ struct saa7134_mpeg_ops { ...@@ -355,6 +364,7 @@ struct saa7134_mpeg_ops {
struct list_head next; struct list_head next;
int (*init)(struct saa7134_dev *dev); int (*init)(struct saa7134_dev *dev);
int (*fini)(struct saa7134_dev *dev); int (*fini)(struct saa7134_dev *dev);
void (*signal_change)(struct saa7134_dev *dev);
}; };
/* global device status */ /* global device status */
...@@ -390,6 +400,7 @@ struct saa7134_dev { ...@@ -390,6 +400,7 @@ struct saa7134_dev {
unsigned int tuner_type; unsigned int tuner_type;
unsigned int tda9887_conf; unsigned int tda9887_conf;
unsigned int gpio_value; unsigned int gpio_value;
unsigned int irq2_mask;
/* i2c i/o */ /* i2c i/o */
struct i2c_adapter i2c_adap; struct i2c_adapter i2c_adap;
...@@ -437,6 +448,7 @@ struct saa7134_dev { ...@@ -437,6 +448,7 @@ struct saa7134_dev {
struct saa7134_input *hw_input; struct saa7134_input *hw_input;
unsigned int hw_mute; unsigned int hw_mute;
int last_carrier; int last_carrier;
int nosignal;
/* SAA7134_MPEG_* */ /* SAA7134_MPEG_* */
struct saa7134_ts ts; struct saa7134_ts ts;
...@@ -447,6 +459,8 @@ struct saa7134_dev { ...@@ -447,6 +459,8 @@ struct saa7134_dev {
struct video_device *empress_dev; struct video_device *empress_dev;
struct videobuf_queue empress_tsq; struct videobuf_queue empress_tsq;
unsigned int empress_users; unsigned int empress_users;
struct work_struct empress_workqueue;
int empress_started;
/* SAA7134_MPEG_DVB only */ /* SAA7134_MPEG_DVB only */
struct videobuf_dvb dvb; struct videobuf_dvb dvb;
...@@ -476,7 +490,6 @@ struct saa7134_dev { ...@@ -476,7 +490,6 @@ struct saa7134_dev {
/* saa7134-core.c */ /* saa7134-core.c */
extern struct list_head saa7134_devlist; extern struct list_head saa7134_devlist;
extern unsigned int saa7134_devcount;
void saa7134_print_ioctl(char *name, unsigned int cmd); void saa7134_print_ioctl(char *name, unsigned int cmd);
void saa7134_track_gpio(struct saa7134_dev *dev, char *msg); void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
......
...@@ -18,14 +18,14 @@ ...@@ -18,14 +18,14 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef _SAA6752HS_H #if 0 /* ndef _SAA6752HS_H */
#define _SAA6752HS_H #define _SAA6752HS_H
enum mpeg_bitrate_mode { enum mpeg_video_bitrate_mode {
MPEG_BITRATE_MODE_VBR = 0, /* Variable bitrate */ MPEG_VIDEO_BITRATE_MODE_VBR = 0, /* Variable bitrate */
MPEG_BITRATE_MODE_CBR = 1, /* Constant bitrate */ MPEG_VIDEO_BITRATE_MODE_CBR = 1, /* Constant bitrate */
MPEG_BITRATE_MODE_MAX MPEG_VIDEO_BITRATE_MODE_MAX
}; };
enum mpeg_audio_bitrate { enum mpeg_audio_bitrate {
...@@ -35,16 +35,33 @@ enum mpeg_audio_bitrate { ...@@ -35,16 +35,33 @@ enum mpeg_audio_bitrate {
MPEG_AUDIO_BITRATE_MAX MPEG_AUDIO_BITRATE_MAX
}; };
enum mpeg_video_format {
MPEG_VIDEO_FORMAT_D1 = 0,
MPEG_VIDEO_FORMAT_2_3_D1 = 1,
MPEG_VIDEO_FORMAT_1_2_D1 = 2,
MPEG_VIDEO_FORMAT_SIF = 3,
MPEG_VIDEO_FORMAT_MAX
};
#define MPEG_VIDEO_TARGET_BITRATE_MAX 27000 #define MPEG_VIDEO_TARGET_BITRATE_MAX 27000
#define MPEG_VIDEO_MAX_BITRATE_MAX 27000 #define MPEG_VIDEO_MAX_BITRATE_MAX 27000
#define MPEG_TOTAL_BITRATE_MAX 27000 #define MPEG_TOTAL_BITRATE_MAX 27000
#define MPEG_PID_MAX ((1 << 14) - 1)
struct mpeg_params { struct mpeg_params {
enum mpeg_bitrate_mode bitrate_mode; enum mpeg_video_bitrate_mode video_bitrate_mode;
unsigned int video_target_bitrate; unsigned int video_target_bitrate;
unsigned int video_max_bitrate; // only used for VBR unsigned int video_max_bitrate; // only used for VBR
enum mpeg_audio_bitrate audio_bitrate; enum mpeg_audio_bitrate audio_bitrate;
unsigned int total_bitrate; unsigned int total_bitrate;
unsigned int pmt_pid;
unsigned int video_pid;
unsigned int audio_pid;
unsigned int pcr_pid;
enum mpeg_video_format video_format;
}; };
#define MPEG_SETPARAMS _IOW('6',100,struct mpeg_params) #define MPEG_SETPARAMS _IOW('6',100,struct mpeg_params)
......
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