aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c1
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c8
-rw-r--r--drivers/media/dvb/mantis/mantis_ca.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_common.h1
-rw-r--r--drivers/media/dvb/mantis/mantis_evm.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_hif.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_ioc.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_pcmcia.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_uart.c1
-rw-r--r--drivers/media/dvb/mantis/mantis_vp1034.c1
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c1
-rw-r--r--drivers/media/radio/Kconfig4
-rw-r--r--drivers/media/radio/si4713-i2c.c4
-rw-r--r--drivers/media/rc/mceusb.c9
-rw-r--r--drivers/media/rc/nuvoton-cir.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c8
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c8
-rw-r--r--drivers/media/video/msp3400-driver.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c4
-rw-r--r--drivers/media/video/tuner-core.c241
-rw-r--r--drivers/media/video/v4l2-ioctl.c18
24 files changed, 186 insertions, 154 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 9e2148a..437912e 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -6,6 +6,7 @@
#ifndef __FLEXCOP_COMMON_H__
#define __FLEXCOP_COMMON_H__
+#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/mutex.h>
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index b2b0c45..55e6533 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 9827804..5b6b451 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1988,6 +1988,14 @@ static int dvb_frontend_open(struct inode *inode, struct file *file)
if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) {
if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0)
goto err0;
+
+ /* If we took control of the bus, we need to force
+ reinitialization. This is because many ts_bus_ctrl()
+ functions strobe the RESET pin on the demod, and if the
+ frontend thread already exists then the dvb_init() routine
+ won't get called (which is what usually does initial
+ register configuration). */
+ fepriv->reinitialise = 1;
}
if ((ret = dvb_generic_open (inode, file)) < 0)
diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c
index 330216f..3d70469 100644
--- a/drivers/media/dvb/mantis/mantis_ca.c
+++ b/drivers/media/dvb/mantis/mantis_ca.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
index bd400d2..49dbca1 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -21,6 +21,7 @@
#ifndef __MANTIS_COMMON_H
#define __MANTIS_COMMON_H
+#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c
index 9f73c2c..36f2256 100644
--- a/drivers/media/dvb/mantis/mantis_evm.c
+++ b/drivers/media/dvb/mantis/mantis_evm.c
@@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c
index 5772ebb..672cf4d 100644
--- a/drivers/media/dvb/mantis/mantis_hif.c
+++ b/drivers/media/dvb/mantis/mantis_hif.c
@@ -23,6 +23,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c
index 479086d..24fcdc6 100644
--- a/drivers/media/dvb/mantis/mantis_ioc.c
+++ b/drivers/media/dvb/mantis/mantis_ioc.c
@@ -24,6 +24,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c
index 5cb545b..2f188c0 100644
--- a/drivers/media/dvb/mantis/mantis_pcmcia.c
+++ b/drivers/media/dvb/mantis/mantis_pcmcia.c
@@ -23,6 +23,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c
index f807c8b..18340da 100644
--- a/drivers/media/dvb/mantis/mantis_uart.c
+++ b/drivers/media/dvb/mantis/mantis_uart.c
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
#include <linux/spinlock.h>
+#include <asm/io.h>
#include <linux/signal.h>
#include <linux/sched.h>
diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c
index 26bc0cb..430ae84 100644
--- a/drivers/media/dvb/mantis/mantis_vp1034.c
+++ b/drivers/media/dvb/mantis/mantis_vp1034.c
@@ -21,6 +21,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
+#include <asm/io.h>
#include "dmxdev.h"
#include "dvbdev.h"
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index 7cb79ec..80fb510 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index e4c97fd..52798a1 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -168,7 +168,7 @@ config RADIO_MAXIRADIO
config RADIO_MIROPCM20
tristate "miroSOUND PCM20 radio"
- depends on ISA && VIDEO_V4L2 && SND
+ depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND
select SND_ISA
select SND_MIRO
---help---
@@ -201,7 +201,7 @@ config RADIO_SF16FMI
config RADIO_SF16FMR2
tristate "SF16FMR2 Radio"
- depends on ISA && VIDEO_V4L2
+ depends on ISA && VIDEO_V4L2 && SND
---help---
Choose Y here if you have one of these FM radio cards.
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index deca2e0..c9f4a8e 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -1033,7 +1033,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
char ps_name[MAX_RDS_PS_NAME + 1];
len = control->size - 1;
- if (len > MAX_RDS_PS_NAME) {
+ if (len < 0 || len > MAX_RDS_PS_NAME) {
rval = -ERANGE;
goto exit;
}
@@ -1057,7 +1057,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
char radio_text[MAX_RDS_RADIO_TEXT + 1];
len = control->size - 1;
- if (len > MAX_RDS_RADIO_TEXT) {
+ if (len < 0 || len > MAX_RDS_RADIO_TEXT) {
rval = -ERANGE;
goto exit;
}
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 06dfe09..ec972dc 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -558,9 +558,10 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
inout, data1);
break;
case MCE_CMD_S_TIMEOUT:
- /* value is in units of 50us, so x*50/100 or x/2 ms */
+ /* value is in units of 50us, so x*50/1000 ms */
dev_info(dev, "%s receive timeout of %d ms\n",
- inout, ((data1 << 8) | data2) / 2);
+ inout,
+ ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000);
break;
case MCE_CMD_G_TIMEOUT:
dev_info(dev, "Get receive timeout\n");
@@ -847,7 +848,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index)
switch (ir->buf_in[index]) {
/* 2-byte return value commands */
case MCE_CMD_S_TIMEOUT:
- ir->rc->timeout = US_TO_NS((hi << 8 | lo) / 2);
+ ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT);
break;
/* 1-byte return value commands */
@@ -1078,7 +1079,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
rc->priv = ir;
rc->driver_type = RC_DRIVER_IR_RAW;
rc->allowed_protos = RC_TYPE_ALL;
- rc->timeout = US_TO_NS(1000);
+ rc->timeout = MS_TO_NS(100);
if (!ir->flags.no_tx) {
rc->s_tx_mask = mceusb_set_tx_mask;
rc->s_tx_carrier = mceusb_set_tx_carrier;
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c
index 565f24c..ce595f9 100644
--- a/drivers/media/rc/nuvoton-cir.c
+++ b/drivers/media/rc/nuvoton-cir.c
@@ -1110,7 +1110,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
rdev->dev.parent = &pdev->dev;
rdev->driver_name = NVT_DRIVER_NAME;
rdev->map_name = RC_MAP_RC6_MCE;
- rdev->timeout = US_TO_NS(1000);
+ rdev->timeout = MS_TO_NS(100);
/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
#if 0
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index a97cf27..834a483 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -3474,7 +3474,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- bttv_call_all(btv, tuner, g_tuner, t);
+ bttv_call_all(btv, tuner, s_tuner, t);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 1933d4d..e80134f 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -695,14 +695,10 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
cx18_call_all(cx, tuner, g_tuner, vt);
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
+ if (vt->type == V4L2_TUNER_RADIO)
strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_RADIO;
- } else {
+ else
strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_ANALOG_TV;
- }
-
return 0;
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 64d9b21..419777a 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -2060,12 +2060,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
goto fail_irq;
}
- if (!pci_enable_msi(pci_dev))
- err = request_irq(pci_dev->irq, cx23885_irq,
- IRQF_DISABLED, dev->name, dev);
- else
- err = request_irq(pci_dev->irq, cx23885_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+ err = request_irq(pci_dev->irq, cx23885_irq,
+ IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n",
dev->name, pci_dev->irq);
@@ -2114,7 +2110,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
- pci_disable_msi(pci_dev);
cx23885_dev_unregister(dev);
v4l2_device_unregister(v4l2_dev);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index f9e347d..120c7d8 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -1184,14 +1184,10 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
ivtv_call_all(itv, tuner, g_tuner, vt);
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+ if (vt->type == V4L2_TUNER_RADIO)
strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_RADIO;
- } else {
+ else
strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
- vt->type = V4L2_TUNER_ANALOG_TV;
- }
-
return 0;
}
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index de5d481..c43c81f 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -480,12 +480,14 @@ static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct msp_state *state = to_state(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (state->radio)
+ if (vt->type != V4L2_TUNER_ANALOG_TV)
return 0;
- if (state->opmode == OPMODE_AUTOSELECT)
- msp_detect_stereo(client);
- vt->audmode = state->audmode;
- vt->rxsubchans = state->rxsubchans;
+ if (!state->radio) {
+ if (state->opmode == OPMODE_AUTOSELECT)
+ msp_detect_stereo(client);
+ vt->rxsubchans = state->rxsubchans;
+ }
+ vt->audmode = state->audmode;
vt->capability |= V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 9d0dd08..e98d382 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -3046,6 +3046,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
struct v4l2_tuner vt;
memset(&vt, 0, sizeof(vt));
+ vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
vt.audmode = hdw->audiomode_val;
v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
}
@@ -5171,6 +5173,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
{
struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
memset(vtp, 0, sizeof(*vtp));
+ vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
hdw->tuner_signal_stale = 0;
/* Note: There apparently is no replacement for VIDIOC_CROPCAP
using v4l2-subdev - therefore we can't support that AT ALL right
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 9363ed9..a03945a 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -714,29 +714,34 @@ static int tuner_remove(struct i2c_client *client)
* returns 0.
* This function is needed for boards that have a separate tuner for
* radio (like devices with tea5767).
+ * NOTE: mt20xx uses V4L2_TUNER_DIGITAL_TV and calls set_tv_freq to
+ * select a TV frequency. So, t_mode = T_ANALOG_TV could actually
+ * be used to represent a Digital TV too.
*/
static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
{
- if ((1 << mode & t->mode_mask) == 0)
+ int t_mode;
+ if (mode == V4L2_TUNER_RADIO)
+ t_mode = T_RADIO;
+ else
+ t_mode = T_ANALOG_TV;
+
+ if ((t_mode & t->mode_mask) == 0)
return -EINVAL;
return 0;
}
/**
- * set_mode_freq - Switch tuner to other mode.
- * @client: struct i2c_client pointer
+ * set_mode - Switch tuner to other mode.
* @t: a pointer to the module's internal struct_tuner
* @mode: enum v4l2_type (radio or TV)
- * @freq: frequency to set (0 means to use the previous one)
*
* If tuner doesn't support the needed mode (radio or TV), prints a
* debug message and returns -EINVAL, changing its state to standby.
- * Otherwise, changes the state and sets frequency to the last value, if
- * the tuner can sleep or if it supports both Radio and TV.
+ * Otherwise, changes the mode and returns 0.
*/
-static int set_mode_freq(struct i2c_client *client, struct tuner *t,
- enum v4l2_tuner_type mode, unsigned int freq)
+static int set_mode(struct tuner *t, enum v4l2_tuner_type mode)
{
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
@@ -752,17 +757,27 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t,
t->mode = mode;
tuner_dbg("Changing to mode %d\n", mode);
}
+ return 0;
+}
+
+/**
+ * set_freq - Set the tuner to the desired frequency.
+ * @t: a pointer to the module's internal struct_tuner
+ * @freq: frequency to set (0 means to use the current frequency)
+ */
+static void set_freq(struct tuner *t, unsigned int freq)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
if (t->mode == V4L2_TUNER_RADIO) {
- if (freq)
- t->radio_freq = freq;
- set_radio_freq(client, t->radio_freq);
+ if (!freq)
+ freq = t->radio_freq;
+ set_radio_freq(client, freq);
} else {
- if (freq)
- t->tv_freq = freq;
- set_tv_freq(client, t->tv_freq);
+ if (!freq)
+ freq = t->tv_freq;
+ set_tv_freq(client, freq);
}
-
- return 0;
}
/*
@@ -817,7 +832,8 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
/**
* tuner_fixup_std - force a given video standard variant
*
- * @t: tuner internal struct
+ * @t: tuner internal struct
+ * @std: TV standard
*
* A few devices or drivers have problem to detect some standard variations.
* On other operational systems, the drivers generally have a per-country
@@ -827,57 +843,39 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq)
* to distinguish all video standard variations, a modprobe parameter can
* be used to force a video standard match.
*/
-static int tuner_fixup_std(struct tuner *t)
+static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std)
{
- if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
+ if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) {
switch (pal[0]) {
case '6':
- tuner_dbg("insmod fixup: PAL => PAL-60\n");
- t->std = V4L2_STD_PAL_60;
- break;
+ return V4L2_STD_PAL_60;
case 'b':
case 'B':
case 'g':
case 'G':
- tuner_dbg("insmod fixup: PAL => PAL-BG\n");
- t->std = V4L2_STD_PAL_BG;
- break;
+ return V4L2_STD_PAL_BG;
case 'i':
case 'I':
- tuner_dbg("insmod fixup: PAL => PAL-I\n");
- t->std = V4L2_STD_PAL_I;
- break;
+ return V4L2_STD_PAL_I;
case 'd':
case 'D':
case 'k':
case 'K':
- tuner_dbg("insmod fixup: PAL => PAL-DK\n");
- t->std = V4L2_STD_PAL_DK;
- break;
+ return V4L2_STD_PAL_DK;
case 'M':
case 'm':
- tuner_dbg("insmod fixup: PAL => PAL-M\n");
- t->std = V4L2_STD_PAL_M;
- break;
+ return V4L2_STD_PAL_M;
case 'N':
case 'n':
- if (pal[1] == 'c' || pal[1] == 'C') {
- tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
- t->std = V4L2_STD_PAL_Nc;
- } else {
- tuner_dbg("insmod fixup: PAL => PAL-N\n");
- t->std = V4L2_STD_PAL_N;
- }
- break;
- case '-':
- /* default parameter, do nothing */
- break;
+ if (pal[1] == 'c' || pal[1] == 'C')
+ return V4L2_STD_PAL_Nc;
+ return V4L2_STD_PAL_N;
default:
tuner_warn("pal= argument not recognised\n");
break;
}
}
- if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
+ if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
switch (secam[0]) {
case 'b':
case 'B':
@@ -885,63 +883,42 @@ static int tuner_fixup_std(struct tuner *t)
case 'G':
case 'h':
case 'H':
- tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
- t->std = V4L2_STD_SECAM_B |
- V4L2_STD_SECAM_G |
- V4L2_STD_SECAM_H;
- break;
+ return V4L2_STD_SECAM_B |
+ V4L2_STD_SECAM_G |
+ V4L2_STD_SECAM_H;
case 'd':
case 'D':
case 'k':
case 'K':
- tuner_dbg("insmod fixup: SECAM => SECAM-DK\n");
- t->std = V4L2_STD_SECAM_DK;
- break;
+ return V4L2_STD_SECAM_DK;
case 'l':
case 'L':
- if ((secam[1] == 'C') || (secam[1] == 'c')) {
- tuner_dbg("insmod fixup: SECAM => SECAM-L'\n");
- t->std = V4L2_STD_SECAM_LC;
- } else {
- tuner_dbg("insmod fixup: SECAM => SECAM-L\n");
- t->std = V4L2_STD_SECAM_L;
- }
- break;
- case '-':
- /* default parameter, do nothing */
- break;
+ if ((secam[1] == 'C') || (secam[1] == 'c'))
+ return V4L2_STD_SECAM_LC;
+ return V4L2_STD_SECAM_L;
default:
tuner_warn("secam= argument not recognised\n");
break;
}
}
- if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
+ if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
switch (ntsc[0]) {
case 'm':
case 'M':
- tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
- t->std = V4L2_STD_NTSC_M;
- break;
+ return V4L2_STD_NTSC_M;
case 'j':
case 'J':
- tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
- t->std = V4L2_STD_NTSC_M_JP;
- break;
+ return V4L2_STD_NTSC_M_JP;
case 'k':
case 'K':
- tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
- t->std = V4L2_STD_NTSC_M_KR;
- break;
- case '-':
- /* default parameter, do nothing */
- break;
+ return V4L2_STD_NTSC_M_KR;
default:
tuner_info("ntsc= argument not recognised\n");
break;
}
}
- return 0;
+ return std;
}
/*
@@ -1016,7 +993,7 @@ static void tuner_status(struct dvb_frontend *fe)
case V4L2_TUNER_RADIO:
p = "radio";
break;
- case V4L2_TUNER_DIGITAL_TV:
+ case V4L2_TUNER_DIGITAL_TV: /* Used by mt20xx */
p = "digital TV";
break;
case V4L2_TUNER_ANALOG_TV:
@@ -1058,10 +1035,9 @@ static void tuner_status(struct dvb_frontend *fe)
static int tuner_s_radio(struct v4l2_subdev *sd)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
- return 0;
+ if (set_mode(t, V4L2_TUNER_RADIO) == 0)
+ set_freq(t, 0);
return 0;
}
@@ -1072,16 +1048,20 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
/**
* tuner_s_power - controls the power state of the tuner
* @sd: pointer to struct v4l2_subdev
- * @on: a zero value puts the tuner to sleep
+ * @on: a zero value puts the tuner to sleep, non-zero wakes it up
*/
static int tuner_s_power(struct v4l2_subdev *sd, int on)
{
struct tuner *t = to_tuner(sd);
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
- /* FIXME: Why this function don't wake the tuner if on != 0 ? */
- if (on)
+ if (on) {
+ if (t->standby && set_mode(t, t->mode) == 0) {
+ tuner_dbg("Waking up tuner\n");
+ set_freq(t, 0);
+ }
return 0;
+ }
tuner_dbg("Putting tuner to sleep\n");
t->standby = true;
@@ -1093,28 +1073,36 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on)
static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
+ if (set_mode(t, V4L2_TUNER_ANALOG_TV))
return 0;
- t->std = std;
- tuner_fixup_std(t);
-
+ t->std = tuner_fixup_std(t, std);
+ if (t->std != std)
+ tuner_dbg("Fixup standard %llx to %llx\n", std, t->std);
+ set_freq(t, 0);
return 0;
}
static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
- return 0;
+ if (set_mode(t, f->type) == 0)
+ set_freq(t, f->frequency);
return 0;
}
+/**
+ * tuner_g_frequency - Get the tuned frequency for the tuner
+ * @sd: pointer to struct v4l2_subdev
+ * @f: pointer to struct v4l2_frequency
+ *
+ * At return, the structure f will be filled with tuner frequency
+ * if the tuner matches the f->type.
+ * Note: f->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
{
struct tuner *t = to_tuner(sd);
@@ -1122,8 +1110,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
if (check_mode(t, f->type) == -EINVAL)
return 0;
- f->type = t->mode;
- if (fe_tuner_ops->get_frequency && !t->standby) {
+ if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) {
u32 abs_freq;
fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
@@ -1131,12 +1118,22 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
DIV_ROUND_CLOSEST(abs_freq, 62500);
} else {
- f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
+ f->frequency = (V4L2_TUNER_RADIO == f->type) ?
t->radio_freq : t->tv_freq;
}
return 0;
}
+/**
+ * tuner_g_tuner - Fill in tuner information
+ * @sd: pointer to struct v4l2_subdev
+ * @vt: pointer to struct v4l2_tuner
+ *
+ * At return, the structure vt will be filled with tuner information
+ * if the tuner matches vt->type.
+ * Note: vt->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{
struct tuner *t = to_tuner(sd);
@@ -1145,48 +1142,57 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
if (check_mode(t, vt->type) == -EINVAL)
return 0;
- vt->type = t->mode;
- if (analog_ops->get_afc)
+ if (vt->type == t->mode && analog_ops->get_afc)
vt->afc = analog_ops->get_afc(&t->fe);
- if (t->mode == V4L2_TUNER_ANALOG_TV)
- vt->capability |= V4L2_TUNER_CAP_NORM;
if (t->mode != V4L2_TUNER_RADIO) {
+ vt->capability |= V4L2_TUNER_CAP_NORM;
vt->rangelow = tv_range[0] * 16;
vt->rangehigh = tv_range[1] * 16;
return 0;
}
/* radio mode */
- vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- vt->rxsubchans =
- (tuner_status & TUNER_STATUS_STEREO) ?
- V4L2_TUNER_SUB_STEREO :
- V4L2_TUNER_SUB_MONO;
+ if (vt->type == t->mode) {
+ vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ if (fe_tuner_ops->get_status) {
+ u32 tuner_status;
+
+ fe_tuner_ops->get_status(&t->fe, &tuner_status);
+ vt->rxsubchans =
+ (tuner_status & TUNER_STATUS_STEREO) ?
+ V4L2_TUNER_SUB_STEREO :
+ V4L2_TUNER_SUB_MONO;
+ }
+ if (analog_ops->has_signal)
+ vt->signal = analog_ops->has_signal(&t->fe);
+ vt->audmode = t->audmode;
}
- if (analog_ops->has_signal)
- vt->signal = analog_ops->has_signal(&t->fe);
vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- vt->audmode = t->audmode;
vt->rangelow = radio_range[0] * 16000;
vt->rangehigh = radio_range[1] * 16000;
return 0;
}
+/**
+ * tuner_s_tuner - Set the tuner's audio mode
+ * @sd: pointer to struct v4l2_subdev
+ * @vt: pointer to struct v4l2_tuner
+ *
+ * Sets the audio mode if the tuner matches vt->type.
+ * Note: vt->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{
struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
+ if (set_mode(t, vt->type))
return 0;
if (t->mode == V4L2_TUNER_RADIO)
t->audmode = vt->audmode;
+ set_freq(t, 0);
return 0;
}
@@ -1221,7 +1227,8 @@ static int tuner_resume(struct i2c_client *c)
tuner_dbg("resume\n");
if (!t->standby)
- set_mode_freq(c, t, t->type, 0);
+ if (set_mode(t, t->mode) == 0)
+ set_freq(t, 0);
return 0;
}
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 506edcc..69e8c6f 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -1822,6 +1822,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_tuner)
break;
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
ret = ops->vidioc_g_tuner(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1840,6 +1842,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_s_tuner)
break;
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
dbgarg(cmd, "index=%d, name=%s, type=%d, "
"capability=0x%x, rangelow=%d, "
"rangehigh=%d, signal=%d, afc=%d, "
@@ -1858,6 +1862,8 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_frequency)
break;
+ p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
ret = ops->vidioc_g_frequency(file, fh, p);
if (!ret)
dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1940,13 +1946,19 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_S_HW_FREQ_SEEK:
{
struct v4l2_hw_freq_seek *p = arg;
+ enum v4l2_tuner_type type;
if (!ops->vidioc_s_hw_freq_seek)
break;
+ type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+ V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
dbgarg(cmd,
- "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
- p->tuner, p->type, p->seek_upward, p->wrap_around);
- ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
+ "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
+ p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
+ if (p->type != type)
+ ret = -EINVAL;
+ else
+ ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
break;
}
case VIDIOC_ENUM_FRAMESIZES: