summaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c150
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c12
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c71
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c83
-rw-r--r--drivers/media/video/em28xx/em28xx.h10
5 files changed, 174 insertions, 152 deletions
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 0f48c0ff5ac3..7c70738479dd 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -31,6 +31,8 @@
#include <media/msp3400.h>
#include <media/saa7115.h>
#include <media/tvp5150.h>
+#include <media/tvaudio.h>
+#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -1240,6 +1242,7 @@ struct em28xx_board em28xx_boards[] = {
[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
.name = "Compro VideoMate ForYou/Stereo",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tvaudio_addr = 0xb0,
.tda9887_conf = TDA9887_PRESENT,
.decoder = EM28XX_TVP5150,
.adecoder = EM28XX_TVAUDIO,
@@ -1444,6 +1447,24 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
};
+/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
+static unsigned short saa711x_addrs[] = {
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
+ I2C_CLIENT_END };
+
+static unsigned short tvp5150_addrs[] = {
+ 0xb8 >> 1,
+ 0xba >> 1,
+ I2C_CLIENT_END
+};
+
+static unsigned short msp3400_addrs[] = {
+ 0x80 >> 1,
+ 0x88 >> 1,
+ I2C_CLIENT_END
+};
+
int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
{
int rc = 0;
@@ -1672,31 +1693,55 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
}
}
-static void em28xx_config_tuner(struct em28xx *dev)
+static void em28xx_tuner_setup(struct em28xx *dev)
{
- struct v4l2_priv_tun_config xc2028_cfg;
struct tuner_setup tun_setup;
struct v4l2_frequency f;
if (dev->tuner_type == TUNER_ABSENT)
return;
+ memset(&tun_setup, 0, sizeof(tun_setup));
+
tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
tun_setup.tuner_callback = em28xx_tuner_callback;
- em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ if (dev->board.radio.type) {
+ tun_setup.type = dev->board.radio.type;
+ tun_setup.addr = dev->board.radio_addr;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+ }
+
+ if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+ }
+
+ if (dev->tda9887_conf) {
+ struct v4l2_priv_tun_config tda9887_cfg;
+
+ tda9887_cfg.tuner = TUNER_TDA9887;
+ tda9887_cfg.priv = &dev->tda9887_conf;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
+ }
if (dev->tuner_type == TUNER_XC2028) {
+ struct v4l2_priv_tun_config xc2028_cfg;
struct xc2028_ctrl ctl;
+ memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
+ memset(&ctl, 0, sizeof(ctl));
+
em28xx_setup_xc3028(dev, &ctl);
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
- em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
}
/* configure tuner */
@@ -1704,7 +1749,7 @@ static void em28xx_config_tuner(struct em28xx *dev)
f.type = V4L2_TUNER_ANALOG_TV;
f.frequency = 9076; /* just a magic number */
dev->ctl_freq = f.frequency;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
}
static int em28xx_hint_board(struct em28xx *dev)
@@ -1911,22 +1956,52 @@ void em28xx_card_setup(struct em28xx *dev)
if (tuner >= 0)
dev->tuner_type = tuner;
-#ifdef CONFIG_MODULES
/* request some modules */
if (dev->board.has_msp34xx)
- request_module("msp3400");
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "msp3400", "msp3400", msp3400_addrs);
+
if (dev->board.decoder == EM28XX_SAA711X)
- request_module("saa7115");
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "saa7115", "saa7115_auto", saa711x_addrs);
+
if (dev->board.decoder == EM28XX_TVP5150)
- request_module("tvp5150");
- if (dev->board.tuner_type != TUNER_ABSENT)
- request_module("tuner");
- if (dev->board.adecoder == EM28XX_TVAUDIO)
- request_module("tvaudio");
-#endif
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tvp5150", "tvp5150", tvp5150_addrs);
- em28xx_config_tuner(dev);
+ if (dev->board.adecoder == EM28XX_TVAUDIO)
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tvaudio", "tvaudio", dev->board.tvaudio_addr);
+
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ if (dev->board.radio.type)
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tuner", "tuner", dev->board.radio_addr);
+
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == 0) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+ struct v4l2_subdev *sd;
+
+ sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev,
+ &dev->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(type));
+
+ if (sd)
+ dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
+ } else {
+ v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ }
+ }
+ em28xx_tuner_setup(dev);
em28xx_ir_init(dev);
}
@@ -1975,6 +2050,9 @@ void em28xx_release_resources(struct em28xx *dev)
em28xx_remove_from_devlist(dev);
em28xx_i2c_unregister(dev);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -1986,6 +2064,7 @@ void em28xx_release_resources(struct em28xx *dev)
* allocates and inits the device structs, registers i2c bus and v4l device
*/
static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
+ struct usb_interface *interface,
int minor)
{
struct em28xx *dev = *devhandle;
@@ -2019,9 +2098,16 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
}
+ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
+ if (retval < 0) {
+ em28xx_errdev("Call to v4l2_device_register() failed!\n");
+ return retval;
+ }
+
/* register i2c bus */
errCode = em28xx_i2c_register(dev);
if (errCode < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
__func__, errCode);
return errCode;
@@ -2033,6 +2119,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* Configure audio */
errCode = em28xx_audio_setup(dev);
if (errCode < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
__func__, errCode);
}
@@ -2077,7 +2164,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
em28xx_init_extension(dev);
/* Save some power by putting tuner to sleep */
- em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
return 0;
@@ -2096,7 +2183,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
struct usb_device *udev;
struct usb_interface *uif;
struct em28xx *dev = NULL;
- int retval = -ENODEV;
+ int retval;
int i, nr, ifnum, isoc_pipe;
char *speed;
char descr[255] = "";
@@ -2118,7 +2205,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
interface->altsetting[0].desc.bInterfaceClass);
em28xx_devused &= ~(1<<nr);
- return -ENODEV;
+ retval = -ENODEV;
+ goto err;
}
endpoint = &interface->cur_altsetting->endpoint[0].desc;
@@ -2151,7 +2239,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
"interface not used by the driver\n");
em28xx_devused &= ~(1<<nr);
- return -ENODEV;
+ retval = -ENODEV;
+ goto err;
}
}
@@ -2194,7 +2283,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
EM28XX_MAXBOARDS);
em28xx_devused &= ~(1<<nr);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
/* allocate memory for our device state and initialize it */
@@ -2202,7 +2292,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
if (dev == NULL) {
em28xx_err(DRIVER_NAME ": out of memory!\n");
em28xx_devused &= ~(1<<nr);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
snprintf(dev->name, 29, "em28xx #%d", nr);
@@ -2229,7 +2320,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
em28xx_errdev("out of memory!\n");
em28xx_devused &= ~(1<<nr);
kfree(dev);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
for (i = 0; i < dev->num_alt ; i++) {
@@ -2244,12 +2336,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
/* allocate device struct */
mutex_init(&dev->lock);
mutex_lock(&dev->lock);
- retval = em28xx_init_dev(&dev, udev, nr);
+ retval = em28xx_init_dev(&dev, udev, interface, nr);
if (retval) {
em28xx_devused &= ~(1<<dev->devno);
kfree(dev);
-
- return retval;
+ goto err;
}
/* save our data pointer in this interface device */
@@ -2263,6 +2354,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
mutex_unlock(&dev->lock);
return 0;
+
+err:
+ return retval;
}
/*
@@ -2288,6 +2382,8 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
wake_up_interruptible_all(&dev->open);
+ v4l2_device_disconnect(&dev->v4l2_dev);
+
if (dev->users) {
em28xx_warn
("device /dev/video%d is open! Deregistration and memory "
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 8f1999ca4803..192b76cdd5d7 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1018,14 +1018,10 @@ EXPORT_SYMBOL_GPL(em28xx_init_isoc);
*/
void em28xx_wake_i2c(struct em28xx *dev)
{
- struct v4l2_routing route;
- int zero = 0;
-
- route.input = INPUT(dev->ctl_input)->vmux;
- route.output = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
- em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+ INPUT(dev->ctl_input)->vmux, 0, 0);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
}
/*
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 02c12fe6361b..f0bf1d960c75 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -459,70 +459,15 @@ static u32 functionality(struct i2c_adapter *adap)
static int attach_inform(struct i2c_client *client)
{
struct em28xx *dev = client->adapter->algo_data;
+ struct IR_i2c *ir = i2c_get_clientdata(client);
switch (client->addr << 1) {
- case 0x86:
- case 0x84:
- case 0x96:
- case 0x94:
- {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- struct tuner_setup tun_setup;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = TUNER_TDA9887;
- tun_setup.addr = client->addr;
-
- em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR,
- &tun_setup);
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &dev->tda9887_conf;
- em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
- break;
- }
- case 0x42:
- dprintk1(1, "attach_inform: saa7114 detected.\n");
- break;
- case 0x4a:
- dprintk1(1, "attach_inform: saa7113 detected.\n");
- break;
- case 0xa0:
- dprintk1(1, "attach_inform: eeprom detected.\n");
- break;
case 0x60:
case 0x8e:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- dprintk1(1, "attach_inform: IR detected (%s).\n",
- ir->phys);
+ dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
em28xx_set_ir(dev, ir);
break;
}
- case 0x80:
- case 0x88:
- dprintk1(1, "attach_inform: msp34xx detected.\n");
- break;
- case 0xb8:
- case 0xba:
- dprintk1(1, "attach_inform: tvp5150 detected.\n");
- break;
-
- case 0xb0:
- dprintk1(1, "attach_inform: tda9874 detected\n");
- break;
-
- default:
- if (!dev->tuner_addr)
- dev->tuner_addr = client->addr;
-
- dprintk1(1, "attach inform: detected I2C address %x\n",
- client->addr << 1);
- dprintk1(1, "driver id %d\n", client->driver->id);
-
- }
return 0;
}
@@ -534,7 +479,6 @@ static struct i2c_algorithm em28xx_algo = {
static struct i2c_adapter em28xx_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
.name = "em28xx",
.id = I2C_HW_B_EM28XX,
.algo = &em28xx_algo,
@@ -595,16 +539,6 @@ void em28xx_do_i2c_scan(struct em28xx *dev)
}
/*
- * em28xx_i2c_call_clients()
- * send commands to all attached i2c devices
- */
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
-{
- BUG_ON(NULL == dev->i2c_adap.algo_data);
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-/*
* em28xx_i2c_register()
* register i2c bus
*/
@@ -618,6 +552,7 @@ int em28xx_i2c_register(struct em28xx *dev)
dev->i2c_adap.dev.parent = &dev->udev->dev;
strcpy(dev->i2c_adap.name, dev->name);
dev->i2c_adap.algo_data = dev;
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
retval = i2c_add_adapter(&dev->i2c_adap);
if (retval < 0) {
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 575472f1e702..882796e84dbc 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -49,7 +49,7 @@
"Sascha Sommer <saschasommer@freenet.de>"
#define DRIVER_DESC "Empia em28xx based USB video device driver"
-#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 1)
+#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 2)
#define em28xx_videodbg(fmt, arg...) do {\
if (video_debug) \
@@ -400,7 +400,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
f.frequency = dev->ctl_freq;
f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
return 0;
}
@@ -515,10 +515,6 @@ static struct videobuf_queue_ops em28xx_video_qops = {
static void video_mux(struct em28xx *dev, int index)
{
- struct v4l2_routing route;
-
- route.input = INPUT(index)->vmux;
- route.output = 0;
dev->ctl_input = index;
dev->ctl_ainput = INPUT(index)->amux;
dev->ctl_aoutput = INPUT(index)->aout;
@@ -526,25 +522,22 @@ static void video_mux(struct em28xx *dev, int index)
if (!dev->ctl_aoutput)
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
+ INPUT(index)->vmux, 0, 0);
if (dev->board.has_msp34xx) {
if (dev->i2s_speed) {
- em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
- &dev->i2s_speed);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
+ s_i2s_clock_freq, dev->i2s_speed);
}
- route.input = dev->ctl_ainput;
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
/* Note: this is msp3400 specific */
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
- &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+ dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0);
}
if (dev->board.adecoder != EM28XX_NOADECODER) {
- route.input = dev->ctl_ainput;
- route.output = dev->ctl_aoutput;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
- &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
+ dev->ctl_ainput, dev->ctl_aoutput, 0);
}
em28xx_audio_analog_set(dev);
@@ -829,7 +822,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
em28xx_resolution_set(dev);
- em28xx_i2c_call_clients(dev, VIDIOC_S_STD, &dev->norm);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
mutex_unlock(&dev->lock);
return 0;
@@ -995,8 +988,9 @@ static int vidioc_queryctrl(struct file *file, void *priv,
}
}
}
+
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_QUERYCTRL, qc);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
mutex_unlock(&dev->lock);
if (qc->type)
@@ -1020,11 +1014,11 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
mutex_lock(&dev->lock);
if (dev->board.has_msp34xx)
- em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
else {
rc = em28xx_get_ctrl(dev, ctrl);
if (rc < 0) {
- em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
rc = 0;
}
}
@@ -1048,7 +1042,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
mutex_lock(&dev->lock);
if (dev->board.has_msp34xx)
- em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
else {
rc = 1;
for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
@@ -1067,7 +1061,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
/* Control not found - try to send it to the attached devices */
if (rc == 1) {
- em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
rc = 0;
}
@@ -1092,10 +1086,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Tuner");
mutex_lock(&dev->lock);
-
- em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
-
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
mutex_unlock(&dev->lock);
+
return 0;
}
@@ -1114,10 +1107,9 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&dev->lock);
-
- em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
-
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
mutex_unlock(&dev->lock);
+
return 0;
}
@@ -1157,7 +1149,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
mutex_unlock(&dev->lock);
@@ -1186,7 +1178,7 @@ static int vidioc_g_chip_ident(struct file *file, void *priv,
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
return 0;
}
@@ -1211,7 +1203,7 @@ static int vidioc_g_register(struct file *file, void *priv,
reg->size = 1;
return 0;
case V4L2_CHIP_MATCH_I2C_DRIVER:
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
@@ -1263,7 +1255,7 @@ static int vidioc_s_register(struct file *file, void *priv,
return rc;
case V4L2_CHIP_MATCH_I2C_DRIVER:
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
@@ -1406,13 +1398,13 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
mutex_lock(&dev->lock);
f->fmt.sliced.service_set = 0;
-
- em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
if (f->fmt.sliced.service_set == 0)
rc = -EINVAL;
mutex_unlock(&dev->lock);
+
return rc;
}
@@ -1428,7 +1420,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
return rc;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
mutex_unlock(&dev->lock);
if (f->fmt.sliced.service_set == 0)
@@ -1532,7 +1524,7 @@ static int radio_g_tuner(struct file *file, void *priv,
t->type = V4L2_TUNER_RADIO;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
mutex_unlock(&dev->lock);
return 0;
@@ -1567,7 +1559,7 @@ static int radio_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
mutex_unlock(&dev->lock);
return 0;
@@ -1655,7 +1647,7 @@ static int em28xx_v4l2_open(struct file *filp)
}
if (fh->radio) {
em28xx_videodbg("video_open: setting radio device\n");
- em28xx_i2c_call_clients(dev, AUDC_SET_RADIO, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
}
dev->users++;
@@ -1738,7 +1730,7 @@ static int em28xx_v4l2_close(struct file *filp)
}
/* Save some power by putting tuner to sleep */
- em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
/* do this before setting alternate! */
em28xx_uninit_isoc(dev);
@@ -1959,11 +1951,12 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
vfd = video_device_alloc();
if (NULL == vfd)
return NULL;
- *vfd = *template;
- vfd->minor = -1;
- vfd->parent = &dev->udev->dev;
- vfd->release = video_device_release;
- vfd->debug = video_debug;
+
+ *vfd = *template;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->release = video_device_release;
+ vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
dev->name, type_name);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index a33a58da016e..4c4e58004f54 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -27,6 +27,7 @@
#include <linux/videodev2.h>
#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
@@ -385,6 +386,8 @@ struct em28xx_board {
unsigned int valid:1;
unsigned char xclk, i2c_speed;
+ unsigned char radio_addr;
+ unsigned short tvaudio_addr;
enum em28xx_decoder decoder;
enum em28xx_adecoder adecoder;
@@ -460,6 +463,7 @@ struct em28xx {
int devno; /* marks the number of this device */
enum em28xx_chip_id chip_id;
+ struct v4l2_device v4l2_dev;
struct em28xx_board board;
unsigned int stream_on:1; /* Locks streams */
@@ -577,11 +581,9 @@ struct em28xx_ops {
};
/* Provided by em28xx-i2c.c */
-
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
void em28xx_do_i2c_scan(struct em28xx *dev);
-int em28xx_i2c_register(struct em28xx *dev);
-int em28xx_i2c_unregister(struct em28xx *dev);
+int em28xx_i2c_register(struct em28xx *dev);
+int em28xx_i2c_unregister(struct em28xx *dev);
/* Provided by em28xx-core.c */