summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/saa7134
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/saa7134')
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-alsa.c6
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c109
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-core.c84
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-empress.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-video.c16
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h25
6 files changed, 141 insertions, 101 deletions
diff --git a/linux/drivers/media/video/saa7134/saa7134-alsa.c b/linux/drivers/media/video/saa7134/saa7134-alsa.c
index 5182d958c..eaa03fc07 100644
--- a/linux/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/linux/drivers/media/video/saa7134/saa7134-alsa.c
@@ -1094,7 +1094,11 @@ static int saa7134_alsa_init(void)
list_for_each(list,&saa7134_devlist) {
dev = list_entry(list, struct saa7134_dev, devlist);
- alsa_device_init(dev);
+ if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
+ printk(KERN_INFO "%s/alsa: %s doesn't support digital audio\n",
+ dev->name, saa7134_boards[dev->board].name);
+ else
+ alsa_device_init(dev);
}
if (dev == NULL)
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index 7740c1601..01cc9543f 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -6270,9 +6270,20 @@ int saa7134_board_init2(struct saa7134_dev *dev)
unsigned char buf;
int board;
+ /* Put here the code that enables the chips that are needed
+ for analog mode and doesn't depend on the tuner attachment.
+ It is also a good idea to get tuner type from eeprom, etc before
+ initializing tuner, since we can avoid loading tuner driver
+ on devices that has TUNER_ABSENT
+ */
switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER:
+ /* Checks if the device has a tuner at 0x60 addr
+ If the device doesn't have a tuner, TUNER_ABSENT
+ will be used at tuner_type, avoiding loading tuner
+ without needing it
+ */
dev->i2c_client.addr = 0x60;
board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
? SAA7134_BOARD_BMK_MPEX_NOTUNER
@@ -6290,11 +6301,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
u8 subaddr;
u8 data[3];
int ret, tuner_t;
-
struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+
subaddr= 0x14;
tuner_t = 0;
+
+ /* Retrieve device data from eeprom, checking for the
+ proper tuner_type.
+ */
ret = i2c_transfer(&dev->i2c_adap, msg, 2);
if (ret != 2) {
printk(KERN_ERR "EEPROM read failure\n");
@@ -6350,12 +6365,14 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name);
break;
}
+ /* break intentionally omitted */
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
{
- /* The Philips EUROPA based hybrid boards have the tuner connected through
- * the channel decoder. We have to make it transparent to find it
+ /* The Philips EUROPA based hybrid boards have the tuner
+ connected through the channel decoder. We have to make it
+ transparent to find it
*/
u8 data[] = { 0x07, 0x02};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
@@ -6376,21 +6393,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
dev->tuner_type = TUNER_PHILIPS_TDA8290;
- saa7134_tuner_setup(dev);
-
data[2] = 0x68;
i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- /* Tuner setup is handled before I2C transfer.
- Due to that, there's no need to do it later
- */
- return 0;
+ break;
}
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ASUSTeK_TVFM7135:
- /* The card below is detected as card=53, but is different */
+ case SAA7134_BOARD_ASUSTeK_TVFM7135:
+ /* The card below is detected as card=53, but is different */
if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
printk(KERN_INFO "%s: P7131 analog only, using "
@@ -6453,22 +6464,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
- case SAA7134_BOARD_KWORLD_ATSC110:
- {
- /* enable tuner */
- int i;
- static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
- 0x00, 0x14, 0x04, 0x17, 0x00 };
- dev->i2c_client.addr = 0x0a;
- for (i = 0; i < 5; i++)
- if (2 != i2c_master_send(&dev->i2c_client,
- &buffer[i*2], 2))
- printk(KERN_WARNING
- "%s: Unable to enable tuner(%i).\n",
- dev->name, i);
- break;
- }
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
/* The T200 and the T200A share the same pci id. Consequently,
@@ -6477,9 +6472,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
/* Don't do this if the board was specifically selected with an
* insmod option or if we have the default configuration T200*/
- if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
+ if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
break;
- if(dev->eedata[0x41] == 0x02) {
+ if (dev->eedata[0x41] == 0x02) {
/* Reconfigure board as T200A */
dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
@@ -6492,6 +6487,58 @@ int saa7134_board_init2(struct saa7134_dev *dev)
break;
}
break;
+ case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
+ case SAA7134_BOARD_KWORLD_ATSC110:
+ {
+ struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
+ int i;
+ static u8 buffer[][2] = {
+ { 0x10, 0x12 },
+ { 0x13, 0x04 },
+ { 0x16, 0x00 },
+ { 0x14, 0x04 },
+ { 0x17, 0x00 },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+ msg.buf = &buffer[i][0];
+ msg.len = ARRAY_SIZE(buffer[0]);
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ printk(KERN_WARNING
+ "%s: Unable to enable tuner(%i).\n",
+ dev->name, i);
+ }
+ break;
+ }
+ } /* switch() */
+
+ /* initialize tuner */
+ if (TUNER_ABSENT != dev->tuner_type) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ /* Note: radio tuner address is always filled in,
+ so we do not need to probe for a radio tuner device. */
+ if (dev->radio_type != UNSET)
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->radio_addr);
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == ADDR_UNSET) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+ } else {
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ }
+ }
+
+ saa7134_tuner_setup(dev);
+
+ switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
{
struct v4l2_priv_tun_config tea5767_cfg;
@@ -6508,7 +6555,5 @@ int saa7134_board_init2(struct saa7134_dev *dev)
}
} /* switch() */
- saa7134_tuner_setup(dev);
-
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c
index 1ba80210e..d499064ee 100644
--- a/linux/drivers/media/video/saa7134/saa7134-core.c
+++ b/linux/drivers/media/video/saa7134/saa7134-core.c
@@ -54,13 +54,9 @@ static unsigned int gpio_tracking;
module_param(gpio_tracking, int, 0644);
MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-static unsigned int alsa;
+static unsigned int alsa = 1;
module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
-
-static unsigned int oss;
-module_param(oss, int, 0644);
-MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
+MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]");
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
@@ -90,8 +86,10 @@ MODULE_PARM_DESC(radio_nr, "radio device number");
MODULE_PARM_DESC(tuner, "tuner type");
MODULE_PARM_DESC(card, "card type");
-static DEFINE_MUTEX(devlist_lock);
+DEFINE_MUTEX(saa7134_devlist_lock);
+EXPORT_SYMBOL(saa7134_devlist_lock);
LIST_HEAD(saa7134_devlist);
+EXPORT_SYMBOL(saa7134_devlist);
static LIST_HEAD(mops_list);
static unsigned int saa7134_devcount;
@@ -201,10 +199,10 @@ static void request_module_async(struct work_struct *work){
request_module("saa7134-empress");
if (card_is_dvb(dev))
request_module("saa7134-dvb");
- if (alsa)
- request_module("saa7134-alsa");
- if (oss)
- request_module("saa7134-oss");
+ if (alsa) {
+ if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
+ request_module("saa7134-alsa");
+ }
}
static void request_submodules(struct saa7134_dev *dev)
@@ -1038,30 +1036,6 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* wait a bit, register i2c bus */
msleep(100);
saa7134_i2c_register(dev);
-
- /* initialize hardware #2 */
- if (TUNER_ABSENT != dev->tuner_type) {
- int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
-
- /* Note: radio tuner address is always filled in,
- so we do not need to probe for a radio tuner device. */
- if (dev->radio_type != UNSET)
- v4l2_i2c_new_subdev(&dev->i2c_adap,
- "tuner", "tuner", dev->radio_addr);
- if (has_demod)
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
- if (dev->tuner_addr == ADDR_UNSET) {
- enum v4l2_i2c_tuner_type type =
- has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
-
- v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
- "tuner", v4l2_i2c_tuner_addrs(type));
- } else {
- v4l2_i2c_new_subdev(&dev->i2c_adap,
- "tuner", "tuner", dev->tuner_addr);
- }
- }
saa7134_board_init2(dev);
saa7134_hwinit2(dev);
@@ -1080,6 +1054,18 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
v4l2_prio_init(&dev->prio);
+ mutex_lock(&saa7134_devlist_lock);
+ list_for_each_entry(mops, &mops_list, next)
+ mpeg_ops_attach(mops, dev);
+ list_add_tail(&dev->devlist, &saa7134_devlist);
+ mutex_unlock(&saa7134_devlist_lock);
+
+ /* check for signal */
+ saa7134_irq_video_signalchange(dev);
+
+ if (TUNER_ABSENT != dev->tuner_type)
+ saa_call_all(dev, core, s_standby, 0);
+
/* register v4l devices */
if (saa7134_no_overlay > 0)
printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
@@ -1117,21 +1103,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* everything worked */
saa7134_devcount++;
- mutex_lock(&devlist_lock);
- list_for_each_entry(mops, &mops_list, next)
- mpeg_ops_attach(mops, dev);
- list_add_tail(&dev->devlist,&saa7134_devlist);
- mutex_unlock(&devlist_lock);
-
- /* check for signal */
- saa7134_irq_video_signalchange(dev);
-
- if (saa7134_dmasound_init && !dev->dmasound.priv_data) {
+ if (saa7134_dmasound_init && !dev->dmasound.priv_data)
saa7134_dmasound_init(dev);
- }
-
- if (TUNER_ABSENT != dev->tuner_type)
- saa_call_all(dev, core, s_standby, 0);
return 0;
@@ -1182,11 +1155,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
saa7134_hwfini(dev);
/* unregister */
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&dev->devlist);
list_for_each_entry(mops, &mops_list, next)
mpeg_ops_detach(mops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
saa7134_devcount--;
saa7134_i2c_unregister(dev);
@@ -1349,11 +1322,11 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_attach(ops, dev);
list_add_tail(&ops->next,&mops_list);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
return 0;
}
@@ -1361,11 +1334,11 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&ops->next);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_detach(ops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
}
EXPORT_SYMBOL(saa7134_ts_register);
@@ -1409,7 +1382,6 @@ module_exit(saa7134_fini);
/* ----------------------------------------------------------- */
EXPORT_SYMBOL(saa7134_set_gpio);
-EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
/* ----------------- for the DMA sound modules --------------- */
diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c
index 3b0b42545..813f5f88d 100644
--- a/linux/drivers/media/video/saa7134/saa7134-empress.c
+++ b/linux/drivers/media/video/saa7134/saa7134-empress.c
@@ -352,6 +352,7 @@ static int empress_s_ctrl(struct file *file, void *priv,
static int empress_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
+ /* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -364,6 +365,7 @@ static int empress_queryctrl(struct file *file, void *priv,
0
};
+ /* Must be sorted from low to high control ID! */
static const u32 mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c
index 2180527b3..be7f98bc0 100644
--- a/linux/drivers/media/video/saa7134/saa7134-video.c
+++ b/linux/drivers/media/video/saa7134/saa7134-video.c
@@ -452,6 +452,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset odd field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -459,6 +460,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset even field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -1333,7 +1335,7 @@ static int video_open(struct file *file)
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int radio = 0;
- lock_kernel();
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist) {
if (dev->video_dev && (dev->video_dev->minor == minor))
goto found;
@@ -1346,19 +1348,20 @@ static int video_open(struct file *file)
goto found;
}
}
- unlock_kernel();
+ mutex_unlock(&saa7134_devlist_lock);
return -ENODEV;
- found:
+
+found:
+ mutex_unlock(&saa7134_devlist_lock);
dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh) {
- unlock_kernel();
+ if (NULL == fh)
return -ENOMEM;
- }
+
file->private_data = fh;
fh->dev = dev;
fh->radio = radio;
@@ -1391,7 +1394,6 @@ static int video_open(struct file *file)
/* switch to video/vbi mode */
video_mux(dev,dev->ctl_input);
}
- unlock_kernel();
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index 9e3b37c73..c9d4d4354 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -447,7 +447,6 @@ struct saa7134_dmasound {
unsigned int bufsize;
struct saa7134_pgtable pt;
struct videobuf_dmabuf dma;
- wait_queue_head_t wq;
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
@@ -594,6 +593,7 @@ struct saa7134_dev {
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
#endif
+ void (*gate_ctrl)(struct saa7134_dev *dev, int open);
};
/* ----------------------------------------------------------- */
@@ -623,15 +623,30 @@ struct saa7134_dev {
V4L2_STD_PAL_60)
#define GRP_EMPRESS (1)
-#define saa_call_all(dev, o, f, args...) \
- v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args)
-#define saa_call_empress(dev, o, f, args...) \
- v4l2_device_call_until_err(&(dev)->v4l2_dev, GRP_EMPRESS, o, f , ##args)
+#define saa_call_all(dev, o, f, args...) do { \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+} while (0)
+
+#define saa_call_empress(dev, o, f, args...) ({ \
+ long _rc; \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \
+ GRP_EMPRESS, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+ _rc; \
+})
/* ----------------------------------------------------------- */
/* saa7134-core.c */
extern struct list_head saa7134_devlist;
+extern struct mutex saa7134_devlist_lock;
extern int saa7134_no_overlay;
void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);