From: "Frank Schäfer" <fschaefer.oss@googlemail.com>
To: Mauro Carvalho Chehab <m.chehab@samsung.com>
Cc: unlisted-recipients:; Linux Media Mailing List
<linux-media@vger.kernel.org>,
Mauro Carvalho Chehab <mchehab@infradead.org>
Subject: Re: [RFC PATCHv2] em28xx: split analog part into a separate module
Date: Thu, 26 Dec 2013 12:55:06 +0100 [thread overview]
Message-ID: <52BC191A.8070405@googlemail.com> (raw)
In-Reply-To: <1387716427-582-1-git-send-email-m.chehab@samsung.com>
Hi Mauro,
Am 22.12.2013 13:47, schrieb Mauro Carvalho Chehab:
> Now that dvb-only devices start to happen, it makes sense
> to split the analog part on a separate module.
>
> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
>
> -
>
> This is a respin of https://patchwork.linuxtv.org/patch/17967/
>
> v2: add a dev->has_video to signalize if the device has a video interface, and
> fix some locks
>
> Compile-tested only.
>
> ---
> drivers/media/usb/em28xx/Kconfig | 6 +-
> drivers/media/usb/em28xx/Makefile | 5 +-
> drivers/media/usb/em28xx/em28xx-cards.c | 94 ++--------------------
> drivers/media/usb/em28xx/em28xx-core.c | 12 +++
> drivers/media/usb/em28xx/em28xx-video.c | 133 ++++++++++++++++++++++++++++----
> drivers/media/usb/em28xx/em28xx.h | 17 ++--
> 6 files changed, 150 insertions(+), 117 deletions(-)
>
> diff --git a/drivers/media/usb/em28xx/Kconfig b/drivers/media/usb/em28xx/Kconfig
> index d6ba514d31eb..838fc9dbb747 100644
> --- a/drivers/media/usb/em28xx/Kconfig
> +++ b/drivers/media/usb/em28xx/Kconfig
> @@ -1,8 +1,12 @@
> config VIDEO_EM28XX
> - tristate "Empia EM28xx USB video capture support"
> + tristate "Empia EM28xx USB devices support"
> depends on VIDEO_DEV && I2C
> select VIDEO_TUNER
> select VIDEO_TVEEPROM
> +
> +config VIDEO_EM28XX_V4L2
> + tristate "Empia EM28xx analog TV, video capture and/or webcam support"
> + depends on VIDEO_EM28XX && I2C
VIDEO_EM28XX already depends on I2C.
> select VIDEOBUF2_VMALLOC
> select VIDEO_SAA711X if MEDIA_SUBDRV_AUTOSELECT
> select VIDEO_TVP5150 if MEDIA_SUBDRV_AUTOSELECT
> diff --git a/drivers/media/usb/em28xx/Makefile b/drivers/media/usb/em28xx/Makefile
> index ad6d48557940..3e2b6b54817d 100644
> --- a/drivers/media/usb/em28xx/Makefile
> +++ b/drivers/media/usb/em28xx/Makefile
> @@ -1,10 +1,11 @@
> -em28xx-y += em28xx-video.o em28xx-i2c.o em28xx-cards.o
> -em28xx-y += em28xx-core.o em28xx-vbi.o em28xx-camera.o
> +em28xx-y += em28xx-core.o em28xx-i2c.o em28xx-cards.o
>
> +em28xx-v4l-objs := em28xx-video.o em28xx-vbi.o em28xx-camera.o
> em28xx-alsa-objs := em28xx-audio.o
> em28xx-rc-objs := em28xx-input.o
>
> obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o
> +obj-$(CONFIG_VIDEO_EM28XX_V4L2) += em28xx-v4l.o
> obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o
> obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o
> obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o
> diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c
> index 36853f16bf97..e1ffd9c6e79d 100644
> --- a/drivers/media/usb/em28xx/em28xx-cards.c
> +++ b/drivers/media/usb/em28xx/em28xx-cards.c
> @@ -2106,7 +2106,7 @@ struct em28xx_board em28xx_boards[] = {
> },
> /* 1b80:e1cc Delock 61959
> * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2
> - * mostly the same as MaxMedia UB-425-TC but different remote */
> + * mostly the same as MaxMedia UB-425-TC but different remote */
> [EM2874_BOARD_DELOCK_61959] = {
> .name = "Delock 61959",
> .tuner_type = TUNER_ABSENT,
> @@ -2955,11 +2955,12 @@ static void request_module_async(struct work_struct *work)
> em28xx_init_extension(dev);
>
> #if defined(CONFIG_MODULES) && defined(MODULE)
> + if (!dev->has_video)
> + request_module("em28xx-v4l2");
if (dev->has_video)
What about audio devices ?
> if (dev->has_audio_class)
> request_module("snd-usb-audio");
> else if (dev->has_alsa_audio)
> request_module("em28xx-alsa");
> -
> if (dev->board.has_dvb)
> request_module("em28xx-dvb");
> if (dev->board.buttons ||
> @@ -2988,8 +2989,6 @@ void em28xx_release_resources(struct em28xx *dev)
> {
> /*FIXME: I2C IR should be disconnected */
>
> - em28xx_release_analog_resources(dev);
> -
> if (dev->def_i2c_bus)
> em28xx_i2c_unregister(dev, 1);
> em28xx_i2c_unregister(dev, 0);
> @@ -3014,7 +3013,6 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
> struct usb_interface *interface,
> int minor)
> {
> - struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
> int retval;
> static const char *default_chip_name = "em28xx";
> const char *chip_name = default_chip_name;
> @@ -3141,15 +3139,6 @@ static int em28xx_init_dev(struct em28xx *dev, 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;
> - }
> -
> - v4l2_ctrl_handler_init(hdl, 8);
> - dev->v4l2_dev.ctrl_handler = hdl;
> -
> rt_mutex_init(&dev->i2c_bus_lock);
>
> /* register i2c bus 0 */
> @@ -3178,75 +3167,11 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev,
> }
> }
>
> - /*
> - * Default format, used for tvp5150 or saa711x output formats
> - */
> - dev->vinmode = 0x10;
> - dev->vinctl = EM28XX_VINCTRL_INTERLACED |
> - EM28XX_VINCTRL_CCIR656_ENABLE;
> -
> /* Do board specific init and eeprom reading */
> em28xx_card_setup(dev);
>
> - /* Configure audio */
> - retval = em28xx_audio_setup(dev);
> - if (retval < 0) {
> - em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
> - __func__, retval);
> - goto fail;
> - }
> - if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
> - v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
> - V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
> - v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
> - V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
> - } else {
> - /* install the em28xx notify callback */
> - v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
> - em28xx_ctrl_notify, dev);
> - v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
> - em28xx_ctrl_notify, dev);
> - }
> -
> - /* wake i2c devices */
> - em28xx_wake_i2c(dev);
> -
> - /* init video dma queues */
> - INIT_LIST_HEAD(&dev->vidq.active);
> - INIT_LIST_HEAD(&dev->vbiq.active);
> -
> - if (dev->board.has_msp34xx) {
> - /* Send a reset to other chips via gpio */
> - retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
> - if (retval < 0) {
> - em28xx_errdev("%s: em28xx_write_reg - "
> - "msp34xx(1) failed! error [%d]\n",
> - __func__, retval);
> - goto fail;
> - }
> - msleep(3);
> -
> - retval = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
> - if (retval < 0) {
> - em28xx_errdev("%s: em28xx_write_reg - "
> - "msp34xx(2) failed! error [%d]\n",
> - __func__, retval);
> - goto fail;
> - }
> - msleep(3);
> - }
> -
> - retval = em28xx_register_analog_devices(dev);
> - if (retval < 0) {
> - goto fail;
> - }
> -
> - /* Save some power by putting tuner to sleep */
> - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
> -
> return 0;
Now the following code is unrechable...
> -fail:
> if (dev->def_i2c_bus)
> em28xx_i2c_unregister(dev, 1);
> em28xx_i2c_unregister(dev, 0);
... up to the "unregister_dev" label.
Either keep the "fail" label and check the success of
em28xx_card_setup() or remove this dead code.
> @@ -3458,6 +3383,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
> dev->alt = -1;
> dev->is_audio_only = has_audio && !(has_video || has_dvb);
> dev->has_alsa_audio = has_audio;
> + dev->has_video = has_video;
> dev->audio_ifnum = ifnum;
>
> /* Checks if audio is provided by some interface */
> @@ -3495,15 +3421,11 @@ static int em28xx_usb_probe(struct usb_interface *interface,
> /* save our data pointer in this interface device */
> usb_set_intfdata(interface, dev);
>
> - /* initialize videobuf2 stuff */
> - em28xx_vb2_setup(dev);
> -
> /* allocate device struct */
> mutex_init(&dev->lock);
> - mutex_lock(&dev->lock);
> retval = em28xx_init_dev(dev, udev, interface, nr);
> if (retval) {
> - goto unlock_and_free;
> + goto err_free;
> }
>
> if (usb_xfer_mode < 0) {
> @@ -3546,7 +3468,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
> if (retval) {
> printk(DRIVER_NAME
> ": Failed to pre-allocate USB transfer buffers for DVB.\n");
> - goto unlock_and_free;
> + goto err_free;
> }
> }
>
> @@ -3555,13 +3477,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
> /* Should be the last thing to do, to avoid newer udev's to
> open the device before fully initializing it
> */
> - mutex_unlock(&dev->lock);
>
> return 0;
>
> -unlock_and_free:
> - mutex_unlock(&dev->lock);
> -
> err_free:
> kfree(dev->alt_max_pkt_size_isoc);
> kfree(dev);
> diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c
> index f6076a512e8f..0f61532d2612 100644
> --- a/drivers/media/usb/em28xx/em28xx-core.c
> +++ b/drivers/media/usb/em28xx/em28xx-core.c
> @@ -33,6 +33,18 @@
>
> #include "em28xx.h"
>
> +#define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \
> + "Markus Rechberger <mrechberger@gmail.com>, " \
> + "Mauro Carvalho Chehab <mchehab@infradead.org>, " \
> + "Sascha Sommer <saschasommer@freenet.de>"
> +
> +#define DRIVER_DESC "Empia em28xx based USB core driver"
You should update the driver description string for the new v4l2 module
in em28xx-video.c.
...
> +
> +MODULE_AUTHOR(DRIVER_AUTHOR);
> +MODULE_DESCRIPTION(DRIVER_DESC);
> +MODULE_LICENSE("GPL");
> +MODULE_VERSION(EM28XX_VERSION);
> +
...
> /* #define ENABLE_DEBUG_ISOC_FRAMES */
>
> static unsigned int core_debug;
> diff --git a/drivers/media/usb/em28xx/em28xx-video.c b/drivers/media/usb/em28xx/em28xx-video.c
> index dd19c9ff76e0..b20e4e7116d3 100644
> --- a/drivers/media/usb/em28xx/em28xx-video.c
> +++ b/drivers/media/usb/em28xx/em28xx-video.c
> @@ -51,8 +51,6 @@
>
> #define DRIVER_DESC "Empia em28xx based USB video device driver"
>
> -#define EM28XX_VERSION "0.2.0"
> -
Some of these DRIVER_XYZ #defines are kept locally, this one is moved to
the header file, other extension modules don't use ist all (strings
hardcoded or corresponding MODULE macros unused)...
Time for a clean-up / unification. :)
> #define em28xx_videodbg(fmt, arg...) do {\
> if (video_debug) \
> printk(KERN_INFO "%s %s :"fmt, \
> @@ -763,7 +761,7 @@ static struct vb2_ops em28xx_video_qops = {
> .wait_finish = vb2_ops_wait_finish,
> };
>
> -int em28xx_vb2_setup(struct em28xx *dev)
> +static int em28xx_vb2_setup(struct em28xx *dev)
> {
> int rc;
> struct vb2_queue *q;
> @@ -831,7 +829,7 @@ static void video_mux(struct em28xx *dev, int index)
> em28xx_audio_analog_set(dev);
> }
>
> -void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
> +static void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv)
> {
> struct em28xx *dev = priv;
>
> @@ -1615,11 +1613,11 @@ static int em28xx_v4l2_open(struct file *filp)
> }
>
> /*
> - * em28xx_realease_resources()
> + * em28xx_v4l2_fini()
> * unregisters the v4l2,i2c and usb devices
> * called when the device gets disconected or at module unload
> */
> -void em28xx_release_analog_resources(struct em28xx *dev)
> +static int em28xx_v4l2_fini(struct em28xx *dev)
> {
>
> /*FIXME: I2C IR should be disconnected */
> @@ -1649,6 +1647,8 @@ void em28xx_release_analog_resources(struct em28xx *dev)
> video_device_release(dev->vdev);
> dev->vdev = NULL;
> }
> +
> + return 0;
> }
>
> /*
> @@ -1790,8 +1790,6 @@ static struct video_device em28xx_radio_template = {
>
> /******************************** usb interface ******************************/
>
> -
> -
> static struct video_device *em28xx_vdev_init(struct em28xx *dev,
> const struct video_device *template,
> const char *type_name)
> @@ -1817,15 +1815,85 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
> return vfd;
> }
>
> -int em28xx_register_analog_devices(struct em28xx *dev)
> +static int em28xx_v4l2_init(struct em28xx *dev)
> {
> u8 val;
> int ret;
> unsigned int maxw;
> + struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
> +
> + if (!dev->has_video) {
Same as above, what about audio devices ?
> + /* This device does not support the v4l2 extension */
> + return 0;
-ENODEV
> + }
>
> printk(KERN_INFO "%s: v4l2 driver version %s\n",
> dev->name, EM28XX_VERSION);
>
> + mutex_lock(&dev->lock);
> +
> + ret = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
> + if (ret < 0) {
> + em28xx_errdev("Call to v4l2_device_register() failed!\n");
> + goto err;
> + }
> +
> + v4l2_ctrl_handler_init(hdl, 8);
> + dev->v4l2_dev.ctrl_handler = hdl;
> +
> + /*
> + * Default format, used for tvp5150 or saa711x output formats
> + */
> + dev->vinmode = 0x10;
> + dev->vinctl = EM28XX_VINCTRL_INTERLACED |
> + EM28XX_VINCTRL_CCIR656_ENABLE;
> +
> + /* Configure audio */
> + ret = em28xx_audio_setup(dev);
> + if (ret < 0) {
> + em28xx_errdev("%s: Error while setting audio - error [%d]!\n",
> + __func__, ret);
> + goto err;
> + }
> + if (dev->audio_mode.ac97 != EM28XX_NO_AC97) {
> + v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
> + V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
> + v4l2_ctrl_new_std(hdl, &em28xx_ctrl_ops,
> + V4L2_CID_AUDIO_VOLUME, 0, 0x1f, 1, 0x1f);
> + } else {
> + /* install the em28xx notify callback */
> + v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_MUTE),
> + em28xx_ctrl_notify, dev);
> + v4l2_ctrl_notify(v4l2_ctrl_find(hdl, V4L2_CID_AUDIO_VOLUME),
> + em28xx_ctrl_notify, dev);
> + }
> +
> + /* wake i2c devices */
> + em28xx_wake_i2c(dev);
> +
> + /* init video dma queues */
> + INIT_LIST_HEAD(&dev->vidq.active);
> + INIT_LIST_HEAD(&dev->vbiq.active);
> +
> + if (dev->board.has_msp34xx) {
> + /* Send a reset to other chips via gpio */
> + ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xf7);
> + if (ret < 0) {
> + em28xx_errdev("%s: em28xx_write_reg - msp34xx(1) failed! error [%d]\n",
> + __func__, ret);
> + goto err;
> + }
> + msleep(3);
> +
> + ret = em28xx_write_reg(dev, EM2820_R08_GPIO_CTRL, 0xff);
> + if (ret < 0) {
> + em28xx_errdev("%s: em28xx_write_reg - msp34xx(2) failed! error [%d]\n",
> + __func__, ret);
> + goto err;
> + }
> + msleep(3);
> + }
> +
> /* set default norm */
> dev->norm = V4L2_STD_PAL;
> v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm);
> @@ -1888,14 +1956,16 @@ int em28xx_register_analog_devices(struct em28xx *dev)
> /* Reset image controls */
> em28xx_colorlevels_set_default(dev);
> v4l2_ctrl_handler_setup(&dev->ctrl_handler);
> - if (dev->ctrl_handler.error)
> - return dev->ctrl_handler.error;
> + ret = dev->ctrl_handler.error;
> + if (ret)
> + goto err;
>
> /* allocate and fill video video_device struct */
> dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video");
> if (!dev->vdev) {
> em28xx_errdev("cannot allocate video_device.\n");
> - return -ENODEV;
> + ret = -ENODEV;
> + goto err;
> }
> dev->vdev->queue = &dev->vb_vidq;
> dev->vdev->queue->lock = &dev->vb_queue_lock;
> @@ -1925,7 +1995,7 @@ int em28xx_register_analog_devices(struct em28xx *dev)
> if (ret) {
> em28xx_errdev("unable to register video device (error=%i).\n",
> ret);
> - return ret;
> + goto err;
> }
>
> /* Allocate and fill vbi video_device struct */
> @@ -1954,7 +2024,7 @@ int em28xx_register_analog_devices(struct em28xx *dev)
> vbi_nr[dev->devno]);
> if (ret < 0) {
> em28xx_errdev("unable to register vbi device\n");
> - return ret;
> + goto err;
> }
> }
>
> @@ -1963,13 +2033,14 @@ int em28xx_register_analog_devices(struct em28xx *dev)
> "radio");
> if (!dev->radio_dev) {
> em28xx_errdev("cannot allocate video_device.\n");
> - return -ENODEV;
> + ret = -ENODEV;
> + goto err;
> }
> ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
> radio_nr[dev->devno]);
> if (ret < 0) {
> em28xx_errdev("can't register radio device\n");
> - return ret;
> + goto err;
> }
> em28xx_info("Registered radio device as %s\n",
> video_device_node_name(dev->radio_dev));
> @@ -1982,5 +2053,33 @@ int em28xx_register_analog_devices(struct em28xx *dev)
> em28xx_info("V4L2 VBI device registered as %s\n",
> video_device_node_name(dev->vbi_dev));
>
> - return 0;
> + /* Save some power by putting tuner to sleep */
> + v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
> +
> + /* initialize videobuf2 stuff */
> + em28xx_vb2_setup(dev);
Are you 100% sure it is safe to do this that late now ?
> +
> +err:
> + mutex_unlock(&dev->lock);
> + return ret;
> }
> +
> +static struct em28xx_ops v4l2_ops = {
> + .id = EM28XX_V4L2,
> + .name = "Em28xx v4l2 Extension",
> + .init = em28xx_v4l2_init,
> + .fini = em28xx_v4l2_fini,
> +};
> +
> +static int __init em28xx_dvb_register(void)
> +{
> + return em28xx_register_extension(&v4l2_ops);
> +}
> +
> +static void __exit em28xx_dvb_unregister(void)
> +{
> + em28xx_unregister_extension(&v4l2_ops);
> +}
> +
> +module_init(em28xx_dvb_register);
> +module_exit(em28xx_dvb_unregister);
Should be em28xx_v4l2_register and em28xx_v4l2_unregister.
> diff --git a/drivers/media/usb/em28xx/em28xx.h b/drivers/media/usb/em28xx/em28xx.h
> index 191ef3593891..bc37d4833dbe 100644
> --- a/drivers/media/usb/em28xx/em28xx.h
> +++ b/drivers/media/usb/em28xx/em28xx.h
> @@ -26,6 +26,8 @@
> #ifndef _EM28XX_H
> #define _EM28XX_H
>
> +#define EM28XX_VERSION "0.2.1"
> +
> #include <linux/workqueue.h>
> #include <linux/i2c.h>
> #include <linux/mutex.h>
> @@ -472,6 +474,7 @@ struct em28xx_eeprom {
> #define EM28XX_AUDIO 0x10
> #define EM28XX_DVB 0x20
> #define EM28XX_RC 0x30
> +#define EM28XX_V4L2 0x40
Reorder ?
> /* em28xx resource types (used for res_get/res_lock etc */
> #define EM28XX_RESOURCE_VIDEO 0x01
> @@ -522,9 +525,13 @@ struct em28xx {
> int model; /* index in the device_data struct */
> int devno; /* marks the number of this device */
> enum em28xx_chip_id chip_id;
> - unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */
>
> + unsigned int is_em25xx:1; /* em25xx/em276x/7x/8x family bridge */
> unsigned char disconnected:1; /* device has been diconnected */
> + unsigned int has_video:1;
> + unsigned int has_audio_class:1;
> + unsigned int has_alsa_audio:1;
> + unsigned int is_audio_only:1;
>
> int audio_ifnum;
>
> @@ -544,10 +551,6 @@ struct em28xx {
> /* Vinmode/Vinctl used at the driver */
> int vinmode, vinctl;
>
> - unsigned int has_audio_class:1;
> - unsigned int has_alsa_audio:1;
> - unsigned int is_audio_only:1;
> -
> /* Controls audio streaming */
> struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
> atomic_t stream_started; /* stream should be running if true */
> @@ -748,10 +751,6 @@ void em28xx_init_extension(struct em28xx *dev);
> void em28xx_close_extension(struct em28xx *dev);
>
> /* Provided by em28xx-video.c */
> -int em28xx_vb2_setup(struct em28xx *dev);
> -int em28xx_register_analog_devices(struct em28xx *dev);
> -void em28xx_release_analog_resources(struct em28xx *dev);
> -void em28xx_ctrl_notify(struct v4l2_ctrl *ctrl, void *priv);
> int em28xx_start_analog_streaming(struct vb2_queue *vq, unsigned int count);
> int em28xx_stop_vbi_streaming(struct vb2_queue *vq);
> extern const struct v4l2_ctrl_ops em28xx_ctrl_ops;
I'll be glad to test the changes with the hardware I have once the
changed code compiles.
Regards,
Frank
next prev parent reply other threads:[~2013-12-26 11:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-22 12:47 [RFC PATCHv2] em28xx: split analog part into a separate module Mauro Carvalho Chehab
2013-12-26 11:55 ` Frank Schäfer [this message]
2013-12-26 14:21 ` Mauro Carvalho Chehab
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52BC191A.8070405@googlemail.com \
--to=fschaefer.oss@googlemail.com \
--cc=m.chehab@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.