From b2fe22d0cf64708c50c26f11b3da8b79809c699b Mon Sep 17 00:00:00 2001 From: Nick Dyer Date: Mon, 18 Jul 2016 18:10:30 -0300 Subject: [media] v4l2-core: Add support for touch devices Some touch controllers send out touch data in a similar way to a greyscale frame grabber. Add new device type VFL_TYPE_TOUCH: - This uses a new device prefix v4l-touch for these devices, to stop generic capture software from treating them as webcams. Otherwise, touch is treated similarly to video capture. - Add V4L2_INPUT_TYPE_TOUCH - Add MEDIA_INTF_T_V4L_TOUCH - Add V4L2_CAP_TOUCH to indicate device is a touch device Add formats: - V4L2_TCH_FMT_DELTA_TD16 for signed 16-bit touch deltas - V4L2_TCH_FMT_DELTA_TD08 for signed 16-bit touch deltas - V4L2_TCH_FMT_TU16 for unsigned 16-bit touch data - V4L2_TCH_FMT_TU08 for unsigned 8-bit touch data This support will be used by: - Atmel maXTouch (atmel_mxt_ts) - Synaptics RMI4. - sur40 Signed-off-by: Nick Dyer Tested-by: Chris Healy Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab Acked-by: Dmitry Torokhov --- include/media/v4l2-dev.h | 4 +++- include/uapi/linux/media.h | 1 + include/uapi/linux/videodev2.h | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index a122b1bd40f9..5272aeec0cec 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -25,7 +25,8 @@ #define VFL_TYPE_RADIO 2 #define VFL_TYPE_SUBDEV 3 #define VFL_TYPE_SDR 4 -#define VFL_TYPE_MAX 5 +#define VFL_TYPE_TOUCH 5 +#define VFL_TYPE_MAX 6 /* Is this a receiver, transmitter or mem-to-mem? */ /* Ignored for VFL_TYPE_SUBDEV. */ @@ -294,6 +295,7 @@ struct video_device * - %VFL_TYPE_RADIO - A radio card * - %VFL_TYPE_SUBDEV - A subdevice * - %VFL_TYPE_SDR - Software Defined Radio + * - %VFL_TYPE_TOUCH - A touch sensor * * .. note:: * diff --git a/include/uapi/linux/media.h b/include/uapi/linux/media.h index 7acf0f634f70..4890787731b8 100644 --- a/include/uapi/linux/media.h +++ b/include/uapi/linux/media.h @@ -307,6 +307,7 @@ struct media_links_enum { #define MEDIA_INTF_T_V4L_RADIO (MEDIA_INTF_T_V4L_BASE + 2) #define MEDIA_INTF_T_V4L_SUBDEV (MEDIA_INTF_T_V4L_BASE + 3) #define MEDIA_INTF_T_V4L_SWRADIO (MEDIA_INTF_T_V4L_BASE + 4) +#define MEDIA_INTF_T_V4L_TOUCH (MEDIA_INTF_T_V4L_BASE + 5) #define MEDIA_INTF_T_ALSA_PCM_CAPTURE (MEDIA_INTF_T_ALSA_BASE) #define MEDIA_INTF_T_ALSA_PCM_PLAYBACK (MEDIA_INTF_T_ALSA_BASE + 1) diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 724f43e69d03..22bad8c741fe 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -440,6 +440,8 @@ struct v4l2_capability { #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ +#define V4L2_CAP_TOUCH 0x10000000 /* Is a touch device */ + #define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ /* @@ -635,6 +637,12 @@ struct v4l2_pix_format { #define V4L2_SDR_FMT_CS14LE v4l2_fourcc('C', 'S', '1', '4') /* complex s14le */ #define V4L2_SDR_FMT_RU12LE v4l2_fourcc('R', 'U', '1', '2') /* real u12le */ +/* Touch formats - used for Touch devices */ +#define V4L2_TCH_FMT_DELTA_TD16 v4l2_fourcc('T', 'D', '1', '6') /* 16-bit signed deltas */ +#define V4L2_TCH_FMT_DELTA_TD08 v4l2_fourcc('T', 'D', '0', '8') /* 8-bit signed deltas */ +#define V4L2_TCH_FMT_TU16 v4l2_fourcc('T', 'U', '1', '6') /* 16-bit unsigned touch data */ +#define V4L2_TCH_FMT_TU08 v4l2_fourcc('T', 'U', '0', '8') /* 8-bit unsigned touch data */ + /* priv field value to indicates that subsequent fields are valid. */ #define V4L2_PIX_FMT_PRIV_MAGIC 0xfeedcafe @@ -1401,6 +1409,7 @@ struct v4l2_input { /* Values for the 'type' field */ #define V4L2_INPUT_TYPE_TUNER 1 #define V4L2_INPUT_TYPE_CAMERA 2 +#define V4L2_INPUT_TYPE_TOUCH 3 /* field 'status' - general */ #define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */ -- cgit v1.2.3-70-g09d2 From f304562ed3c97e237a77b3da57b0e43f264bd82a Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 31 Jul 2016 08:12:22 -0300 Subject: [media] soc-camera/sh_mobile_csi2: remove unused driver The sh_mobile_csi2 isn't used anymore (was it ever?), so remove it. Especially since the soc-camera framework is being deprecated. Signed-off-by: Hans Verkuil Acked-by: Laurent Pinchart Cc: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/Kconfig | 7 - drivers/media/platform/soc_camera/Makefile | 1 - .../platform/soc_camera/sh_mobile_ceu_camera.c | 229 +----------- drivers/media/platform/soc_camera/sh_mobile_csi2.c | 400 --------------------- include/media/drv-intf/sh_mobile_ceu.h | 1 - include/media/drv-intf/sh_mobile_csi2.h | 48 --- 6 files changed, 10 insertions(+), 676 deletions(-) delete mode 100644 drivers/media/platform/soc_camera/sh_mobile_csi2.c delete mode 100644 include/media/drv-intf/sh_mobile_csi2.h (limited to 'include') diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig index 39f66414f621..99cf471a5fc0 100644 --- a/drivers/media/platform/soc_camera/Kconfig +++ b/drivers/media/platform/soc_camera/Kconfig @@ -35,13 +35,6 @@ config VIDEO_RCAR_VIN_OLD ---help--- This is a v4l2 driver for the R-Car VIN Interface -config VIDEO_SH_MOBILE_CSI2 - tristate "SuperH Mobile MIPI CSI-2 Interface driver" - depends on VIDEO_DEV && SOC_CAMERA && HAVE_CLK - depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST - ---help--- - This is a v4l2 driver for the SuperH MIPI CSI-2 Interface - config VIDEO_SH_MOBILE_CEU tristate "SuperH Mobile CEU Interface driver" depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK diff --git a/drivers/media/platform/soc_camera/Makefile b/drivers/media/platform/soc_camera/Makefile index 7703cb7ce456..ee8f9a4ae2a4 100644 --- a/drivers/media/platform/soc_camera/Makefile +++ b/drivers/media/platform/soc_camera/Makefile @@ -9,5 +9,4 @@ obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o -obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2) += sh_mobile_csi2.o obj-$(CONFIG_VIDEO_RCAR_VIN_OLD) += rcar_vin.o diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 02b519dde42a..05eafe3a421e 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -99,11 +98,6 @@ struct sh_mobile_ceu_buffer { struct sh_mobile_ceu_dev { struct soc_camera_host ici; - /* Asynchronous CSI2 linking */ - struct v4l2_async_subdev *csi2_asd; - struct v4l2_subdev *csi2_sd; - /* Synchronous probing compatibility */ - struct platform_device *csi2_pdev; unsigned int irq; void __iomem *base; @@ -517,74 +511,20 @@ out: return IRQ_HANDLED; } -static struct v4l2_subdev *find_csi2(struct sh_mobile_ceu_dev *pcdev) -{ - struct v4l2_subdev *sd; - - if (pcdev->csi2_sd) - return pcdev->csi2_sd; - - if (pcdev->csi2_asd) { - char name[] = "sh-mobile-csi2"; - v4l2_device_for_each_subdev(sd, &pcdev->ici.v4l2_dev) - if (!strncmp(name, sd->name, sizeof(name) - 1)) { - pcdev->csi2_sd = sd; - return sd; - } - } - - return NULL; -} - -static struct v4l2_subdev *csi2_subdev(struct sh_mobile_ceu_dev *pcdev, - struct soc_camera_device *icd) -{ - struct v4l2_subdev *sd = pcdev->csi2_sd; - - return sd && sd->grp_id == soc_camera_grp_id(icd) ? sd : NULL; -} - static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct sh_mobile_ceu_dev *pcdev = ici->priv; - struct v4l2_subdev *csi2_sd = find_csi2(pcdev); - int ret; - - if (csi2_sd) { - csi2_sd->grp_id = soc_camera_grp_id(icd); - v4l2_set_subdev_hostdata(csi2_sd, icd); - } - - ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); - if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) - return ret; - - /* - * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver - * has not found this soc-camera device among its clients - */ - if (csi2_sd && ret == -ENODEV) - csi2_sd->grp_id = 0; - dev_info(icd->parent, - "SuperH Mobile CEU%s driver attached to camera %d\n", - csi2_sd && csi2_sd->grp_id ? "/CSI-2" : "", icd->devnum); + "SuperH Mobile CEU driver attached to camera %d\n", + icd->devnum); return 0; } static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct sh_mobile_ceu_dev *pcdev = ici->priv; - struct v4l2_subdev *csi2_sd = find_csi2(pcdev); - dev_info(icd->parent, "SuperH Mobile CEU driver detached from camera %d\n", icd->devnum); - - v4l2_subdev_call(csi2_sd, core, s_power, 0); } /* Called with .host_lock held */ @@ -704,12 +644,6 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd) cdwdr_width *= 2; } - /* CSI2 special configuration */ - if (csi2_subdev(pcdev, icd)) { - in_width = ((in_width - 2) * 2); - left_offset *= 2; - } - /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */ camor = left_offset | (top_offset << 16); @@ -758,13 +692,6 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr) ceu_write(pcdev, CAPSR, capsr); } -/* Find the bus subdevice driver, e.g., CSI2 */ -static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev, - struct soc_camera_device *icd) -{ - return csi2_subdev(pcdev, icd) ? : soc_camera_to_subdev(icd); -} - #define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \ V4L2_MBUS_PCLK_SAMPLE_RISING | \ V4L2_MBUS_HSYNC_ACTIVE_HIGH | \ @@ -778,7 +705,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; - struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd); + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct sh_mobile_ceu_cam *cam = icd->host_priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; unsigned long value, common_flags = CEU_BUS_FLAGS; @@ -866,9 +793,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; - if (csi2_subdev(pcdev, icd)) /* CSI2 mode */ - value |= 3 << 12; - else if (pcdev->is_16bit) + if (pcdev->is_16bit) value |= 1 << 12; else if (pcdev->flags & SH_CEU_FLAG_LOWER_8BIT) value |= 2 << 12; @@ -923,9 +848,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd) static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd, unsigned char buswidth) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct sh_mobile_ceu_dev *pcdev = ici->priv; - struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd); + struct v4l2_subdev *sd = soc_camera_to_subdev(icd); unsigned long common_flags = CEU_BUS_FLAGS; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; int ret; @@ -1046,12 +969,9 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int return 0; } - if (!csi2_subdev(pcdev, icd)) { - /* Are there any restrictions in the CSI-2 case? */ - ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); - if (ret < 0) - return 0; - } + ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); + if (ret < 0) + return 0; if (!icd->host_priv) { struct v4l2_subdev_format fmt = { @@ -1721,12 +1641,11 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) struct resource *res; void __iomem *base; unsigned int irq; - int err, i; + int err; struct bus_wait wait = { .completion = COMPLETION_INITIALIZER_ONSTACK(wait.completion), .notifier.notifier_call = bus_notify, }; - struct sh_mobile_ceu_companion *csi2; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); @@ -1821,132 +1740,16 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) pcdev->ici.capabilities = SOCAM_HOST_CAP_STRIDE; if (pcdev->pdata && pcdev->pdata->asd_sizes) { - struct v4l2_async_subdev **asd; - char name[] = "sh-mobile-csi2"; - int j; - - /* - * CSI2 interfacing: several groups can use CSI2, pick up the - * first one - */ - asd = pcdev->pdata->asd; - for (j = 0; pcdev->pdata->asd_sizes[j]; j++) { - for (i = 0; i < pcdev->pdata->asd_sizes[j]; i++, asd++) { - dev_dbg(&pdev->dev, "%s(): subdev #%d, type %u\n", - __func__, i, (*asd)->match_type); - if ((*asd)->match_type == V4L2_ASYNC_MATCH_DEVNAME && - !strncmp(name, (*asd)->match.device_name.name, - sizeof(name) - 1)) { - pcdev->csi2_asd = *asd; - break; - } - } - if (pcdev->csi2_asd) - break; - } - pcdev->ici.asd = pcdev->pdata->asd; pcdev->ici.asd_sizes = pcdev->pdata->asd_sizes; } - /* Legacy CSI2 interfacing */ - csi2 = pcdev->pdata ? pcdev->pdata->csi2 : NULL; - if (csi2) { - /* - * TODO: remove this once all users are converted to - * asynchronous CSI2 probing. If it has to be kept, csi2 - * platform device resources have to be added, using - * platform_device_add_resources() - */ - struct platform_device *csi2_pdev = - platform_device_alloc("sh-mobile-csi2", csi2->id); - struct sh_csi2_pdata *csi2_pdata = csi2->platform_data; - - if (!csi2_pdev) { - err = -ENOMEM; - goto exit_free_clk; - } - - pcdev->csi2_pdev = csi2_pdev; - - err = platform_device_add_data(csi2_pdev, csi2_pdata, - sizeof(*csi2_pdata)); - if (err < 0) - goto exit_pdev_put; - - csi2_pdev->resource = csi2->resource; - csi2_pdev->num_resources = csi2->num_resources; - - err = platform_device_add(csi2_pdev); - if (err < 0) - goto exit_pdev_put; - - wait.dev = &csi2_pdev->dev; - - err = bus_register_notifier(&platform_bus_type, &wait.notifier); - if (err < 0) - goto exit_pdev_unregister; - - /* - * From this point the driver module will not unload, until - * we complete the completion. - */ - - if (!csi2_pdev->dev.driver) { - complete(&wait.completion); - /* Either too late, or probing failed */ - bus_unregister_notifier(&platform_bus_type, &wait.notifier); - err = -ENXIO; - goto exit_pdev_unregister; - } - - /* - * The module is still loaded, in the worst case it is hanging - * in device release on our completion. So, _now_ dereferencing - * the "owner" is safe! - */ - - err = try_module_get(csi2_pdev->dev.driver->owner); - - /* Let notifier complete, if it has been locked */ - complete(&wait.completion); - bus_unregister_notifier(&platform_bus_type, &wait.notifier); - if (!err) { - err = -ENODEV; - goto exit_pdev_unregister; - } - - pcdev->csi2_sd = platform_get_drvdata(csi2_pdev); - } - err = soc_camera_host_register(&pcdev->ici); if (err) - goto exit_csi2_unregister; - - if (csi2) { - err = v4l2_device_register_subdev(&pcdev->ici.v4l2_dev, - pcdev->csi2_sd); - dev_dbg(&pdev->dev, "%s(): ret(register_subdev) = %d\n", - __func__, err); - if (err < 0) - goto exit_host_unregister; - /* v4l2_device_register_subdev() took a reference too */ - module_put(pcdev->csi2_sd->owner); - } + goto exit_free_clk; return 0; -exit_host_unregister: - soc_camera_host_unregister(&pcdev->ici); -exit_csi2_unregister: - if (csi2) { - module_put(pcdev->csi2_pdev->dev.driver->owner); -exit_pdev_unregister: - platform_device_del(pcdev->csi2_pdev); -exit_pdev_put: - pcdev->csi2_pdev->resource = NULL; - platform_device_put(pcdev->csi2_pdev); - } exit_free_clk: pm_runtime_disable(&pdev->dev); exit_release_mem: @@ -1958,21 +1761,11 @@ exit_release_mem: static int sh_mobile_ceu_remove(struct platform_device *pdev) { struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); - struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, - struct sh_mobile_ceu_dev, ici); - struct platform_device *csi2_pdev = pcdev->csi2_pdev; soc_camera_host_unregister(soc_host); pm_runtime_disable(&pdev->dev); if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) dma_release_declared_memory(&pdev->dev); - if (csi2_pdev && csi2_pdev->dev.driver) { - struct module *csi2_drv = csi2_pdev->dev.driver->owner; - platform_device_del(csi2_pdev); - csi2_pdev->resource = NULL; - platform_device_put(csi2_pdev); - module_put(csi2_drv); - } return 0; } @@ -2012,8 +1805,6 @@ static struct platform_driver sh_mobile_ceu_driver = { static int __init sh_mobile_ceu_init(void) { - /* Whatever return code */ - request_module("sh_mobile_csi2"); return platform_driver_register(&sh_mobile_ceu_driver); } diff --git a/drivers/media/platform/soc_camera/sh_mobile_csi2.c b/drivers/media/platform/soc_camera/sh_mobile_csi2.c deleted file mode 100644 index 09b18365a4b1..000000000000 --- a/drivers/media/platform/soc_camera/sh_mobile_csi2.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Driver for the SH-Mobile MIPI CSI-2 unit - * - * Copyright (C) 2010, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SH_CSI2_TREF 0x00 -#define SH_CSI2_SRST 0x04 -#define SH_CSI2_PHYCNT 0x08 -#define SH_CSI2_CHKSUM 0x0C -#define SH_CSI2_VCDT 0x10 - -struct sh_csi2 { - struct v4l2_subdev subdev; - unsigned int irq; - unsigned long mipi_flags; - void __iomem *base; - struct platform_device *pdev; - struct sh_csi2_client_config *client; -}; - -static void sh_csi2_hwinit(struct sh_csi2 *priv); - -static int sh_csi2_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_format *format) -{ - struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); - struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; - struct v4l2_mbus_framefmt *mf = &format->format; - u32 tmp = (priv->client->channel & 3) << 8; - - if (format->pad) - return -EINVAL; - - if (mf->width > 8188) - mf->width = 8188; - else if (mf->width & 1) - mf->width &= ~1; - - switch (pdata->type) { - case SH_CSI2C: - switch (mf->code) { - case MEDIA_BUS_FMT_UYVY8_2X8: /* YUV422 */ - case MEDIA_BUS_FMT_YUYV8_1_5X8: /* YUV420 */ - case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ - case MEDIA_BUS_FMT_SBGGR8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - break; - default: - /* All MIPI CSI-2 devices must support one of primary formats */ - mf->code = MEDIA_BUS_FMT_YUYV8_2X8; - } - break; - case SH_CSI2I: - switch (mf->code) { - case MEDIA_BUS_FMT_Y8_1X8: /* RAW8 */ - case MEDIA_BUS_FMT_SBGGR8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - case MEDIA_BUS_FMT_SBGGR10_1X10: /* RAW10 */ - case MEDIA_BUS_FMT_SBGGR12_1X12: /* RAW12 */ - break; - default: - /* All MIPI CSI-2 devices must support one of primary formats */ - mf->code = MEDIA_BUS_FMT_SBGGR8_1X8; - } - break; - } - - if (format->which == V4L2_SUBDEV_FORMAT_TRY) { - cfg->try_fmt = *mf; - return 0; - } - - if (mf->width > 8188 || mf->width & 1) - return -EINVAL; - - switch (mf->code) { - case MEDIA_BUS_FMT_UYVY8_2X8: - tmp |= 0x1e; /* YUV422 8 bit */ - break; - case MEDIA_BUS_FMT_YUYV8_1_5X8: - tmp |= 0x18; /* YUV420 8 bit */ - break; - case MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE: - tmp |= 0x21; /* RGB555 */ - break; - case MEDIA_BUS_FMT_RGB565_2X8_BE: - tmp |= 0x22; /* RGB565 */ - break; - case MEDIA_BUS_FMT_Y8_1X8: - case MEDIA_BUS_FMT_SBGGR8_1X8: - case MEDIA_BUS_FMT_SGRBG8_1X8: - tmp |= 0x2a; /* RAW8 */ - break; - default: - return -EINVAL; - } - - iowrite32(tmp, priv->base + SH_CSI2_VCDT); - - return 0; -} - -static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd, - struct v4l2_mbus_config *cfg) -{ - struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); - - if (!priv->mipi_flags) { - struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); - struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); - struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; - unsigned long common_flags, csi2_flags; - struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,}; - int ret; - - /* Check if we can support this camera */ - csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | - V4L2_MBUS_CSI2_1_LANE; - - switch (pdata->type) { - case SH_CSI2C: - if (priv->client->lanes != 1) - csi2_flags |= V4L2_MBUS_CSI2_2_LANE; - break; - case SH_CSI2I: - switch (priv->client->lanes) { - default: - csi2_flags |= V4L2_MBUS_CSI2_4_LANE; - case 3: - csi2_flags |= V4L2_MBUS_CSI2_3_LANE; - case 2: - csi2_flags |= V4L2_MBUS_CSI2_2_LANE; - } - } - - ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &client_cfg); - if (ret == -ENOIOCTLCMD) - common_flags = csi2_flags; - else if (!ret) - common_flags = soc_mbus_config_compatible(&client_cfg, - csi2_flags); - else - common_flags = 0; - - if (!common_flags) - return -EINVAL; - - /* All good: camera MIPI configuration supported */ - priv->mipi_flags = common_flags; - } - - if (cfg) { - cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | - V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | - V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH; - cfg->type = V4L2_MBUS_PARALLEL; - } - - return 0; -} - -static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd, - const struct v4l2_mbus_config *cfg) -{ - struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); - struct soc_camera_device *icd = v4l2_get_subdev_hostdata(sd); - struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd); - struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,}; - int ret = sh_csi2_g_mbus_config(sd, NULL); - - if (ret < 0) - return ret; - - pm_runtime_get_sync(&priv->pdev->dev); - - sh_csi2_hwinit(priv); - - client_cfg.flags = priv->mipi_flags; - - return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg); -} - -static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = { - .g_mbus_config = sh_csi2_g_mbus_config, - .s_mbus_config = sh_csi2_s_mbus_config, -}; - -static struct v4l2_subdev_pad_ops sh_csi2_subdev_pad_ops = { - .set_fmt = sh_csi2_set_fmt, -}; - -static void sh_csi2_hwinit(struct sh_csi2 *priv) -{ - struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; - __u32 tmp = 0x10; /* Enable MIPI CSI clock lane */ - - /* Reflect registers immediately */ - iowrite32(0x00000001, priv->base + SH_CSI2_TREF); - /* reset CSI2 harware */ - iowrite32(0x00000001, priv->base + SH_CSI2_SRST); - udelay(5); - iowrite32(0x00000000, priv->base + SH_CSI2_SRST); - - switch (pdata->type) { - case SH_CSI2C: - if (priv->client->lanes == 1) - tmp |= 1; - else - /* Default - both lanes */ - tmp |= 3; - break; - case SH_CSI2I: - if (!priv->client->lanes || priv->client->lanes > 4) - /* Default - all 4 lanes */ - tmp |= 0xf; - else - tmp |= (1 << priv->client->lanes) - 1; - } - - if (priv->client->phy == SH_CSI2_PHY_MAIN) - tmp |= 0x8000; - - iowrite32(tmp, priv->base + SH_CSI2_PHYCNT); - - tmp = 0; - if (pdata->flags & SH_CSI2_ECC) - tmp |= 2; - if (pdata->flags & SH_CSI2_CRC) - tmp |= 1; - iowrite32(tmp, priv->base + SH_CSI2_CHKSUM); -} - -static int sh_csi2_client_connect(struct sh_csi2 *priv) -{ - struct device *dev = v4l2_get_subdevdata(&priv->subdev); - struct sh_csi2_pdata *pdata = dev->platform_data; - struct soc_camera_device *icd = v4l2_get_subdev_hostdata(&priv->subdev); - int i; - - if (priv->client) - return -EBUSY; - - for (i = 0; i < pdata->num_clients; i++) - if ((pdata->clients[i].pdev && - &pdata->clients[i].pdev->dev == icd->pdev) || - (icd->control && - strcmp(pdata->clients[i].name, dev_name(icd->control)))) - break; - - dev_dbg(dev, "%s(%p): found #%d\n", __func__, dev, i); - - if (i == pdata->num_clients) - return -ENODEV; - - priv->client = pdata->clients + i; - - return 0; -} - -static void sh_csi2_client_disconnect(struct sh_csi2 *priv) -{ - if (!priv->client) - return; - - priv->client = NULL; - - pm_runtime_put(v4l2_get_subdevdata(&priv->subdev)); -} - -static int sh_csi2_s_power(struct v4l2_subdev *sd, int on) -{ - struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev); - - if (on) - return sh_csi2_client_connect(priv); - - sh_csi2_client_disconnect(priv); - return 0; -} - -static struct v4l2_subdev_core_ops sh_csi2_subdev_core_ops = { - .s_power = sh_csi2_s_power, -}; - -static struct v4l2_subdev_ops sh_csi2_subdev_ops = { - .core = &sh_csi2_subdev_core_ops, - .video = &sh_csi2_subdev_video_ops, - .pad = &sh_csi2_subdev_pad_ops, -}; - -static int sh_csi2_probe(struct platform_device *pdev) -{ - struct resource *res; - unsigned int irq; - int ret; - struct sh_csi2 *priv; - /* Platform data specify the PHY, lanes, ECC, CRC */ - struct sh_csi2_pdata *pdata = pdev->dev.platform_data; - - if (!pdata) - return -EINVAL; - - priv = devm_kzalloc(&pdev->dev, sizeof(struct sh_csi2), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - /* Interrupt unused so far */ - irq = platform_get_irq(pdev, 0); - - if (!res || (int)irq <= 0) { - dev_err(&pdev->dev, "Not enough CSI2 platform resources.\n"); - return -ENODEV; - } - - /* TODO: Add support for CSI2I. Careful: different register layout! */ - if (pdata->type != SH_CSI2C) { - dev_err(&pdev->dev, "Only CSI2C supported ATM.\n"); - return -EINVAL; - } - - priv->irq = irq; - - priv->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); - - priv->pdev = pdev; - priv->subdev.owner = THIS_MODULE; - priv->subdev.dev = &pdev->dev; - platform_set_drvdata(pdev, &priv->subdev); - - v4l2_subdev_init(&priv->subdev, &sh_csi2_subdev_ops); - v4l2_set_subdevdata(&priv->subdev, &pdev->dev); - - snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.mipi-csi", - dev_name(&pdev->dev)); - - ret = v4l2_async_register_subdev(&priv->subdev); - if (ret < 0) - return ret; - - pm_runtime_enable(&pdev->dev); - - dev_dbg(&pdev->dev, "CSI2 probed.\n"); - - return 0; -} - -static int sh_csi2_remove(struct platform_device *pdev) -{ - struct v4l2_subdev *subdev = platform_get_drvdata(pdev); - struct sh_csi2 *priv = container_of(subdev, struct sh_csi2, subdev); - - v4l2_async_unregister_subdev(&priv->subdev); - pm_runtime_disable(&pdev->dev); - - return 0; -} - -static struct platform_driver __refdata sh_csi2_pdrv = { - .remove = sh_csi2_remove, - .probe = sh_csi2_probe, - .driver = { - .name = "sh-mobile-csi2", - }, -}; - -module_platform_driver(sh_csi2_pdrv); - -MODULE_DESCRIPTION("SH-Mobile MIPI CSI-2 driver"); -MODULE_AUTHOR("Guennadi Liakhovetski "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:sh-mobile-csi2"); diff --git a/include/media/drv-intf/sh_mobile_ceu.h b/include/media/drv-intf/sh_mobile_ceu.h index 7f57056c22ba..2f43f7d9e28d 100644 --- a/include/media/drv-intf/sh_mobile_ceu.h +++ b/include/media/drv-intf/sh_mobile_ceu.h @@ -21,7 +21,6 @@ struct sh_mobile_ceu_info { unsigned long flags; int max_width; int max_height; - struct sh_mobile_ceu_companion *csi2; struct v4l2_async_subdev **asd; /* Flat array, arranged in groups */ unsigned int *asd_sizes; /* 0-terminated array pf asd group sizes */ }; diff --git a/include/media/drv-intf/sh_mobile_csi2.h b/include/media/drv-intf/sh_mobile_csi2.h deleted file mode 100644 index 14030db51f13..000000000000 --- a/include/media/drv-intf/sh_mobile_csi2.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Driver header for the SH-Mobile MIPI CSI-2 unit - * - * Copyright (C) 2010, Guennadi Liakhovetski - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef SH_MIPI_CSI -#define SH_MIPI_CSI - -#include - -enum sh_csi2_phy { - SH_CSI2_PHY_MAIN, - SH_CSI2_PHY_SUB, -}; - -enum sh_csi2_type { - SH_CSI2C, - SH_CSI2I, -}; - -#define SH_CSI2_CRC (1 << 0) -#define SH_CSI2_ECC (1 << 1) - -struct platform_device; - -struct sh_csi2_client_config { - enum sh_csi2_phy phy; - unsigned char lanes; /* bitmask[3:0] */ - unsigned char channel; /* 0..3 */ - struct platform_device *pdev; /* client platform device */ - const char *name; /* async matching: client name */ -}; - -struct v4l2_device; - -struct sh_csi2_pdata { - enum sh_csi2_type type; - unsigned int flags; - struct sh_csi2_client_config *clients; - int num_clients; -}; - -#endif -- cgit v1.2.3-70-g09d2 From 7e0739cd9c40752fc9d31cac86e3a31d5537be18 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 4 Aug 2016 05:51:12 -0300 Subject: [media] videodev2.h: fix sYCC/AdobeYCC default quantization range The default quantization range of the Y'CbCr encodings of sRGB and AdobeRGB are full range instead of limited range according to the corresponding standards. Fix this in the V4L2_MAP_QUANTIZATION_DEFAULT macro. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/pixfmt-007.rst | 4 ++-- include/uapi/linux/videodev2.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/Documentation/media/uapi/v4l/pixfmt-007.rst b/Documentation/media/uapi/v4l/pixfmt-007.rst index f097268ffc54..c45d8794e8eb 100644 --- a/Documentation/media/uapi/v4l/pixfmt-007.rst +++ b/Documentation/media/uapi/v4l/pixfmt-007.rst @@ -367,7 +367,7 @@ The :ref:`adobergb` standard defines the colorspace used by computer graphics that use the AdobeRGB colorspace. This is also known as the :ref:`oprgb` standard. The default transfer function is ``V4L2_XFER_FUNC_ADOBERGB``. The default Y'CbCr encoding is -``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is limited +``V4L2_YCBCR_ENC_601``. The default Y'CbCr quantization is full range. The chromaticities of the primary colors and the white reference are: @@ -448,7 +448,7 @@ the following ``V4L2_YCBCR_ENC_601`` encoding: Y' is clamped to the range [0…1] and Cb and Cr are clamped to the range [-0.5…0.5]. This transform is identical to one defined in SMPTE -170M/BT.601. The Y'CbCr quantization is limited range. +170M/BT.601. The Y'CbCr quantization is full range. .. _col-bt2020: diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 22bad8c741fe..0ec15222a6ca 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -345,8 +345,8 @@ enum v4l2_quantization { /* * The default for R'G'B' quantization is always full range, except * for the BT2020 colorspace. For Y'CbCr the quantization is always - * limited range, except for COLORSPACE_JPEG, SYCC, XV601 or XV709: - * those are full range. + * limited range, except for COLORSPACE_JPEG, SRGB, ADOBERGB, + * XV601 or XV709: those are full range. */ V4L2_QUANTIZATION_DEFAULT = 0, V4L2_QUANTIZATION_FULL_RANGE = 1, @@ -361,7 +361,8 @@ enum v4l2_quantization { #define V4L2_MAP_QUANTIZATION_DEFAULT(is_rgb, colsp, ycbcr_enc) \ (((is_rgb) && (colsp) == V4L2_COLORSPACE_BT2020) ? V4L2_QUANTIZATION_LIM_RANGE : \ (((is_rgb) || (ycbcr_enc) == V4L2_YCBCR_ENC_XV601 || \ - (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) ? \ + (ycbcr_enc) == V4L2_YCBCR_ENC_XV709 || (colsp) == V4L2_COLORSPACE_JPEG) || \ + (colsp) == V4L2_COLORSPACE_ADOBERGB || (colsp) == V4L2_COLORSPACE_SRGB ? \ V4L2_QUANTIZATION_FULL_RANGE : V4L2_QUANTIZATION_LIM_RANGE)) enum v4l2_priority { -- cgit v1.2.3-70-g09d2 From adca8c8e251fdbdb6b28e3ef7a5ca24b597b82d8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 4 Aug 2016 06:01:48 -0300 Subject: [media] videodev2.h: put V4L2_YCBCR_ENC_SYCC under #ifndef __KERNEL__ This define is a duplicate of V4L2_YCBCR_ENC_601. So mark it as 'should not be used' and put it under #ifndef __KERNEL__ to prevent drivers from referring to it. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/uapi/linux/videodev2.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 0ec15222a6ca..5529741202b5 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -292,13 +292,11 @@ enum v4l2_ycbcr_encoding { * various colorspaces: * * V4L2_COLORSPACE_SMPTE170M, V4L2_COLORSPACE_470_SYSTEM_M, - * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_ADOBERGB and - * V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 + * V4L2_COLORSPACE_470_SYSTEM_BG, V4L2_COLORSPACE_SRGB, + * V4L2_COLORSPACE_ADOBERGB and V4L2_COLORSPACE_JPEG: V4L2_YCBCR_ENC_601 * * V4L2_COLORSPACE_REC709 and V4L2_COLORSPACE_DCI_P3: V4L2_YCBCR_ENC_709 * - * V4L2_COLORSPACE_SRGB: V4L2_YCBCR_ENC_SYCC - * * V4L2_COLORSPACE_BT2020: V4L2_YCBCR_ENC_BT2020 * * V4L2_COLORSPACE_SMPTE240M: V4L2_YCBCR_ENC_SMPTE240M @@ -317,8 +315,14 @@ enum v4l2_ycbcr_encoding { /* Rec. 709/EN 61966-2-4 Extended Gamut -- HDTV */ V4L2_YCBCR_ENC_XV709 = 4, - /* sYCC (Y'CbCr encoding of sRGB) */ +#ifndef __KERNEL__ + /* + * sYCC (Y'CbCr encoding of sRGB), identical to ENC_601. It was added + * originally due to a misunderstanding of the sYCC standard. It should + * not be used, instead use V4L2_YCBCR_ENC_601. + */ V4L2_YCBCR_ENC_SYCC = 5, +#endif /* BT.2020 Non-constant Luminance Y'CbCr */ V4L2_YCBCR_ENC_BT2020 = 6, -- cgit v1.2.3-70-g09d2 From 10d5509c8d50a2c2f761a08a616530dced35e2d8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 14 Dec 2015 08:25:32 -0200 Subject: [media] v4l2: remove g/s_crop from video ops Replace all calls to g/s_crop by calls to the get/set_selection pad ops. Remove the old g/s_crop video ops since they are now no longer used. The cropcap video op is now only used to pass pixelaspect information, and is only needed if the pixelaspect is not 1:1. Signed-off-by: Hans Verkuil Cc: Guennadi Liakhovetski Acked-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/ak881x.c | 28 +++-- drivers/media/i2c/soc_camera/imx074.c | 42 +++---- drivers/media/i2c/soc_camera/mt9m001.c | 70 ++++++----- drivers/media/i2c/soc_camera/mt9m111.c | 57 ++++----- drivers/media/i2c/soc_camera/mt9t031.c | 54 +++++---- drivers/media/i2c/soc_camera/mt9t112.c | 60 +++++----- drivers/media/i2c/soc_camera/mt9v022.c | 68 ++++++----- drivers/media/i2c/soc_camera/ov2640.c | 41 +++---- drivers/media/i2c/soc_camera/ov5642.c | 53 +++++---- drivers/media/i2c/soc_camera/ov6650.c | 74 ++++++------ drivers/media/i2c/soc_camera/ov772x.c | 44 ++++--- drivers/media/i2c/soc_camera/ov9640.c | 41 +++---- drivers/media/i2c/soc_camera/ov9740.c | 41 +++---- drivers/media/i2c/soc_camera/rj54n1cb0c.c | 52 +++++---- drivers/media/i2c/soc_camera/tw9910.c | 47 +++----- drivers/media/i2c/tvp5150.c | 81 +++++++------ drivers/media/platform/omap3isp/ispvideo.c | 88 +++++++++----- drivers/media/platform/sh_vou.c | 15 ++- drivers/media/platform/soc_camera/pxa_camera.c | 17 ++- drivers/media/platform/soc_camera/rcar_vin.c | 30 +++-- .../platform/soc_camera/sh_mobile_ceu_camera.c | 38 +++--- drivers/media/platform/soc_camera/soc_camera.c | 130 ++++++--------------- .../platform/soc_camera/soc_camera_platform.c | 45 +++---- drivers/media/platform/soc_camera/soc_scale_crop.c | 97 ++++++++------- drivers/media/platform/soc_camera/soc_scale_crop.h | 6 +- drivers/staging/media/omap4iss/iss_video.c | 99 ++++++++++++++++ include/media/soc_camera.h | 7 +- include/media/v4l2-subdev.h | 6 - 28 files changed, 751 insertions(+), 680 deletions(-) (limited to 'include') diff --git a/drivers/media/i2c/ak881x.c b/drivers/media/i2c/ak881x.c index d9f2b6b76d59..3a795dcb7d8e 100644 --- a/drivers/media/i2c/ak881x.c +++ b/drivers/media/i2c/ak881x.c @@ -124,21 +124,27 @@ static int ak881x_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int ak881x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) +static int ak881x_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ak881x *ak881x = to_ak881x(client); - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = 720; - a->bounds.height = ak881x->lines; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = 720; + sel->r.height = ak881x->lines; + return 0; + default: + return -EINVAL; + } } static int ak881x_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) @@ -207,13 +213,13 @@ static struct v4l2_subdev_core_ops ak881x_subdev_core_ops = { }; static struct v4l2_subdev_video_ops ak881x_subdev_video_ops = { - .cropcap = ak881x_cropcap, .s_std_output = ak881x_s_std_output, .s_stream = ak881x_s_stream, }; static const struct v4l2_subdev_pad_ops ak881x_subdev_pad_ops = { .enum_mbus_code = ak881x_enum_mbus_code, + .get_selection = ak881x_get_selection, .set_fmt = ak881x_fill_fmt, .get_fmt = ak881x_fill_fmt, }; diff --git a/drivers/media/i2c/soc_camera/imx074.c b/drivers/media/i2c/soc_camera/imx074.c index f68c2352c63c..05b55cfe8147 100644 --- a/drivers/media/i2c/soc_camera/imx074.c +++ b/drivers/media/i2c/soc_camera/imx074.c @@ -209,31 +209,26 @@ static int imx074_get_fmt(struct v4l2_subdev *sd, return 0; } -static int imx074_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int imx074_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - struct v4l2_rect *rect = &a->c; - - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - rect->top = 0; - rect->left = 0; - rect->width = IMX074_WIDTH; - rect->height = IMX074_HEIGHT; - - return 0; -} + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; -static int imx074_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = IMX074_WIDTH; - a->bounds.height = IMX074_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = IMX074_WIDTH; + sel->r.height = IMX074_HEIGHT; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP: + return 0; + default: + return -EINVAL; + } } static int imx074_enum_mbus_code(struct v4l2_subdev *sd, @@ -278,8 +273,6 @@ static int imx074_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { .s_stream = imx074_s_stream, - .g_crop = imx074_g_crop, - .cropcap = imx074_cropcap, .g_mbus_config = imx074_g_mbus_config, }; @@ -289,6 +282,7 @@ static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { static const struct v4l2_subdev_pad_ops imx074_subdev_pad_ops = { .enum_mbus_code = imx074_enum_mbus_code, + .get_selection = imx074_get_selection, .get_fmt = imx074_get_fmt, .set_fmt = imx074_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/mt9m001.c b/drivers/media/i2c/soc_camera/mt9m001.c index 69becc358659..3d6378d4491c 100644 --- a/drivers/media/i2c/soc_camera/mt9m001.c +++ b/drivers/media/i2c/soc_camera/mt9m001.c @@ -171,13 +171,19 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int mt9m001_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); - struct v4l2_rect rect = a->c; - int ret; + struct v4l2_rect rect = sel->r; const u16 hblank = 9, vblank = 25; + int ret; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; if (mt9m001->fmts == mt9m001_colour_fmts) /* @@ -225,29 +231,30 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return ret; } -static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int mt9m001_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); - a->c = mt9m001->rect; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = MT9M001_COLUMN_SKIP; - a->bounds.top = MT9M001_ROW_SKIP; - a->bounds.width = MT9M001_MAX_WIDTH; - a->bounds.height = MT9M001_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = MT9M001_COLUMN_SKIP; + sel->r.top = MT9M001_ROW_SKIP; + sel->r.width = MT9M001_MAX_WIDTH; + sel->r.height = MT9M001_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = mt9m001->rect; + return 0; + default: + return -EINVAL; + } } static int mt9m001_get_fmt(struct v4l2_subdev *sd, @@ -275,18 +282,18 @@ static int mt9m001_s_fmt(struct v4l2_subdev *sd, { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9m001 *mt9m001 = to_mt9m001(client); - struct v4l2_crop a = { - .c = { - .left = mt9m001->rect.left, - .top = mt9m001->rect.top, - .width = mf->width, - .height = mf->height, - }, + struct v4l2_subdev_selection sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + .r.left = mt9m001->rect.left, + .r.top = mt9m001->rect.top, + .r.width = mf->width, + .r.height = mf->height, }; int ret; /* No support for scaling so far, just crop. TODO: use skipping */ - ret = mt9m001_s_crop(sd, &a); + ret = mt9m001_set_selection(sd, NULL, &sel); if (!ret) { mf->width = mt9m001->rect.width; mf->height = mt9m001->rect.height; @@ -625,9 +632,6 @@ static int mt9m001_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { .s_stream = mt9m001_s_stream, - .s_crop = mt9m001_s_crop, - .g_crop = mt9m001_g_crop, - .cropcap = mt9m001_cropcap, .g_mbus_config = mt9m001_g_mbus_config, .s_mbus_config = mt9m001_s_mbus_config, }; @@ -638,6 +642,8 @@ static const struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9m001_subdev_pad_ops = { .enum_mbus_code = mt9m001_enum_mbus_code, + .get_selection = mt9m001_get_selection, + .set_selection = mt9m001_set_selection, .get_fmt = mt9m001_get_fmt, .set_fmt = mt9m001_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/mt9m111.c b/drivers/media/i2c/soc_camera/mt9m111.c index 6dfaead6aaa8..6c8d1123658c 100644 --- a/drivers/media/i2c/soc_camera/mt9m111.c +++ b/drivers/media/i2c/soc_camera/mt9m111.c @@ -383,14 +383,18 @@ static int mt9m111_reset(struct mt9m111 *mt9m111) return ret; } -static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int mt9m111_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - struct v4l2_rect rect = a->c; - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9m111 *mt9m111 = to_mt9m111(client); + struct v4l2_rect rect = sel->r; int width, height; int ret; - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; if (mt9m111->fmt->code == MEDIA_BUS_FMT_SBGGR8_1X8 || @@ -421,30 +425,30 @@ static int mt9m111_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return ret; } -static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int mt9m111_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); - - a->c = mt9m111->rect; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} + struct i2c_client *client = v4l2_get_subdevdata(sd); + struct mt9m111 *mt9m111 = to_mt9m111(client); -static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; - a->bounds.left = MT9M111_MIN_DARK_COLS; - a->bounds.top = MT9M111_MIN_DARK_ROWS; - a->bounds.width = MT9M111_MAX_WIDTH; - a->bounds.height = MT9M111_MAX_HEIGHT; - a->defrect = a->bounds; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = MT9M111_MIN_DARK_COLS; + sel->r.top = MT9M111_MIN_DARK_ROWS; + sel->r.width = MT9M111_MAX_WIDTH; + sel->r.height = MT9M111_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = mt9m111->rect; + return 0; + default: + return -EINVAL; + } } static int mt9m111_get_fmt(struct v4l2_subdev *sd, @@ -867,14 +871,13 @@ static int mt9m111_g_mbus_config(struct v4l2_subdev *sd, } static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { - .s_crop = mt9m111_s_crop, - .g_crop = mt9m111_g_crop, - .cropcap = mt9m111_cropcap, .g_mbus_config = mt9m111_g_mbus_config, }; static const struct v4l2_subdev_pad_ops mt9m111_subdev_pad_ops = { .enum_mbus_code = mt9m111_enum_mbus_code, + .get_selection = mt9m111_get_selection, + .set_selection = mt9m111_set_selection, .get_fmt = mt9m111_get_fmt, .set_fmt = mt9m111_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/mt9t031.c b/drivers/media/i2c/soc_camera/mt9t031.c index 5c8e3ffe3b27..3aa5569065ad 100644 --- a/drivers/media/i2c/soc_camera/mt9t031.c +++ b/drivers/media/i2c/soc_camera/mt9t031.c @@ -264,7 +264,7 @@ static int mt9t031_set_params(struct i2c_client *client, /* * The caller provides a supported format, as guaranteed by - * .set_fmt(FORMAT_TRY), soc_camera_s_crop() and soc_camera_cropcap() + * .set_fmt(FORMAT_TRY), soc_camera_s_selection() and soc_camera_cropcap() */ if (ret >= 0) ret = reg_write(client, MT9T031_COLUMN_START, rect->left); @@ -294,11 +294,17 @@ static int mt9t031_set_params(struct i2c_client *client, return ret < 0 ? ret : 0; } -static int mt9t031_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int mt9t031_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - struct v4l2_rect rect = a->c; struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t031 *mt9t031 = to_mt9t031(client); + struct v4l2_rect rect = sel->r; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; rect.width = ALIGN(rect.width, 2); rect.height = ALIGN(rect.height, 2); @@ -312,29 +318,30 @@ static int mt9t031_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return mt9t031_set_params(client, &rect, mt9t031->xskip, mt9t031->yskip); } -static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int mt9t031_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t031 *mt9t031 = to_mt9t031(client); - a->c = mt9t031->rect; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = MT9T031_COLUMN_SKIP; - a->bounds.top = MT9T031_ROW_SKIP; - a->bounds.width = MT9T031_MAX_WIDTH; - a->bounds.height = MT9T031_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = MT9T031_COLUMN_SKIP; + sel->r.top = MT9T031_ROW_SKIP; + sel->r.width = MT9T031_MAX_WIDTH; + sel->r.height = MT9T031_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = mt9t031->rect; + return 0; + default: + return -EINVAL; + } } static int mt9t031_get_fmt(struct v4l2_subdev *sd, @@ -721,9 +728,6 @@ static int mt9t031_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { .s_stream = mt9t031_s_stream, - .s_crop = mt9t031_s_crop, - .g_crop = mt9t031_g_crop, - .cropcap = mt9t031_cropcap, .g_mbus_config = mt9t031_g_mbus_config, .s_mbus_config = mt9t031_s_mbus_config, }; @@ -734,6 +738,8 @@ static const struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9t031_subdev_pad_ops = { .enum_mbus_code = mt9t031_enum_mbus_code, + .get_selection = mt9t031_get_selection, + .set_selection = mt9t031_set_selection, .get_fmt = mt9t031_get_fmt, .set_fmt = mt9t031_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/mt9t112.c b/drivers/media/i2c/soc_camera/mt9t112.c index 6a1b2a9f9a09..2ef22241ec14 100644 --- a/drivers/media/i2c/soc_camera/mt9t112.c +++ b/drivers/media/i2c/soc_camera/mt9t112.c @@ -867,39 +867,48 @@ static int mt9t112_set_params(struct mt9t112_priv *priv, return 0; } -static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = MAX_WIDTH; - a->bounds.height = MAX_HEIGHT; - a->defrect.left = 0; - a->defrect.top = 0; - a->defrect.width = VGA_WIDTH; - a->defrect.height = VGA_HEIGHT; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; -} - -static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int mt9t112_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); - a->c = priv->frame; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = MAX_WIDTH; + sel->r.height = MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = VGA_WIDTH; + sel->r.height = VGA_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = priv->frame; + return 0; + default: + return -EINVAL; + } } -static int mt9t112_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int mt9t112_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9t112_priv *priv = to_mt9t112(client); - const struct v4l2_rect *rect = &a->c; + const struct v4l2_rect *rect = &sel->r; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; return mt9t112_set_params(priv, rect, priv->format->code); } @@ -1024,15 +1033,14 @@ static int mt9t112_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = { .s_stream = mt9t112_s_stream, - .cropcap = mt9t112_cropcap, - .g_crop = mt9t112_g_crop, - .s_crop = mt9t112_s_crop, .g_mbus_config = mt9t112_g_mbus_config, .s_mbus_config = mt9t112_s_mbus_config, }; static const struct v4l2_subdev_pad_ops mt9t112_subdev_pad_ops = { .enum_mbus_code = mt9t112_enum_mbus_code, + .get_selection = mt9t112_get_selection, + .set_selection = mt9t112_set_selection, .get_fmt = mt9t112_get_fmt, .set_fmt = mt9t112_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/mt9v022.c b/drivers/media/i2c/soc_camera/mt9v022.c index 2721e583bfa0..6a14ab5e4f2d 100644 --- a/drivers/media/i2c/soc_camera/mt9v022.c +++ b/drivers/media/i2c/soc_camera/mt9v022.c @@ -276,14 +276,20 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable) return 0; } -static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int mt9v022_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); - struct v4l2_rect rect = a->c; + struct v4l2_rect rect = sel->r; int min_row, min_blank; int ret; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + /* Bayer format - even size lengths */ if (mt9v022->fmts == mt9v022_colour_fmts) { rect.width = ALIGN(rect.width, 2); @@ -350,29 +356,30 @@ static int mt9v022_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return 0; } -static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int mt9v022_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); - a->c = mt9v022->rect; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = MT9V022_COLUMN_SKIP; - a->bounds.top = MT9V022_ROW_SKIP; - a->bounds.width = MT9V022_MAX_WIDTH; - a->bounds.height = MT9V022_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = MT9V022_COLUMN_SKIP; + sel->r.top = MT9V022_ROW_SKIP; + sel->r.width = MT9V022_MAX_WIDTH; + sel->r.height = MT9V022_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = mt9v022->rect; + return 0; + default: + return -EINVAL; + } } static int mt9v022_get_fmt(struct v4l2_subdev *sd, @@ -400,13 +407,13 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, { struct i2c_client *client = v4l2_get_subdevdata(sd); struct mt9v022 *mt9v022 = to_mt9v022(client); - struct v4l2_crop a = { - .c = { - .left = mt9v022->rect.left, - .top = mt9v022->rect.top, - .width = mf->width, - .height = mf->height, - }, + struct v4l2_subdev_selection sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + .r.left = mt9v022->rect.left, + .r.top = mt9v022->rect.top, + .r.width = mf->width, + .r.height = mf->height, }; int ret; @@ -430,7 +437,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd, } /* No support for scaling on this camera, just crop. */ - ret = mt9v022_s_crop(sd, &a); + ret = mt9v022_set_selection(sd, NULL, &sel); if (!ret) { mf->width = mt9v022->rect.width; mf->height = mt9v022->rect.height; @@ -853,9 +860,6 @@ static int mt9v022_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { .s_stream = mt9v022_s_stream, - .s_crop = mt9v022_s_crop, - .g_crop = mt9v022_g_crop, - .cropcap = mt9v022_cropcap, .g_mbus_config = mt9v022_g_mbus_config, .s_mbus_config = mt9v022_s_mbus_config, }; @@ -866,6 +870,8 @@ static const struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { static const struct v4l2_subdev_pad_ops mt9v022_subdev_pad_ops = { .enum_mbus_code = mt9v022_enum_mbus_code, + .get_selection = mt9v022_get_selection, + .set_selection = mt9v022_set_selection, .get_fmt = mt9v022_get_fmt, .set_fmt = mt9v022_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/ov2640.c b/drivers/media/i2c/soc_camera/ov2640.c index 9b4f5deec748..56de18263359 100644 --- a/drivers/media/i2c/soc_camera/ov2640.c +++ b/drivers/media/i2c/soc_camera/ov2640.c @@ -928,29 +928,25 @@ static int ov2640_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int ov2640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) -{ - a->c.left = 0; - a->c.top = 0; - a->c.width = UXGA_WIDTH; - a->c.height = UXGA_HEIGHT; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) +static int ov2640_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = UXGA_WIDTH; - a->bounds.height = UXGA_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = UXGA_WIDTH; + sel->r.height = UXGA_HEIGHT; + return 0; + default: + return -EINVAL; + } } static int ov2640_video_probe(struct i2c_client *client) @@ -1024,13 +1020,12 @@ static int ov2640_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { .s_stream = ov2640_s_stream, - .cropcap = ov2640_cropcap, - .g_crop = ov2640_g_crop, .g_mbus_config = ov2640_g_mbus_config, }; static const struct v4l2_subdev_pad_ops ov2640_subdev_pad_ops = { .enum_mbus_code = ov2640_enum_mbus_code, + .get_selection = ov2640_get_selection, .get_fmt = ov2640_get_fmt, .set_fmt = ov2640_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/ov5642.c b/drivers/media/i2c/soc_camera/ov5642.c index bab9ac0c1764..3d185bd622a3 100644 --- a/drivers/media/i2c/soc_camera/ov5642.c +++ b/drivers/media/i2c/soc_camera/ov5642.c @@ -850,13 +850,19 @@ static int ov5642_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int ov5642_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5642 *priv = to_ov5642(client); - struct v4l2_rect rect = a->c; + struct v4l2_rect rect = sel->r; int ret; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + v4l_bound_align_image(&rect.width, 48, OV5642_MAX_WIDTH, 1, &rect.height, 32, OV5642_MAX_HEIGHT, 1, 0); @@ -878,32 +884,30 @@ static int ov5642_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return ret; } -static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int ov5642_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov5642 *priv = to_ov5642(client); - struct v4l2_rect *rect = &a->c; - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; - *rect = priv->crop_rect; - - return 0; -} - -static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = OV5642_MAX_WIDTH; - a->bounds.height = OV5642_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = OV5642_MAX_WIDTH; + sel->r.height = OV5642_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = priv->crop_rect; + return 0; + default: + return -EINVAL; + } } static int ov5642_g_mbus_config(struct v4l2_subdev *sd, @@ -940,14 +944,13 @@ static int ov5642_s_power(struct v4l2_subdev *sd, int on) } static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { - .s_crop = ov5642_s_crop, - .g_crop = ov5642_g_crop, - .cropcap = ov5642_cropcap, .g_mbus_config = ov5642_g_mbus_config, }; static const struct v4l2_subdev_pad_ops ov5642_subdev_pad_ops = { .enum_mbus_code = ov5642_enum_mbus_code, + .get_selection = ov5642_get_selection, + .set_selection = ov5642_set_selection, .get_fmt = ov5642_get_fmt, .set_fmt = ov5642_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/ov6650.c b/drivers/media/i2c/soc_camera/ov6650.c index 1f8af1ee8352..4bf2995e1cb8 100644 --- a/drivers/media/i2c/soc_camera/ov6650.c +++ b/drivers/media/i2c/soc_camera/ov6650.c @@ -432,25 +432,43 @@ static int ov6650_s_power(struct v4l2_subdev *sd, int on) return soc_camera_set_power(&client->dev, ssdd, priv->clk, on); } -static int ov6650_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int ov6650_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov6650 *priv = to_ov6650(client); - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->c = priv->rect; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = DEF_HSTRT << 1; + sel->r.top = DEF_VSTRT << 1; + sel->r.width = W_CIF; + sel->r.height = H_CIF; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = priv->rect; + return 0; + default: + return -EINVAL; + } } -static int ov6650_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int ov6650_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct ov6650 *priv = to_ov6650(client); - struct v4l2_rect rect = a->c; + struct v4l2_rect rect = sel->r; int ret; - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; rect.left = ALIGN(rect.left, 2); @@ -483,22 +501,6 @@ static int ov6650_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return ret; } -static int ov6650_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - a->bounds.left = DEF_HSTRT << 1; - a->bounds.top = DEF_VSTRT << 1; - a->bounds.width = W_CIF; - a->bounds.height = H_CIF; - a->defrect = a->bounds; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; -} - static int ov6650_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_format *format) @@ -549,16 +551,15 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) struct soc_camera_sense *sense = icd->sense; struct ov6650 *priv = to_ov6650(client); bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); - struct v4l2_crop a = { - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .c = { - .left = priv->rect.left + (priv->rect.width >> 1) - - (mf->width >> (1 - half_scale)), - .top = priv->rect.top + (priv->rect.height >> 1) - - (mf->height >> (1 - half_scale)), - .width = mf->width << half_scale, - .height = mf->height << half_scale, - }, + struct v4l2_subdev_selection sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + .r.left = priv->rect.left + (priv->rect.width >> 1) - + (mf->width >> (1 - half_scale)), + .r.top = priv->rect.top + (priv->rect.height >> 1) - + (mf->height >> (1 - half_scale)), + .r.width = mf->width << half_scale, + .r.height = mf->height << half_scale, }; u32 code = mf->code; unsigned long mclk, pclk; @@ -672,7 +673,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) dev_dbg(&client->dev, "pixel clock divider: %ld.%ld\n", mclk / pclk, 10 * mclk % pclk / pclk); - ret = ov6650_s_crop(sd, &a); + ret = ov6650_set_selection(sd, NULL, &sel); if (!ret) ret = ov6650_reg_rmw(client, REG_COMA, coma_set, coma_mask); if (!ret) @@ -943,9 +944,6 @@ static int ov6650_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov6650_video_ops = { .s_stream = ov6650_s_stream, - .cropcap = ov6650_cropcap, - .g_crop = ov6650_g_crop, - .s_crop = ov6650_s_crop, .g_parm = ov6650_g_parm, .s_parm = ov6650_s_parm, .g_mbus_config = ov6650_g_mbus_config, @@ -954,6 +952,8 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = { static const struct v4l2_subdev_pad_ops ov6650_pad_ops = { .enum_mbus_code = ov6650_enum_mbus_code, + .get_selection = ov6650_get_selection, + .set_selection = ov6650_set_selection, .get_fmt = ov6650_get_fmt, .set_fmt = ov6650_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/ov772x.c b/drivers/media/i2c/soc_camera/ov772x.c index a43410c1e254..7e68762b3a4b 100644 --- a/drivers/media/i2c/soc_camera/ov772x.c +++ b/drivers/media/i2c/soc_camera/ov772x.c @@ -851,29 +851,28 @@ ov772x_set_fmt_error: return ret; } -static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) -{ - a->c.left = 0; - a->c.top = 0; - a->c.width = VGA_WIDTH; - a->c.height = VGA_HEIGHT; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) +static int ov772x_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = OV772X_MAX_WIDTH; - a->bounds.height = OV772X_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + sel->r.left = 0; + sel->r.top = 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.width = OV772X_MAX_WIDTH; + sel->r.height = OV772X_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r.width = VGA_WIDTH; + sel->r.height = VGA_HEIGHT; + return 0; + default: + return -EINVAL; + } } static int ov772x_get_fmt(struct v4l2_subdev *sd, @@ -1030,13 +1029,12 @@ static int ov772x_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { .s_stream = ov772x_s_stream, - .cropcap = ov772x_cropcap, - .g_crop = ov772x_g_crop, .g_mbus_config = ov772x_g_mbus_config, }; static const struct v4l2_subdev_pad_ops ov772x_subdev_pad_ops = { .enum_mbus_code = ov772x_enum_mbus_code, + .get_selection = ov772x_get_selection, .get_fmt = ov772x_get_fmt, .set_fmt = ov772x_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/ov9640.c b/drivers/media/i2c/soc_camera/ov9640.c index 8caae1c07541..8c93c57af71c 100644 --- a/drivers/media/i2c/soc_camera/ov9640.c +++ b/drivers/media/i2c/soc_camera/ov9640.c @@ -561,29 +561,25 @@ static int ov9640_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int ov9640_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) -{ - a->c.left = 0; - a->c.top = 0; - a->c.width = W_SXGA; - a->c.height = H_SXGA; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) +static int ov9640_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = W_SXGA; - a->bounds.height = H_SXGA; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + sel->r.left = 0; + sel->r.top = 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP: + sel->r.width = W_SXGA; + sel->r.height = H_SXGA; + return 0; + default: + return -EINVAL; + } } static int ov9640_video_probe(struct i2c_client *client) @@ -667,13 +663,12 @@ static int ov9640_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov9640_video_ops = { .s_stream = ov9640_s_stream, - .cropcap = ov9640_cropcap, - .g_crop = ov9640_g_crop, .g_mbus_config = ov9640_g_mbus_config, }; static const struct v4l2_subdev_pad_ops ov9640_pad_ops = { .enum_mbus_code = ov9640_enum_mbus_code, + .get_selection = ov9640_get_selection, .set_fmt = ov9640_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/ov9740.c b/drivers/media/i2c/soc_camera/ov9740.c index 03a7fc7316ae..0da632d7d33a 100644 --- a/drivers/media/i2c/soc_camera/ov9740.c +++ b/drivers/media/i2c/soc_camera/ov9740.c @@ -737,29 +737,25 @@ static int ov9740_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = OV9740_MAX_WIDTH; - a->bounds.height = OV9740_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; -} - -static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int ov9740_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - a->c.left = 0; - a->c.top = 0; - a->c.width = OV9740_MAX_WIDTH; - a->c.height = OV9740_MAX_HEIGHT; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = OV9740_MAX_WIDTH; + sel->r.height = OV9740_MAX_HEIGHT; + return 0; + default: + return -EINVAL; + } } /* Set status of additional camera capabilities */ @@ -914,8 +910,6 @@ static int ov9740_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops ov9740_video_ops = { .s_stream = ov9740_s_stream, - .cropcap = ov9740_cropcap, - .g_crop = ov9740_g_crop, .g_mbus_config = ov9740_g_mbus_config, }; @@ -929,6 +923,7 @@ static struct v4l2_subdev_core_ops ov9740_core_ops = { static const struct v4l2_subdev_pad_ops ov9740_pad_ops = { .enum_mbus_code = ov9740_enum_mbus_code, + .get_selection = ov9740_get_selection, .set_fmt = ov9740_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/rj54n1cb0c.c b/drivers/media/i2c/soc_camera/rj54n1cb0c.c index aa7bfbb4ad71..bc8ec59a3fbd 100644 --- a/drivers/media/i2c/soc_camera/rj54n1cb0c.c +++ b/drivers/media/i2c/soc_camera/rj54n1cb0c.c @@ -538,15 +538,21 @@ static int rj54n1_commit(struct i2c_client *client) static int rj54n1_sensor_scale(struct v4l2_subdev *sd, s32 *in_w, s32 *in_h, s32 *out_w, s32 *out_h); -static int rj54n1_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int rj54n1_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct rj54n1 *rj54n1 = to_rj54n1(client); - const struct v4l2_rect *rect = &a->c; + const struct v4l2_rect *rect = &sel->r; int dummy = 0, output_w, output_h, input_w = rect->width, input_h = rect->height; int ret; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; + /* arbitrary minimum width and height, edges unimportant */ soc_camera_limit_side(&dummy, &input_w, RJ54N1_COLUMN_SKIP, 8, RJ54N1_MAX_WIDTH); @@ -573,29 +579,30 @@ static int rj54n1_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return 0; } -static int rj54n1_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int rj54n1_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct rj54n1 *rj54n1 = to_rj54n1(client); - a->c = rj54n1->rect; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int rj54n1_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - a->bounds.left = RJ54N1_COLUMN_SKIP; - a->bounds.top = RJ54N1_ROW_SKIP; - a->bounds.width = RJ54N1_MAX_WIDTH; - a->bounds.height = RJ54N1_MAX_HEIGHT; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = RJ54N1_COLUMN_SKIP; + sel->r.top = RJ54N1_ROW_SKIP; + sel->r.width = RJ54N1_MAX_WIDTH; + sel->r.height = RJ54N1_MAX_HEIGHT; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = rj54n1->rect; + return 0; + default: + return -EINVAL; + } } static int rj54n1_get_fmt(struct v4l2_subdev *sd, @@ -1246,15 +1253,14 @@ static int rj54n1_s_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { .s_stream = rj54n1_s_stream, - .g_crop = rj54n1_g_crop, - .s_crop = rj54n1_s_crop, - .cropcap = rj54n1_cropcap, .g_mbus_config = rj54n1_g_mbus_config, .s_mbus_config = rj54n1_s_mbus_config, }; static const struct v4l2_subdev_pad_ops rj54n1_subdev_pad_ops = { .enum_mbus_code = rj54n1_enum_mbus_code, + .get_selection = rj54n1_get_selection, + .set_selection = rj54n1_set_selection, .get_fmt = rj54n1_get_fmt, .set_fmt = rj54n1_set_fmt, }; diff --git a/drivers/media/i2c/soc_camera/tw9910.c b/drivers/media/i2c/soc_camera/tw9910.c index 06aff81787a7..4002c07f3857 100644 --- a/drivers/media/i2c/soc_camera/tw9910.c +++ b/drivers/media/i2c/soc_camera/tw9910.c @@ -676,44 +676,28 @@ tw9910_set_fmt_error: return ret; } -static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int tw9910_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct i2c_client *client = v4l2_get_subdevdata(sd); struct tw9910_priv *priv = to_tw9910(client); - a->c.left = 0; - a->c.top = 0; - if (priv->norm & V4L2_STD_NTSC) { - a->c.width = 640; - a->c.height = 480; - } else { - a->c.width = 768; - a->c.height = 576; - } - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - struct i2c_client *client = v4l2_get_subdevdata(sd); - struct tw9910_priv *priv = to_tw9910(client); + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; + /* Only CROP, CROP_DEFAULT and CROP_BOUNDS are supported */ + if (sel->target > V4L2_SEL_TGT_CROP_BOUNDS) + return -EINVAL; - a->bounds.left = 0; - a->bounds.top = 0; + sel->r.left = 0; + sel->r.top = 0; if (priv->norm & V4L2_STD_NTSC) { - a->bounds.width = 640; - a->bounds.height = 480; + sel->r.width = 640; + sel->r.height = 480; } else { - a->bounds.width = 768; - a->bounds.height = 576; + sel->r.width = 768; + sel->r.height = 576; } - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - return 0; } @@ -921,8 +905,6 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { .s_std = tw9910_s_std, .g_std = tw9910_g_std, .s_stream = tw9910_s_stream, - .cropcap = tw9910_cropcap, - .g_crop = tw9910_g_crop, .g_mbus_config = tw9910_g_mbus_config, .s_mbus_config = tw9910_s_mbus_config, .g_tvnorms = tw9910_g_tvnorms, @@ -930,6 +912,7 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { static const struct v4l2_subdev_pad_ops tw9910_subdev_pad_ops = { .enum_mbus_code = tw9910_enum_mbus_code, + .get_selection = tw9910_get_selection, .get_fmt = tw9910_get_fmt, .set_fmt = tw9910_set_fmt, }; diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c index 0b6d46c453bf..b7648fda519c 100644 --- a/drivers/media/i2c/tvp5150.c +++ b/drivers/media/i2c/tvp5150.c @@ -871,19 +871,22 @@ static int tvp5150_fill_fmt(struct v4l2_subdev *sd, return 0; } -static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) +static int tvp5150_set_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - struct v4l2_rect rect = a->c; struct tvp5150 *decoder = to_tvp5150(sd); + struct v4l2_rect rect = sel->r; v4l2_std_id std; - unsigned int hmax; + int hmax; + + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE || + sel->target != V4L2_SEL_TGT_CROP) + return -EINVAL; v4l2_dbg(1, debug, sd, "%s left=%d, top=%d, width=%d, height=%d\n", __func__, rect.left, rect.top, rect.width, rect.height); - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - /* tvp5150 has some special limits */ rect.left = clamp(rect.left, 0, TVP5150_MAX_CROP_LEFT); rect.width = clamp_t(unsigned int, rect.width, @@ -924,44 +927,39 @@ static int tvp5150_s_crop(struct v4l2_subdev *sd, const struct v4l2_crop *a) return 0; } -static int tvp5150_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) +static int tvp5150_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { - struct tvp5150 *decoder = to_tvp5150(sd); - - a->c = decoder->rect; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int tvp5150_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) -{ - struct tvp5150 *decoder = to_tvp5150(sd); + struct tvp5150 *decoder = container_of(sd, struct tvp5150, sd); v4l2_std_id std; - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) return -EINVAL; - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = TVP5150_H_MAX; - - /* Calculate height based on current standard */ - if (decoder->norm == V4L2_STD_ALL) - std = tvp5150_read_std(sd); - else - std = decoder->norm; - - if (std & V4L2_STD_525_60) - a->bounds.height = TVP5150_V_MAX_525_60; - else - a->bounds.height = TVP5150_V_MAX_OTHERS; - - a->defrect = a->bounds; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; - - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = TVP5150_H_MAX; + + /* Calculate height based on current standard */ + if (decoder->norm == V4L2_STD_ALL) + std = tvp5150_read_std(sd); + else + std = decoder->norm; + if (std & V4L2_STD_525_60) + sel->r.height = TVP5150_V_MAX_525_60; + else + sel->r.height = TVP5150_V_MAX_OTHERS; + return 0; + case V4L2_SEL_TGT_CROP: + sel->r = decoder->rect; + return 0; + default: + return -EINVAL; + } } static int tvp5150_g_mbus_config(struct v4l2_subdev *sd, @@ -1233,9 +1231,6 @@ static const struct v4l2_subdev_video_ops tvp5150_video_ops = { .s_std = tvp5150_s_std, .s_stream = tvp5150_s_stream, .s_routing = tvp5150_s_routing, - .s_crop = tvp5150_s_crop, - .g_crop = tvp5150_g_crop, - .cropcap = tvp5150_cropcap, .g_mbus_config = tvp5150_g_mbus_config, }; @@ -1251,6 +1246,8 @@ static const struct v4l2_subdev_pad_ops tvp5150_pad_ops = { .enum_frame_size = tvp5150_enum_frame_size, .set_fmt = tvp5150_fill_fmt, .get_fmt = tvp5150_fill_fmt, + .get_selection = tvp5150_get_selection, + .set_selection = tvp5150_set_selection, }; static const struct v4l2_subdev_ops tvp5150_ops = { diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 7d9f35976d18..7354469670b7 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -772,40 +772,45 @@ isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format) } static int -isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) -{ - struct isp_video *video = video_drvdata(file); - struct v4l2_subdev *subdev; - int ret; - - subdev = isp_video_remote_subdev(video, NULL); - if (subdev == NULL) - return -EINVAL; - - mutex_lock(&video->mutex); - ret = v4l2_subdev_call(subdev, video, cropcap, cropcap); - mutex_unlock(&video->mutex); - - return ret == -ENOIOCTLCMD ? -ENOTTY : ret; -} - -static int -isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) +isp_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) { struct isp_video *video = video_drvdata(file); struct v4l2_subdev_format format; struct v4l2_subdev *subdev; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + }; u32 pad; int ret; + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + break; + case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + break; + default: + return -EINVAL; + } subdev = isp_video_remote_subdev(video, &pad); if (subdev == NULL) return -EINVAL; - /* Try the get crop operation first and fallback to get format if not + /* Try the get selection operation first and fallback to get format if not * implemented. */ - ret = v4l2_subdev_call(subdev, video, g_crop, crop); + sdsel.pad = pad; + ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel); + if (!ret) + sel->r = sdsel.r; if (ret != -ENOIOCTLCMD) return ret; @@ -815,28 +820,50 @@ isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop) if (ret < 0) return ret == -ENOIOCTLCMD ? -ENOTTY : ret; - crop->c.left = 0; - crop->c.top = 0; - crop->c.width = format.format.width; - crop->c.height = format.format.height; + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = format.format.width; + sel->r.height = format.format.height; return 0; } static int -isp_video_set_crop(struct file *file, void *fh, const struct v4l2_crop *crop) +isp_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel) { struct isp_video *video = video_drvdata(file); struct v4l2_subdev *subdev; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; + u32 pad; int ret; - subdev = isp_video_remote_subdev(video, NULL); + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + break; + case V4L2_SEL_TGT_COMPOSE: + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + break; + default: + return -EINVAL; + } + subdev = isp_video_remote_subdev(video, &pad); if (subdev == NULL) return -EINVAL; + sdsel.pad = pad; mutex_lock(&video->mutex); - ret = v4l2_subdev_call(subdev, video, s_crop, crop); + ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel); mutex_unlock(&video->mutex); + if (!ret) + sel->r = sdsel.r; return ret == -ENOIOCTLCMD ? -ENOTTY : ret; } @@ -1252,9 +1279,8 @@ static const struct v4l2_ioctl_ops isp_video_ioctl_ops = { .vidioc_g_fmt_vid_out = isp_video_get_format, .vidioc_s_fmt_vid_out = isp_video_set_format, .vidioc_try_fmt_vid_out = isp_video_try_format, - .vidioc_cropcap = isp_video_cropcap, - .vidioc_g_crop = isp_video_get_crop, - .vidioc_s_crop = isp_video_set_crop, + .vidioc_g_selection = isp_video_get_selection, + .vidioc_s_selection = isp_video_set_selection, .vidioc_g_parm = isp_video_get_param, .vidioc_s_parm = isp_video_set_param, .vidioc_reqbufs = isp_video_reqbufs, diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index e1f39b4cf1cd..4ee7b1570f62 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -937,7 +937,10 @@ static int sh_vou_s_selection(struct file *file, void *fh, { struct v4l2_rect *rect = &sel->r; struct sh_vou_device *vou_dev = video_drvdata(file); - struct v4l2_crop sd_crop = {.type = V4L2_BUF_TYPE_VIDEO_OUTPUT}; + struct v4l2_subdev_selection sd_sel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_COMPOSE, + }; struct v4l2_pix_format *pix = &vou_dev->pix; struct sh_vou_geometry geo; struct v4l2_subdev_format format = { @@ -978,14 +981,14 @@ static int sh_vou_s_selection(struct file *file, void *fh, geo.in_height = pix->height; /* Configure the encoder one-to-one, position at 0, ignore errors */ - sd_crop.c.width = geo.output.width; - sd_crop.c.height = geo.output.height; + sd_sel.r.width = geo.output.width; + sd_sel.r.height = geo.output.height; /* - * We first issue a S_CROP, so that the subsequent S_FMT delivers the + * We first issue a S_SELECTION, so that the subsequent S_FMT delivers the * final encoder configuration. */ - v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, video, - s_crop, &sd_crop); + v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad, + set_selection, NULL, &sd_sel); format.format.width = geo.output.width; format.format.height = geo.output.height; ret = v4l2_device_call_until_err(&vou_dev->v4l2_dev, 0, pad, diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 2aaf4a8f71a0..ebbe514d64e2 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -1280,10 +1280,10 @@ static int pxa_camera_check_frame(u32 width, u32 height) (width & 0x01); } -static int pxa_camera_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) +static int pxa_camera_set_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { - const struct v4l2_rect *rect = &a->c; + const struct v4l2_rect *rect = &sel->r; struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct pxa_camera_dev *pcdev = ici->priv; @@ -1298,13 +1298,19 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, struct v4l2_mbus_framefmt *mf = &fmt.format; struct pxa_cam *cam = icd->host_priv; u32 fourcc = icd->current_fmt->host_fmt->fourcc; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; int ret; /* If PCLK is used to latch data from the sensor, check sense */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) icd->sense = &sense; - ret = v4l2_subdev_call(sd, video, s_crop, a); + ret = v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); icd->sense = NULL; @@ -1313,6 +1319,7 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd, rect->width, rect->height, rect->left, rect->top); return ret; } + sel->r = sdsel.r; ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt); if (ret < 0) @@ -1592,7 +1599,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = { .remove = pxa_camera_remove_device, .clock_start = pxa_camera_clock_start, .clock_stop = pxa_camera_clock_stop, - .set_crop = pxa_camera_set_crop, + .set_selection = pxa_camera_set_selection, .get_formats = pxa_camera_get_formats, .put_formats = pxa_camera_put_formats, .set_fmt = pxa_camera_set_fmt, diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index 9c137522c660..077f12d1575f 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -515,7 +515,7 @@ struct rcar_vin_cam { unsigned int out_width; unsigned int out_height; /* - * User window from S_CROP / G_CROP, produced by client cropping and + * User window from S_SELECTION / G_SELECTION, produced by client cropping and * scaling, VIN scaling and VIN cropping, mapped back onto the client * input window */ @@ -1471,16 +1471,15 @@ static void rcar_vin_put_formats(struct soc_camera_device *icd) icd->host_priv = NULL; } -static int rcar_vin_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) +static int rcar_vin_set_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { - struct v4l2_crop a_writable = *a; - const struct v4l2_rect *rect = &a_writable.c; + const struct v4l2_rect *rect = &sel->r; struct soc_camera_host *ici = to_soc_camera_host(icd->parent); struct rcar_vin_priv *priv = ici->priv; - struct v4l2_crop cam_crop; + struct v4l2_selection cam_sel; struct rcar_vin_cam *cam = icd->host_priv; - struct v4l2_rect *cam_rect = &cam_crop.c; + struct v4l2_rect *cam_rect = &cam_sel.r; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct device *dev = icd->parent; struct v4l2_subdev_format fmt = { @@ -1490,15 +1489,15 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd, u32 vnmc; int ret, i; - dev_dbg(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height, + dev_dbg(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height, rect->left, rect->top); /* During camera cropping its output window can change too, stop VIN */ capture_stop_preserve(priv, &vnmc); dev_dbg(dev, "VNMC_REG 0x%x\n", vnmc); - /* Apply iterative camera S_CROP for new input window. */ - ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop, + /* Apply iterative camera S_SELECTION for new input window. */ + ret = soc_camera_client_s_selection(sd, sel, &cam_sel, &cam->rect, &cam->subrect); if (ret < 0) return ret; @@ -1551,13 +1550,12 @@ static int rcar_vin_set_crop(struct soc_camera_device *icd, return ret; } -static int rcar_vin_get_crop(struct soc_camera_device *icd, - struct v4l2_crop *a) +static int rcar_vin_get_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { struct rcar_vin_cam *cam = icd->host_priv; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->c = cam->subrect; + sel->r = cam->subrect; return 0; } @@ -1824,8 +1822,8 @@ static struct soc_camera_host_ops rcar_vin_host_ops = { .remove = rcar_vin_remove_device, .get_formats = rcar_vin_get_formats, .put_formats = rcar_vin_put_formats, - .get_crop = rcar_vin_get_crop, - .set_crop = rcar_vin_set_crop, + .get_selection = rcar_vin_get_selection, + .set_selection = rcar_vin_set_selection, .try_fmt = rcar_vin_try_fmt, .set_fmt = rcar_vin_set_fmt, .poll = rcar_vin_poll, diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 05eafe3a421e..e5571c8a368e 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -134,7 +134,7 @@ struct sh_mobile_ceu_cam { unsigned int width; unsigned int height; /* - * User window from S_CROP / G_CROP, produced by client cropping and + * User window from S_SELECTION / G_SELECTION, produced by client cropping and * scaling, CEU scaling and CEU cropping, mapped back onto the client * input window */ @@ -1109,17 +1109,16 @@ static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd) * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of * scaling and cropping algorithms and for the meaning of referenced here steps. */ -static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, - const struct v4l2_crop *a) +static int sh_mobile_ceu_set_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { - struct v4l2_crop a_writable = *a; - const struct v4l2_rect *rect = &a_writable.c; + struct v4l2_rect *rect = &sel->r; struct device *dev = icd->parent; struct soc_camera_host *ici = to_soc_camera_host(dev); struct sh_mobile_ceu_dev *pcdev = ici->priv; - struct v4l2_crop cam_crop; + struct v4l2_selection cam_sel; struct sh_mobile_ceu_cam *cam = icd->host_priv; - struct v4l2_rect *cam_rect = &cam_crop.c; + struct v4l2_rect *cam_rect = &cam_sel.r; struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct v4l2_subdev_format fmt = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, @@ -1131,7 +1130,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, u32 capsr, cflcr; int ret; - dev_geo(dev, "S_CROP(%ux%u@%u:%u)\n", rect->width, rect->height, + dev_geo(dev, "S_SELECTION(%ux%u@%u:%u)\n", rect->width, rect->height, rect->left, rect->top); /* During camera cropping its output window can change too, stop CEU */ @@ -1139,10 +1138,10 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); /* - * 1. - 2. Apply iterative camera S_CROP for new input window, read back + * 1. - 2. Apply iterative camera S_SELECTION for new input window, read back * actual camera rectangle. */ - ret = soc_camera_client_s_crop(sd, &a_writable, &cam_crop, + ret = soc_camera_client_s_selection(sd, sel, &cam_sel, &cam->rect, &cam->subrect); if (ret < 0) return ret; @@ -1251,13 +1250,12 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, return ret; } -static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd, - struct v4l2_crop *a) +static int sh_mobile_ceu_get_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { struct sh_mobile_ceu_cam *cam = icd->host_priv; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->c = cam->subrect; + sel->r = cam->subrect; return 0; } @@ -1499,8 +1497,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, return ret; } -static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd, - const struct v4l2_crop *a) +static int sh_mobile_ceu_set_liveselection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); @@ -1519,7 +1517,7 @@ static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd, "Client failed to stop the stream: %d\n", ret); else /* Do the crop, if it fails, there's nothing more we can do */ - sh_mobile_ceu_set_crop(icd, a); + sh_mobile_ceu_set_selection(icd, sel); dev_geo(icd->parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height); @@ -1600,9 +1598,9 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { .clock_stop = sh_mobile_ceu_clock_stop, .get_formats = sh_mobile_ceu_get_formats, .put_formats = sh_mobile_ceu_put_formats, - .get_crop = sh_mobile_ceu_get_crop, - .set_crop = sh_mobile_ceu_set_crop, - .set_livecrop = sh_mobile_ceu_set_livecrop, + .get_selection = sh_mobile_ceu_get_selection, + .set_selection = sh_mobile_ceu_set_selection, + .set_liveselection = sh_mobile_ceu_set_liveselection, .set_fmt = sh_mobile_ceu_set_fmt, .try_fmt = sh_mobile_ceu_try_fmt, .poll = sh_mobile_ceu_poll, diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index 46c7186f7867..edd1c1de4e33 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -581,7 +581,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd, dev_dbg(icd->pdev, "S_FMT(%c%c%c%c, %ux%u)\n", pixfmtstr(pix->pixelformat), pix->width, pix->height); - /* We always call try_fmt() before set_fmt() or set_crop() */ + /* We always call try_fmt() before set_fmt() or set_selection() */ ret = soc_camera_try_fmt(icd, f); if (ret < 0) return ret; @@ -1025,72 +1025,6 @@ static int soc_camera_streamoff(struct file *file, void *priv, return ret; } -static int soc_camera_cropcap(struct file *file, void *fh, - struct v4l2_cropcap *a) -{ - struct soc_camera_device *icd = file->private_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - - return ici->ops->cropcap(icd, a); -} - -static int soc_camera_g_crop(struct file *file, void *fh, - struct v4l2_crop *a) -{ - struct soc_camera_device *icd = file->private_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - int ret; - - ret = ici->ops->get_crop(icd, a); - - return ret; -} - -/* - * According to the V4L2 API, drivers shall not update the struct v4l2_crop - * argument with the actual geometry, instead, the user shall use G_CROP to - * retrieve it. - */ -static int soc_camera_s_crop(struct file *file, void *fh, - const struct v4l2_crop *a) -{ - struct soc_camera_device *icd = file->private_data; - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - const struct v4l2_rect *rect = &a->c; - struct v4l2_crop current_crop; - int ret; - - if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - dev_dbg(icd->pdev, "S_CROP(%ux%u@%u:%u)\n", - rect->width, rect->height, rect->left, rect->top); - - current_crop.type = a->type; - - /* If get_crop fails, we'll let host and / or client drivers decide */ - ret = ici->ops->get_crop(icd, ¤t_crop); - - /* Prohibit window size change with initialised buffers */ - if (ret < 0) { - dev_err(icd->pdev, - "S_CROP denied: getting current crop failed\n"); - } else if ((a->c.width == current_crop.c.width && - a->c.height == current_crop.c.height) || - !is_streaming(ici, icd)) { - /* same size or not streaming - use .set_crop() */ - ret = ici->ops->set_crop(icd, a); - } else if (ici->ops->set_livecrop) { - ret = ici->ops->set_livecrop(icd, a); - } else { - dev_err(icd->pdev, - "S_CROP denied: queue initialised and sizes differ\n"); - ret = -EBUSY; - } - - return ret; -} - static int soc_camera_g_selection(struct file *file, void *fh, struct v4l2_selection *s) { @@ -1101,9 +1035,6 @@ static int soc_camera_g_selection(struct file *file, void *fh, if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (!ici->ops->get_selection) - return -ENOTTY; - return ici->ops->get_selection(icd, s); } @@ -1135,10 +1066,11 @@ static int soc_camera_s_selection(struct file *file, void *fh, return -EBUSY; } - if (!ici->ops->set_selection) - return -ENOTTY; - - ret = ici->ops->set_selection(icd, s); + if (s->target == V4L2_SEL_TGT_CROP && is_streaming(ici, icd) && + ici->ops->set_liveselection) + ret = ici->ops->set_liveselection(icd, s); + else + ret = ici->ops->set_selection(icd, s); if (!ret && s->target == V4L2_SEL_TGT_COMPOSE) { icd->user_width = s->r.width; @@ -1881,23 +1813,40 @@ static int soc_camera_remove(struct soc_camera_device *icd) return 0; } -static int default_cropcap(struct soc_camera_device *icd, - struct v4l2_cropcap *a) +static int default_g_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - return v4l2_subdev_call(sd, video, cropcap, a); -} + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + }; + int ret; -static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a) -{ - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - return v4l2_subdev_call(sd, video, g_crop, a); + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); + if (ret) + return ret; + sel->r = sdsel.r; + return 0; } -static int default_s_crop(struct soc_camera_device *icd, const struct v4l2_crop *a) +static int default_s_selection(struct soc_camera_device *icd, + struct v4l2_selection *sel) { struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - return v4l2_subdev_call(sd, video, s_crop, a); + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; + int ret; + + ret = v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); + if (ret) + return ret; + sel->r = sdsel.r; + return 0; } static int default_g_parm(struct soc_camera_device *icd, @@ -1968,12 +1917,10 @@ int soc_camera_host_register(struct soc_camera_host *ici) !ici->v4l2_dev.dev) return -EINVAL; - if (!ici->ops->set_crop) - ici->ops->set_crop = default_s_crop; - if (!ici->ops->get_crop) - ici->ops->get_crop = default_g_crop; - if (!ici->ops->cropcap) - ici->ops->cropcap = default_cropcap; + if (!ici->ops->set_selection) + ici->ops->set_selection = default_s_selection; + if (!ici->ops->get_selection) + ici->ops->get_selection = default_g_selection; if (!ici->ops->set_parm) ici->ops->set_parm = default_s_parm; if (!ici->ops->get_parm) @@ -2126,9 +2073,6 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { .vidioc_expbuf = soc_camera_expbuf, .vidioc_streamon = soc_camera_streamon, .vidioc_streamoff = soc_camera_streamoff, - .vidioc_cropcap = soc_camera_cropcap, - .vidioc_g_crop = soc_camera_g_crop, - .vidioc_s_crop = soc_camera_s_crop, .vidioc_g_selection = soc_camera_g_selection, .vidioc_s_selection = soc_camera_s_selection, .vidioc_g_parm = soc_camera_g_parm, diff --git a/drivers/media/platform/soc_camera/soc_camera_platform.c b/drivers/media/platform/soc_camera/soc_camera_platform.c index a51d2a42998c..534d6c3c6d60 100644 --- a/drivers/media/platform/soc_camera/soc_camera_platform.c +++ b/drivers/media/platform/soc_camera/soc_camera_platform.c @@ -76,35 +76,27 @@ static int soc_camera_platform_enum_mbus_code(struct v4l2_subdev *sd, return 0; } -static int soc_camera_platform_g_crop(struct v4l2_subdev *sd, - struct v4l2_crop *a) -{ - struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); - - a->c.left = 0; - a->c.top = 0; - a->c.width = p->format.width; - a->c.height = p->format.height; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - return 0; -} - -static int soc_camera_platform_cropcap(struct v4l2_subdev *sd, - struct v4l2_cropcap *a) +static int soc_camera_platform_get_selection(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_selection *sel) { struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); - a->bounds.left = 0; - a->bounds.top = 0; - a->bounds.width = p->format.width; - a->bounds.height = p->format.height; - a->defrect = a->bounds; - a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - a->pixelaspect.numerator = 1; - a->pixelaspect.denominator = 1; + if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) + return -EINVAL; - return 0; + switch (sel->target) { + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + case V4L2_SEL_TGT_CROP: + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = p->format.width; + sel->r.height = p->format.height; + return 0; + default: + return -EINVAL; + } } static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd, @@ -120,13 +112,12 @@ static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd, static struct v4l2_subdev_video_ops platform_subdev_video_ops = { .s_stream = soc_camera_platform_s_stream, - .cropcap = soc_camera_platform_cropcap, - .g_crop = soc_camera_platform_g_crop, .g_mbus_config = soc_camera_platform_g_mbus_config, }; static const struct v4l2_subdev_pad_ops platform_subdev_pad_ops = { .enum_mbus_code = soc_camera_platform_enum_mbus_code, + .get_selection = soc_camera_platform_get_selection, .get_fmt = soc_camera_platform_fill_fmt, .set_fmt = soc_camera_platform_fill_fmt, }; diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.c b/drivers/media/platform/soc_camera/soc_scale_crop.c index bda29bc1b933..f77252d6ccd3 100644 --- a/drivers/media/platform/soc_camera/soc_scale_crop.c +++ b/drivers/media/platform/soc_camera/soc_scale_crop.c @@ -40,24 +40,22 @@ static bool is_inside(const struct v4l2_rect *r1, const struct v4l2_rect *r2) /* Get and store current client crop */ int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect) { - struct v4l2_crop crop; - struct v4l2_cropcap cap; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP, + }; int ret; - crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, g_crop, &crop); + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); if (!ret) { - *rect = crop.c; + *rect = sdsel.r; return ret; } - /* Camera driver doesn't support .g_crop(), assume default rectangle */ - cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, cropcap, &cap); + sdsel.target = V4L2_SEL_TGT_CROP_DEFAULT; + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); if (!ret) - *rect = cap.defrect; + *rect = sdsel.r; return ret; } @@ -93,17 +91,27 @@ static void update_subrect(struct v4l2_rect *rect, struct v4l2_rect *subrect) * 2. if (1) failed, try to double the client image until we get one big enough * 3. if (2) failed, try to request the maximum image */ -int soc_camera_client_s_crop(struct v4l2_subdev *sd, - struct v4l2_crop *crop, struct v4l2_crop *cam_crop, +int soc_camera_client_s_selection(struct v4l2_subdev *sd, + struct v4l2_selection *sel, struct v4l2_selection *cam_sel, struct v4l2_rect *target_rect, struct v4l2_rect *subrect) { - struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; + struct v4l2_subdev_selection bounds = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP_BOUNDS, + }; + struct v4l2_rect *rect = &sel->r, *cam_rect = &cam_sel->r; struct device *dev = sd->v4l2_dev->dev; - struct v4l2_cropcap cap; int ret; unsigned int width, height; - v4l2_subdev_call(sd, video, s_crop, crop); + v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); + sel->r = sdsel.r; ret = soc_camera_client_g_rect(sd, cam_rect); if (ret < 0) return ret; @@ -113,29 +121,29 @@ int soc_camera_client_s_crop(struct v4l2_subdev *sd, * be within camera cropcap bounds */ if (!memcmp(rect, cam_rect, sizeof(*rect))) { - /* Even if camera S_CROP failed, but camera rectangle matches */ - dev_dbg(dev, "Camera S_CROP successful for %dx%d@%d:%d\n", + /* Even if camera S_SELECTION failed, but camera rectangle matches */ + dev_dbg(dev, "Camera S_SELECTION successful for %dx%d@%d:%d\n", rect->width, rect->height, rect->left, rect->top); *target_rect = *cam_rect; return 0; } /* Try to fix cropping, that camera hasn't managed to set */ - dev_geo(dev, "Fix camera S_CROP for %dx%d@%d:%d to %dx%d@%d:%d\n", + dev_geo(dev, "Fix camera S_SELECTION for %dx%d@%d:%d to %dx%d@%d:%d\n", cam_rect->width, cam_rect->height, cam_rect->left, cam_rect->top, rect->width, rect->height, rect->left, rect->top); /* We need sensor maximum rectangle */ - ret = v4l2_subdev_call(sd, video, cropcap, &cap); + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &bounds); if (ret < 0) return ret; /* Put user requested rectangle within sensor bounds */ - soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2, - cap.bounds.width); - soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4, - cap.bounds.height); + soc_camera_limit_side(&rect->left, &rect->width, sdsel.r.left, 2, + bounds.r.width); + soc_camera_limit_side(&rect->top, &rect->height, sdsel.r.top, 4, + bounds.r.height); /* * Popular special case - some cameras can only handle fixed sizes like @@ -150,7 +158,7 @@ int soc_camera_client_s_crop(struct v4l2_subdev *sd, */ while (!ret && (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) && - (cap.bounds.width > width || cap.bounds.height > height)) { + (bounds.r.width > width || bounds.r.height > height)) { width *= 2; height *= 2; @@ -168,36 +176,40 @@ int soc_camera_client_s_crop(struct v4l2_subdev *sd, * Instead we just drop to the left and top bounds. */ if (cam_rect->left > rect->left) - cam_rect->left = cap.bounds.left; + cam_rect->left = bounds.r.left; if (cam_rect->left + cam_rect->width < rect->left + rect->width) cam_rect->width = rect->left + rect->width - cam_rect->left; if (cam_rect->top > rect->top) - cam_rect->top = cap.bounds.top; + cam_rect->top = bounds.r.top; if (cam_rect->top + cam_rect->height < rect->top + rect->height) cam_rect->height = rect->top + rect->height - cam_rect->top; - v4l2_subdev_call(sd, video, s_crop, cam_crop); + sdsel.r = *cam_rect; + v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); + *cam_rect = sdsel.r; ret = soc_camera_client_g_rect(sd, cam_rect); - dev_geo(dev, "Camera S_CROP %d for %dx%d@%d:%d\n", ret, + dev_geo(dev, "Camera S_SELECTION %d for %dx%d@%d:%d\n", ret, cam_rect->width, cam_rect->height, cam_rect->left, cam_rect->top); } - /* S_CROP must not modify the rectangle */ + /* S_SELECTION must not modify the rectangle */ if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) { /* * The camera failed to configure a suitable cropping, * we cannot use the current rectangle, set to max */ - *cam_rect = cap.bounds; - v4l2_subdev_call(sd, video, s_crop, cam_crop); + sdsel.r = bounds.r; + v4l2_subdev_call(sd, pad, set_selection, NULL, &sdsel); + *cam_rect = sdsel.r; + ret = soc_camera_client_g_rect(sd, cam_rect); - dev_geo(dev, "Camera S_CROP %d for max %dx%d@%d:%d\n", ret, + dev_geo(dev, "Camera S_SELECTION %d for max %dx%d@%d:%d\n", ret, cam_rect->width, cam_rect->height, cam_rect->left, cam_rect->top); } @@ -209,7 +221,7 @@ int soc_camera_client_s_crop(struct v4l2_subdev *sd, return ret; } -EXPORT_SYMBOL(soc_camera_client_s_crop); +EXPORT_SYMBOL(soc_camera_client_s_selection); /* Iterative set_fmt, also updates cached client crop on success */ static int client_set_fmt(struct soc_camera_device *icd, @@ -221,7 +233,10 @@ static int client_set_fmt(struct soc_camera_device *icd, struct device *dev = icd->parent; struct v4l2_mbus_framefmt *mf = &format->format; unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; - struct v4l2_cropcap cap; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = V4L2_SEL_TGT_CROP_BOUNDS, + }; bool host_1to1; int ret; @@ -243,16 +258,14 @@ static int client_set_fmt(struct soc_camera_device *icd, if (!host_can_scale) goto update_cache; - cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - - ret = v4l2_subdev_call(sd, video, cropcap, &cap); + ret = v4l2_subdev_call(sd, pad, get_selection, NULL, &sdsel); if (ret < 0) return ret; - if (max_width > cap.bounds.width) - max_width = cap.bounds.width; - if (max_height > cap.bounds.height) - max_height = cap.bounds.height; + if (max_width > sdsel.r.width) + max_width = sdsel.r.width; + if (max_height > sdsel.r.height) + max_height = sdsel.r.height; /* Camera set a format, but geometry is not precise, try to improve */ tmp_w = mf->width; diff --git a/drivers/media/platform/soc_camera/soc_scale_crop.h b/drivers/media/platform/soc_camera/soc_scale_crop.h index 184a30dff541..9ca469312a1f 100644 --- a/drivers/media/platform/soc_camera/soc_scale_crop.h +++ b/drivers/media/platform/soc_camera/soc_scale_crop.h @@ -16,7 +16,7 @@ struct soc_camera_device; -struct v4l2_crop; +struct v4l2_selection; struct v4l2_mbus_framefmt; struct v4l2_pix_format; struct v4l2_rect; @@ -31,8 +31,8 @@ static inline unsigned int soc_camera_shift_scale(unsigned int size, #define soc_camera_calc_scale(in, shift, out) soc_camera_shift_scale(in, shift, out) int soc_camera_client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); -int soc_camera_client_s_crop(struct v4l2_subdev *sd, - struct v4l2_crop *crop, struct v4l2_crop *cam_crop, +int soc_camera_client_s_selection(struct v4l2_subdev *sd, + struct v4l2_selection *sel, struct v4l2_selection *cam_sel, struct v4l2_rect *target_rect, struct v4l2_rect *subrect); int soc_camera_client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect, struct v4l2_rect *subrect, diff --git a/drivers/staging/media/omap4iss/iss_video.c b/drivers/staging/media/omap4iss/iss_video.c index 90b7ff56722d..c16927ac8eb0 100644 --- a/drivers/staging/media/omap4iss/iss_video.c +++ b/drivers/staging/media/omap4iss/iss_video.c @@ -645,6 +645,103 @@ iss_video_try_format(struct file *file, void *fh, struct v4l2_format *format) return 0; } +static int +iss_video_get_selection(struct file *file, void *fh, struct v4l2_selection *sel) +{ + struct iss_video *video = video_drvdata(file); + struct v4l2_subdev_format format; + struct v4l2_subdev *subdev; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + }; + u32 pad; + int ret; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + case V4L2_SEL_TGT_CROP_BOUNDS: + case V4L2_SEL_TGT_CROP_DEFAULT: + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + break; + case V4L2_SEL_TGT_COMPOSE: + case V4L2_SEL_TGT_COMPOSE_BOUNDS: + case V4L2_SEL_TGT_COMPOSE_DEFAULT: + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + break; + default: + return -EINVAL; + } + subdev = iss_video_remote_subdev(video, &pad); + if (subdev == NULL) + return -EINVAL; + + /* Try the get selection operation first and fallback to get format if not + * implemented. + */ + sdsel.pad = pad; + ret = v4l2_subdev_call(subdev, pad, get_selection, NULL, &sdsel); + if (!ret) + sel->r = sdsel.r; + if (ret != -ENOIOCTLCMD) + return ret; + + format.pad = pad; + format.which = V4L2_SUBDEV_FORMAT_ACTIVE; + ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format); + if (ret < 0) + return ret == -ENOIOCTLCMD ? -ENOTTY : ret; + + sel->r.left = 0; + sel->r.top = 0; + sel->r.width = format.format.width; + sel->r.height = format.format.height; + + return 0; +} + +static int +iss_video_set_selection(struct file *file, void *fh, struct v4l2_selection *sel) +{ + struct iss_video *video = video_drvdata(file); + struct v4l2_subdev *subdev; + struct v4l2_subdev_selection sdsel = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + .target = sel->target, + .flags = sel->flags, + .r = sel->r, + }; + u32 pad; + int ret; + + switch (sel->target) { + case V4L2_SEL_TGT_CROP: + if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) + return -EINVAL; + break; + case V4L2_SEL_TGT_COMPOSE: + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + break; + default: + return -EINVAL; + } + subdev = iss_video_remote_subdev(video, &pad); + if (subdev == NULL) + return -EINVAL; + + sdsel.pad = pad; + mutex_lock(&video->mutex); + ret = v4l2_subdev_call(subdev, pad, set_selection, NULL, &sdsel); + mutex_unlock(&video->mutex); + if (!ret) + sel->r = sdsel.r; + + return ret == -ENOIOCTLCMD ? -ENOTTY : ret; +} + static int iss_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a) { @@ -971,6 +1068,8 @@ static const struct v4l2_ioctl_ops iss_video_ioctl_ops = { .vidioc_g_fmt_vid_out = iss_video_get_format, .vidioc_s_fmt_vid_out = iss_video_set_format, .vidioc_try_fmt_vid_out = iss_video_try_format, + .vidioc_g_selection = iss_video_get_selection, + .vidioc_s_selection = iss_video_set_selection, .vidioc_g_parm = iss_video_get_param, .vidioc_s_parm = iss_video_set_param, .vidioc_reqbufs = iss_video_reqbufs, diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 97aa13314bfd..1a15c3e4efd3 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -105,16 +105,13 @@ struct soc_camera_host_ops { int (*get_formats)(struct soc_camera_device *, unsigned int, struct soc_camera_format_xlate *); void (*put_formats)(struct soc_camera_device *); - int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *); - int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *); - int (*set_crop)(struct soc_camera_device *, const struct v4l2_crop *); int (*get_selection)(struct soc_camera_device *, struct v4l2_selection *); int (*set_selection)(struct soc_camera_device *, struct v4l2_selection *); /* - * The difference to .set_crop() is, that .set_livecrop is not allowed + * The difference to .set_selection() is, that .set_liveselection is not allowed * to change the output sizes */ - int (*set_livecrop)(struct soc_camera_device *, const struct v4l2_crop *); + int (*set_liveselection)(struct soc_camera_device *, struct v4l2_selection *); int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); void (*init_videobuf)(struct videobuf_queue *, diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 2a2240c99b30..22ea819ada95 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -360,10 +360,6 @@ struct v4l2_mbus_frame_desc { * * @cropcap: callback for %VIDIOC_CROPCAP ioctl handler code. * - * @g_crop: callback for %VIDIOC_G_CROP ioctl handler code. - * - * @s_crop: callback for %VIDIOC_S_CROP ioctl handler code. - * * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code. * * @s_parm: callback for %VIDIOC_S_PARM ioctl handler code. @@ -403,8 +399,6 @@ struct v4l2_subdev_video_ops { int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); - int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); - int (*s_crop)(struct v4l2_subdev *sd, const struct v4l2_crop *crop); int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*g_frame_interval)(struct v4l2_subdev *sd, -- cgit v1.2.3-70-g09d2 From ecf37493f4bda87b77c83a4f64132e287cb55fc8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 4 Jul 2016 05:08:01 -0300 Subject: [media] v4l2-subdev: rename cropcap to g_pixelaspect The old cropcap video op is now only used to pass the pixelaspect ratio, so rename it. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/adv7180.c | 12 ++++++------ drivers/media/platform/rcar-vin/rcar-v4l2.c | 2 +- include/media/v4l2-subdev.h | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/drivers/media/i2c/adv7180.c b/drivers/media/i2c/adv7180.c index c367ad6f6327..515ea6ae41d7 100644 --- a/drivers/media/i2c/adv7180.c +++ b/drivers/media/i2c/adv7180.c @@ -761,16 +761,16 @@ static int adv7180_g_mbus_config(struct v4l2_subdev *sd, return 0; } -static int adv7180_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *cropcap) +static int adv7180_g_pixelaspect(struct v4l2_subdev *sd, struct v4l2_fract *aspect) { struct adv7180_state *state = to_state(sd); if (state->curr_norm & V4L2_STD_525_60) { - cropcap->pixelaspect.numerator = 11; - cropcap->pixelaspect.denominator = 10; + aspect->numerator = 11; + aspect->denominator = 10; } else { - cropcap->pixelaspect.numerator = 54; - cropcap->pixelaspect.denominator = 59; + aspect->numerator = 54; + aspect->denominator = 59; } return 0; @@ -823,7 +823,7 @@ static const struct v4l2_subdev_video_ops adv7180_video_ops = { .g_input_status = adv7180_g_input_status, .s_routing = adv7180_s_routing, .g_mbus_config = adv7180_g_mbus_config, - .cropcap = adv7180_cropcap, + .g_pixelaspect = adv7180_g_pixelaspect, .g_tvnorms = adv7180_g_tvnorms, .s_stream = adv7180_s_stream, }; diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index d0e9d65b9cf3..62ca7e35517e 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -385,7 +385,7 @@ static int rvin_cropcap(struct file *file, void *priv, if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - return v4l2_subdev_call(sd, video, cropcap, crop); + return v4l2_subdev_call(sd, video, g_pixelaspect, &crop->pixelaspect); } static int rvin_enum_input(struct file *file, void *priv, diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 22ea819ada95..de5117a01b98 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -358,7 +358,7 @@ struct v4l2_mbus_frame_desc { * @s_stream: used to notify the driver that a video stream will start or has * stopped. * - * @cropcap: callback for %VIDIOC_CROPCAP ioctl handler code. + * @g_pixelaspect: callback to return the pixelaspect ratio. * * @g_parm: callback for %VIDIOC_G_PARM ioctl handler code. * @@ -398,7 +398,7 @@ struct v4l2_subdev_video_ops { int (*g_tvnorms_output)(struct v4l2_subdev *sd, v4l2_std_id *std); int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); - int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); + int (*g_pixelaspect)(struct v4l2_subdev *sd, struct v4l2_fract *aspect); int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); int (*g_frame_interval)(struct v4l2_subdev *sd, -- cgit v1.2.3-70-g09d2 From 0ff657b0f6120cb53f98b1b42c87af34670edff5 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 21 Jul 2016 09:14:02 -0300 Subject: [media] vb2: don't return NULL for alloc and get_userptr ops Always return an ERR_PTR() instead of NULL. This makes the behavior of alloc, get_userptr and attach_dmabuf the same. Update the documentation in videobuf2-core.h as well. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 12 ++++++++---- drivers/media/v4l2-core/videobuf2-dma-sg.c | 13 +++++++------ drivers/media/v4l2-core/videobuf2-vmalloc.c | 13 ++++++++----- include/media/videobuf2-core.h | 6 +++--- 4 files changed, 26 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index f50ff6f33c6f..71d8bd8dcc81 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -198,6 +198,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) q->is_output ? DMA_TO_DEVICE : DMA_FROM_DEVICE; void *mem_priv; int plane; + int ret = -ENOMEM; /* * Allocate memory for all planes in this buffer @@ -209,8 +210,11 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb) mem_priv = call_ptr_memop(vb, alloc, q->alloc_devs[plane] ? : q->dev, q->dma_attrs, size, dma_dir, q->gfp_flags); - if (IS_ERR_OR_NULL(mem_priv)) + if (IS_ERR(mem_priv)) { + if (mem_priv) + ret = PTR_ERR(mem_priv); goto free; + } /* Associate allocator private data with this plane */ vb->planes[plane].mem_priv = mem_priv; @@ -224,7 +228,7 @@ free: vb->planes[plane - 1].mem_priv = NULL; } - return -ENOMEM; + return ret; } /** @@ -1136,10 +1140,10 @@ static int __qbuf_userptr(struct vb2_buffer *vb, const void *pb) q->alloc_devs[plane] ? : q->dev, planes[plane].m.userptr, planes[plane].length, dma_dir); - if (IS_ERR_OR_NULL(mem_priv)) { + if (IS_ERR(mem_priv)) { dprintk(1, "failed acquiring userspace " "memory for plane %d\n", plane); - ret = mem_priv ? PTR_ERR(mem_priv) : -EINVAL; + ret = PTR_ERR(mem_priv); goto err; } vb->planes[plane].mem_priv = mem_priv; diff --git a/drivers/media/v4l2-core/videobuf2-dma-sg.c b/drivers/media/v4l2-core/videobuf2-dma-sg.c index bd82d709ee82..e0165c10b82f 100644 --- a/drivers/media/v4l2-core/videobuf2-dma-sg.c +++ b/drivers/media/v4l2-core/videobuf2-dma-sg.c @@ -104,11 +104,12 @@ static void *vb2_dma_sg_alloc(struct device *dev, unsigned long dma_attrs, int ret; int num_pages; - if (WARN_ON(dev == NULL)) - return NULL; + if (WARN_ON(!dev)) + return ERR_PTR(-EINVAL); + buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) - return NULL; + return ERR_PTR(-ENOMEM); buf->vaddr = NULL; buf->dma_dir = dma_dir; @@ -166,7 +167,7 @@ fail_pages_alloc: kfree(buf->pages); fail_pages_array_alloc: kfree(buf); - return NULL; + return ERR_PTR(-ENOMEM); } static void vb2_dma_sg_put(void *buf_priv) @@ -226,7 +227,7 @@ static void *vb2_dma_sg_get_userptr(struct device *dev, unsigned long vaddr, buf = kzalloc(sizeof *buf, GFP_KERNEL); if (!buf) - return NULL; + return ERR_PTR(-ENOMEM); buf->vaddr = NULL; buf->dev = dev; @@ -266,7 +267,7 @@ userptr_fail_sgtable: vb2_destroy_framevec(vec); userptr_fail_pfnvec: kfree(buf); - return NULL; + return ERR_PTR(-ENOMEM); } /* diff --git a/drivers/media/v4l2-core/videobuf2-vmalloc.c b/drivers/media/v4l2-core/videobuf2-vmalloc.c index c2820a6e164d..ab3227b75c84 100644 --- a/drivers/media/v4l2-core/videobuf2-vmalloc.c +++ b/drivers/media/v4l2-core/videobuf2-vmalloc.c @@ -41,7 +41,7 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, buf = kzalloc(sizeof(*buf), GFP_KERNEL | gfp_flags); if (!buf) - return NULL; + return ERR_PTR(-ENOMEM); buf->size = size; buf->vaddr = vmalloc_user(buf->size); @@ -53,7 +53,7 @@ static void *vb2_vmalloc_alloc(struct device *dev, unsigned long attrs, if (!buf->vaddr) { pr_debug("vmalloc of size %ld failed\n", buf->size); kfree(buf); - return NULL; + return ERR_PTR(-ENOMEM); } atomic_inc(&buf->refcount); @@ -77,17 +77,20 @@ static void *vb2_vmalloc_get_userptr(struct device *dev, unsigned long vaddr, struct vb2_vmalloc_buf *buf; struct frame_vector *vec; int n_pages, offset, i; + int ret = -ENOMEM; buf = kzalloc(sizeof(*buf), GFP_KERNEL); if (!buf) - return NULL; + return ERR_PTR(-ENOMEM); buf->dma_dir = dma_dir; offset = vaddr & ~PAGE_MASK; buf->size = size; vec = vb2_create_framevec(vaddr, size, dma_dir == DMA_FROM_DEVICE); - if (IS_ERR(vec)) + if (IS_ERR(vec)) { + ret = PTR_ERR(vec); goto fail_pfnvec_create; + } buf->vec = vec; n_pages = frame_vector_count(vec); if (frame_vector_to_pages(vec) < 0) { @@ -117,7 +120,7 @@ fail_map: fail_pfnvec_create: kfree(buf); - return NULL; + return ERR_PTR(ret); } static void vb2_vmalloc_put_userptr(void *buf_priv) diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index a4a9a55a0c42..b6546db670ca 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -33,7 +33,7 @@ struct vb2_threadio_data; /** * struct vb2_mem_ops - memory handling/memory allocator operations * @alloc: allocate video memory and, optionally, allocator private data, - * return NULL on failure or a pointer to allocator private, + * return ERR_PTR() on failure or a pointer to allocator private, * per-buffer data on success; the returned private structure * will then be passed as buf_priv argument to other ops in this * structure. Additional gfp_flags to use when allocating the @@ -50,14 +50,14 @@ struct vb2_threadio_data; * USERPTR memory types; vaddr is the address passed to the * videobuf layer when queuing a video buffer of USERPTR type; * should return an allocator private per-buffer structure - * associated with the buffer on success, NULL on failure; + * associated with the buffer on success, ERR_PTR() on failure; * the returned private structure will then be passed as buf_priv * argument to other ops in this structure. * @put_userptr: inform the allocator that a USERPTR buffer will no longer * be used. * @attach_dmabuf: attach a shared struct dma_buf for a hardware operation; * used for DMABUF memory types; dev is the alloc device - * dbuf is the shared dma_buf; returns NULL on failure; + * dbuf is the shared dma_buf; returns ERR_PTR() on failure; * allocator private per-buffer structure on success; * this needs to be used for further accesses to the buffer. * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF -- cgit v1.2.3-70-g09d2 From bb5147aa42777efe8fec262eab579cfba4500133 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 11 Aug 2016 02:10:10 -0300 Subject: [media] media-entity.h: remove redundant macro definition for gobj_to_link() The macro gobj_to_link() is defined twice in media-entity.h. Let's remove one. Signed-off-by: Liu Ying Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 09b03c17784d..afd61713ea3b 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -520,9 +520,6 @@ static inline bool media_entity_enum_intersects( #define gobj_to_link(gobj) \ container_of(gobj, struct media_link, graph_obj) -#define gobj_to_link(gobj) \ - container_of(gobj, struct media_link, graph_obj) - #define gobj_to_pad(gobj) \ container_of(gobj, struct media_pad, graph_obj) -- cgit v1.2.3-70-g09d2 From f598a6e362bb287a50085ffe0c3c8506127919f9 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 11 Aug 2016 02:10:09 -0300 Subject: [media] media-entity.h: Correct KernelDoc of media_entity_enum_empty() The function media_entity_enum_empty() returns true when the bitmap of the input parameter media entity enumeration is empty instead of marked. This patch corrects the return value description of the function. Signed-off-by: Liu Ying Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index afd61713ea3b..fa874ad4870e 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -486,7 +486,7 @@ media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, * * @ent_enum: Entity enumeration * - * Returns true if the entity was marked. + * Returns true if the entity was empty. */ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) { -- cgit v1.2.3-70-g09d2 From 6a21b728732390deb75536dd9253d958ca9223d0 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Thu, 11 Aug 2016 02:10:11 -0300 Subject: [media] media-entity.h: remove redundant macro definition for gobj_to_pad() The macro gobj_to_pad() is defined twice in media-entity.h. Let's remove one. Signed-off-by: Liu Ying Signed-off-by: Mauro Carvalho Chehab --- include/media/media-entity.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include') diff --git a/include/media/media-entity.h b/include/media/media-entity.h index fa874ad4870e..7bf6885dd37f 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -520,9 +520,6 @@ static inline bool media_entity_enum_intersects( #define gobj_to_link(gobj) \ container_of(gobj, struct media_link, graph_obj) -#define gobj_to_pad(gobj) \ - container_of(gobj, struct media_pad, graph_obj) - #define gobj_to_intf(gobj) \ container_of(gobj, struct media_interface, graph_obj) -- cgit v1.2.3-70-g09d2 From a53d2f299dc83340c695e153363a2f21641d5f58 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 11 Aug 2016 13:28:16 -0300 Subject: [media] v4l2-async: remove unneeded .registered_async callback The v4l2_subdev_core_ops .registered_async callback was added to notify a subdev when its entity has been registered with the media device, to allow for example to modify the media graph (i.e: adding entities/links). But that's not needed since there is already a .registered callback in struct v4l2_subdev_internal_ops that's called after the entity has been registered with the media device in v4l2_device_register_subdev(). Suggested-by: Sakari Ailus Signed-off-by: Javier Martinez Canillas Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-async.c | 7 ------- include/media/v4l2-subdev.h | 3 --- 2 files changed, 10 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index a4b224d92572..5bada202b2d3 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -119,13 +119,6 @@ static int v4l2_async_test_notify(struct v4l2_async_notifier *notifier, return ret; } - ret = v4l2_subdev_call(sd, core, registered_async); - if (ret < 0 && ret != -ENOIOCTLCMD) { - if (notifier->unbind) - notifier->unbind(notifier, sd, asd); - return ret; - } - if (list_empty(¬ifier->waiting) && notifier->complete) return notifier->complete(notifier); diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index de5117a01b98..6e1d044e3ee8 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -184,8 +184,6 @@ struct v4l2_subdev_io_pin_config { * for it to be warned when the value of a control changes. * * @unsubscribe_event: remove event subscription from the control framework. - * - * @registered_async: the subdevice has been registered async. */ struct v4l2_subdev_core_ops { int (*log_status)(struct v4l2_subdev *sd); @@ -211,7 +209,6 @@ struct v4l2_subdev_core_ops { struct v4l2_event_subscription *sub); int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub); - int (*registered_async)(struct v4l2_subdev *sd); }; /** -- cgit v1.2.3-70-g09d2 From 697a521fbc6dd6f64489d0feeb09631b227fcd67 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 11 Aug 2016 07:43:50 -0300 Subject: [media] smiapp: Rename smiapp_platform_data as smiapp_hwconfig This is really configuration to the driver originating from DT or elsewhere. Do not call it platform data. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 140 ++++++++++++++++---------------- drivers/media/i2c/smiapp/smiapp-quirk.c | 4 +- drivers/media/i2c/smiapp/smiapp.h | 2 +- include/media/i2c/smiapp.h | 2 +- 4 files changed, 74 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index d08ab6c8357c..92a6859b45ab 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -625,12 +625,12 @@ static int smiapp_init_late_controls(struct smiapp_sensor *sensor) 0, max_value, 1, max_value); } - for (max = 0; sensor->platform_data->op_sys_clock[max + 1]; max++); + for (max = 0; sensor->hwcfg->op_sys_clock[max + 1]; max++); sensor->link_freq = v4l2_ctrl_new_int_menu( &sensor->src->ctrl_handler, &smiapp_ctrl_ops, V4L2_CID_LINK_FREQ, __fls(*valid_link_freqs), - __ffs(*valid_link_freqs), sensor->platform_data->op_sys_clock); + __ffs(*valid_link_freqs), sensor->hwcfg->op_sys_clock); return sensor->src->ctrl_handler.error; } @@ -833,8 +833,8 @@ static int smiapp_get_mbus_formats(struct smiapp_sensor *sensor) pll->bits_per_pixel = f->compressed; - for (j = 0; sensor->platform_data->op_sys_clock[j]; j++) { - pll->link_freq = sensor->platform_data->op_sys_clock[j]; + for (j = 0; sensor->hwcfg->op_sys_clock[j]; j++) { + pll->link_freq = sensor->hwcfg->op_sys_clock[j]; rval = smiapp_pll_try(sensor, pll); dev_dbg(&client->dev, "link freq %u Hz, bpp %u %s\n", @@ -1032,22 +1032,22 @@ static int smiapp_change_cci_addr(struct smiapp_sensor *sensor) int rval; u32 val; - client->addr = sensor->platform_data->i2c_addr_dfl; + client->addr = sensor->hwcfg->i2c_addr_dfl; rval = smiapp_write(sensor, SMIAPP_REG_U8_CCI_ADDRESS_CONTROL, - sensor->platform_data->i2c_addr_alt << 1); + sensor->hwcfg->i2c_addr_alt << 1); if (rval) return rval; - client->addr = sensor->platform_data->i2c_addr_alt; + client->addr = sensor->hwcfg->i2c_addr_alt; /* verify addr change went ok */ rval = smiapp_read(sensor, SMIAPP_REG_U8_CCI_ADDRESS_CONTROL, &val); if (rval) return rval; - if (val != sensor->platform_data->i2c_addr_alt << 1) + if (val != sensor->hwcfg->i2c_addr_alt << 1) return -ENODEV; return 0; @@ -1061,13 +1061,13 @@ static int smiapp_change_cci_addr(struct smiapp_sensor *sensor) static int smiapp_setup_flash_strobe(struct smiapp_sensor *sensor) { struct smiapp_flash_strobe_parms *strobe_setup; - unsigned int ext_freq = sensor->platform_data->ext_clk; + unsigned int ext_freq = sensor->hwcfg->ext_clk; u32 tmp; u32 strobe_adjustment; u32 strobe_width_high_rs; int rval; - strobe_setup = sensor->platform_data->strobe_setup; + strobe_setup = sensor->hwcfg->strobe_setup; /* * How to calculate registers related to strobe length. Please @@ -1179,7 +1179,7 @@ static int smiapp_setup_flash_strobe(struct smiapp_sensor *sensor) strobe_setup->trigger); out: - sensor->platform_data->strobe_setup->trigger = 0; + sensor->hwcfg->strobe_setup->trigger = 0; return rval; } @@ -1201,9 +1201,9 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) } usleep_range(1000, 1000); - if (sensor->platform_data->set_xclk) - rval = sensor->platform_data->set_xclk( - &sensor->src->sd, sensor->platform_data->ext_clk); + if (sensor->hwcfg->set_xclk) + rval = sensor->hwcfg->set_xclk( + &sensor->src->sd, sensor->hwcfg->ext_clk); else rval = clk_prepare_enable(sensor->ext_clk); if (rval < 0) { @@ -1212,10 +1212,10 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) } usleep_range(1000, 1000); - if (gpio_is_valid(sensor->platform_data->xshutdown)) - gpio_set_value(sensor->platform_data->xshutdown, 1); + if (gpio_is_valid(sensor->hwcfg->xshutdown)) + gpio_set_value(sensor->hwcfg->xshutdown, 1); - sleep = SMIAPP_RESET_DELAY(sensor->platform_data->ext_clk); + sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk); usleep_range(sleep, sleep); /* @@ -1229,7 +1229,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) * is found. */ - if (sensor->platform_data->i2c_addr_alt) { + if (sensor->hwcfg->i2c_addr_alt) { rval = smiapp_change_cci_addr(sensor); if (rval) { dev_err(&client->dev, "cci address change error\n"); @@ -1244,7 +1244,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) goto out_cci_addr_fail; } - if (sensor->platform_data->i2c_addr_alt) { + if (sensor->hwcfg->i2c_addr_alt) { rval = smiapp_change_cci_addr(sensor); if (rval) { dev_err(&client->dev, "cci address change error\n"); @@ -1261,14 +1261,14 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) rval = smiapp_write( sensor, SMIAPP_REG_U16_EXTCLK_FREQUENCY_MHZ, - sensor->platform_data->ext_clk / (1000000 / (1 << 8))); + sensor->hwcfg->ext_clk / (1000000 / (1 << 8))); if (rval) { dev_err(&client->dev, "extclk frequency set failed\n"); goto out_cci_addr_fail; } rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_LANE_MODE, - sensor->platform_data->lanes - 1); + sensor->hwcfg->lanes - 1); if (rval) { dev_err(&client->dev, "csi lane mode set failed\n"); goto out_cci_addr_fail; @@ -1282,7 +1282,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) } rval = smiapp_write(sensor, SMIAPP_REG_U8_CSI_SIGNALLING_MODE, - sensor->platform_data->csi_signalling_mode); + sensor->hwcfg->csi_signalling_mode); if (rval) { dev_err(&client->dev, "csi signalling mode set failed\n"); goto out_cci_addr_fail; @@ -1322,10 +1322,10 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) return 0; out_cci_addr_fail: - if (gpio_is_valid(sensor->platform_data->xshutdown)) - gpio_set_value(sensor->platform_data->xshutdown, 0); - if (sensor->platform_data->set_xclk) - sensor->platform_data->set_xclk(&sensor->src->sd, 0); + if (gpio_is_valid(sensor->hwcfg->xshutdown)) + gpio_set_value(sensor->hwcfg->xshutdown, 0); + if (sensor->hwcfg->set_xclk) + sensor->hwcfg->set_xclk(&sensor->src->sd, 0); else clk_disable_unprepare(sensor->ext_clk); @@ -1343,15 +1343,15 @@ static void smiapp_power_off(struct smiapp_sensor *sensor) * really see a power off and next time the cci address change * will fail. So do a soft reset explicitly here. */ - if (sensor->platform_data->i2c_addr_alt) + if (sensor->hwcfg->i2c_addr_alt) smiapp_write(sensor, SMIAPP_REG_U8_SOFTWARE_RESET, SMIAPP_SOFTWARE_RESET); - if (gpio_is_valid(sensor->platform_data->xshutdown)) - gpio_set_value(sensor->platform_data->xshutdown, 0); - if (sensor->platform_data->set_xclk) - sensor->platform_data->set_xclk(&sensor->src->sd, 0); + if (gpio_is_valid(sensor->hwcfg->xshutdown)) + gpio_set_value(sensor->hwcfg->xshutdown, 0); + if (sensor->hwcfg->set_xclk) + sensor->hwcfg->set_xclk(&sensor->src->sd, 0); else clk_disable_unprepare(sensor->ext_clk); usleep_range(5000, 5000); @@ -1491,8 +1491,8 @@ static int smiapp_start_streaming(struct smiapp_sensor *sensor) if ((sensor->limits[SMIAPP_LIMIT_FLASH_MODE_CAPABILITY] & (SMIAPP_FLASH_MODE_CAPABILITY_SINGLE_STROBE | SMIAPP_FLASH_MODE_CAPABILITY_MULTIPLE_STROBE)) && - sensor->platform_data->strobe_setup != NULL && - sensor->platform_data->strobe_setup->trigger != 0) { + sensor->hwcfg->strobe_setup != NULL && + sensor->hwcfg->strobe_setup->trigger != 0) { rval = smiapp_setup_flash_strobe(sensor); if (rval) goto out; @@ -2309,7 +2309,7 @@ smiapp_sysfs_nvm_read(struct device *dev, struct device_attribute *attr, if (!sensor->nvm_size) { /* NVM not read yet - read it now */ - sensor->nvm_size = sensor->platform_data->nvm_size; + sensor->nvm_size = sensor->hwcfg->nvm_size; if (smiapp_set_power(subdev, 1) < 0) return -ENODEV; if (smiapp_read_nvm(sensor, sensor->nvm)) { @@ -2554,7 +2554,7 @@ static int smiapp_init(struct smiapp_sensor *sensor) return PTR_ERR(sensor->vana); } - if (!sensor->platform_data->set_xclk) { + if (!sensor->hwcfg->set_xclk) { sensor->ext_clk = devm_clk_get(&client->dev, NULL); if (IS_ERR(sensor->ext_clk)) { dev_err(&client->dev, "could not get clock\n"); @@ -2562,23 +2562,23 @@ static int smiapp_init(struct smiapp_sensor *sensor) } rval = clk_set_rate(sensor->ext_clk, - sensor->platform_data->ext_clk); + sensor->hwcfg->ext_clk); if (rval < 0) { dev_err(&client->dev, "unable to set clock freq to %u\n", - sensor->platform_data->ext_clk); + sensor->hwcfg->ext_clk); return rval; } } - if (gpio_is_valid(sensor->platform_data->xshutdown)) { + if (gpio_is_valid(sensor->hwcfg->xshutdown)) { rval = devm_gpio_request_one( - &client->dev, sensor->platform_data->xshutdown, 0, + &client->dev, sensor->hwcfg->xshutdown, 0, "SMIA++ xshutdown"); if (rval < 0) { dev_err(&client->dev, "unable to acquire reset gpio %d\n", - sensor->platform_data->xshutdown); + sensor->hwcfg->xshutdown); return rval; } } @@ -2612,7 +2612,7 @@ static int smiapp_init(struct smiapp_sensor *sensor) * * Rotation also changes the bayer pattern. */ - if (sensor->platform_data->module_board_orient == + if (sensor->hwcfg->module_board_orient == SMIAPP_MODULE_BOARD_ORIENT_180) sensor->hvflip_inv_mask = SMIAPP_IMAGE_ORIENTATION_HFLIP | SMIAPP_IMAGE_ORIENTATION_VFLIP; @@ -2661,9 +2661,9 @@ static int smiapp_init(struct smiapp_sensor *sensor) /* SMIA++ NVM initialization - it will be read from the sensor * when it is first requested by userspace. */ - if (sensor->minfo.smiapp_version && sensor->platform_data->nvm_size) { + if (sensor->minfo.smiapp_version && sensor->hwcfg->nvm_size) { sensor->nvm = devm_kzalloc(&client->dev, - sensor->platform_data->nvm_size, GFP_KERNEL); + sensor->hwcfg->nvm_size, GFP_KERNEL); if (sensor->nvm == NULL) { dev_err(&client->dev, "nvm buf allocation failed\n"); rval = -ENOMEM; @@ -2706,8 +2706,8 @@ static int smiapp_init(struct smiapp_sensor *sensor) /* prepare PLL configuration input values */ pll->bus_type = SMIAPP_PLL_BUS_TYPE_CSI2; - pll->csi2.lanes = sensor->platform_data->lanes; - pll->ext_clk_freq_hz = sensor->platform_data->ext_clk; + pll->csi2.lanes = sensor->hwcfg->lanes; + pll->ext_clk_freq_hz = sensor->hwcfg->ext_clk; pll->scale_n = sensor->limits[SMIAPP_LIMIT_SCALER_N_MIN]; /* Profile 0 sensors have no separate OP clock branch. */ if (sensor->minfo.smiapp_profile == SMIAPP_PROFILE_0) @@ -2984,9 +2984,9 @@ static int smiapp_resume(struct device *dev) #endif /* CONFIG_PM */ -static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) +static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) { - struct smiapp_platform_data *pdata; + struct smiapp_hwconfig *hwcfg; struct v4l2_of_endpoint *bus_cfg; struct device_node *ep; int i; @@ -3003,58 +3003,58 @@ static struct smiapp_platform_data *smiapp_get_pdata(struct device *dev) if (IS_ERR(bus_cfg)) goto out_err; - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) + hwcfg = devm_kzalloc(dev, sizeof(*hwcfg), GFP_KERNEL); + if (!hwcfg) goto out_err; switch (bus_cfg->bus_type) { case V4L2_MBUS_CSI2: - pdata->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2; + hwcfg->csi_signalling_mode = SMIAPP_CSI_SIGNALLING_MODE_CSI2; break; /* FIXME: add CCP2 support. */ default: goto out_err; } - pdata->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; - dev_dbg(dev, "lanes %u\n", pdata->lanes); + hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; + dev_dbg(dev, "lanes %u\n", hwcfg->lanes); /* xshutdown GPIO is optional */ - pdata->xshutdown = of_get_named_gpio(dev->of_node, "reset-gpios", 0); + hwcfg->xshutdown = of_get_named_gpio(dev->of_node, "reset-gpios", 0); /* NVM size is not mandatory */ of_property_read_u32(dev->of_node, "nokia,nvm-size", - &pdata->nvm_size); + &hwcfg->nvm_size); rval = of_property_read_u32(dev->of_node, "clock-frequency", - &pdata->ext_clk); + &hwcfg->ext_clk); if (rval) { dev_warn(dev, "can't get clock-frequency\n"); goto out_err; } - dev_dbg(dev, "reset %d, nvm %d, clk %d, csi %d\n", pdata->xshutdown, - pdata->nvm_size, pdata->ext_clk, pdata->csi_signalling_mode); + dev_dbg(dev, "reset %d, nvm %d, clk %d, csi %d\n", hwcfg->xshutdown, + hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode); if (!bus_cfg->nr_of_link_frequencies) { dev_warn(dev, "no link frequencies defined\n"); goto out_err; } - pdata->op_sys_clock = devm_kcalloc( + hwcfg->op_sys_clock = devm_kcalloc( dev, bus_cfg->nr_of_link_frequencies + 1 /* guardian */, - sizeof(*pdata->op_sys_clock), GFP_KERNEL); - if (!pdata->op_sys_clock) + sizeof(*hwcfg->op_sys_clock), GFP_KERNEL); + if (!hwcfg->op_sys_clock) goto out_err; for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) { - pdata->op_sys_clock[i] = bus_cfg->link_frequencies[i]; - dev_dbg(dev, "freq %d: %lld\n", i, pdata->op_sys_clock[i]); + hwcfg->op_sys_clock[i] = bus_cfg->link_frequencies[i]; + dev_dbg(dev, "freq %d: %lld\n", i, hwcfg->op_sys_clock[i]); } v4l2_of_free_endpoint(bus_cfg); of_node_put(ep); - return pdata; + return hwcfg; out_err: v4l2_of_free_endpoint(bus_cfg); @@ -3066,17 +3066,17 @@ static int smiapp_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct smiapp_sensor *sensor; - struct smiapp_platform_data *pdata = smiapp_get_pdata(&client->dev); + struct smiapp_hwconfig *hwcfg = smiapp_get_hwconfig(&client->dev); int rval; - if (pdata == NULL) + if (hwcfg == NULL) return -ENODEV; sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL); if (sensor == NULL) return -ENOMEM; - sensor->platform_data = pdata; + sensor->hwcfg = hwcfg; mutex_init(&sensor->mutex); mutex_init(&sensor->power_mutex); sensor->src = &sensor->ssds[sensor->ssds_used]; @@ -3119,10 +3119,10 @@ static int smiapp_remove(struct i2c_client *client) v4l2_async_unregister_subdev(subdev); if (sensor->power_count) { - if (gpio_is_valid(sensor->platform_data->xshutdown)) - gpio_set_value(sensor->platform_data->xshutdown, 0); - if (sensor->platform_data->set_xclk) - sensor->platform_data->set_xclk(&sensor->src->sd, 0); + if (gpio_is_valid(sensor->hwcfg->xshutdown)) + gpio_set_value(sensor->hwcfg->xshutdown, 0); + if (sensor->hwcfg->set_xclk) + sensor->hwcfg->set_xclk(&sensor->src->sd, 0); else clk_disable_unprepare(sensor->ext_clk); sensor->power_count = 0; diff --git a/drivers/media/i2c/smiapp/smiapp-quirk.c b/drivers/media/i2c/smiapp/smiapp-quirk.c index abf9ea7a0fb7..d7e22bc9812e 100644 --- a/drivers/media/i2c/smiapp/smiapp-quirk.c +++ b/drivers/media/i2c/smiapp/smiapp-quirk.c @@ -178,13 +178,13 @@ static int jt8ev1_post_poweron(struct smiapp_sensor *sensor) if (rval < 0) return rval; - switch (sensor->platform_data->ext_clk) { + switch (sensor->hwcfg->ext_clk) { case 9600000: return smiapp_write_8s(sensor, regs_96, ARRAY_SIZE(regs_96)); default: dev_warn(&client->dev, "no MSRs for %d Hz ext_clk\n", - sensor->platform_data->ext_clk); + sensor->hwcfg->ext_clk); return 0; } } diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index 2174f89a00db..6ff095ae5faf 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -197,7 +197,7 @@ struct smiapp_sensor { struct smiapp_subdev *binner; struct smiapp_subdev *scaler; struct smiapp_subdev *pixel_array; - struct smiapp_platform_data *platform_data; + struct smiapp_hwconfig *hwcfg; struct regulator *vana; struct clk *ext_clk; u32 limits[SMIAPP_LIMIT_LAST]; diff --git a/include/media/i2c/smiapp.h b/include/media/i2c/smiapp.h index 029142ddb95c..a4a1b510c9d3 100644 --- a/include/media/i2c/smiapp.h +++ b/include/media/i2c/smiapp.h @@ -57,7 +57,7 @@ struct smiapp_flash_strobe_parms { u8 trigger; }; -struct smiapp_platform_data { +struct smiapp_hwconfig { /* * Change the cci address if i2c_addr_alt is set. * Both default and alternate cci addr need to be present -- cgit v1.2.3-70-g09d2 From 567716c5817cbcc482f70724d7f98aa6702c6e4c Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Sat, 13 Aug 2016 12:46:50 -0300 Subject: [media] smiapp: Switch to gpiod API for GPIO control Switch from the old gpio API to the new descriptor based gpiod API. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 36 +++++++++++----------------------- drivers/media/i2c/smiapp/smiapp.h | 1 + include/media/i2c/smiapp.h | 3 --- 3 files changed, 12 insertions(+), 28 deletions(-) (limited to 'include') diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 103e33583f68..061f44a611c1 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -1212,8 +1212,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) } usleep_range(1000, 1000); - if (gpio_is_valid(sensor->hwcfg->xshutdown)) - gpio_set_value(sensor->hwcfg->xshutdown, 1); + gpiod_set_value(sensor->xshutdown, 1); sleep = SMIAPP_RESET_DELAY(sensor->hwcfg->ext_clk); usleep_range(sleep, sleep); @@ -1322,8 +1321,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) return 0; out_cci_addr_fail: - if (gpio_is_valid(sensor->hwcfg->xshutdown)) - gpio_set_value(sensor->hwcfg->xshutdown, 0); + gpiod_set_value(sensor->xshutdown, 0); if (sensor->hwcfg->set_xclk) sensor->hwcfg->set_xclk(&sensor->src->sd, 0); else @@ -1348,8 +1346,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor) SMIAPP_REG_U8_SOFTWARE_RESET, SMIAPP_SOFTWARE_RESET); - if (gpio_is_valid(sensor->hwcfg->xshutdown)) - gpio_set_value(sensor->hwcfg->xshutdown, 0); + gpiod_set_value(sensor->xshutdown, 0); if (sensor->hwcfg->set_xclk) sensor->hwcfg->set_xclk(&sensor->src->sd, 0); else @@ -2572,17 +2569,10 @@ static int smiapp_init(struct smiapp_sensor *sensor) } } - if (gpio_is_valid(sensor->hwcfg->xshutdown)) { - rval = devm_gpio_request_one( - &client->dev, sensor->hwcfg->xshutdown, 0, - "SMIA++ xshutdown"); - if (rval < 0) { - dev_err(&client->dev, - "unable to acquire reset gpio %d\n", - sensor->hwcfg->xshutdown); - return rval; - } - } + sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown", + GPIOD_OUT_LOW); + if (IS_ERR(sensor->xshutdown)) + return PTR_ERR(sensor->xshutdown); rval = smiapp_power_on(sensor); if (rval) @@ -3020,9 +3010,6 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) hwcfg->lanes = bus_cfg->bus.mipi_csi2.num_data_lanes; dev_dbg(dev, "lanes %u\n", hwcfg->lanes); - /* xshutdown GPIO is optional */ - hwcfg->xshutdown = of_get_named_gpio(dev->of_node, "reset-gpios", 0); - /* NVM size is not mandatory */ of_property_read_u32(dev->of_node, "nokia,nvm-size", &hwcfg->nvm_size); @@ -3034,8 +3021,8 @@ static struct smiapp_hwconfig *smiapp_get_hwconfig(struct device *dev) goto out_err; } - dev_dbg(dev, "reset %d, nvm %d, clk %d, csi %d\n", hwcfg->xshutdown, - hwcfg->nvm_size, hwcfg->ext_clk, hwcfg->csi_signalling_mode); + dev_dbg(dev, "nvm %d, clk %d, csi %d\n", hwcfg->nvm_size, + hwcfg->ext_clk, hwcfg->csi_signalling_mode); if (!bus_cfg->nr_of_link_frequencies) { dev_warn(dev, "no link frequencies defined\n"); @@ -3120,8 +3107,7 @@ static int smiapp_remove(struct i2c_client *client) v4l2_async_unregister_subdev(subdev); if (sensor->power_count) { - if (gpio_is_valid(sensor->hwcfg->xshutdown)) - gpio_set_value(sensor->hwcfg->xshutdown, 0); + gpiod_set_value(sensor->xshutdown, 0); if (sensor->hwcfg->set_xclk) sensor->hwcfg->set_xclk(&sensor->src->sd, 0); else diff --git a/drivers/media/i2c/smiapp/smiapp.h b/drivers/media/i2c/smiapp/smiapp.h index 6ff095ae5faf..c504bd8f36b8 100644 --- a/drivers/media/i2c/smiapp/smiapp.h +++ b/drivers/media/i2c/smiapp/smiapp.h @@ -200,6 +200,7 @@ struct smiapp_sensor { struct smiapp_hwconfig *hwcfg; struct regulator *vana; struct clk *ext_clk; + struct gpio_desc *xshutdown; u32 limits[SMIAPP_LIMIT_LAST]; u8 nbinning_subtypes; struct smiapp_binning_subtype binning_subtypes[SMIAPP_BINNING_SUBTYPES]; diff --git a/include/media/i2c/smiapp.h b/include/media/i2c/smiapp.h index a4a1b510c9d3..eacc3f4e3deb 100644 --- a/include/media/i2c/smiapp.h +++ b/include/media/i2c/smiapp.h @@ -36,8 +36,6 @@ #define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE 1 #define SMIAPP_CSI_SIGNALLING_MODE_CSI2 2 -#define SMIAPP_NO_XSHUTDOWN -1 - /* * Sometimes due to board layout considerations the camera module can be * mounted rotated. The typical rotation used is 180 degrees which can be @@ -77,7 +75,6 @@ struct smiapp_hwconfig { struct smiapp_flash_strobe_parms *strobe_setup; int (*set_xclk)(struct v4l2_subdev *sd, int hz); - int32_t xshutdown; /* gpio or SMIAPP_NO_XSHUTDOWN */ }; #endif /* __SMIAPP_H_ */ -- cgit v1.2.3-70-g09d2 From e62c30e76829d46bf11d170fd81b735f13a014ac Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Wed, 31 Aug 2016 09:38:54 -0300 Subject: [media] smiapp: Remove set_xclk() callback from hwconfig The clock framework is generally so well supported that there's no reason to keep this one around. Signed-off-by: Sakari Ailus Reviewed-by: Sebastian Reichel Signed-off-by: Mauro Carvalho Chehab --- drivers/media/i2c/smiapp/smiapp-core.c | 49 ++++++++++++---------------------- include/media/i2c/smiapp.h | 2 -- 2 files changed, 17 insertions(+), 34 deletions(-) (limited to 'include') diff --git a/drivers/media/i2c/smiapp/smiapp-core.c b/drivers/media/i2c/smiapp/smiapp-core.c index 061f44a611c1..d8b78c678f77 100644 --- a/drivers/media/i2c/smiapp/smiapp-core.c +++ b/drivers/media/i2c/smiapp/smiapp-core.c @@ -1201,11 +1201,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) } usleep_range(1000, 1000); - if (sensor->hwcfg->set_xclk) - rval = sensor->hwcfg->set_xclk( - &sensor->src->sd, sensor->hwcfg->ext_clk); - else - rval = clk_prepare_enable(sensor->ext_clk); + rval = clk_prepare_enable(sensor->ext_clk); if (rval < 0) { dev_dbg(&client->dev, "failed to enable xclk\n"); goto out_xclk_fail; @@ -1322,10 +1318,7 @@ static int smiapp_power_on(struct smiapp_sensor *sensor) out_cci_addr_fail: gpiod_set_value(sensor->xshutdown, 0); - if (sensor->hwcfg->set_xclk) - sensor->hwcfg->set_xclk(&sensor->src->sd, 0); - else - clk_disable_unprepare(sensor->ext_clk); + clk_disable_unprepare(sensor->ext_clk); out_xclk_fail: regulator_disable(sensor->vana); @@ -1347,10 +1340,7 @@ static void smiapp_power_off(struct smiapp_sensor *sensor) SMIAPP_SOFTWARE_RESET); gpiod_set_value(sensor->xshutdown, 0); - if (sensor->hwcfg->set_xclk) - sensor->hwcfg->set_xclk(&sensor->src->sd, 0); - else - clk_disable_unprepare(sensor->ext_clk); + clk_disable_unprepare(sensor->ext_clk); usleep_range(5000, 5000); regulator_disable(sensor->vana); sensor->streaming = false; @@ -2551,22 +2541,20 @@ static int smiapp_init(struct smiapp_sensor *sensor) return PTR_ERR(sensor->vana); } - if (!sensor->hwcfg->set_xclk) { - sensor->ext_clk = devm_clk_get(&client->dev, NULL); - if (IS_ERR(sensor->ext_clk)) { - dev_err(&client->dev, "could not get clock (%ld)\n", - PTR_ERR(sensor->ext_clk)); - return -EPROBE_DEFER; - } + sensor->ext_clk = devm_clk_get(&client->dev, NULL); + if (IS_ERR(sensor->ext_clk)) { + dev_err(&client->dev, "could not get clock (%ld)\n", + PTR_ERR(sensor->ext_clk)); + return -EPROBE_DEFER; + } - rval = clk_set_rate(sensor->ext_clk, - sensor->hwcfg->ext_clk); - if (rval < 0) { - dev_err(&client->dev, - "unable to set clock freq to %u\n", - sensor->hwcfg->ext_clk); - return rval; - } + rval = clk_set_rate(sensor->ext_clk, + sensor->hwcfg->ext_clk); + if (rval < 0) { + dev_err(&client->dev, + "unable to set clock freq to %u\n", + sensor->hwcfg->ext_clk); + return rval; } sensor->xshutdown = devm_gpiod_get_optional(&client->dev, "xshutdown", @@ -3108,10 +3096,7 @@ static int smiapp_remove(struct i2c_client *client) if (sensor->power_count) { gpiod_set_value(sensor->xshutdown, 0); - if (sensor->hwcfg->set_xclk) - sensor->hwcfg->set_xclk(&sensor->src->sd, 0); - else - clk_disable_unprepare(sensor->ext_clk); + clk_disable_unprepare(sensor->ext_clk); sensor->power_count = 0; } diff --git a/include/media/i2c/smiapp.h b/include/media/i2c/smiapp.h index eacc3f4e3deb..635007e7441a 100644 --- a/include/media/i2c/smiapp.h +++ b/include/media/i2c/smiapp.h @@ -73,8 +73,6 @@ struct smiapp_hwconfig { enum smiapp_module_board_orient module_board_orient; struct smiapp_flash_strobe_parms *strobe_setup; - - int (*set_xclk)(struct v4l2_subdev *sd, int hz); }; #endif /* __SMIAPP_H_ */ -- cgit v1.2.3-70-g09d2 From 48a7c4bac94dfb367d1d64123b5182536912c03e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Aug 2016 16:09:11 -0300 Subject: [media] docs-rst: improve the kAPI documentation for the mediactl There are several issues on the documentation: - the media.h header were not properly referenced; - verbatim expressions were not properly marked as such; - struct member references were wrong; - some notes were not using the right markup; - a comment that were moved to the kernel-doc markup were duplicated as a comment inside the struct media_entity; - some args were not pointing to the struct they're using; - macros weren't documented. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-device.h | 115 ++++++++++++-------- include/media/media-devnode.h | 2 +- include/media/media-entity.h | 237 ++++++++++++++++++++++++++++-------------- 3 files changed, 231 insertions(+), 123 deletions(-) (limited to 'include') diff --git a/include/media/media-device.h b/include/media/media-device.h index 28195242386c..481dd6c672cb 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -53,7 +53,7 @@ struct media_entity_notify { * @dev: Parent device * @devnode: Media device node * @driver_name: Optional device driver name. If not set, calls to - * %MEDIA_IOC_DEVICE_INFO will return dev->driver->name. + * %MEDIA_IOC_DEVICE_INFO will return ``dev->driver->name``. * This is needed for USB drivers for example, as otherwise * they'll all appear as if the driver name was "usb". * @model: Device model name @@ -102,16 +102,18 @@ struct media_entity_notify { * sink entity and deactivate the link between them. Drivers * should call this handler to release the source. * - * Note: Bridge driver is expected to implement and set the - * handler when media_device is registered or when - * bridge driver finds the media_device during probe. - * Bridge driver sets source_priv with information - * necessary to run enable/disable source handlers. - * * Use-case: find tuner entity connected to the decoder * entity and check if it is available, and activate the - * the link between them from enable_source and deactivate - * from disable_source. + * the link between them from @enable_source and deactivate + * from @disable_source. + * + * .. note:: + * + * Bridge driver is expected to implement and set the + * handler when &media_device is registered or when + * bridge driver finds the media_device during probe. + * Bridge driver sets source_priv with information + * necessary to run @enable_source and @disable_source handlers. */ struct media_device { /* dev->driver_data points to this struct. */ @@ -168,7 +170,7 @@ struct usb_device; * @ent_enum: Entity enumeration to be initialised * @mdev: The related media device * - * Returns zero on success or a negative error code. + * Return: zero on success or a negative error code. */ static inline __must_check int media_entity_enum_init( struct media_entity_enum *ent_enum, struct media_device *mdev) @@ -211,36 +213,38 @@ void media_device_cleanup(struct media_device *mdev); * * Users, should, instead, call the media_device_register() macro. * - * The caller is responsible for initializing the media_device structure before - * registration. The following fields must be set: + * The caller is responsible for initializing the &media_device structure + * before registration. The following fields of &media_device must be set: * - * - dev must point to the parent device (usually a &pci_dev, &usb_interface or - * &platform_device instance). + * - &media_entity.dev must point to the parent device (usually a &pci_dev, + * &usb_interface or &platform_device instance). * - * - model must be filled with the device model name as a NUL-terminated UTF-8 - * string. The device/model revision must not be stored in this field. + * - &media_entity.model must be filled with the device model name as a + * NUL-terminated UTF-8 string. The device/model revision must not be + * stored in this field. * * The following fields are optional: * - * - serial is a unique serial number stored as a NUL-terminated ASCII string. - * The field is big enough to store a GUID in text form. If the hardware - * doesn't provide a unique serial number this field must be left empty. + * - &media_entity.serial is a unique serial number stored as a + * NUL-terminated ASCII string. The field is big enough to store a GUID + * in text form. If the hardware doesn't provide a unique serial number + * this field must be left empty. * - * - bus_info represents the location of the device in the system as a - * NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to - * "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices, - * the usb_make_path() function must be used. This field is used by - * applications to distinguish between otherwise identical devices that don't - * provide a serial number. + * - &media_entity.bus_info represents the location of the device in the + * system as a NUL-terminated ASCII string. For PCI/PCIe devices + * &media_entity.bus_info must be set to "PCI:" (or "PCIe:") followed by + * the value of pci_name(). For USB devices,the usb_make_path() function + * must be used. This field is used by applications to distinguish between + * otherwise identical devices that don't provide a serial number. * - * - hw_revision is the hardware device revision in a driver-specific format. - * When possible the revision should be formatted with the KERNEL_VERSION - * macro. + * - &media_entity.hw_revision is the hardware device revision in a + * driver-specific format. When possible the revision should be formatted + * with the KERNEL_VERSION() macro. * - * - driver_version is formatted with the KERNEL_VERSION macro. The version - * minor must be incremented when new features are added to the userspace API - * without breaking binary compatibility. The version major must be - * incremented when binary compatibility is broken. + * - &media_entity.driver_version is formatted with the KERNEL_VERSION() + * macro. The version minor must be incremented when new features are added + * to the userspace API without breaking binary compatibility. The version + * major must be incremented when binary compatibility is broken. * * .. note:: * @@ -252,6 +256,16 @@ void media_device_cleanup(struct media_device *mdev); */ int __must_check __media_device_register(struct media_device *mdev, struct module *owner); + + +/** + * media_device_register() - Registers a media device element + * + * @mdev: pointer to struct &media_device + * + * This macro calls __media_device_register() passing %THIS_MODULE as + * the __media_device_register() second argument (**owner**). + */ #define media_device_register(mdev) __media_device_register(mdev, THIS_MODULE) /** @@ -259,7 +273,6 @@ int __must_check __media_device_register(struct media_device *mdev, * * @mdev: pointer to struct &media_device * - * * It is safe to call this function on an unregistered (but initialised) * media device. */ @@ -285,14 +298,15 @@ void media_device_unregister(struct media_device *mdev); * framework. * * If the device has pads, media_entity_pads_init() should be called before - * this function. Otherwise, the &media_entity.@pad and &media_entity.@num_pads + * this function. Otherwise, the &media_entity.pad and &media_entity.num_pads * should be zeroed before calling this function. * * Entities have flags that describe the entity capabilities and state: * - * %MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type. - * This can be used to report the default audio and video devices or the - * default camera sensor. + * %MEDIA_ENT_FL_DEFAULT + * indicates the default entity for a given type. + * This can be used to report the default audio and video devices or the + * default camera sensor. * * .. note:: * @@ -331,8 +345,10 @@ void media_device_unregister_entity(struct media_entity *entity); * @mdev: The media device * @nptr: The media_entity_notify * - * Note: When a new entity is registered, all the registered - * media_entity_notify callbacks are invoked. + * .. note:: + * + * When a new entity is registered, all the registered + * media_entity_notify callbacks are invoked. */ int __must_check media_device_register_entity_notify(struct media_device *mdev, @@ -410,11 +426,13 @@ void media_device_pci_init(struct media_device *mdev, * @board_name: media device name. If %NULL, the routine will use the usb * product name, if available. * @driver_name: name of the driver. if %NULL, the routine will use the name - * given by udev->dev->driver->name, with is usually the wrong + * given by ``udev->dev->driver->name``, with is usually the wrong * thing to do. * - * NOTE: It is better to call media_device_usb_init() instead, as - * such macro fills driver_name with %KBUILD_MODNAME. + * .. note:: + * + * It is better to call media_device_usb_init() instead, as + * such macro fills driver_name with %KBUILD_MODNAME. */ void __media_device_usb_init(struct media_device *mdev, struct usb_device *udev, @@ -472,6 +490,19 @@ static inline void __media_device_usb_init(struct media_device *mdev, #endif /* CONFIG_MEDIA_CONTROLLER */ +/** + * media_device_usb_init() - create and initialize a + * struct &media_device from a PCI device. + * + * @mdev: pointer to struct &media_device + * @udev: pointer to struct usb_device + * @name: media device name. If %NULL, the routine will use the usb + * product name, if available. + * + * This macro calls media_device_usb_init() passing the + * media_device_usb_init() **driver_name** parameter filled with + * %KBUILD_MODNAME. + */ #define media_device_usb_init(mdev, udev, name) \ __media_device_usb_init(mdev, udev, name, KBUILD_MODNAME) diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 37d494805944..972168e90413 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -75,7 +75,7 @@ struct media_file_operations { * @cdev: struct cdev pointer character device * @parent: parent device * @minor: device node minor number - * @flags: flags, combination of the MEDIA_FLAG_* constants + * @flags: flags, combination of the ``MEDIA_FLAG_*`` constants * @release: release callback called at the end of media_devnode_release() * * This structure represents a media-related device node. diff --git a/include/media/media-entity.h b/include/media/media-entity.h index 7bf6885dd37f..e21958c7c5d9 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -56,7 +56,7 @@ enum media_gobj_type { /** * struct media_gobj - Define a graph object. * - * @mdev: Pointer to the struct media_device that owns the object + * @mdev: Pointer to the struct &media_device that owns the object * @id: Non-zero object ID identifier. The ID should be unique * inside a media_device, as it is composed by * %MEDIA_BITS_PER_TYPE to store the type plus @@ -162,7 +162,9 @@ struct media_link { * @graph_obj: Embedded structure containing the media object common data * @entity: Entity this pad belongs to * @index: Pad index in the entity pads array, numbered from 0 to n - * @flags: Pad flags, as defined in uapi/media.h (MEDIA_PAD_FL_*) + * @flags: Pad flags, as defined in + * :ref:`include/uapi/linux/media.h ` + * (seek for ``MEDIA_PAD_FL_*``) */ struct media_pad { struct media_gobj graph_obj; /* must be first field in struct */ @@ -182,7 +184,7 @@ struct media_pad { * * .. note:: * - * Those these callbacks are called with struct media_device.@graph_mutex + * Those these callbacks are called with struct &media_device.graph_mutex * mutex held. */ struct media_entity_operations { @@ -210,7 +212,7 @@ struct media_entity_operations { * This allows runtime type identification of media entities and safe casting to * the correct object type. For instance, a media entity structure instance * embedded in a v4l2_subdev structure instance will have the type - * MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a v4l2_subdev + * %MEDIA_ENTITY_TYPE_V4L2_SUBDEV and can safely be cast to a &v4l2_subdev * structure using the container_of() macro. */ enum media_entity_type { @@ -225,9 +227,12 @@ enum media_entity_type { * @graph_obj: Embedded structure containing the media object common data. * @name: Entity name. * @obj_type: Type of the object that implements the media_entity. - * @function: Entity main function, as defined in uapi/media.h - * (MEDIA_ENT_F_*) - * @flags: Entity flags, as defined in uapi/media.h (MEDIA_ENT_FL_*) + * @function: Entity main function, as defined in + * :ref:`include/uapi/linux/media.h ` + * (seek for ``MEDIA_ENT_F_*``) + * @flags: Entity flags, as defined in + * :ref:`include/uapi/linux/media.h ` + * (seek for ``MEDIA_ENT_FL_*``) * @num_pads: Number of sink and source pads. * @num_links: Total number of links, forward and back, enabled and disabled. * @num_backlinks: Number of backlinks @@ -246,9 +251,12 @@ enum media_entity_type { * @minor: Devnode minor number (zero if not applicable). Kept just * for backward compatibility. * - * NOTE: @stream_count and @use_count reference counts must never be - * negative, but are signed integers on purpose: a simple WARN_ON(<0) check - * can be used to detect reference count bugs that would make them negative. + * .. note:: + * + * @stream_count and @use_count reference counts must never be + * negative, but are signed integers on purpose: a simple ``WARN_ON(<0)`` + * check can be used to detect reference count bugs that would make them + * negative. */ struct media_entity { struct media_gobj graph_obj; /* must be first field in struct */ @@ -267,10 +275,6 @@ struct media_entity { const struct media_entity_operations *ops; - /* Reference counts must never be negative, but are signed integers on - * purpose: a simple WARN_ON(<0) check can be used to detect reference - * count bugs that would make them negative. - */ int stream_count; int use_count; @@ -289,10 +293,16 @@ struct media_entity { * * @graph_obj: embedded graph object * @links: List of links pointing to graph entities - * @type: Type of the interface as defined in the - * uapi/media/media.h header, e. g. - * MEDIA_INTF_T_* - * @flags: Interface flags as defined in uapi/media/media.h + * @type: Type of the interface as defined in + * :ref:`include/uapi/linux/media.h ` + * (seek for ``MEDIA_INTF_T_*``) + * @flags: Interface flags as defined in + * :ref:`include/uapi/linux/media.h ` + * (seek for ``MEDIA_INTF_FL_*``) + * + * .. note:: + * + * Currently, no flags for &media_interface is defined. */ struct media_interface { struct media_gobj graph_obj; @@ -319,7 +329,7 @@ struct media_intf_devnode { /** * media_entity_id() - return the media entity graph object id * - * @entity: pointer to entity + * @entity: pointer to &media_entity */ static inline u32 media_entity_id(struct media_entity *entity) { @@ -329,7 +339,7 @@ static inline u32 media_entity_id(struct media_entity *entity) /** * media_type() - return the media object type * - * @gobj: pointer to the media graph object + * @gobj: Pointer to the struct &media_gobj graph object */ static inline enum media_gobj_type media_type(struct media_gobj *gobj) { @@ -339,7 +349,7 @@ static inline enum media_gobj_type media_type(struct media_gobj *gobj) /** * media_id() - return the media object ID * - * @gobj: pointer to the media graph object + * @gobj: Pointer to the struct &media_gobj graph object */ static inline u32 media_id(struct media_gobj *gobj) { @@ -350,7 +360,7 @@ static inline u32 media_id(struct media_gobj *gobj) * media_gobj_gen_id() - encapsulates type and ID on at the object ID * * @type: object type as define at enum &media_gobj_type. - * @local_id: next ID, from struct &media_device.@id. + * @local_id: next ID, from struct &media_device.id. */ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) { @@ -366,9 +376,9 @@ static inline u32 media_gobj_gen_id(enum media_gobj_type type, u64 local_id) * is_media_entity_v4l2_video_device() - Check if the entity is a video_device * @entity: pointer to entity * - * Return: true if the entity is an instance of a video_device object and can + * Return: %true if the entity is an instance of a video_device object and can * safely be cast to a struct video_device using the container_of() macro, or - * false otherwise. + * %false otherwise. */ static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity) { @@ -379,9 +389,9 @@ static inline bool is_media_entity_v4l2_video_device(struct media_entity *entity * is_media_entity_v4l2_subdev() - Check if the entity is a v4l2_subdev * @entity: pointer to entity * - * Return: true if the entity is an instance of a v4l2_subdev object and can - * safely be cast to a struct v4l2_subdev using the container_of() macro, or - * false otherwise. + * Return: %true if the entity is an instance of a &v4l2_subdev object and can + * safely be cast to a struct &v4l2_subdev using the container_of() macro, or + * %false otherwise. */ static inline bool is_media_entity_v4l2_subdev(struct media_entity *entity) { @@ -452,7 +462,7 @@ static inline void media_entity_enum_clear(struct media_entity_enum *ent_enum, * @ent_enum: Entity enumeration * @entity: Entity to be tested * - * Returns true if the entity was marked. + * Returns %true if the entity was marked. */ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, struct media_entity *entity) @@ -469,7 +479,7 @@ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, * @ent_enum: Entity enumeration * @entity: Entity to be tested * - * Returns true if the entity was marked, and mark it before doing so. + * Returns %true if the entity was marked, and mark it before doing so. */ static inline bool media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, @@ -486,7 +496,7 @@ media_entity_enum_test_and_set(struct media_entity_enum *ent_enum, * * @ent_enum: Entity enumeration * - * Returns true if the entity was empty. + * Return: %true if the entity was empty. */ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) { @@ -499,7 +509,8 @@ static inline bool media_entity_enum_empty(struct media_entity_enum *ent_enum) * @ent_enum1: First entity enumeration * @ent_enum2: Second entity enumeration * - * Returns true if entity enumerations e and f intersect, otherwise false. + * Return: %true if entity enumerations @ent_enum1 and @ent_enum2 intersect, + * otherwise %false. */ static inline bool media_entity_enum_intersects( struct media_entity_enum *ent_enum1, @@ -511,33 +522,63 @@ static inline bool media_entity_enum_intersects( min(ent_enum1->idx_max, ent_enum2->idx_max)); } +/** + * gobj_to_entity - returns the struct &media_entity pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_entity(gobj) \ container_of(gobj, struct media_entity, graph_obj) +/** + * gobj_to_entity - returns the struct &media_pad pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_pad(gobj) \ container_of(gobj, struct media_pad, graph_obj) +/** + * gobj_to_entity - returns the struct &media_link pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_link(gobj) \ container_of(gobj, struct media_link, graph_obj) +/** + * gobj_to_entity - returns the struct &media_interface pointer from the + * @gobj contained on it. + * + * @gobj: Pointer to the struct &media_gobj graph object + */ #define gobj_to_intf(gobj) \ container_of(gobj, struct media_interface, graph_obj) +/** + * gobj_to_entity - returns the struct media_intf_devnode pointer from the + * @intf contained on it. + * + * @intf: Pointer to struct &media_intf_devnode + */ #define intf_to_devnode(intf) \ container_of(intf, struct media_intf_devnode, intf) /** * media_gobj_create - Initialize a graph object * - * @mdev: Pointer to the media_device that contains the object + * @mdev: Pointer to the &media_device that contains the object * @type: Type of the object - * @gobj: Pointer to the graph object + * @gobj: Pointer to the struct &media_gobj graph object * - * This routine initializes the embedded struct media_gobj inside a - * media graph object. It is called automatically if media_*_create\(\) - * calls are used. However, if the object (entity, link, pad, interface) - * is embedded on some other object, this function should be called before - * registering the object at the media controller. + * This routine initializes the embedded struct &media_gobj inside a + * media graph object. It is called automatically if ``media_*_create`` + * function calls are used. However, if the object (entity, link, pad, + * interface) is embedded on some other object, this function should be + * called before registering the object at the media controller. */ void media_gobj_create(struct media_device *mdev, enum media_gobj_type type, @@ -546,7 +587,7 @@ void media_gobj_create(struct media_device *mdev, /** * media_gobj_destroy - Stop using a graph object on a media device * - * @gobj: Pointer to the graph object + * @gobj: Pointer to the struct &media_gobj graph object * * This should be called by all routines like media_device_unregister() * that remove/destroy media graph objects. @@ -561,11 +602,11 @@ void media_gobj_destroy(struct media_gobj *gobj); * @pads: Array of @num_pads pads. * * The pads array is managed by the entity driver and passed to - * media_entity_pads_init() where its pointer will be stored in the entity - * structure. + * media_entity_pads_init() where its pointer will be stored in the + * &media_entity structure. * * If no pads are needed, drivers could either directly fill - * &media_entity->@num_pads with 0 and &media_entity->@pads with NULL or call + * &media_entity->num_pads with 0 and &media_entity->pads with %NULL or call * this function that will do the same. * * As the number of pads is known in advance, the pads array is not allocated @@ -595,18 +636,21 @@ static inline void media_entity_cleanup(struct media_entity *entity) {}; * @source_pad: number of the source pad in the pads array * @sink: pointer to &media_entity of the sink pad. * @sink_pad: number of the sink pad in the pads array. - * @flags: Link flags, as defined in include/uapi/linux/media.h. + * @flags: Link flags, as defined in + * :ref:`include/uapi/linux/media.h ` + * ( seek for ``MEDIA_LNK_FL_*``) * * Valid values for flags: * - * - A %MEDIA_LNK_FL_ENABLED flag indicates that the link is enabled and can - * be used to transfer media data. When two or more links target a sink pad, - * only one of them can be enabled at a time. + * %MEDIA_LNK_FL_ENABLED + * Indicates that the link is enabled and can be used to transfer media data. + * When two or more links target a sink pad, only one of them can be + * enabled at a time. * - * - A %MEDIA_LNK_FL_IMMUTABLE flag indicates that the link enabled state can't - * be modified at runtime. If %MEDIA_LNK_FL_IMMUTABLE is set, then - * %MEDIA_LNK_FL_ENABLED must also be set since an immutable link is - * always enabled. + * %MEDIA_LNK_FL_IMMUTABLE + * Indicates that the link enabled state can't be modified at runtime. If + * %MEDIA_LNK_FL_IMMUTABLE is set, then %MEDIA_LNK_FL_ENABLED must also be + * set, since an immutable link is always enabled. * * .. note:: * @@ -624,17 +668,17 @@ __must_check int media_create_pad_link(struct media_entity *source, * @source_function: Function of the source entities. Used only if @source is * NULL. * @source: pointer to &media_entity of the source pad. If NULL, it will use - * all entities that matches the @sink_function. + * all entities that matches the @sink_function. * @source_pad: number of the source pad in the pads array * @sink_function: Function of the sink entities. Used only if @sink is NULL. * @sink: pointer to &media_entity of the sink pad. If NULL, it will use - * all entities that matches the @sink_function. + * all entities that matches the @sink_function. * @sink_pad: number of the sink pad in the pads array. * @flags: Link flags, as defined in include/uapi/linux/media.h. - * @allow_both_undefined: if true, then both @source and @sink can be NULL. + * @allow_both_undefined: if %true, then both @source and @sink can be NULL. * In such case, it will create a crossbar between all entities that * matches @source_function to all entities that matches @sink_function. - * If false, it will return 0 and won't create any link if both @source + * If %false, it will return 0 and won't create any link if both @source * and @sink are NULL. * * Valid values for flags: @@ -654,9 +698,11 @@ __must_check int media_create_pad_link(struct media_entity *source, * creates link by link, this function is meant to allow 1:n, n:1 and even * cross-bar (n:n) links. * - * NOTE: Before calling this function, media_entity_pads_init() and - * media_device_register_entity() should be called previously for the entities - * to be linked. + * .. note:: + * + * Before calling this function, media_entity_pads_init() and + * media_device_register_entity() should be called previously for the + * entities to be linked. */ int media_create_pad_links(const struct media_device *mdev, const u32 source_function, @@ -715,7 +761,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags); * flags. * * Media device drivers can be notified of link setup operations by setting the - * media_device::link_notify pointer to a callback function. If provided, the + * &media_device.link_notify pointer to a callback function. If provided, the * notification callback will be called before enabling and after disabling * links. * @@ -725,7 +771,7 @@ int __media_entity_setup_link(struct media_link *link, u32 flags); * * Link configuration must not have any side effect on other links. If an * enabled link at a sink pad prevents another link at the same pad from - * being enabled, the link_setup operation must return -EBUSY and can't + * being enabled, the link_setup operation must return %-EBUSY and can't * implicitly disable the first enabled link. * * .. note:: @@ -741,8 +787,8 @@ int media_entity_setup_link(struct media_link *link, u32 flags); * @source: Source pad * @sink: Sink pad * - * Return a pointer to the link between the two entities. If no such link - * exists, return NULL. + * Return: returns a pointer to the link between the two entities. If no + * such link exists, return %NULL. */ struct media_link *media_entity_find_link(struct media_pad *source, struct media_pad *sink); @@ -754,8 +800,8 @@ struct media_link *media_entity_find_link(struct media_pad *source, * Search for a remote pad connected to the given pad by iterating over all * links originating or terminating at that pad until an enabled link is found. * - * Return a pointer to the pad at the remote end of the first found enabled - * link, or NULL if no enabled link has been found. + * Return: returns a pointer to the pad at the remote end of the first found + * enabled link, or %NULL if no enabled link has been found. */ struct media_pad *media_entity_remote_pad(struct media_pad *pad); @@ -766,12 +812,18 @@ struct media_pad *media_entity_remote_pad(struct media_pad *pad); * * Get a reference to the parent media device module. * - * The function will return immediately if @entity is NULL. + * The function will return immediately if @entity is %NULL. * - * Return a pointer to the entity on success or NULL on failure. + * Return: returns a pointer to the entity on success or %NULL on failure. */ struct media_entity *media_entity_get(struct media_entity *entity); +/** + * media_entity_graph_walk_init - Allocate resources used by graph walk. + * + * @graph: Media graph structure that will be used to walk the graph + * @mdev: Pointer to the &media_device that contains the object + */ __must_check int media_entity_graph_walk_init( struct media_entity_graph *graph, struct media_device *mdev); @@ -789,12 +841,14 @@ void media_entity_graph_walk_cleanup(struct media_entity_graph *graph); * * Release the reference count acquired by media_entity_get(). * - * The function will return immediately if @entity is NULL. + * The function will return immediately if @entity is %NULL. */ void media_entity_put(struct media_entity *entity); /** - * media_entity_graph_walk_start - Start walking the media graph at a given entity + * media_entity_graph_walk_start - Start walking the media graph at a + * given entity + * * @graph: Media graph structure that will be used to walk the graph * @entity: Starting entity * @@ -818,8 +872,8 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph, * The graph structure must have been previously initialized with a call to * media_entity_graph_walk_start(). * - * Return the next entity in the graph or NULL if the whole graph have been - * traversed. + * Return: returns the next entity in the graph or %NULL if the whole graph + * have been traversed. */ struct media_entity * media_entity_graph_walk_next(struct media_entity_graph *graph); @@ -830,8 +884,8 @@ media_entity_graph_walk_next(struct media_entity_graph *graph); * @pipe: Media pipeline to be assigned to all entities in the pipeline. * * Mark all entities connected to a given entity through enabled links, either - * directly or indirectly, as streaming. The given pipeline object is assigned to - * every entity in the pipeline and stored in the media_entity pipe field. + * directly or indirectly, as streaming. The given pipeline object is assigned + * to every entity in the pipeline and stored in the media_entity pipe field. * * Calls to this function can be nested, in which case the same number of * media_entity_pipeline_stop() calls will be required to stop streaming. The @@ -857,7 +911,7 @@ __must_check int __media_entity_pipeline_start(struct media_entity *entity, * * Mark all entities connected to a given entity through enabled links, either * directly or indirectly, as not streaming. The media_entity pipe field is - * reset to NULL. + * reset to %NULL. * * If multiple calls to media_entity_pipeline_start() have been made, the same * number of calls to this function are required to mark the pipeline as not @@ -878,14 +932,21 @@ void __media_entity_pipeline_stop(struct media_entity *entity); * media_devnode_create() - creates and initializes a device node interface * * @mdev: pointer to struct &media_device - * @type: type of the interface, as given by MEDIA_INTF_T_* macros - * as defined in the uapi/media/media.h header. - * @flags: Interface flags as defined in uapi/media/media.h. + * @type: type of the interface, as given by + * :ref:`include/uapi/linux/media.h ` + * ( seek for ``MEDIA_INTF_T_*``) macros. + * @flags: Interface flags, as defined in + * :ref:`include/uapi/linux/media.h ` + * ( seek for ``MEDIA_INTF_FL_*``) * @major: Device node major number. * @minor: Device node minor number. * * Return: if succeeded, returns a pointer to the newly allocated * &media_intf_devnode pointer. + * + * .. note:: + * + * Currently, no flags for &media_interface is defined. */ struct media_intf_devnode * __must_check media_devnode_create(struct media_device *mdev, @@ -907,15 +968,19 @@ struct media_link * * * @entity: pointer to %media_entity * @intf: pointer to %media_interface - * @flags: Link flags, as defined in include/uapi/linux/media.h. + * @flags: Link flags, as defined in + * :ref:`include/uapi/linux/media.h ` + * ( seek for ``MEDIA_LNK_FL_*``) * * * Valid values for flags: * - * - The %MEDIA_LNK_FL_ENABLED flag indicates that the interface is connected to - * the entity hardware. That's the default value for interfaces. An - * interface may be disabled if the hardware is busy due to the usage - * of some other interface that it is currently controlling the hardware. + * %MEDIA_LNK_FL_ENABLED + * Indicates that the interface is connected to the entity hardware. + * That's the default value for interfaces. An interface may be disabled if + * the hardware is busy due to the usage of some other interface that it is + * currently controlling the hardware. + * * A typical example is an hybrid TV device that handle only one type of * stream on a given time. So, when the digital TV is streaming, * the V4L2 interfaces won't be enabled, as such device is not able to @@ -971,6 +1036,18 @@ void __media_remove_intf_links(struct media_interface *intf); */ void media_remove_intf_links(struct media_interface *intf); +/** + * media_entity_call - Calls a struct media_entity_operations operation on + * an entity + * + * @entity: entity where the @operation will be called + * @operation: type of the operation. Should be the name of a member of + * struct &media_entity_operations. + * + * This helper function will check if @operation is not %NULL. On such case, + * it will issue a call to @operation\(@entity, @args\). + */ + #define media_entity_call(entity, operation, args...) \ (((entity)->ops && (entity)->ops->operation) ? \ (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD) -- cgit v1.2.3-70-g09d2 From 9fa7235f88386c9a5f5013a90f0c6fe8aa6fe828 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Aug 2016 17:00:22 -0300 Subject: [media] rc-map.h: document structs/enums on it There are some structs/enums that aren't documented via kernel-doc markup. Add documentation for them. Fix those warnings: ./include/media/rc-map.h:103: WARNING: c:type reference target not found: rc_map_list ./include/media/rc-map.h:110: WARNING: c:type reference target not found: rc_map_list ./include/media/rc-map.h:117: WARNING: c:type reference target not found: rc_map Signed-off-by: Mauro Carvalho Chehab --- include/media/rc-map.h | 94 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/include/media/rc-map.h b/include/media/rc-map.h index daa75fcc1ff1..173ad58fb61b 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -11,27 +11,51 @@ #include +/** + * enum rc_type - type of the Remote Controller protocol + * + * @RC_TYPE_UNKNOWN: Protocol not known + * @RC_TYPE_OTHER: Protocol known but proprietary + * @RC_TYPE_RC5: Philips RC5 protocol + * @RC_TYPE_RC5X: Philips RC5x protocol + * @RC_TYPE_RC5_SZ: StreamZap variant of RC5 + * @RC_TYPE_JVC: JVC protocol + * @RC_TYPE_SONY12: Sony 12 bit protocol + * @RC_TYPE_SONY15: Sony 15 bit protocol + * @RC_TYPE_SONY20: Sony 20 bit protocol + * @RC_TYPE_NEC: NEC protocol + * @RC_TYPE_SANYO: Sanyo protocol + * @RC_TYPE_MCE_KBD: RC6-ish MCE keyboard/mouse + * @RC_TYPE_RC6_0: Philips RC6-0-16 protocol + * @RC_TYPE_RC6_6A_20: Philips RC6-6A-20 protocol + * @RC_TYPE_RC6_6A_24: Philips RC6-6A-24 protocol + * @RC_TYPE_RC6_6A_32: Philips RC6-6A-32 protocol + * @RC_TYPE_RC6_MCE: MCE (Philips RC6-6A-32 subtype) protocol + * @RC_TYPE_SHARP: Sharp protocol + * @RC_TYPE_XMP: XMP protocol + * @RC_TYPE_CEC: CEC protocol + */ enum rc_type { - RC_TYPE_UNKNOWN = 0, /* Protocol not known */ - RC_TYPE_OTHER = 1, /* Protocol known but proprietary */ - RC_TYPE_RC5 = 2, /* Philips RC5 protocol */ - RC_TYPE_RC5X = 3, /* Philips RC5x protocol */ - RC_TYPE_RC5_SZ = 4, /* StreamZap variant of RC5 */ - RC_TYPE_JVC = 5, /* JVC protocol */ - RC_TYPE_SONY12 = 6, /* Sony 12 bit protocol */ - RC_TYPE_SONY15 = 7, /* Sony 15 bit protocol */ - RC_TYPE_SONY20 = 8, /* Sony 20 bit protocol */ - RC_TYPE_NEC = 9, /* NEC protocol */ - RC_TYPE_SANYO = 10, /* Sanyo protocol */ - RC_TYPE_MCE_KBD = 11, /* RC6-ish MCE keyboard/mouse */ - RC_TYPE_RC6_0 = 12, /* Philips RC6-0-16 protocol */ - RC_TYPE_RC6_6A_20 = 13, /* Philips RC6-6A-20 protocol */ - RC_TYPE_RC6_6A_24 = 14, /* Philips RC6-6A-24 protocol */ - RC_TYPE_RC6_6A_32 = 15, /* Philips RC6-6A-32 protocol */ - RC_TYPE_RC6_MCE = 16, /* MCE (Philips RC6-6A-32 subtype) protocol */ - RC_TYPE_SHARP = 17, /* Sharp protocol */ - RC_TYPE_XMP = 18, /* XMP protocol */ - RC_TYPE_CEC = 19, /* CEC protocol */ + RC_TYPE_UNKNOWN = 0, + RC_TYPE_OTHER = 1, + RC_TYPE_RC5 = 2, + RC_TYPE_RC5X = 3, + RC_TYPE_RC5_SZ = 4, + RC_TYPE_JVC = 5, + RC_TYPE_SONY12 = 6, + RC_TYPE_SONY15 = 7, + RC_TYPE_SONY20 = 8, + RC_TYPE_NEC = 9, + RC_TYPE_SANYO = 10, + RC_TYPE_MCE_KBD = 11, + RC_TYPE_RC6_0 = 12, + RC_TYPE_RC6_6A_20 = 13, + RC_TYPE_RC6_6A_24 = 14, + RC_TYPE_RC6_6A_32 = 15, + RC_TYPE_RC6_MCE = 16, + RC_TYPE_SHARP = 17, + RC_TYPE_XMP = 18, + RC_TYPE_CEC = 19, }; #define RC_BIT_NONE 0ULL @@ -76,21 +100,45 @@ enum rc_type { #define RC_SCANCODE_RC6_0(sys, cmd) (((sys) << 8) | (cmd)) #define RC_SCANCODE_RC6_6A(vendor, sys, cmd) (((vendor) << 16) | ((sys) << 8) | (cmd)) +/** + * struct rc_map_table - represents a scancode/keycode pair + * + * @scancode: scan code (u32) + * @keycode: Linux input keycode + */ struct rc_map_table { u32 scancode; u32 keycode; }; +/** + * struct rc_map - represents a keycode map table + * + * @scan: pointer to struct &rc_map_table + * @size: Max number of entries + * @len: Number of entries that are in use + * @alloc: size of *scan, in bytes + * @rc_type: type of the remote controller protocol, as defined at + * enum &rc_type + * @name: name of the key map table + * @lock: lock to protect access to this structure + */ struct rc_map { struct rc_map_table *scan; - unsigned int size; /* Max number of entries */ - unsigned int len; /* Used number of entries */ - unsigned int alloc; /* Size of *scan in bytes */ + unsigned int size; + unsigned int len; + unsigned int alloc; enum rc_type rc_type; const char *name; spinlock_t lock; }; +/** + * struct rc_map_list - list of the registered &rc_map maps + * + * @list: pointer to struct &list_head + * @map: pointer to struct &rc_map + */ struct rc_map_list { struct list_head list; struct rc_map map; -- cgit v1.2.3-70-g09d2 From 2257e180101c910c2d93dd226ab1e500e4a6813c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Aug 2016 17:26:15 -0300 Subject: [media] v4l2-ctrls: document some extra data structures The typedefs and a macro are not defined. While here, improve a few bits on the documentation. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-ctrls.h | 51 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 178a88d45aea..b8e043f63825 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -93,6 +93,16 @@ struct v4l2_ctrl_type_ops { union v4l2_ctrl_ptr ptr); }; +/** + * typedef v4l2_ctrl_notify_fnc - typedef for a notify argument with a function + * that should be called when a control value has changed. + * + * @ctrl: pointer to struct &v4l2_ctrl + * @priv: control private data + * + * This typedef definition is used as an argument to v4l2_ctrl_notify() + * and as an argument at struct &v4l2_ctrl_handler. + */ typedef void (*v4l2_ctrl_notify_fnc)(struct v4l2_ctrl *ctrl, void *priv); /** @@ -369,17 +379,38 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, * @key: Used by the lock validator if CONFIG_LOCKDEP is set. * @name: Used by the lock validator if CONFIG_LOCKDEP is set. * - * Returns an error if the buckets could not be allocated. This error will - * also be stored in @hdl->error. + * .. attention:: + * + * Never use this call directly, always use the v4l2_ctrl_handler_init() + * macro that hides the @key and @name arguments. * - * Never use this call directly, always use the v4l2_ctrl_handler_init - * macro that hides the @key and @name arguments. + * Return: returns an error if the buckets could not be allocated. This + * error will also be stored in @hdl->error. */ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, unsigned int nr_of_controls_hint, struct lock_class_key *key, const char *name); #ifdef CONFIG_LOCKDEP + +/** + * v4l2_ctrl_handler_init - + * + * @hdl: The control handler. + * @nr_of_controls_hint: A hint of how many controls this handler is + * expected to refer to. This is the total number, so including + * any inherited controls. It doesn't have to be precise, but if + * it is way off, then you either waste memory (too many buckets + * are allocated) or the control lookup becomes slower (not enough + * buckets are allocated, so there are more slow list lookups). + * It will always work, though. + * + * This helper function creates a static struct &lock_class_key and + * calls v4l2_ctrl_handler_init_class(), providing a proper name for the lock + * validador. + * + * Use this helper function to initialize a control handler. + */ #define v4l2_ctrl_handler_init(hdl, nr_of_controls_hint) \ ( \ ({ \ @@ -564,6 +595,13 @@ struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, u32 id, u8 max, u8 def, const s64 *qmenu_int); +/** + * typedef v4l2_ctrl_filter - Typedef to define the filter function to be + * used when adding a control handler. + * + * @ctrl: pointer to struct &v4l2_ctrl. + */ + typedef bool (*v4l2_ctrl_filter)(const struct v4l2_ctrl *ctrl); /** @@ -635,8 +673,8 @@ void v4l2_ctrl_cluster(unsigned int ncontrols, struct v4l2_ctrl **controls); * be marked active, and any reads will just return the current value without * going through g_volatile_ctrl. * - * In addition, this function will set the V4L2_CTRL_FLAG_UPDATE flag - * on the autofoo control and V4L2_CTRL_FLAG_INACTIVE on the foo control(s) + * In addition, this function will set the %V4L2_CTRL_FLAG_UPDATE flag + * on the autofoo control and %V4L2_CTRL_FLAG_INACTIVE on the foo control(s) * if autofoo is in auto mode. */ void v4l2_ctrl_auto_cluster(unsigned int ncontrols, @@ -686,7 +724,6 @@ void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active); */ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed); - /** *__v4l2_ctrl_modify_range() - Unlocked variant of v4l2_ctrl_modify_range() * -- cgit v1.2.3-70-g09d2 From fb91161a32bfe907720aff92318660ca8f6b9e71 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Aug 2016 18:43:02 -0300 Subject: [media] v4l2-ctrls.h: fix doc reference for prepare_ext_ctrls() The prepare_ext_ctrls() function is actually internal to the v4l2-ctrls.c implementation, so it doesn't have a declaration for the kAPI header to reference it. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-ctrls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index b8e043f63825..3207449327d7 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -239,7 +239,7 @@ struct v4l2_ctrl { * @next: Single-link list node for the hash. * @ctrl: The actual control information. * @helper: Pointer to helper struct. Used internally in - * prepare_ext_ctrls(). + * ``prepare_ext_ctrls`` function at ``v4l2-ctrl.c``. * * Each control handler has a list of these refs. The list_head is used to * keep a sorted-by-control-ID list of all controls, while the next pointer -- cgit v1.2.3-70-g09d2 From ffa0441edca1ae462bdafe2743a4cde16f407f3a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Aug 2016 18:40:21 -0300 Subject: [media] docs-rst: use C domain for enum references on uapi Change the parse-headers.pl and the corresponding files to use the C domain for enum references. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/hist-v4l2.rst | 2 +- Documentation/media/uapi/v4l/subdev-formats.rst | 2 +- Documentation/media/uapi/v4l/v4l2.rst | 2 +- Documentation/media/uapi/v4l/vidioc-dqevent.rst | 2 +- Documentation/media/uapi/v4l/vidioc-g-priority.rst | 2 +- Documentation/media/uapi/v4l/vidioc-queryctrl.rst | 14 +++++++------- Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst | 10 +++++----- include/media/v4l2-dev.h | 12 ++++++------ 8 files changed, 23 insertions(+), 23 deletions(-) (limited to 'include') diff --git a/Documentation/media/uapi/v4l/hist-v4l2.rst b/Documentation/media/uapi/v4l/hist-v4l2.rst index a84895968349..bd45431ed00e 100644 --- a/Documentation/media/uapi/v4l/hist-v4l2.rst +++ b/Documentation/media/uapi/v4l/hist-v4l2.rst @@ -1361,7 +1361,7 @@ V4L2 in Linux 3.19 :ref:`v4l2_quantization ` fields to struct :c:type:`v4l2_pix_format`, struct :c:type:`v4l2_pix_format_mplane` and - struct :ref:`v4l2_mbus_framefmt `. + struct :c:type:`v4l2_mbus_framefmt`. V4L2 in Linux 4.4 diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 52013b55ea80..f0d7754f1906 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -7,7 +7,7 @@ Media Bus Formats .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| -.. _v4l2-mbus-framefmt: +.. c:type:: v4l2_mbus_framefmt .. flat-table:: struct v4l2_mbus_framefmt :header-rows: 0 diff --git a/Documentation/media/uapi/v4l/v4l2.rst b/Documentation/media/uapi/v4l/v4l2.rst index 785d4cdd2f85..e020c57f98d4 100644 --- a/Documentation/media/uapi/v4l/v4l2.rst +++ b/Documentation/media/uapi/v4l/v4l2.rst @@ -116,7 +116,7 @@ Rewrote Colorspace chapter, added new enum :ref:`v4l2_quantization ` fields to struct :c:type:`v4l2_pix_format`, struct :c:type:`v4l2_pix_format_mplane` and struct -:ref:`v4l2_mbus_framefmt `. +:c:type:`v4l2_mbus_framefmt`. :revision: 3.17 / 2014-08-04 (*lp, hv*) diff --git a/Documentation/media/uapi/v4l/vidioc-dqevent.rst b/Documentation/media/uapi/v4l/vidioc-dqevent.rst index cf0e98f5112f..3038f349049c 100644 --- a/Documentation/media/uapi/v4l/vidioc-dqevent.rst +++ b/Documentation/media/uapi/v4l/vidioc-dqevent.rst @@ -356,7 +356,7 @@ call. - - The type of the control. See enum - :ref:`v4l2_ctrl_type `. + :c:type:`v4l2_ctrl_type`. - .. row 3 diff --git a/Documentation/media/uapi/v4l/vidioc-g-priority.rst b/Documentation/media/uapi/v4l/vidioc-g-priority.rst index d6a07c076837..cbd2a3cbb18e 100644 --- a/Documentation/media/uapi/v4l/vidioc-g-priority.rst +++ b/Documentation/media/uapi/v4l/vidioc-g-priority.rst @@ -44,7 +44,7 @@ an enum v4l2_priority variable and call :ref:`VIDIOC_S_PRIORITY ` how + control. See enum :c:type:`v4l2_ctrl_type` how the minimum value is to be used for each possible control type. Note that this a signed 32-bit value. @@ -153,7 +153,7 @@ See also the examples in :ref:`control`. - ``maximum`` - Maximum value, inclusive. This field gives an upper bound for the - control. See enum :ref:`v4l2_ctrl_type ` how + control. See enum :c:type:`v4l2_ctrl_type` how the maximum value is to be used for each possible control type. Note that this a signed 32-bit value. @@ -164,7 +164,7 @@ See also the examples in :ref:`control`. - ``step`` - This field gives a step size for the control. See enum - :ref:`v4l2_ctrl_type ` how the step value is + :c:type:`v4l2_ctrl_type` how the step value is to be used for each possible control type. Note that this an unsigned 32-bit value. @@ -269,7 +269,7 @@ See also the examples in :ref:`control`. - ``minimum`` - Minimum value, inclusive. This field gives a lower bound for the - control. See enum :ref:`v4l2_ctrl_type ` how + control. See enum :c:type:`v4l2_ctrl_type` how the minimum value is to be used for each possible control type. Note that this a signed 64-bit value. @@ -280,7 +280,7 @@ See also the examples in :ref:`control`. - ``maximum`` - Maximum value, inclusive. This field gives an upper bound for the - control. See enum :ref:`v4l2_ctrl_type ` how + control. See enum :c:type:`v4l2_ctrl_type` how the maximum value is to be used for each possible control type. Note that this a signed 64-bit value. @@ -291,7 +291,7 @@ See also the examples in :ref:`control`. - ``step`` - This field gives a step size for the control. See enum - :ref:`v4l2_ctrl_type ` how the step value is + :c:type:`v4l2_ctrl_type` how the step value is to be used for each possible control type. Note that this an unsigned 64-bit value. @@ -456,7 +456,7 @@ See also the examples in :ref:`control`. .. tabularcolumns:: |p{5.8cm}|p{1.4cm}|p{1.0cm}|p{1.4cm}|p{6.9cm}| -.. _v4l2-ctrl-type: +.. c:type:: v4l2_ctrl_type .. cssclass:: longtable diff --git a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst index 2df1342ac6ea..90d876faa5b9 100644 --- a/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst +++ b/Documentation/media/uapi/v4l/vidioc-subdev-g-fmt.rst @@ -38,7 +38,7 @@ These ioctls are used to negotiate the frame format at specific subdev pads in the image pipeline. To retrieve the current format applications set the ``pad`` field of a -struct :ref:`v4l2_subdev_format ` to the desired +struct :c:type:`v4l2_subdev_format` to the desired pad number as reported by the media API and the ``which`` field to ``V4L2_SUBDEV_FORMAT_ACTIVE``. When they call the ``VIDIOC_SUBDEV_G_FMT`` ioctl with a pointer to this structure the @@ -49,7 +49,7 @@ To change the current format applications set both the ``pad`` and the ``VIDIOC_SUBDEV_S_FMT`` ioctl with a pointer to this structure the driver verifies the requested format, adjusts it based on the hardware capabilities and configures the device. Upon return the struct -:ref:`v4l2_subdev_format ` contains the current +:c:type:`v4l2_subdev_format` contains the current format as would be returned by a ``VIDIOC_SUBDEV_G_FMT`` call. Applications can query the device capabilities by setting the ``which`` @@ -78,7 +78,7 @@ should be as close as possible to the original request. .. tabularcolumns:: |p{4.4cm}|p{4.4cm}|p{8.7cm}| -.. _v4l2-subdev-format: +.. c:type:: v4l2_subdev_format .. flat-table:: struct v4l2_subdev_format :header-rows: 0 @@ -105,7 +105,7 @@ should be as close as possible to the original request. - .. row 3 - - struct :ref:`v4l2_mbus_framefmt ` + - struct :c:type:`v4l2_mbus_framefmt` - ``format`` @@ -164,7 +164,7 @@ EBUSY fix the problem first. Only returned by ``VIDIOC_SUBDEV_S_FMT`` EINVAL - The struct :ref:`v4l2_subdev_format ` + The struct :c:type:`v4l2_subdev_format` ``pad`` references a non-existing pad, or the ``which`` field references a non-existing format. diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 5272aeec0cec..477e90d89a04 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -56,7 +56,7 @@ struct v4l2_ctrl_handler; * * .. note:: * The size of @prios array matches the number of priority types defined - * by :ref:`enum v4l2_priority `. + * by enum &v4l2_priority. */ struct v4l2_prio_state { atomic_t prios[4]; @@ -73,8 +73,8 @@ void v4l2_prio_init(struct v4l2_prio_state *global); * v4l2_prio_change - changes the v4l2 file handler priority * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: pointer to the desired priority, as defined by :ref:`enum v4l2_priority ` - * @new: Priority type requested, as defined by :ref:`enum v4l2_priority `. + * @local: pointer to the desired priority, as defined by enum &v4l2_priority + * @new: Priority type requested, as defined by enum &v4l2_priority. * * .. note:: * This function should be used only by the V4L2 core. @@ -86,7 +86,7 @@ int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local, * v4l2_prio_open - Implements the priority logic for a file handler open * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: pointer to the desired priority, as defined by :ref:`enum v4l2_priority ` + * @local: pointer to the desired priority, as defined by enum &v4l2_priority * * .. note:: * This function should be used only by the V4L2 core. @@ -97,7 +97,7 @@ void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local); * v4l2_prio_close - Implements the priority logic for a file handler close * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: priority to be released, as defined by :ref:`enum v4l2_priority ` + * @local: priority to be released, as defined by enum &v4l2_priority * * .. note:: * This function should be used only by the V4L2 core. @@ -118,7 +118,7 @@ enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); * v4l2_prio_close - Implements the priority logic for a file handler close * * @global: pointer to the &struct v4l2_prio_state of the device node. - * @local: desired priority, as defined by :ref:`enum v4l2_priority ` local + * @local: desired priority, as defined by enum &v4l2_priority local * * .. note:: * This function should be used only by the V4L2 core. -- cgit v1.2.3-70-g09d2 From f8441a4334107ccd69c07164a38d9dde451cd85d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Aug 2016 19:29:58 -0300 Subject: [media] v4l2-ctrls.h: Fix some c:type references Now that the uAPI is using c:type, let's use it here too. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-ctrls.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index 3207449327d7..beea0a2c0894 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -973,9 +973,9 @@ extern const struct v4l2_subscribed_event_ops v4l2_ctrl_sub_ev_ops; * v4l2_ctrl_replace - Function to be used as a callback to * &struct v4l2_subscribed_event_ops replace\(\) * - * @old: pointer to :ref:`struct v4l2_event ` with the reported + * @old: pointer to struct &v4l2_event with the reported * event; - * @new: pointer to :ref:`struct v4l2_event ` with the modified + * @new: pointer to struct &v4l2_event with the modified * event; */ void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new); @@ -984,9 +984,9 @@ void v4l2_ctrl_replace(struct v4l2_event *old, const struct v4l2_event *new); * v4l2_ctrl_merge - Function to be used as a callback to * &struct v4l2_subscribed_event_ops merge(\) * - * @old: pointer to :ref:`struct v4l2_event ` with the reported + * @old: pointer to struct &v4l2_event with the reported * event; - * @new: pointer to :ref:`struct v4l2_event ` with the merged + * @new: pointer to struct &v4l2_event with the merged * event; */ void v4l2_ctrl_merge(const struct v4l2_event *old, struct v4l2_event *new); -- cgit v1.2.3-70-g09d2 From bba65c132fe4e57682861ff826e259efd7845492 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 30 Aug 2016 12:18:09 -0300 Subject: [media] v4l2-ioctl.h: document the remaining functions There are several undocumented functions here; document them. While here, make checkpatch.pl happy. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/conf_nitpick.py | 1 + include/media/v4l2-ioctl.h | 510 +++++++++++++++++++++--------------- 2 files changed, 305 insertions(+), 206 deletions(-) (limited to 'include') diff --git a/Documentation/media/conf_nitpick.py b/Documentation/media/conf_nitpick.py index 1c7928abace5..1f3ef3ded2d4 100644 --- a/Documentation/media/conf_nitpick.py +++ b/Documentation/media/conf_nitpick.py @@ -96,5 +96,6 @@ nitpick_ignore = [ ("c:type", "__user"), ("c:type", "usb_device"), ("c:type", "usb_interface"), + ("c:type", "v4l2_std_id"), ("c:type", "video_system_t"), ] diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index 8b1d19bc9b0e..574ff2ae94be 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -287,273 +287,286 @@ struct v4l2_ioctl_ops { /* ioctl callbacks */ /* VIDIOC_QUERYCAP handler */ - int (*vidioc_querycap)(struct file *file, void *fh, struct v4l2_capability *cap); + int (*vidioc_querycap)(struct file *file, void *fh, + struct v4l2_capability *cap); /* VIDIOC_ENUM_FMT handlers */ - int (*vidioc_enum_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vid_overlay) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_overlay)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_fmtdesc *f); int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); - int (*vidioc_enum_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); + int (*vidioc_enum_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_fmtdesc *f); /* VIDIOC_G_FMT handlers */ - int (*vidioc_g_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_g_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_g_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_g_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_g_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_g_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_g_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_g_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_g_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_format *f); /* VIDIOC_S_FMT handlers */ - int (*vidioc_s_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_s_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_s_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_s_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_s_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_s_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_s_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_s_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_s_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_format *f); /* VIDIOC_TRY_FMT handlers */ - int (*vidioc_try_fmt_vid_cap) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_try_fmt_vid_cap)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_vid_overlay)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_vid_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_try_fmt_vid_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_vid_out_overlay)(struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_vbi_out) (struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_vbi_out)(struct file *file, void *fh, + struct v4l2_format *f); int (*vidioc_try_fmt_sliced_vbi_cap)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, - struct v4l2_format *f); + struct v4l2_format *f); int (*vidioc_try_fmt_vid_cap_mplane)(struct file *file, void *fh, struct v4l2_format *f); int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh, struct v4l2_format *f); - int (*vidioc_try_fmt_sdr_cap) (struct file *file, void *fh, - struct v4l2_format *f); - int (*vidioc_try_fmt_sdr_out) (struct file *file, void *fh, - struct v4l2_format *f); + int (*vidioc_try_fmt_sdr_cap)(struct file *file, void *fh, + struct v4l2_format *f); + int (*vidioc_try_fmt_sdr_out)(struct file *file, void *fh, + struct v4l2_format *f); /* Buffer handlers */ - int (*vidioc_reqbufs) (struct file *file, void *fh, struct v4l2_requestbuffers *b); - int (*vidioc_querybuf)(struct file *file, void *fh, struct v4l2_buffer *b); - int (*vidioc_qbuf) (struct file *file, void *fh, struct v4l2_buffer *b); - int (*vidioc_expbuf) (struct file *file, void *fh, - struct v4l2_exportbuffer *e); - int (*vidioc_dqbuf) (struct file *file, void *fh, struct v4l2_buffer *b); - - int (*vidioc_create_bufs)(struct file *file, void *fh, struct v4l2_create_buffers *b); - int (*vidioc_prepare_buf)(struct file *file, void *fh, struct v4l2_buffer *b); - - int (*vidioc_overlay) (struct file *file, void *fh, unsigned int i); - int (*vidioc_g_fbuf) (struct file *file, void *fh, - struct v4l2_framebuffer *a); - int (*vidioc_s_fbuf) (struct file *file, void *fh, - const struct v4l2_framebuffer *a); + int (*vidioc_reqbufs)(struct file *file, void *fh, + struct v4l2_requestbuffers *b); + int (*vidioc_querybuf)(struct file *file, void *fh, + struct v4l2_buffer *b); + int (*vidioc_qbuf)(struct file *file, void *fh, + struct v4l2_buffer *b); + int (*vidioc_expbuf)(struct file *file, void *fh, + struct v4l2_exportbuffer *e); + int (*vidioc_dqbuf)(struct file *file, void *fh, + struct v4l2_buffer *b); + + int (*vidioc_create_bufs)(struct file *file, void *fh, + struct v4l2_create_buffers *b); + int (*vidioc_prepare_buf)(struct file *file, void *fh, + struct v4l2_buffer *b); + + int (*vidioc_overlay)(struct file *file, void *fh, unsigned int i); + int (*vidioc_g_fbuf)(struct file *file, void *fh, + struct v4l2_framebuffer *a); + int (*vidioc_s_fbuf)(struct file *file, void *fh, + const struct v4l2_framebuffer *a); /* Stream on/off */ - int (*vidioc_streamon) (struct file *file, void *fh, enum v4l2_buf_type i); - int (*vidioc_streamoff)(struct file *file, void *fh, enum v4l2_buf_type i); - - /* Standard handling - ENUMSTD is handled by videodev.c + int (*vidioc_streamon)(struct file *file, void *fh, + enum v4l2_buf_type i); + int (*vidioc_streamoff)(struct file *file, void *fh, + enum v4l2_buf_type i); + + /* + * Standard handling + * + * Note: ENUMSTD is handled by videodev.c */ - int (*vidioc_g_std) (struct file *file, void *fh, v4l2_std_id *norm); - int (*vidioc_s_std) (struct file *file, void *fh, v4l2_std_id norm); - int (*vidioc_querystd) (struct file *file, void *fh, v4l2_std_id *a); + int (*vidioc_g_std)(struct file *file, void *fh, v4l2_std_id *norm); + int (*vidioc_s_std)(struct file *file, void *fh, v4l2_std_id norm); + int (*vidioc_querystd)(struct file *file, void *fh, v4l2_std_id *a); /* Input handling */ int (*vidioc_enum_input)(struct file *file, void *fh, struct v4l2_input *inp); - int (*vidioc_g_input) (struct file *file, void *fh, unsigned int *i); - int (*vidioc_s_input) (struct file *file, void *fh, unsigned int i); + int (*vidioc_g_input)(struct file *file, void *fh, unsigned int *i); + int (*vidioc_s_input)(struct file *file, void *fh, unsigned int i); /* Output handling */ - int (*vidioc_enum_output) (struct file *file, void *fh, + int (*vidioc_enum_output)(struct file *file, void *fh, struct v4l2_output *a); - int (*vidioc_g_output) (struct file *file, void *fh, unsigned int *i); - int (*vidioc_s_output) (struct file *file, void *fh, unsigned int i); + int (*vidioc_g_output)(struct file *file, void *fh, unsigned int *i); + int (*vidioc_s_output)(struct file *file, void *fh, unsigned int i); /* Control handling */ - int (*vidioc_queryctrl) (struct file *file, void *fh, - struct v4l2_queryctrl *a); - int (*vidioc_query_ext_ctrl) (struct file *file, void *fh, - struct v4l2_query_ext_ctrl *a); - int (*vidioc_g_ctrl) (struct file *file, void *fh, - struct v4l2_control *a); - int (*vidioc_s_ctrl) (struct file *file, void *fh, - struct v4l2_control *a); - int (*vidioc_g_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_s_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_try_ext_ctrls) (struct file *file, void *fh, - struct v4l2_ext_controls *a); - int (*vidioc_querymenu) (struct file *file, void *fh, - struct v4l2_querymenu *a); + int (*vidioc_queryctrl)(struct file *file, void *fh, + struct v4l2_queryctrl *a); + int (*vidioc_query_ext_ctrl)(struct file *file, void *fh, + struct v4l2_query_ext_ctrl *a); + int (*vidioc_g_ctrl)(struct file *file, void *fh, + struct v4l2_control *a); + int (*vidioc_s_ctrl)(struct file *file, void *fh, + struct v4l2_control *a); + int (*vidioc_g_ext_ctrls)(struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_s_ext_ctrls)(struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_try_ext_ctrls)(struct file *file, void *fh, + struct v4l2_ext_controls *a); + int (*vidioc_querymenu)(struct file *file, void *fh, + struct v4l2_querymenu *a); /* Audio ioctls */ - int (*vidioc_enumaudio) (struct file *file, void *fh, - struct v4l2_audio *a); - int (*vidioc_g_audio) (struct file *file, void *fh, - struct v4l2_audio *a); - int (*vidioc_s_audio) (struct file *file, void *fh, - const struct v4l2_audio *a); + int (*vidioc_enumaudio)(struct file *file, void *fh, + struct v4l2_audio *a); + int (*vidioc_g_audio)(struct file *file, void *fh, + struct v4l2_audio *a); + int (*vidioc_s_audio)(struct file *file, void *fh, + const struct v4l2_audio *a); /* Audio out ioctls */ - int (*vidioc_enumaudout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_g_audout) (struct file *file, void *fh, - struct v4l2_audioout *a); - int (*vidioc_s_audout) (struct file *file, void *fh, - const struct v4l2_audioout *a); - int (*vidioc_g_modulator) (struct file *file, void *fh, - struct v4l2_modulator *a); - int (*vidioc_s_modulator) (struct file *file, void *fh, - const struct v4l2_modulator *a); + int (*vidioc_enumaudout)(struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_g_audout)(struct file *file, void *fh, + struct v4l2_audioout *a); + int (*vidioc_s_audout)(struct file *file, void *fh, + const struct v4l2_audioout *a); + int (*vidioc_g_modulator)(struct file *file, void *fh, + struct v4l2_modulator *a); + int (*vidioc_s_modulator)(struct file *file, void *fh, + const struct v4l2_modulator *a); /* Crop ioctls */ - int (*vidioc_cropcap) (struct file *file, void *fh, - struct v4l2_cropcap *a); - int (*vidioc_g_crop) (struct file *file, void *fh, - struct v4l2_crop *a); - int (*vidioc_s_crop) (struct file *file, void *fh, - const struct v4l2_crop *a); - int (*vidioc_g_selection) (struct file *file, void *fh, - struct v4l2_selection *s); - int (*vidioc_s_selection) (struct file *file, void *fh, - struct v4l2_selection *s); + int (*vidioc_cropcap)(struct file *file, void *fh, + struct v4l2_cropcap *a); + int (*vidioc_g_crop)(struct file *file, void *fh, + struct v4l2_crop *a); + int (*vidioc_s_crop)(struct file *file, void *fh, + const struct v4l2_crop *a); + int (*vidioc_g_selection)(struct file *file, void *fh, + struct v4l2_selection *s); + int (*vidioc_s_selection)(struct file *file, void *fh, + struct v4l2_selection *s); /* Compression ioctls */ - int (*vidioc_g_jpegcomp) (struct file *file, void *fh, - struct v4l2_jpegcompression *a); - int (*vidioc_s_jpegcomp) (struct file *file, void *fh, - const struct v4l2_jpegcompression *a); - int (*vidioc_g_enc_index) (struct file *file, void *fh, - struct v4l2_enc_idx *a); - int (*vidioc_encoder_cmd) (struct file *file, void *fh, - struct v4l2_encoder_cmd *a); - int (*vidioc_try_encoder_cmd) (struct file *file, void *fh, - struct v4l2_encoder_cmd *a); - int (*vidioc_decoder_cmd) (struct file *file, void *fh, - struct v4l2_decoder_cmd *a); - int (*vidioc_try_decoder_cmd) (struct file *file, void *fh, - struct v4l2_decoder_cmd *a); + int (*vidioc_g_jpegcomp)(struct file *file, void *fh, + struct v4l2_jpegcompression *a); + int (*vidioc_s_jpegcomp)(struct file *file, void *fh, + const struct v4l2_jpegcompression *a); + int (*vidioc_g_enc_index)(struct file *file, void *fh, + struct v4l2_enc_idx *a); + int (*vidioc_encoder_cmd)(struct file *file, void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_try_encoder_cmd)(struct file *file, void *fh, + struct v4l2_encoder_cmd *a); + int (*vidioc_decoder_cmd)(struct file *file, void *fh, + struct v4l2_decoder_cmd *a); + int (*vidioc_try_decoder_cmd)(struct file *file, void *fh, + struct v4l2_decoder_cmd *a); /* Stream type-dependent parameter ioctls */ - int (*vidioc_g_parm) (struct file *file, void *fh, - struct v4l2_streamparm *a); - int (*vidioc_s_parm) (struct file *file, void *fh, - struct v4l2_streamparm *a); + int (*vidioc_g_parm)(struct file *file, void *fh, + struct v4l2_streamparm *a); + int (*vidioc_s_parm)(struct file *file, void *fh, + struct v4l2_streamparm *a); /* Tuner ioctls */ - int (*vidioc_g_tuner) (struct file *file, void *fh, - struct v4l2_tuner *a); - int (*vidioc_s_tuner) (struct file *file, void *fh, - const struct v4l2_tuner *a); - int (*vidioc_g_frequency) (struct file *file, void *fh, - struct v4l2_frequency *a); - int (*vidioc_s_frequency) (struct file *file, void *fh, - const struct v4l2_frequency *a); - int (*vidioc_enum_freq_bands) (struct file *file, void *fh, - struct v4l2_frequency_band *band); + int (*vidioc_g_tuner)(struct file *file, void *fh, + struct v4l2_tuner *a); + int (*vidioc_s_tuner)(struct file *file, void *fh, + const struct v4l2_tuner *a); + int (*vidioc_g_frequency)(struct file *file, void *fh, + struct v4l2_frequency *a); + int (*vidioc_s_frequency)(struct file *file, void *fh, + const struct v4l2_frequency *a); + int (*vidioc_enum_freq_bands)(struct file *file, void *fh, + struct v4l2_frequency_band *band); /* Sliced VBI cap */ - int (*vidioc_g_sliced_vbi_cap) (struct file *file, void *fh, - struct v4l2_sliced_vbi_cap *a); + int (*vidioc_g_sliced_vbi_cap)(struct file *file, void *fh, + struct v4l2_sliced_vbi_cap *a); /* Log status ioctl */ - int (*vidioc_log_status) (struct file *file, void *fh); + int (*vidioc_log_status)(struct file *file, void *fh); - int (*vidioc_s_hw_freq_seek) (struct file *file, void *fh, - const struct v4l2_hw_freq_seek *a); + int (*vidioc_s_hw_freq_seek)(struct file *file, void *fh, + const struct v4l2_hw_freq_seek *a); /* Debugging ioctls */ #ifdef CONFIG_VIDEO_ADV_DEBUG - int (*vidioc_g_register) (struct file *file, void *fh, - struct v4l2_dbg_register *reg); - int (*vidioc_s_register) (struct file *file, void *fh, - const struct v4l2_dbg_register *reg); + int (*vidioc_g_register)(struct file *file, void *fh, + struct v4l2_dbg_register *reg); + int (*vidioc_s_register)(struct file *file, void *fh, + const struct v4l2_dbg_register *reg); - int (*vidioc_g_chip_info) (struct file *file, void *fh, - struct v4l2_dbg_chip_info *chip); + int (*vidioc_g_chip_info)(struct file *file, void *fh, + struct v4l2_dbg_chip_info *chip); #endif - int (*vidioc_enum_framesizes) (struct file *file, void *fh, - struct v4l2_frmsizeenum *fsize); + int (*vidioc_enum_framesizes)(struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize); - int (*vidioc_enum_frameintervals) (struct file *file, void *fh, - struct v4l2_frmivalenum *fival); + int (*vidioc_enum_frameintervals)(struct file *file, void *fh, + struct v4l2_frmivalenum *fival); /* DV Timings IOCTLs */ - int (*vidioc_s_dv_timings) (struct file *file, void *fh, - struct v4l2_dv_timings *timings); - int (*vidioc_g_dv_timings) (struct file *file, void *fh, - struct v4l2_dv_timings *timings); - int (*vidioc_query_dv_timings) (struct file *file, void *fh, - struct v4l2_dv_timings *timings); - int (*vidioc_enum_dv_timings) (struct file *file, void *fh, - struct v4l2_enum_dv_timings *timings); - int (*vidioc_dv_timings_cap) (struct file *file, void *fh, - struct v4l2_dv_timings_cap *cap); - int (*vidioc_g_edid) (struct file *file, void *fh, struct v4l2_edid *edid); - int (*vidioc_s_edid) (struct file *file, void *fh, struct v4l2_edid *edid); - - int (*vidioc_subscribe_event) (struct v4l2_fh *fh, - const struct v4l2_event_subscription *sub); + int (*vidioc_s_dv_timings)(struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_g_dv_timings)(struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_query_dv_timings)(struct file *file, void *fh, + struct v4l2_dv_timings *timings); + int (*vidioc_enum_dv_timings)(struct file *file, void *fh, + struct v4l2_enum_dv_timings *timings); + int (*vidioc_dv_timings_cap)(struct file *file, void *fh, + struct v4l2_dv_timings_cap *cap); + int (*vidioc_g_edid)(struct file *file, void *fh, + struct v4l2_edid *edid); + int (*vidioc_s_edid)(struct file *file, void *fh, + struct v4l2_edid *edid); + + int (*vidioc_subscribe_event)(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub); int (*vidioc_unsubscribe_event)(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub); /* For other private ioctls */ - long (*vidioc_default) (struct file *file, void *fh, - bool valid_prio, unsigned int cmd, void *arg); + long (*vidioc_default)(struct file *file, void *fh, + bool valid_prio, unsigned int cmd, void *arg); }; @@ -573,38 +586,123 @@ struct v4l2_ioctl_ops { #define V4L2_DEV_DEBUG_POLL 0x10 /* Video standard functions */ -extern const char *v4l2_norm_to_name(v4l2_std_id id); -extern void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod); -extern int v4l2_video_std_construct(struct v4l2_standard *vs, + +/** + * v4l2_norm_to_name - Ancillary routine to analog TV standard name from its ID. + * + * @id: analog TV standard ID. + * + * Return: returns a string with the name of the analog TV standard. + * If the standard is not found or if @id points to multiple standard, + * it returns "Unknown". + */ +const char *v4l2_norm_to_name(v4l2_std_id id); + +/** + * v4l2_video_std_frame_period - Ancillary routine that fills a + * struct &v4l2_fract pointer with the default framerate fraction. + * + * @id: analog TV sdandard ID. + * @frameperiod: struct &v4l2_fract pointer to be filled + * + */ +void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod); + +/** + * v4l2_video_std_construct - Ancillary routine that fills in the fields of + * a &v4l2_standard structure according to the @id parameter. + * + * @vs: struct &v4l2_standard pointer to be filled + * @id: analog TV sdandard ID. + * @name: name of the standard to be used + * + * .. note:: + * + * This ancillary routine is obsolete. Shouldn't be used on newer drivers. + */ +int v4l2_video_std_construct(struct v4l2_standard *vs, int id, const char *name); -/* Prints the ioctl in a human-readable format. If prefix != NULL, - then do printk(KERN_DEBUG "%s: ", prefix) first. */ -extern void v4l_printk_ioctl(const char *prefix, unsigned int cmd); -/* Internal use only: get the mutex (if any) that we need to lock for the - given command. */ +/** + * v4l_printk_ioctl - Ancillary routine that prints the ioctl in a + * human-readable format. + * + * @prefix: prefix to be added at the ioctl prints. + * @cmd: ioctl name + * + * .. note:: + * + * If prefix != %NULL, then it will issue a + * ``printk(KERN_DEBUG "%s: ", prefix)`` first. + */ +void v4l_printk_ioctl(const char *prefix, unsigned int cmd); + struct video_device; -extern struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned cmd); + + +/** + * v4l2_ioctl_get_lock - get the mutex (if any) that it is need to lock for + * a given command. + * + * @vdev: Pointer to struct &video_device. + * @cmd: Ioctl name. + * + * .. note:: Internal use only. Should not be used outside V4L2 core. + */ +struct mutex *v4l2_ioctl_get_lock(struct video_device *vdev, unsigned int cmd); /* names for fancy debug output */ extern const char *v4l2_field_names[]; extern const char *v4l2_type_names[]; #ifdef CONFIG_COMPAT -/* 32 Bits compatibility layer for 64 bits processors */ -extern long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, - unsigned long arg); +/** + * v4l2_compat_ioctl32 -32 Bits compatibility layer for 64 bits processors + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + */ +long int v4l2_compat_ioctl32(struct file *file, unsigned int cmd, + unsigned long arg); #endif -typedef long (*v4l2_kioctl)(struct file *file, - unsigned int cmd, void *arg); +/** + * typedef v4l2_kioctl - Typedef used to pass an ioctl handler. + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + */ +typedef long (*v4l2_kioctl)(struct file *file, unsigned int cmd, void *arg); -/* Include support for obsoleted stuff */ -extern long video_usercopy(struct file *file, unsigned int cmd, - unsigned long arg, v4l2_kioctl func); +/** + * video_usercopy - copies data from/to userspace memory when an ioctl is + * issued. + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + * @func: function that will handle the ioctl + * + * .. note:: + * + * This routine should be used only inside the V4L2 core. + */ +long int video_usercopy(struct file *file, unsigned int cmd, + unsigned long int arg, v4l2_kioctl func); -/* Standard handlers for V4L ioctl's */ -extern long video_ioctl2(struct file *file, - unsigned int cmd, unsigned long arg); +/** + * video_ioctl2 - Handles a V4L2 ioctl. + * + * @file: Pointer to struct &file. + * @cmd: Ioctl name. + * @arg: Ioctl argument. + * + * Method used to hancle an ioctl. Should be used to fill the + * &v4l2_ioctl_ops.unlocked_ioctl on all V4L2 drivers. + */ +long int video_ioctl2(struct file *file, + unsigned int cmd, unsigned long int arg); #endif /* _V4L2_IOCTL_H */ -- cgit v1.2.3-70-g09d2 From 65d7aba0d3c32fc686fe19e146b8cd8a0a87952d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 30 Aug 2016 19:16:25 -0300 Subject: [media] v4l2-device.h: fix some doc tags Fix some minor issues at the documentation tags on this file, adding cross-references where needed, and fixing some broken ones. While here, fix a few spaces before tabs to make Checkpatch happier. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-device.h | 68 ++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index a9d6aa41790e..8ffa94009d1a 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h @@ -39,7 +39,7 @@ struct v4l2_ctrl_handler; * if this struct is embedded into a larger struct. * @name: unique device name, by default the driver name + bus ID * @notify: notify callback called by some sub-devices. - * @ctrl_handler: The control handler. May be NULL. + * @ctrl_handler: The control handler. May be %NULL. * @prio: Device's priority state * @ref: Keep track of the references to this struct. * @release: Release function that is called when the ref count @@ -53,8 +53,8 @@ struct v4l2_ctrl_handler; * * .. note:: * - * #) dev->driver_data points to this struct. - * #) dev might be NULL if there is no parent device + * #) @dev->driver_data points to this struct. + * #) @dev might be %NULL if there is no parent device */ struct v4l2_device { @@ -76,10 +76,10 @@ struct v4l2_device { /** * v4l2_device_get - gets a V4L2 device reference * - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: pointer to struct &v4l2_device * * This is an ancillary routine meant to increment the usage for the - * struct v4l2_device pointed by @v4l2_dev. + * struct &v4l2_device pointed by @v4l2_dev. */ static inline void v4l2_device_get(struct v4l2_device *v4l2_dev) { @@ -89,23 +89,23 @@ static inline void v4l2_device_get(struct v4l2_device *v4l2_dev) /** * v4l2_device_put - putss a V4L2 device reference * - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: pointer to struct &v4l2_device * * This is an ancillary routine meant to decrement the usage for the - * struct v4l2_device pointed by @v4l2_dev. + * struct &v4l2_device pointed by @v4l2_dev. */ int v4l2_device_put(struct v4l2_device *v4l2_dev); /** - * v4l2_device_register -Initialize v4l2_dev and make dev->driver_data - * point to v4l2_dev. + * v4l2_device_register - Initialize v4l2_dev and make @dev->driver_data + * point to @v4l2_dev. * - * @dev: pointer to struct device - * @v4l2_dev: pointer to struct v4l2_device + * @dev: pointer to struct &device + * @v4l2_dev: pointer to struct &v4l2_device * * .. note:: - * dev may be NULL in rare cases (ISA devices). - * In such case the caller must fill in the v4l2_dev->name field + * @dev may be %NULL in rare cases (ISA devices). + * In such case the caller must fill in the @v4l2_dev->name field * before calling this function. */ int __must_check v4l2_device_register(struct device *dev, @@ -113,14 +113,14 @@ int __must_check v4l2_device_register(struct device *dev, /** * v4l2_device_set_name - Optional function to initialize the - * name field of struct v4l2_device + * name field of struct &v4l2_device * - * @v4l2_dev: pointer to struct v4l2_device + * @v4l2_dev: pointer to struct &v4l2_device * @basename: base name for the device name * @instance: pointer to a static atomic_t var with the instance usage for - * the device driver. + * the device driver. * - * v4l2_device_set_name() initializes the name field of struct v4l2_device + * v4l2_device_set_name() initializes the name field of struct &v4l2_device * using the driver name and a driver-global atomic_t instance. * * This function will increment the instance counter and returns the @@ -132,7 +132,7 @@ int __must_check v4l2_device_register(struct device *dev, * * ... * - * instance = v4l2_device_set_name(&v4l2_dev, "foo", &drv_instance); + * instance = v4l2_device_set_name(&\ v4l2_dev, "foo", &\ drv_instance); * * The first time this is called the name field will be set to foo0 and * this function returns 0. If the name ends with a digit (e.g. cx18), @@ -147,16 +147,16 @@ int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, * @v4l2_dev: pointer to struct v4l2_device * * Should be called when the USB parent disconnects. - * Since the parent disappears, this ensures that v4l2_dev doesn't have + * Since the parent disappears, this ensures that @v4l2_dev doesn't have * an invalid parent pointer. * - * .. note:: This function sets v4l2_dev->dev to NULL. + * .. note:: This function sets @v4l2_dev->dev to NULL. */ void v4l2_device_disconnect(struct v4l2_device *v4l2_dev); /** * v4l2_device_unregister - Unregister all sub-devices and any other - * resources related to v4l2_dev. + * resources related to @v4l2_dev. * * @v4l2_dev: pointer to struct v4l2_device */ @@ -165,8 +165,8 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev); /** * v4l2_device_register_subdev - Registers a subdev with a v4l2 device. * - * @v4l2_dev: pointer to struct v4l2_device - * @sd: pointer to struct v4l2_subdev + * @v4l2_dev: pointer to struct &v4l2_device + * @sd: pointer to struct &v4l2_subdev * * While registered, the subdev module is marked as in-use. * @@ -179,7 +179,7 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, /** * v4l2_device_unregister_subdev - Unregisters a subdev with a v4l2 device. * - * @sd: pointer to struct v4l2_subdev + * @sd: pointer to struct &v4l2_subdev * * .. note :: * @@ -191,7 +191,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /** * v4l2_device_register_subdev_nodes - Registers device nodes for all subdevs * of the v4l2 device that are marked with - * the V4L2_SUBDEV_FL_HAS_DEVNODE flag. + * the %V4L2_SUBDEV_FL_HAS_DEVNODE flag. * * @v4l2_dev: pointer to struct v4l2_device */ @@ -201,9 +201,9 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); /** * v4l2_subdev_notify - Sends a notification to v4l2_device. * - * @sd: pointer to struct v4l2_subdev + * @sd: pointer to struct &v4l2_subdev * @notification: type of notification. Please notice that the notification - * type is driver-specific. + * type is driver-specific. * @arg: arguments for the notification. Those are specific to each * notification type. */ @@ -222,7 +222,7 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ #define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \ - do { \ + do { \ list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) \ if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ (sd)->ops->o->f((sd) , ##args); \ @@ -241,15 +241,15 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ #define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \ -({ \ +({ \ long __err = 0; \ \ list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) { \ if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ __err = (sd)->ops->o->f((sd) , ##args); \ if (__err && __err != -ENOIOCTLCMD) \ - break; \ - } \ + break; \ + } \ (__err == -ENOIOCTLCMD) ? 0 : __err; \ }) @@ -276,7 +276,7 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, match them all). If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ +#define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ ({ \ struct v4l2_subdev *__sd; \ __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ @@ -300,8 +300,8 @@ static inline void v4l2_subdev_notify(struct v4l2_subdev *sd, /* * Call the specified callback for all subdevs where grp_id & grpmsk != 0 - * (if grpmsk == `0, then match them all). If the callback returns an error - * other than 0 or -ENOIOCTLCMD, then return with that error code. Note that + * (if grpmsk == 0, then match them all). If the callback returns an error + * other than 0 or %-ENOIOCTLCMD, then return with that error code. Note that * you cannot add or delete a subdev while walking the subdevs list. */ #define v4l2_device_mask_call_until_err(v4l2_dev, grpmsk, o, f, args...) \ -- cgit v1.2.3-70-g09d2 From f06606e56bc61d65cbc1ad3a8dc6e81ec1b2034e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 30 Aug 2016 20:11:11 -0300 Subject: [media] v4l2-dv-timings.h: let kernel-doc parte the typedef argument Now that scripts/kernel-doc was fixed to parse the typedef argument used here, let it produce documentation. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dv-timings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-dv-timings.h b/include/media/v4l2-dv-timings.h index 65caadf13eec..0a7d9e1fc8c8 100644 --- a/include/media/v4l2-dv-timings.h +++ b/include/media/v4l2-dv-timings.h @@ -28,8 +28,8 @@ */ extern const struct v4l2_dv_timings v4l2_dv_timings_presets[]; -/* - * v4l2_check_dv_timings_fnc - timings check callback +/** + * typedef v4l2_check_dv_timings_fnc - timings check callback * * @t: the v4l2_dv_timings struct. * @handle: a handle from the driver. -- cgit v1.2.3-70-g09d2 From 59d44bbe46fe876c55d5cc051d552b1debb1c454 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 30 Aug 2016 21:08:17 -0300 Subject: [media] v4l2-subdev.h: fix a doc nitpick warning One markup tag is wrong here. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 6e1d044e3ee8..2c1e328ccb1d 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -226,7 +226,7 @@ struct v4l2_subdev_core_ops { * * @g_tuner: callback for %VIDIOC_G_TUNER ioctl handler code. * - * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. &vt->type must be + * @s_tuner: callback for %VIDIOC_S_TUNER ioctl handler code. @vt->type must be * filled in. Normally done by video_ioctl2 or the * bridge driver. * -- cgit v1.2.3-70-g09d2 From 848d10314bfe1be79f5ca4deb3d2bf81f6adcf38 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 31 Aug 2016 16:34:07 -0300 Subject: [media] fix broken references on dvb/video*rst Trivially fix those broken references, by copying the structs fron the header, just like other API documentation at the DVB side. This doesn't have the level of quality used at the V4L2 side of the API, but, as this documents a deprecated API, used only by av7110 driver, it doesn't make much sense to invest time making it better. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/dvb/video-command.rst | 30 ++++++++++++++++++++++ Documentation/media/uapi/dvb/video-get-event.rst | 17 ++++++++++++ Documentation/media/uapi/dvb/video-get-navi.rst | 10 +++++++- Documentation/media/uapi/dvb/video-get-size.rst | 10 ++++++++ Documentation/media/uapi/dvb/video-get-status.rst | 11 ++++++++ .../media/uapi/dvb/video-select-source.rst | 10 ++++++++ .../media/uapi/dvb/video-set-attributes.rst | 16 ++++++++++++ .../media/uapi/dvb/video-set-display-format.rst | 2 +- Documentation/media/uapi/dvb/video-set-format.rst | 9 +++++++ .../media/uapi/dvb/video-set-highlight.rst | 26 ++++++++++++++++++- .../media/uapi/dvb/video-set-spu-palette.rst | 10 +++++++- Documentation/media/uapi/dvb/video-set-spu.rst | 11 +++++++- include/uapi/linux/dvb/video.h | 3 ++- 13 files changed, 159 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/Documentation/media/uapi/dvb/video-command.rst b/Documentation/media/uapi/dvb/video-command.rst index 4772562036f1..536d0fdd8399 100644 --- a/Documentation/media/uapi/dvb/video-command.rst +++ b/Documentation/media/uapi/dvb/video-command.rst @@ -59,6 +59,36 @@ subset of the ``v4l2_decoder_cmd`` struct, so refer to the :ref:`VIDIOC_DECODER_CMD` documentation for more information. +.. c:type:: struct video_command + +.. code-block:: c + + /* The structure must be zeroed before use by the application + This ensures it can be extended safely in the future. */ + struct video_command { + __u32 cmd; + __u32 flags; + union { + struct { + __u64 pts; + } stop; + + struct { + /* 0 or 1000 specifies normal speed, + 1 specifies forward single stepping, + -1 specifies backward single stepping, + >1: playback at speed/1000 of the normal speed, + <-1: reverse playback at (-speed/1000) of the normal speed. */ + __s32 speed; + __u32 format; + } play; + + struct { + __u32 data[16]; + } raw; + }; + }; + Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-get-event.rst b/Documentation/media/uapi/dvb/video-get-event.rst index 8c0c622c380b..6ad14cdb894a 100644 --- a/Documentation/media/uapi/dvb/video-get-event.rst +++ b/Documentation/media/uapi/dvb/video-get-event.rst @@ -64,6 +64,23 @@ included in the exceptfds argument, and for poll(), POLLPRI should be specified as the wake-up condition. Read-only permissions are sufficient for this ioctl call. +.. c:type:: video_event + +.. code-block:: c + + struct video_event { + __s32 type; + #define VIDEO_EVENT_SIZE_CHANGED 1 + #define VIDEO_EVENT_FRAME_RATE_CHANGED 2 + #define VIDEO_EVENT_DECODER_STOPPED 3 + #define VIDEO_EVENT_VSYNC 4 + __kernel_time_t timestamp; + union { + video_size_t size; + unsigned int frame_rate; /* in frames per 1000sec */ + unsigned char vsync_field; /* unknown/odd/even/progressive */ + } u; + }; Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-get-navi.rst b/Documentation/media/uapi/dvb/video-get-navi.rst index b8de9ccf38c2..114a9ac48b9e 100644 --- a/Documentation/media/uapi/dvb/video-get-navi.rst +++ b/Documentation/media/uapi/dvb/video-get-navi.rst @@ -16,7 +16,7 @@ VIDEO_GET_NAVI Synopsis -------- -.. c:function:: int ioctl(fd, VIDEO_GET_NAVI , video_navi_pack_t *navipack) +.. c:function:: int ioctl(fd, VIDEO_GET_NAVI , struct video_navi_pack *navipack) :name: VIDEO_GET_NAVI @@ -54,6 +54,14 @@ This ioctl returns navigational information from the DVD stream. This is especially needed if an encoded stream has to be decoded by the hardware. +.. c:type:: video_navi_pack + +.. code-block::c + + typedef struct video_navi_pack { + int length; /* 0 ... 1024 */ + __u8 data[1024]; + } video_navi_pack_t; Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-get-size.rst b/Documentation/media/uapi/dvb/video-get-size.rst index ce8b4c6b41a5..d077fe2305a0 100644 --- a/Documentation/media/uapi/dvb/video-get-size.rst +++ b/Documentation/media/uapi/dvb/video-get-size.rst @@ -52,6 +52,16 @@ Description This ioctl returns the size and aspect ratio. +.. c:type:: video_size_t + +.. code-block::c + + typedef struct { + int w; + int h; + video_format_t aspect_ratio; + } video_size_t; + Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-get-status.rst b/Documentation/media/uapi/dvb/video-get-status.rst index 7b6a278b5246..ed6ea19827a6 100644 --- a/Documentation/media/uapi/dvb/video-get-status.rst +++ b/Documentation/media/uapi/dvb/video-get-status.rst @@ -53,6 +53,17 @@ Description This ioctl call asks the Video Device to return the current status of the device. +.. c:type:: video_status + +.. code-block:: c + + struct video_status { + int video_blank; /* blank video on freeze? */ + video_play_state_t play_state; /* current state of playback */ + video_stream_source_t stream_source; /* current source (demux/memory) */ + video_format_t video_format; /* current aspect ratio of stream*/ + video_displayformat_t display_format;/* selected cropping mode */ + }; Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-select-source.rst b/Documentation/media/uapi/dvb/video-select-source.rst index eaa1088f07da..2f4fbf4b490c 100644 --- a/Documentation/media/uapi/dvb/video-select-source.rst +++ b/Documentation/media/uapi/dvb/video-select-source.rst @@ -58,6 +58,16 @@ This ioctl call informs the video device which source shall be used for the input data. The possible sources are demux or memory. If memory is selected, the data is fed to the video device through the write command. +.. c:type:: video_stream_source_t + +.. code-block:: c + + typedef enum { + VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */ + VIDEO_SOURCE_MEMORY /* If this source is selected, the stream + comes from the user through the write + system call */ + } video_stream_source_t; Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-set-attributes.rst b/Documentation/media/uapi/dvb/video-set-attributes.rst index 8901520d7e43..b2f11a6746e9 100644 --- a/Documentation/media/uapi/dvb/video-set-attributes.rst +++ b/Documentation/media/uapi/dvb/video-set-attributes.rst @@ -55,6 +55,22 @@ information about the stream. Some hardware may not need this information, but the call also tells the hardware to prepare for DVD playback. +.. c:type:: video_attributes_t + +.. code-block::c + + typedef __u16 video_attributes_t; + /* bits: descr. */ + /* 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ + /* 13-12 TV system (0=525/60, 1=625/50) */ + /* 11-10 Aspect ratio (0=4:3, 3=16:9) */ + /* 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ + /* 7 line 21-1 data present in GOP (1=yes, 0=no) */ + /* 6 line 21-2 data present in GOP (1=yes, 0=no) */ + /* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ + /* 2 source letterboxed (1=yes, 0=no) */ + /* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ + Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-set-display-format.rst b/Documentation/media/uapi/dvb/video-set-display-format.rst index 6abf19479939..2ef7401781be 100644 --- a/Documentation/media/uapi/dvb/video-set-display-format.rst +++ b/Documentation/media/uapi/dvb/video-set-display-format.rst @@ -16,7 +16,7 @@ VIDEO_SET_DISPLAY_FORMAT Synopsis -------- -.. c:function:: int ioctl(fd, VIDEO_SET_DISPLAY_FORMAT, video_display_format_t format) +.. c:function:: int ioctl(fd, VIDEO_SET_DISPLAY_FORMAT) :name: VIDEO_SET_DISPLAY_FORMAT diff --git a/Documentation/media/uapi/dvb/video-set-format.rst b/Documentation/media/uapi/dvb/video-set-format.rst index 117618525538..4239a4e365bb 100644 --- a/Documentation/media/uapi/dvb/video-set-format.rst +++ b/Documentation/media/uapi/dvb/video-set-format.rst @@ -54,6 +54,15 @@ This ioctl sets the screen format (aspect ratio) of the connected output device (TV) so that the output of the decoder can be adjusted accordingly. +.. c:type:: video_format_t + +.. code-block:: c + + typedef enum { + VIDEO_FORMAT_4_3, /* Select 4:3 format */ + VIDEO_FORMAT_16_9, /* Select 16:9 format. */ + VIDEO_FORMAT_221_1 /* 2.21:1 */ + } video_format_t; Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-set-highlight.rst b/Documentation/media/uapi/dvb/video-set-highlight.rst index d93b69eef15b..90aeafd923b7 100644 --- a/Documentation/media/uapi/dvb/video-set-highlight.rst +++ b/Documentation/media/uapi/dvb/video-set-highlight.rst @@ -16,7 +16,7 @@ VIDEO_SET_HIGHLIGHT Synopsis -------- -.. c:function:: int ioctl(fd, VIDEO_SET_HIGHLIGHT ,video_highlight_t *vhilite) +.. c:function:: int ioctl(fd, VIDEO_SET_HIGHLIGHT, struct video_highlight *vhilite) :name: VIDEO_SET_HIGHLIGHT @@ -53,6 +53,30 @@ Description This ioctl sets the SPU highlight information for the menu access of a DVD. +.. c:type:: video_highlight + +.. code-block:: c + + typedef + struct video_highlight { + int active; /* 1=show highlight, 0=hide highlight */ + __u8 contrast1; /* 7- 4 Pattern pixel contrast */ + /* 3- 0 Background pixel contrast */ + __u8 contrast2; /* 7- 4 Emphasis pixel-2 contrast */ + /* 3- 0 Emphasis pixel-1 contrast */ + __u8 color1; /* 7- 4 Pattern pixel color */ + /* 3- 0 Background pixel color */ + __u8 color2; /* 7- 4 Emphasis pixel-2 color */ + /* 3- 0 Emphasis pixel-1 color */ + __u32 ypos; /* 23-22 auto action mode */ + /* 21-12 start y */ + /* 9- 0 end y */ + __u32 xpos; /* 23-22 button color number */ + /* 21-12 start x */ + /* 9- 0 end x */ + } video_highlight_t; + + Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-set-spu-palette.rst b/Documentation/media/uapi/dvb/video-set-spu-palette.rst index b24f7882089a..51a1913d21d2 100644 --- a/Documentation/media/uapi/dvb/video-set-spu-palette.rst +++ b/Documentation/media/uapi/dvb/video-set-spu-palette.rst @@ -16,7 +16,7 @@ VIDEO_SET_SPU_PALETTE Synopsis -------- -.. c:function:: int ioctl(fd, VIDEO_SET_SPU_PALETTE, video_spu_palette_t *palette ) +.. c:function:: int ioctl(fd, VIDEO_SET_SPU_PALETTE, struct video_spu_palette *palette ) :name: VIDEO_SET_SPU_PALETTE @@ -52,6 +52,14 @@ Description This ioctl sets the SPU color palette. +.. c:type:: video_spu_palette + +.. code-block::c + + typedef struct video_spu_palette { /* SPU Palette information */ + int length; + __u8 __user *palette; + } video_spu_palette_t; Return Value ------------ diff --git a/Documentation/media/uapi/dvb/video-set-spu.rst b/Documentation/media/uapi/dvb/video-set-spu.rst index 2a7f0625de38..739e5e7bd133 100644 --- a/Documentation/media/uapi/dvb/video-set-spu.rst +++ b/Documentation/media/uapi/dvb/video-set-spu.rst @@ -16,7 +16,7 @@ VIDEO_SET_SPU Synopsis -------- -.. c:function:: int ioctl(fd, VIDEO_SET_SPU , video_spu_t *spu) +.. c:function:: int ioctl(fd, VIDEO_SET_SPU , struct video_spu *spu) :name: VIDEO_SET_SPU @@ -54,6 +54,15 @@ Description This ioctl activates or deactivates SPU decoding in a DVD input stream. It can only be used, if the driver is able to handle a DVD stream. +.. c:type:: struct video_spu + +.. code-block:: c + + typedef struct video_spu { + int active; + int stream_id; + } video_spu_t; + Return Value ------------ diff --git a/include/uapi/linux/dvb/video.h b/include/uapi/linux/dvb/video.h index 49392564f9d6..260f033a5b54 100644 --- a/include/uapi/linux/dvb/video.h +++ b/include/uapi/linux/dvb/video.h @@ -206,7 +206,8 @@ typedef __u16 video_attributes_t; /* 6 line 21-2 data present in GOP (1=yes, 0=no) */ /* 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ /* 2 source letterboxed (1=yes, 0=no) */ -/* 0 film/camera mode (0=camera, 1=film (625/50 only)) */ +/* 0 film/camera mode (0= + *camera, 1=film (625/50 only)) */ /* bit definitions for capabilities: */ -- cgit v1.2.3-70-g09d2 From c13dce18b8266566e951b1d4b9bbbbbf25a00068 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 08:18:04 -0300 Subject: [media] rc-map.h: fix a Sphinx warning ./include/media/rc-map.h:121: WARNING: Inline emphasis start-string without end-string. Signed-off-by: Mauro Carvalho Chehab --- include/media/rc-map.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 173ad58fb61b..3c8edb34f84a 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -117,7 +117,7 @@ struct rc_map_table { * @scan: pointer to struct &rc_map_table * @size: Max number of entries * @len: Number of entries that are in use - * @alloc: size of *scan, in bytes + * @alloc: size of \*scan, in bytes * @rc_type: type of the remote controller protocol, as defined at * enum &rc_type * @name: name of the key map table -- cgit v1.2.3-70-g09d2 From 82631b5bb268f670613db110177483ae3e85f913 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 09:57:24 -0300 Subject: [media] mc-core.rst: fix a warning about an internal routine Fix this warning: Documentation/media/kapi/mc-core.rst:97: WARNING: c:func reference target not found: media_devnode_release The media_device_release() is a function internal to media-devnode.c, and not exported elsewhere. So, we can't cross-reference it here. Make it explicit at the documentation. Signed-off-by: Mauro Carvalho Chehab --- include/media/media-devnode.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h index 972168e90413..cd23e915764c 100644 --- a/include/media/media-devnode.h +++ b/include/media/media-devnode.h @@ -76,7 +76,8 @@ struct media_file_operations { * @parent: parent device * @minor: device node minor number * @flags: flags, combination of the ``MEDIA_FLAG_*`` constants - * @release: release callback called at the end of media_devnode_release() + * @release: release callback called at the end of ``media_devnode_release()`` + * routine at media-device.c. * * This structure represents a media-related device node. * -- cgit v1.2.3-70-g09d2 From 4781646c1e13b23ed31eb12f7e314824d98ce066 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 10:16:27 -0300 Subject: [media] v4l2-mem2mem.h: move descriptions from .c file Several routines are somewhat documented at v4l2-mem2mem.c file. Move what's there to the header file. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-mem2mem.c | 128 +------------------------------- include/media/v4l2-mem2mem.h | 132 +++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 127 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/v4l2-mem2mem.c b/drivers/media/v4l2-core/v4l2-mem2mem.c index 61d56c940f80..6bc27e7b2a33 100644 --- a/drivers/media/v4l2-core/v4l2-mem2mem.c +++ b/drivers/media/v4l2-core/v4l2-mem2mem.c @@ -76,9 +76,6 @@ static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx, return &m2m_ctx->cap_q_ctx; } -/** - * v4l2_m2m_get_vq() - return vb2_queue for the given type - */ struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) { @@ -92,9 +89,6 @@ struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL(v4l2_m2m_get_vq); -/** - * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers - */ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx) { struct v4l2_m2m_buffer *b; @@ -113,10 +107,6 @@ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx) } EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf); -/** - * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and - * return it - */ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx) { struct v4l2_m2m_buffer *b; @@ -140,10 +130,6 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove); * Scheduling handlers */ -/** - * v4l2_m2m_get_curr_priv() - return driver private data for the currently - * running instance or NULL if no instance is running - */ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev) { unsigned long flags; @@ -188,26 +174,6 @@ static void v4l2_m2m_try_run(struct v4l2_m2m_dev *m2m_dev) m2m_dev->m2m_ops->device_run(m2m_dev->curr_ctx->priv); } -/** - * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to - * the pending job queue and add it if so. - * @m2m_ctx: m2m context assigned to the instance to be checked - * - * There are three basic requirements an instance has to meet to be able to run: - * 1) at least one source buffer has to be queued, - * 2) at least one destination buffer has to be queued, - * 3) streaming has to be on. - * - * If a queue is buffered (for example a decoder hardware ringbuffer that has - * to be drained before doing streamoff), allow scheduling without v4l2 buffers - * on that queue. - * - * There may also be additional, custom requirements. In such case the driver - * should supply a custom callback (job_ready in v4l2_m2m_ops) that should - * return 1 if the instance is ready. - * An example of the above could be an instance that requires more than one - * src/dst buffer per transaction. - */ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx) { struct v4l2_m2m_dev *m2m_dev; @@ -311,18 +277,6 @@ static void v4l2_m2m_cancel_job(struct v4l2_m2m_ctx *m2m_ctx) } } -/** - * v4l2_m2m_job_finish() - inform the framework that a job has been finished - * and have it clean up - * - * Called by a driver to yield back the device after it has finished with it. - * Should be called as soon as possible after reaching a state which allows - * other instances to take control of the device. - * - * This function has to be called only after device_run() callback has been - * called on the driver. To prevent recursion, it should not be called directly - * from the device_run() callback though. - */ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx) { @@ -350,9 +304,6 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, } EXPORT_SYMBOL(v4l2_m2m_job_finish); -/** - * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer - */ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs) { @@ -370,11 +321,6 @@ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs); -/** - * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer - * - * See v4l2_m2m_mmap() documentation for details. - */ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf) { @@ -400,10 +346,6 @@ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf); -/** - * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on - * the type - */ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf) { @@ -419,10 +361,6 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf); -/** - * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on - * the type - */ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf) { @@ -433,10 +371,6 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); -/** - * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on - * the type - */ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf) { @@ -452,10 +386,6 @@ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_prepare_buf); -/** - * v4l2_m2m_create_bufs() - create a source or destination buffer, depending - * on the type - */ int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_create_buffers *create) { @@ -466,10 +396,6 @@ int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_create_bufs); -/** - * v4l2_m2m_expbuf() - export a source or destination buffer, depending on - * the type - */ int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_exportbuffer *eb) { @@ -479,9 +405,7 @@ int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, return vb2_expbuf(vq, eb); } EXPORT_SYMBOL_GPL(v4l2_m2m_expbuf); -/** - * v4l2_m2m_streamon() - turn on streaming for a video queue - */ + int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) { @@ -497,9 +421,6 @@ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_streamon); -/** - * v4l2_m2m_streamoff() - turn off streaming for a video queue - */ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) { @@ -540,14 +461,6 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); -/** - * v4l2_m2m_poll() - poll replacement, for destination buffers only - * - * Call from the driver's poll() function. Will poll both queues. If a buffer - * is available to dequeue (with dqbuf) from the source queue, this will - * indicate that a non-blocking write can be performed, while read will be - * returned in case of the destination queue. - */ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct poll_table_struct *wait) { @@ -626,16 +539,6 @@ end: } EXPORT_SYMBOL_GPL(v4l2_m2m_poll); -/** - * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer - * - * Call from driver's mmap() function. Will handle mmap() for both queues - * seamlessly for videobuffer, which will receive normal per-queue offsets and - * proper videobuf queue pointers. The differentiation is made outside videobuf - * by adding a predefined offset to buffers from one of the queues and - * subtracting it before passing it back to videobuf. Only drivers (and - * thus applications) receive modified offsets. - */ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct vm_area_struct *vma) { @@ -653,11 +556,6 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, } EXPORT_SYMBOL(v4l2_m2m_mmap); -/** - * v4l2_m2m_init() - initialize per-driver m2m data - * - * Usually called from driver's probe() function. - */ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops) { struct v4l2_m2m_dev *m2m_dev; @@ -679,26 +577,12 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops) } EXPORT_SYMBOL_GPL(v4l2_m2m_init); -/** - * v4l2_m2m_release() - cleans up and frees a m2m_dev structure - * - * Usually called from driver's remove() function. - */ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev) { kfree(m2m_dev); } EXPORT_SYMBOL_GPL(v4l2_m2m_release); -/** - * v4l2_m2m_ctx_init() - allocate and initialize a m2m context - * @priv - driver's instance private data - * @m2m_dev - a previously initialized m2m_dev struct - * @vq_init - a callback for queue type-specific initialization function to be - * used for initializing videobuf_queues - * - * Usually called from driver's open() function. - */ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev, void *drv_priv, int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)) @@ -744,11 +628,6 @@ err: } EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init); -/** - * v4l2_m2m_ctx_release() - release m2m context - * - * Usually called from driver's release() function. - */ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx) { /* wait until the current context is dequeued from job_queue */ @@ -761,11 +640,6 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx) } EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_release); -/** - * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. - * - * Call from buf_queue(), videobuf_queue_ops callback. - */ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf) { diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 5a9597dd1ee0..e5449a2c8475 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -94,13 +94,52 @@ struct v4l2_m2m_buffer { struct list_head list; }; +/** + * v4l2_m2m_get_curr_priv() - return driver private data for the currently + * running instance or NULL if no instance is running + */ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); +/** + * v4l2_m2m_get_vq() - return vb2_queue for the given type + */ struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); +/** + * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to + * the pending job queue and add it if so. + * @m2m_ctx: m2m context assigned to the instance to be checked + * + * There are three basic requirements an instance has to meet to be able to run: + * 1) at least one source buffer has to be queued, + * 2) at least one destination buffer has to be queued, + * 3) streaming has to be on. + * + * If a queue is buffered (for example a decoder hardware ringbuffer that has + * to be drained before doing streamoff), allow scheduling without v4l2 buffers + * on that queue. + * + * There may also be additional, custom requirements. In such case the driver + * should supply a custom callback (job_ready in v4l2_m2m_ops) that should + * return 1 if the instance is ready. + * An example of the above could be an instance that requires more than one + * src/dst buffer per transaction. + */ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); +/** + * v4l2_m2m_job_finish() - inform the framework that a job has been finished + * and have it clean up + * + * Called by a driver to yield back the device after it has finished with it. + * Should be called as soon as possible after reaching a state which allows + * other instances to take control of the device. + * + * This function has to be called only after device_run() callback has been + * called on the driver. To prevent recursion, it should not be called directly + * from the device_run() callback though. + */ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx); @@ -110,38 +149,114 @@ v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) vb2_buffer_done(&buf->vb2_buf, state); } +/** + * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer + */ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs); +/** + * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer + * + * See v4l2_m2m_mmap() documentation for details. + */ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); +/** + * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on + * the type + */ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); + +/** + * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on + * the type + */ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); + +/** + * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on + * the type + */ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); + +/** + * v4l2_m2m_create_bufs() - create a source or destination buffer, depending + * on the type + */ int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_create_buffers *create); +/** + * v4l2_m2m_expbuf() - export a source or destination buffer, depending on + * the type + */ int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_exportbuffer *eb); +/** + * v4l2_m2m_streamon() - turn on streaming for a video queue + */ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); + +/** + * v4l2_m2m_streamoff() - turn off streaming for a video queue + */ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); +/** + * v4l2_m2m_poll() - poll replacement, for destination buffers only + * + * Call from the driver's poll() function. Will poll both queues. If a buffer + * is available to dequeue (with dqbuf) from the source queue, this will + * indicate that a non-blocking write can be performed, while read will be + * returned in case of the destination queue. + */ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct poll_table_struct *wait); +/** + * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer + * + * Call from driver's mmap() function. Will handle mmap() for both queues + * seamlessly for videobuffer, which will receive normal per-queue offsets and + * proper videobuf queue pointers. The differentiation is made outside videobuf + * by adding a predefined offset to buffers from one of the queues and + * subtracting it before passing it back to videobuf. Only drivers (and + * thus applications) receive modified offsets. + */ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct vm_area_struct *vma); +/** + * v4l2_m2m_init() - initialize per-driver m2m data + * + * Usually called from driver's probe() function. + */ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); + +/** + * v4l2_m2m_release() - cleans up and frees a m2m_dev structure + * + * Usually called from driver's remove() function. + */ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); +/** + * v4l2_m2m_ctx_init() - allocate and initialize a m2m context + * @priv - driver's instance private data + * @m2m_dev - a previously initialized m2m_dev struct + * @vq_init - a callback for queue type-specific initialization function to be + * used for initializing videobuf_queues + * + * Usually called from driver's open() function. + */ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev, void *drv_priv, int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)); @@ -158,8 +273,18 @@ static inline void v4l2_m2m_set_dst_buffered(struct v4l2_m2m_ctx *m2m_ctx, m2m_ctx->cap_q_ctx.buffered = buffered; } +/** + * v4l2_m2m_ctx_release() - release m2m context + * + * Usually called from driver's release() function. + */ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); +/** + * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. + * + * Call from buf_queue(), videobuf_queue_ops callback. + */ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf); @@ -187,6 +312,9 @@ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) return m2m_ctx->cap_q_ctx.num_rdy; } +/** + * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers + */ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); /** @@ -233,6 +361,10 @@ struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) return &m2m_ctx->cap_q_ctx.q; } +/** + * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and + * return it + */ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); /** -- cgit v1.2.3-70-g09d2 From dcbd87358929ed989732a9866e683e33d0018461 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 10:39:58 -0300 Subject: [media] v4l2-mem2mem.h: document function arguments There are lots of troubles with the function arguments on this file. Fix them. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-mem2mem.h | 93 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index e5449a2c8475..00410bd14772 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -97,11 +97,16 @@ struct v4l2_m2m_buffer { /** * v4l2_m2m_get_curr_priv() - return driver private data for the currently * running instance or NULL if no instance is running + * + * @m2m_dev: pointer to struct &v4l2_m2m_dev */ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); /** * v4l2_m2m_get_vq() - return vb2_queue for the given type + * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type */ struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); @@ -109,7 +114,8 @@ struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_try_schedule() - check whether an instance is ready to be added to * the pending job queue and add it if so. - * @m2m_ctx: m2m context assigned to the instance to be checked + * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx * * There are three basic requirements an instance has to meet to be able to run: * 1) at least one source buffer has to be queued, @@ -132,6 +138,9 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); * v4l2_m2m_job_finish() - inform the framework that a job has been finished * and have it clean up * + * @m2m_dev: pointer to struct &v4l2_m2m_dev + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * * Called by a driver to yield back the device after it has finished with it. * Should be called as soon as possible after reaching a state which allows * other instances to take control of the device. @@ -151,6 +160,10 @@ v4l2_m2m_buf_done(struct vb2_v4l2_buffer *buf, enum vb2_buffer_state state) /** * v4l2_m2m_reqbufs() - multi-queue-aware REQBUFS multiplexer + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @reqbufs: pointer to struct &v4l2_requestbuffers */ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_requestbuffers *reqbufs); @@ -158,6 +171,10 @@ int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_querybuf() - multi-queue-aware QUERYBUF multiplexer * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer + * * See v4l2_m2m_mmap() documentation for details. */ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, @@ -166,6 +183,10 @@ int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_qbuf() - enqueue a source or destination buffer, depending on * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer */ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); @@ -173,6 +194,10 @@ int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_dqbuf() - dequeue a source or destination buffer, depending on * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer */ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); @@ -180,6 +205,10 @@ int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_prepare_buf() - prepare a source or destination buffer, depending on * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @buf: pointer to struct &v4l2_buffer */ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_buffer *buf); @@ -187,6 +216,10 @@ int v4l2_m2m_prepare_buf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_create_bufs() - create a source or destination buffer, depending * on the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @create: pointer to struct &v4l2_create_buffers */ int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_create_buffers *create); @@ -194,18 +227,30 @@ int v4l2_m2m_create_bufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_expbuf() - export a source or destination buffer, depending on * the type + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @eb: pointer to struct &v4l2_exportbuffer */ int v4l2_m2m_expbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, struct v4l2_exportbuffer *eb); /** * v4l2_m2m_streamon() - turn on streaming for a video queue + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type */ int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); /** * v4l2_m2m_streamoff() - turn off streaming for a video queue + * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @type: type of the V4L2 buffer, as defined by enum &v4l2_buf_type */ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); @@ -213,6 +258,10 @@ int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_poll() - poll replacement, for destination buffers only * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @wait: pointer to struct &poll_table_struct + * * Call from the driver's poll() function. Will poll both queues. If a buffer * is available to dequeue (with dqbuf) from the source queue, this will * indicate that a non-blocking write can be performed, while read will be @@ -224,6 +273,10 @@ unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_mmap() - source and destination queues-aware mmap multiplexer * + * @file: pointer to struct &file + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @vma: pointer to struct &vm_area_struct + * * Call from driver's mmap() function. Will handle mmap() for both queues * seamlessly for videobuffer, which will receive normal per-queue offsets and * proper videobuf queue pointers. The differentiation is made outside videobuf @@ -237,6 +290,8 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_init() - initialize per-driver m2m data * + * @m2m_ops: pointer to struct v4l2_m2m_ops + * * Usually called from driver's probe() function. */ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); @@ -244,16 +299,19 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); /** * v4l2_m2m_release() - cleans up and frees a m2m_dev structure * + * @m2m_dev: pointer to struct &v4l2_m2m_dev + * * Usually called from driver's remove() function. */ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); /** * v4l2_m2m_ctx_init() - allocate and initialize a m2m context - * @priv - driver's instance private data - * @m2m_dev - a previously initialized m2m_dev struct - * @vq_init - a callback for queue type-specific initialization function to be - * used for initializing videobuf_queues + * + * @m2m_dev: a previously initialized m2m_dev struct + * @drv_priv: driver's instance private data + * @queue_init: a callback for queue type-specific initialization function + * to be used for initializing videobuf_queues * * Usually called from driver's open() function. */ @@ -276,6 +334,8 @@ static inline void v4l2_m2m_set_dst_buffered(struct v4l2_m2m_ctx *m2m_ctx, /** * v4l2_m2m_ctx_release() - release m2m context * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * * Usually called from driver's release() function. */ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); @@ -283,6 +343,9 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); /** * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. * + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx + * @vbuf: pointer to struct &vb2_v4l2_buffer + * * Call from buf_queue(), videobuf_queue_ops callback. */ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, @@ -292,7 +355,7 @@ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for * use * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) @@ -304,7 +367,7 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) * v4l2_m2m_num_src_bufs_ready() - return the number of destination buffers * ready for use * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) @@ -314,6 +377,8 @@ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) /** * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers + * + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx */ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); @@ -321,7 +386,7 @@ void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx); * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready * buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) { @@ -332,7 +397,7 @@ static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) * v4l2_m2m_next_dst_buf() - return next destination buffer from the list of * ready buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) { @@ -342,7 +407,7 @@ static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) /** * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) @@ -353,7 +418,7 @@ struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) /** * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) @@ -364,6 +429,8 @@ struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) /** * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and * return it + * + * @q_ctx: pointer to struct @v4l2_m2m_queue_ctx */ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); @@ -371,7 +438,7 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx); * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready * buffers and return it * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) { @@ -382,7 +449,7 @@ static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) * v4l2_m2m_dst_buf_remove() - take off a destination buffer from the list of * ready buffers and return it * - * @m2m_ctx: pointer to struct v4l2_m2m_ctx + * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx */ static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) { -- cgit v1.2.3-70-g09d2 From 5fa5edbe59a7ab8ab649268fcb578662dfb7ca99 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 10:16:36 -0300 Subject: [media] v4l2-mem2mem.h: document the public structures Most structures here are not documented. Add a documentation for them. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-mem2mem.h | 67 +++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 00410bd14772..cfa4f5e521a7 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -41,9 +41,9 @@ * This function does not have to (and will usually not) wait * until the device enters a state when it can be stopped. * @lock: optional. Define a driver's own lock callback, instead of using - * m2m_ctx->q_lock. + * &v4l2_m2m_ctx->q_lock. * @unlock: optional. Define a driver's own unlock callback, instead of - * using m2m_ctx->q_lock. + * using &v4l2_m2m_ctx->q_lock. */ struct v4l2_m2m_ops { void (*device_run)(void *priv); @@ -53,31 +53,59 @@ struct v4l2_m2m_ops { void (*unlock)(void *priv); }; +/** + * struct v4l2_m2m_dev - opaque struct used to represent a V4L2 M2M device. + * + * This structure is has the per-device context for a memory to memory + * device, and it is used internally at v4l2-mem2mem.c. + */ struct v4l2_m2m_dev; +/** + * struct v4l2_m2m_queue_ctx - represents a queue for buffers ready to be + * processed + * + * @q: pointer to struct &vb2_queue + * @rdy_queue: List of V4L2 mem-to-mem queues + * @rdy_spinlock: spin lock to protect the struct usage + * @num_rdy: number of buffers ready to be processed + * @buffered: is the queue buffered? + * + * Queue for buffers ready to be processed as soon as this + * instance receives access to the device. + */ + struct v4l2_m2m_queue_ctx { -/* private: internal use only */ struct vb2_queue q; - /* Queue for buffers ready to be processed as soon as this - * instance receives access to the device */ struct list_head rdy_queue; spinlock_t rdy_spinlock; u8 num_rdy; bool buffered; }; +/** + * struct v4l2_m2m_ctx - Memory to memory context structure + * + * @q_lock: struct &mutex lock + * @m2m_dev: pointer to struct &v4l2_m2m_dev + * @cap_q_ctx: Capture (output to memory) queue context + * @out_q_ctx: Output (input from memory) queue context + * @queue: List of memory to memory contexts + * @job_flags: Job queue flags, used internally by v4l2-mem2mem.c: + * %TRANS_QUEUED, %TRANS_RUNNING and %TRANS_ABORT. + * @finished: Wait queue used to signalize when a job queue finished. + * @priv: Instance private data + */ struct v4l2_m2m_ctx { /* optional cap/out vb2 queues lock */ struct mutex *q_lock; -/* private: internal use only */ + /* internal use only */ struct v4l2_m2m_dev *m2m_dev; - /* Capture (output to memory) queue context */ struct v4l2_m2m_queue_ctx cap_q_ctx; - /* Output (input from memory) queue context */ struct v4l2_m2m_queue_ctx out_q_ctx; /* For device job queue */ @@ -85,10 +113,15 @@ struct v4l2_m2m_ctx { unsigned long job_flags; wait_queue_head_t finished; - /* Instance private data */ void *priv; }; +/** + * struct v4l2_m2m_buffer - Memory to memory buffer + * + * @vb: pointer to struct &vb2_v4l2_buffer + * @list: list of m2m buffers + */ struct v4l2_m2m_buffer { struct vb2_v4l2_buffer vb; struct list_head list; @@ -145,9 +178,9 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); * Should be called as soon as possible after reaching a state which allows * other instances to take control of the device. * - * This function has to be called only after device_run() callback has been - * called on the driver. To prevent recursion, it should not be called directly - * from the device_run() callback though. + * This function has to be called only after &v4l2_m2m_ops->device_run + * callback has been called on the driver. To prevent recursion, it should + * not be called directly from the &v4l2_m2m_ops->device_run callback though. */ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, struct v4l2_m2m_ctx *m2m_ctx); @@ -292,7 +325,9 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, * * @m2m_ops: pointer to struct v4l2_m2m_ops * - * Usually called from driver's probe() function. + * Usually called from driver's ``probe()`` function. + * + * Return: returns an opaque pointer to the internal data to handle M2M context */ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); @@ -301,7 +336,7 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); * * @m2m_dev: pointer to struct &v4l2_m2m_dev * - * Usually called from driver's remove() function. + * Usually called from driver's ``remove()`` function. */ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); @@ -313,7 +348,7 @@ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); * @queue_init: a callback for queue type-specific initialization function * to be used for initializing videobuf_queues * - * Usually called from driver's open() function. + * Usually called from driver's ``open()`` function. */ struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev, void *drv_priv, @@ -346,7 +381,7 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx * @vbuf: pointer to struct &vb2_v4l2_buffer * - * Call from buf_queue(), videobuf_queue_ops callback. + * Call from videobuf_queue_ops->ops->buf_queue, videobuf_queue_ops callback. */ void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_v4l2_buffer *vbuf); -- cgit v1.2.3-70-g09d2 From 9f8d3a2ee78110afc2aee85d979b869faac257e7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 17:20:44 -0300 Subject: [media] v4l2-mem2mem.h: make kernel-doc parse v4l2-mem2mem.h again The kernel-doc C parser doesn't like opaque structures. So, document it on another way. This should get rid of this warning: ./include/media/v4l2-mem2mem.h:62: error: Cannot parse struct or union! Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-mem2mem.h | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index cfa4f5e521a7..498c99baf8ac 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -53,12 +53,6 @@ struct v4l2_m2m_ops { void (*unlock)(void *priv); }; -/** - * struct v4l2_m2m_dev - opaque struct used to represent a V4L2 M2M device. - * - * This structure is has the per-device context for a memory to memory - * device, and it is used internally at v4l2-mem2mem.c. - */ struct v4l2_m2m_dev; /** @@ -88,7 +82,7 @@ struct v4l2_m2m_queue_ctx { * struct v4l2_m2m_ctx - Memory to memory context structure * * @q_lock: struct &mutex lock - * @m2m_dev: pointer to struct &v4l2_m2m_dev + * @m2m_dev: opaque pointer to the internal data to handle M2M context * @cap_q_ctx: Capture (output to memory) queue context * @out_q_ctx: Output (input from memory) queue context * @queue: List of memory to memory contexts @@ -131,7 +125,7 @@ struct v4l2_m2m_buffer { * v4l2_m2m_get_curr_priv() - return driver private data for the currently * running instance or NULL if no instance is running * - * @m2m_dev: pointer to struct &v4l2_m2m_dev + * @m2m_dev: opaque pointer to the internal data to handle M2M context */ void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); @@ -171,7 +165,7 @@ void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx); * v4l2_m2m_job_finish() - inform the framework that a job has been finished * and have it clean up * - * @m2m_dev: pointer to struct &v4l2_m2m_dev + * @m2m_dev: opaque pointer to the internal data to handle M2M context * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx * * Called by a driver to yield back the device after it has finished with it. @@ -334,7 +328,7 @@ struct v4l2_m2m_dev *v4l2_m2m_init(const struct v4l2_m2m_ops *m2m_ops); /** * v4l2_m2m_release() - cleans up and frees a m2m_dev structure * - * @m2m_dev: pointer to struct &v4l2_m2m_dev + * @m2m_dev: opaque pointer to the internal data to handle M2M context * * Usually called from driver's ``remove()`` function. */ @@ -343,7 +337,7 @@ void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); /** * v4l2_m2m_ctx_init() - allocate and initialize a m2m context * - * @m2m_dev: a previously initialized m2m_dev struct + * @m2m_dev: opaque pointer to the internal data to handle M2M context * @drv_priv: driver's instance private data * @queue_init: a callback for queue type-specific initialization function * to be used for initializing videobuf_queues -- cgit v1.2.3-70-g09d2 From 88b7eb092efb8197d29d5202d77d1fb919419ec5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 13:34:37 -0300 Subject: [media] videobuf2-core.h: move function descriptions from c file There are several functions that were documented at the .c file. As we only include the headers, we need to move them to there, in order to have documentation. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-core.c | 254 ----------------------------- include/media/videobuf2-core.h | 269 +++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+), 254 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index bfe85879c563..21900202ff83 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -528,10 +528,6 @@ static int __vb2_queue_free(struct vb2_queue *q, unsigned int buffers) return 0; } -/** - * vb2_buffer_in_use() - return true if the buffer is in use and - * the queue cannot be freed (by the means of REQBUFS(0)) call - */ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb) { unsigned int plane; @@ -564,16 +560,6 @@ static bool __buffers_in_use(struct vb2_queue *q) return false; } -/** - * vb2_core_querybuf() - query video buffer information - * @q: videobuf queue - * @index: id number of the buffer - * @pb: buffer struct passed from userspace - * - * Should be called from vidioc_querybuf ioctl handler in driver. - * The passed buffer should have been verified. - * This function fills the relevant information for the userspace. - */ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb) { call_void_bufop(q, fill_user_buffer, q->bufs[index], pb); @@ -620,10 +606,6 @@ static int __verify_dmabuf_ops(struct vb2_queue *q) return 0; } -/** - * vb2_verify_memory_type() - Check whether the memory type and buffer type - * passed to a buffer operation are compatible with the queue. - */ int vb2_verify_memory_type(struct vb2_queue *q, enum vb2_memory memory, unsigned int type) { @@ -670,30 +652,6 @@ int vb2_verify_memory_type(struct vb2_queue *q, } EXPORT_SYMBOL(vb2_verify_memory_type); -/** - * vb2_core_reqbufs() - Initiate streaming - * @q: videobuf2 queue - * @memory: memory type - * @count: requested buffer count - * - * Should be called from vidioc_reqbufs ioctl handler of a driver. - * This function: - * 1) verifies streaming parameters passed from the userspace, - * 2) sets up the queue, - * 3) negotiates number of buffers and planes per buffer with the driver - * to be used during streaming, - * 4) allocates internal buffer structures (struct vb2_buffer), according to - * the agreed parameters, - * 5) for MMAP memory type, allocates actual video memory, using the - * memory handling/allocation routines provided during queue initialization - * - * If req->count is 0, all the memory will be freed instead. - * If the queue has been allocated previously (by a previous vb2_reqbufs) call - * and the queue is not busy, memory will be reallocated. - * - * The return values from this function are intended to be directly returned - * from vidioc_reqbufs handler in driver. - */ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int *count) { @@ -819,22 +777,6 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, } EXPORT_SYMBOL_GPL(vb2_core_reqbufs); -/** - * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs - * @q: videobuf2 queue - * @memory: memory type - * @count: requested buffer count - * @parg: parameter passed to device driver - * - * Should be called from vidioc_create_bufs ioctl handler of a driver. - * This function: - * 1) verifies parameter sanity - * 2) calls the .queue_setup() queue operation - * 3) performs any necessary memory allocations - * - * The return values from this function are intended to be directly returned - * from vidioc_create_bufs handler in driver. - */ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int *count, unsigned requested_planes, const unsigned requested_sizes[]) @@ -924,14 +866,6 @@ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, } EXPORT_SYMBOL_GPL(vb2_core_create_bufs); -/** - * vb2_plane_vaddr() - Return a kernel virtual address of a given plane - * @vb: vb2_buffer to which the plane in question belongs to - * @plane_no: plane number for which the address is to be returned - * - * This function returns a kernel virtual address of a given plane if - * such a mapping exist, NULL otherwise. - */ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no) { if (plane_no > vb->num_planes || !vb->planes[plane_no].mem_priv) @@ -942,17 +876,6 @@ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no) } EXPORT_SYMBOL_GPL(vb2_plane_vaddr); -/** - * vb2_plane_cookie() - Return allocator specific cookie for the given plane - * @vb: vb2_buffer to which the plane in question belongs to - * @plane_no: plane number for which the cookie is to be returned - * - * This function returns an allocator specific cookie for a given plane if - * available, NULL otherwise. The allocator should provide some simple static - * inline function, which would convert this cookie to the allocator specific - * type that can be used directly by the driver to access the buffer. This can - * be for example physical address, pointer to scatter list or IOMMU mapping. - */ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no) { if (plane_no >= vb->num_planes || !vb->planes[plane_no].mem_priv) @@ -962,26 +885,6 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no) } EXPORT_SYMBOL_GPL(vb2_plane_cookie); -/** - * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished - * @vb: vb2_buffer returned from the driver - * @state: either VB2_BUF_STATE_DONE if the operation finished successfully, - * VB2_BUF_STATE_ERROR if the operation finished with an error or - * VB2_BUF_STATE_QUEUED if the driver wants to requeue buffers. - * If start_streaming fails then it should return buffers with state - * VB2_BUF_STATE_QUEUED to put them back into the queue. - * - * This function should be called by the driver after a hardware operation on - * a buffer is finished and the buffer may be returned to userspace. The driver - * cannot use this buffer anymore until it is queued back to it by videobuf - * by the means of buf_queue callback. Only buffers previously queued to the - * driver by buf_queue can be passed to this function. - * - * While streaming a buffer can only be returned in state DONE or ERROR. - * The start_streaming op can also return them in case the DMA engine cannot - * be started for some reason. In that case the buffers should be returned with - * state QUEUED. - */ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) { struct vb2_queue *q = vb->vb2_queue; @@ -1040,18 +943,6 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) } EXPORT_SYMBOL_GPL(vb2_buffer_done); -/** - * vb2_discard_done() - discard all buffers marked as DONE - * @q: videobuf2 queue - * - * This function is intended to be used with suspend/resume operations. It - * discards all 'done' buffers as they would be too old to be requested after - * resume. - * - * Drivers must stop the hardware and synchronize with interrupt handlers and/or - * delayed works before calling this function to make sure no buffer will be - * touched by the driver and/or hardware. - */ void vb2_discard_done(struct vb2_queue *q) { struct vb2_buffer *vb; @@ -1384,22 +1275,6 @@ static int __buf_prepare(struct vb2_buffer *vb, const void *pb) return ret; } -/** - * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace - * to the kernel - * @q: videobuf2 queue - * @index: id number of the buffer - * @pb: buffer structure passed from userspace to vidioc_prepare_buf - * handler in driver - * - * Should be called from vidioc_prepare_buf ioctl handler of a driver. - * The passed buffer should have been verified. - * This function calls buf_prepare callback in the driver (if provided), - * in which driver-specific buffer initialization can be performed, - * - * The return values from this function are intended to be directly returned - * from vidioc_prepare_buf handler in driver. - */ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb) { struct vb2_buffer *vb; @@ -1488,24 +1363,6 @@ static int vb2_start_streaming(struct vb2_queue *q) return ret; } -/** - * vb2_core_qbuf() - Queue a buffer from userspace - * @q: videobuf2 queue - * @index: id number of the buffer - * @pb: buffer structure passed from userspace to vidioc_qbuf handler - * in driver - * - * Should be called from vidioc_qbuf ioctl handler of a driver. - * The passed buffer should have been verified. - * This function: - * 1) if necessary, calls buf_prepare callback in the driver (if provided), in - * which driver-specific buffer initialization can be performed, - * 2) if streaming is on, queues the buffer in driver by the means of buf_queue - * callback for processing. - * - * The return values from this function are intended to be directly returned - * from vidioc_qbuf handler in driver. - */ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb) { struct vb2_buffer *vb; @@ -1686,15 +1543,6 @@ static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb, return ret; } -/** - * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2 - * @q: videobuf2 queue - * - * This function will wait until all buffers that have been given to the driver - * by buf_queue() are given back to vb2 with vb2_buffer_done(). It doesn't call - * wait_prepare, wait_finish pair. It is intended to be called with all locks - * taken, for example from stop_streaming() callback. - */ int vb2_wait_for_all_buffers(struct vb2_queue *q) { if (!q->streaming) { @@ -1732,28 +1580,6 @@ static void __vb2_dqbuf(struct vb2_buffer *vb) } } -/** - * vb2_core_dqbuf() - Dequeue a buffer to the userspace - * @q: videobuf2 queue - * @pindex: pointer to the buffer index. May be NULL - * @pb: buffer structure passed from userspace to vidioc_dqbuf handler - * in driver - * @nonblocking: if true, this call will not sleep waiting for a buffer if no - * buffers ready for dequeuing are present. Normally the driver - * would be passing (file->f_flags & O_NONBLOCK) here - * - * Should be called from vidioc_dqbuf ioctl handler of a driver. - * The passed buffer should have been verified. - * This function: - * 1) calls buf_finish callback in the driver (if provided), in which - * driver can perform any additional operations that may be required before - * returning the buffer to userspace, such as cache sync, - * 2) the buffer struct members are filled with relevant information for - * the userspace. - * - * The return values from this function are intended to be directly returned - * from vidioc_dqbuf handler in driver. - */ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, bool nonblocking) { @@ -1917,19 +1743,6 @@ int vb2_core_streamon(struct vb2_queue *q, unsigned int type) } EXPORT_SYMBOL_GPL(vb2_core_streamon); -/** - * vb2_queue_error() - signal a fatal error on the queue - * @q: videobuf2 queue - * - * Flag that a fatal unrecoverable error has occurred and wake up all processes - * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing - * buffers will return -EIO. - * - * The error flag will be cleared when cancelling the queue, either from - * vb2_streamoff or vb2_queue_release. Drivers should thus not call this - * function before starting the stream, otherwise the error flag will remain set - * until the queue is released when closing the device node. - */ void vb2_queue_error(struct vb2_queue *q) { q->error = 1; @@ -1992,19 +1805,6 @@ static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off, return -EINVAL; } -/** - * vb2_core_expbuf() - Export a buffer as a file descriptor - * @q: videobuf2 queue - * @fd: file descriptor associated with DMABUF (set by driver) * - * @type: buffer type - * @index: id number of the buffer - * @plane: index of the plane to be exported, 0 for single plane queues - * @flags: flags for newly created file, currently only O_CLOEXEC is - * supported, refer to manual of open syscall for more details - * - * The return values from this function are intended to be directly returned - * from vidioc_expbuf handler in driver. - */ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, unsigned int index, unsigned int plane, unsigned int flags) { @@ -2076,25 +1876,6 @@ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, } EXPORT_SYMBOL_GPL(vb2_core_expbuf); -/** - * vb2_mmap() - map video buffers into application address space - * @q: videobuf2 queue - * @vma: vma passed to the mmap file operation handler in the driver - * - * Should be called from mmap file operation handler of a driver. - * This function maps one plane of one of the available video buffers to - * userspace. To map whole video memory allocated on reqbufs, this function - * has to be called once per each plane per each buffer previously allocated. - * - * When the userspace application calls mmap, it passes to it an offset returned - * to it earlier by the means of vidioc_querybuf handler. That offset acts as - * a "cookie", which is then used to identify the plane to be mapped. - * This function finds a plane with a matching offset and a mapping is performed - * by the means of a provided memory operation. - * - * The return values from this function are intended to be directly returned - * from the mmap handler in driver. - */ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma) { unsigned long off = vma->vm_pgoff << PAGE_SHIFT; @@ -2196,17 +1977,6 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, EXPORT_SYMBOL_GPL(vb2_get_unmapped_area); #endif -/** - * vb2_core_queue_init() - initialize a videobuf2 queue - * @q: videobuf2 queue; this structure should be allocated in driver - * - * The vb2_queue structure should be allocated by the driver. The driver is - * responsible of clearing it's content and setting initial values for some - * required entries before calling this function. - * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer - * to the struct vb2_queue description in include/media/videobuf2-core.h - * for more information. - */ int vb2_core_queue_init(struct vb2_queue *q) { /* @@ -2236,14 +2006,6 @@ EXPORT_SYMBOL_GPL(vb2_core_queue_init); static int __vb2_init_fileio(struct vb2_queue *q, int read); static int __vb2_cleanup_fileio(struct vb2_queue *q); -/** - * vb2_core_queue_release() - stop streaming, release the queue and free memory - * @q: videobuf2 queue - * - * This function stops streaming and performs necessary clean ups, including - * freeing video buffer memory. The driver is responsible for freeing - * the vb2_queue structure itself. - */ void vb2_core_queue_release(struct vb2_queue *q) { __vb2_cleanup_fileio(q); @@ -2254,22 +2016,6 @@ void vb2_core_queue_release(struct vb2_queue *q) } EXPORT_SYMBOL_GPL(vb2_core_queue_release); -/** - * vb2_core_poll() - implements poll userspace operation - * @q: videobuf2 queue - * @file: file argument passed to the poll file operation handler - * @wait: wait argument passed to the poll file operation handler - * - * This function implements poll file operation handler for a driver. - * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will - * be informed that the file descriptor of a video device is available for - * reading. - * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor - * will be reported as available for writing. - * - * The return values from this function are intended to be directly returned - * from poll handler in driver. - */ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, poll_table *wait) { diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index b6546db670ca..68f93dacb38f 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -536,35 +536,274 @@ struct vb2_queue { #endif }; +/** + * vb2_plane_vaddr() - Return a kernel virtual address of a given plane + * @vb: vb2_buffer to which the plane in question belongs to + * @plane_no: plane number for which the address is to be returned + * + * This function returns a kernel virtual address of a given plane if + * such a mapping exist, NULL otherwise. + */ void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no); + +/** + * vb2_plane_cookie() - Return allocator specific cookie for the given plane + * @vb: vb2_buffer to which the plane in question belongs to + * @plane_no: plane number for which the cookie is to be returned + * + * This function returns an allocator specific cookie for a given plane if + * available, NULL otherwise. The allocator should provide some simple static + * inline function, which would convert this cookie to the allocator specific + * type that can be used directly by the driver to access the buffer. This can + * be for example physical address, pointer to scatter list or IOMMU mapping. + */ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); +/** + * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished + * @vb: vb2_buffer returned from the driver + * @state: either %VB2_BUF_STATE_DONE if the operation finished successfully, + * %VB2_BUF_STATE_ERROR if the operation finished with an error or + * %VB2_BUF_STATE_QUEUED if the driver wants to requeue buffers. + * If start_streaming fails then it should return buffers with state + * %VB2_BUF_STATE_QUEUED to put them back into the queue. + * + * This function should be called by the driver after a hardware operation on + * a buffer is finished and the buffer may be returned to userspace. The driver + * cannot use this buffer anymore until it is queued back to it by videobuf + * by the means of buf_queue callback. Only buffers previously queued to the + * driver by buf_queue can be passed to this function. + * + * While streaming a buffer can only be returned in state DONE or ERROR. + * The start_streaming op can also return them in case the DMA engine cannot + * be started for some reason. In that case the buffers should be returned with + * state QUEUED. + */ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state); + +/** + * vb2_discard_done() - discard all buffers marked as DONE + * @q: videobuf2 queue + * + * This function is intended to be used with suspend/resume operations. It + * discards all 'done' buffers as they would be too old to be requested after + * resume. + * + * Drivers must stop the hardware and synchronize with interrupt handlers and/or + * delayed works before calling this function to make sure no buffer will be + * touched by the driver and/or hardware. + */ void vb2_discard_done(struct vb2_queue *q); + +/** + * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2 + * @q: videobuf2 queue + * + * This function will wait until all buffers that have been given to the driver + * by buf_queue() are given back to vb2 with vb2_buffer_done(). It doesn't call + * wait_prepare, wait_finish pair. It is intended to be called with all locks + * taken, for example from stop_streaming() callback. + */ int vb2_wait_for_all_buffers(struct vb2_queue *q); +/** + * vb2_core_querybuf() - query video buffer information + * @q: videobuf queue + * @index: id number of the buffer + * @pb: buffer struct passed from userspace + * + * Should be called from vidioc_querybuf ioctl handler in driver. + * The passed buffer should have been verified. + * This function fills the relevant information for the userspace. + */ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb); + +/** + * vb2_core_reqbufs() - Initiate streaming + * @q: videobuf2 queue + * @memory: memory type + * @count: requested buffer count + * + * Should be called from vidioc_reqbufs ioctl handler of a driver. + * This function: + * 1) verifies streaming parameters passed from the userspace, + * 2) sets up the queue, + * 3) negotiates number of buffers and planes per buffer with the driver + * to be used during streaming, + * 4) allocates internal buffer structures (struct vb2_buffer), according to + * the agreed parameters, + * 5) for MMAP memory type, allocates actual video memory, using the + * memory handling/allocation routines provided during queue initialization + * + * If req->count is 0, all the memory will be freed instead. + * If the queue has been allocated previously (by a previous vb2_reqbufs) call + * and the queue is not busy, memory will be reallocated. + * + * The return values from this function are intended to be directly returned + * from vidioc_reqbufs handler in driver. + */ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int *count); + +/** + * vb2_core_create_bufs() - Allocate buffers and any required auxiliary structs + * @q: videobuf2 queue + * @memory: memory type + * @count: requested buffer count + * @parg: parameter passed to device driver + * + * Should be called from vidioc_create_bufs ioctl handler of a driver. + * This function: + * 1) verifies parameter sanity + * 2) calls the .queue_setup() queue operation + * 3) performs any necessary memory allocations + * + * The return values from this function are intended to be directly returned + * from vidioc_create_bufs handler in driver. + */ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, unsigned int *count, unsigned requested_planes, const unsigned int requested_sizes[]); + +/** + * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace + * to the kernel + * @q: videobuf2 queue + * @index: id number of the buffer + * @pb: buffer structure passed from userspace to vidioc_prepare_buf + * handler in driver + * + * Should be called from vidioc_prepare_buf ioctl handler of a driver. + * The passed buffer should have been verified. + * This function calls buf_prepare callback in the driver (if provided), + * in which driver-specific buffer initialization can be performed, + * + * The return values from this function are intended to be directly returned + * from vidioc_prepare_buf handler in driver. + */ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); + +/** + * vb2_core_qbuf() - Queue a buffer from userspace + * @q: videobuf2 queue + * @index: id number of the buffer + * @pb: buffer structure passed from userspace to vidioc_qbuf handler + * in driver + * + * Should be called from vidioc_qbuf ioctl handler of a driver. + * The passed buffer should have been verified. + * This function: + * 1) if necessary, calls buf_prepare callback in the driver (if provided), in + * which driver-specific buffer initialization can be performed, + * 2) if streaming is on, queues the buffer in driver by the means of buf_queue + * callback for processing. + * + * The return values from this function are intended to be directly returned + * from vidioc_qbuf handler in driver. + */ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb); + +/** + * vb2_core_dqbuf() - Dequeue a buffer to the userspace + * @q: videobuf2 queue + * @pindex: pointer to the buffer index. May be NULL + * @pb: buffer structure passed from userspace to vidioc_dqbuf handler + * in driver + * @nonblocking: if true, this call will not sleep waiting for a buffer if no + * buffers ready for dequeuing are present. Normally the driver + * would be passing (file->f_flags & O_NONBLOCK) here + * + * Should be called from vidioc_dqbuf ioctl handler of a driver. + * The passed buffer should have been verified. + * This function: + * 1) calls buf_finish callback in the driver (if provided), in which + * driver can perform any additional operations that may be required before + * returning the buffer to userspace, such as cache sync, + * 2) the buffer struct members are filled with relevant information for + * the userspace. + * + * The return values from this function are intended to be directly returned + * from vidioc_dqbuf handler in driver. + */ int vb2_core_dqbuf(struct vb2_queue *q, unsigned int *pindex, void *pb, bool nonblocking); int vb2_core_streamon(struct vb2_queue *q, unsigned int type); int vb2_core_streamoff(struct vb2_queue *q, unsigned int type); +/** + * vb2_core_expbuf() - Export a buffer as a file descriptor + * @q: videobuf2 queue + * @fd: file descriptor associated with DMABUF (set by driver) * + * @type: buffer type + * @index: id number of the buffer + * @plane: index of the plane to be exported, 0 for single plane queues + * @flags: flags for newly created file, currently only O_CLOEXEC is + * supported, refer to manual of open syscall for more details + * + * The return values from this function are intended to be directly returned + * from vidioc_expbuf handler in driver. + */ int vb2_core_expbuf(struct vb2_queue *q, int *fd, unsigned int type, unsigned int index, unsigned int plane, unsigned int flags); +/** + * vb2_core_queue_init() - initialize a videobuf2 queue + * @q: videobuf2 queue; this structure should be allocated in driver + * + * The vb2_queue structure should be allocated by the driver. The driver is + * responsible of clearing it's content and setting initial values for some + * required entries before calling this function. + * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer + * to the struct vb2_queue description in include/media/videobuf2-core.h + * for more information. + */ int vb2_core_queue_init(struct vb2_queue *q); + +/** + * vb2_core_queue_release() - stop streaming, release the queue and free memory + * @q: videobuf2 queue + * + * This function stops streaming and performs necessary clean ups, including + * freeing video buffer memory. The driver is responsible for freeing + * the vb2_queue structure itself. + */ void vb2_core_queue_release(struct vb2_queue *q); +/** + * vb2_queue_error() - signal a fatal error on the queue + * @q: videobuf2 queue + * + * Flag that a fatal unrecoverable error has occurred and wake up all processes + * waiting on the queue. Polling will now set POLLERR and queuing and dequeuing + * buffers will return -EIO. + * + * The error flag will be cleared when cancelling the queue, either from + * vb2_streamoff or vb2_queue_release. Drivers should thus not call this + * function before starting the stream, otherwise the error flag will remain set + * until the queue is released when closing the device node. + */ void vb2_queue_error(struct vb2_queue *q); +/** + * vb2_mmap() - map video buffers into application address space + * @q: videobuf2 queue + * @vma: vma passed to the mmap file operation handler in the driver + * + * Should be called from mmap file operation handler of a driver. + * This function maps one plane of one of the available video buffers to + * userspace. To map whole video memory allocated on reqbufs, this function + * has to be called once per each plane per each buffer previously allocated. + * + * When the userspace application calls mmap, it passes to it an offset returned + * to it earlier by the means of vidioc_querybuf handler. That offset acts as + * a "cookie", which is then used to identify the plane to be mapped. + * This function finds a plane with a matching offset and a mapping is performed + * by the means of a provided memory operation. + * + * The return values from this function are intended to be directly returned + * from the mmap handler in driver. + */ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma); #ifndef CONFIG_MMU unsigned long vb2_get_unmapped_area(struct vb2_queue *q, @@ -573,6 +812,23 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, unsigned long pgoff, unsigned long flags); #endif + +/** + * vb2_core_poll() - implements poll userspace operation + * @q: videobuf2 queue + * @file: file argument passed to the poll file operation handler + * @wait: wait argument passed to the poll file operation handler + * + * This function implements poll file operation handler for a driver. + * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will + * be informed that the file descriptor of a video device is available for + * reading. + * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor + * will be reported as available for writing. + * + * The return values from this function are intended to be directly returned + * from poll handler in driver. + */ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, poll_table *wait); size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, @@ -717,7 +973,20 @@ static inline void vb2_clear_last_buffer_dequeued(struct vb2_queue *q) * The following functions are not part of the vb2 core API, but are useful * functions for videobuf2-*. */ + +/** + * vb2_buffer_in_use() - return true if the buffer is in use and + * the queue cannot be freed (by the means of REQBUFS(0)) call + * + * @vb: buffer for which plane size should be returned + * @q: videobuf queue + */ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb); + +/** + * vb2_verify_memory_type() - Check whether the memory type and buffer type + * passed to a buffer operation are compatible with the queue. + */ int vb2_verify_memory_type(struct vb2_queue *q, enum vb2_memory memory, unsigned int type); #endif /* _MEDIA_VIDEOBUF2_CORE_H */ -- cgit v1.2.3-70-g09d2 From 52839f66edde1ed709390b55a0d3f82593203308 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 14:08:00 -0300 Subject: [media] videobuf2-core.h: document enum vb2_memory This enum was not documented. Document it. Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-core.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 68f93dacb38f..65eeca83687a 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -20,6 +20,20 @@ #define VB2_MAX_FRAME (32) #define VB2_MAX_PLANES (8) +/** + * enum vb2_memory - type of memory model used to make the buffers visible + * on userspace. + * + * @VB2_MEMORY_UNKNOWN: Buffer status is unknown or it is not used yet on + * userspace. + * @VB2_MEMORY_MMAP: The buffers are allocated by the Kernel and it is + * memory mapped via mmap() ioctl. This model is + * also used when the user is using the buffers via + * read() or write() system calls. + * @VB2_MEMORY_USERPTR: The buffers was allocated in userspace and it is + * memory mapped via mmap() ioctl. + * @VB2_MEMORY_DMABUF: The buffers are passed to userspace via DMA buffer. + */ enum vb2_memory { VB2_MEMORY_UNKNOWN = 0, VB2_MEMORY_MMAP = 1, -- cgit v1.2.3-70-g09d2 From f286f4dfc50a9f4d777534794a773eb4fbbedd72 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 14:08:34 -0300 Subject: [media] videobuf2-core.h: improve documentation There are several small issues with the documentation. Fix them, in order to avoid producing warnings. While here, also make checkpatch.pl happy. Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-core.h | 143 ++++++++++++++++++++++++----------------- 1 file changed, 85 insertions(+), 58 deletions(-) (limited to 'include') diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 65eeca83687a..9a144f2d9083 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -49,13 +49,13 @@ struct vb2_threadio_data; * @alloc: allocate video memory and, optionally, allocator private data, * return ERR_PTR() on failure or a pointer to allocator private, * per-buffer data on success; the returned private structure - * will then be passed as buf_priv argument to other ops in this + * will then be passed as @buf_priv argument to other ops in this * structure. Additional gfp_flags to use when allocating the * are also passed to this operation. These flags are from the * gfp_flags field of vb2_queue. * @put: inform the allocator that the buffer will no longer be used; * usually will result in the allocator freeing the buffer (if - * no other users of this buffer are present); the buf_priv + * no other users of this buffer are present); the @buf_priv * argument is the allocator private per-buffer structure * previously returned from the alloc callback. * @get_dmabuf: acquire userspace memory for a hardware operation; used for @@ -65,7 +65,7 @@ struct vb2_threadio_data; * videobuf layer when queuing a video buffer of USERPTR type; * should return an allocator private per-buffer structure * associated with the buffer on success, ERR_PTR() on failure; - * the returned private structure will then be passed as buf_priv + * the returned private structure will then be passed as @buf_priv * argument to other ops in this structure. * @put_userptr: inform the allocator that a USERPTR buffer will no longer * be used. @@ -75,7 +75,7 @@ struct vb2_threadio_data; * allocator private per-buffer structure on success; * this needs to be used for further accesses to the buffer. * @detach_dmabuf: inform the exporter of the buffer that the current DMABUF - * buffer is no longer used; the buf_priv argument is the + * buffer is no longer used; the @buf_priv argument is the * allocator private per-buffer structure previously returned * from the attach_dmabuf callback. * @map_dmabuf: request for access to the dmabuf from allocator; the allocator @@ -109,11 +109,13 @@ struct vb2_threadio_data; * * #) Required ops for read/write access types: alloc, put, num_users, vaddr. * - * #) Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, map_dmabuf, unmap_dmabuf. + * #) Required ops for DMABUF types: attach_dmabuf, detach_dmabuf, + * map_dmabuf, unmap_dmabuf. */ struct vb2_mem_ops { void *(*alloc)(struct device *dev, unsigned long attrs, - unsigned long size, enum dma_data_direction dma_dir, + unsigned long size, + enum dma_data_direction dma_dir, gfp_t gfp_flags); void (*put)(void *buf_priv); struct dma_buf *(*get_dmabuf)(void *buf_priv, unsigned long flags); @@ -126,7 +128,8 @@ struct vb2_mem_ops { void (*prepare)(void *buf_priv); void (*finish)(void *buf_priv); - void *(*attach_dmabuf)(struct device *dev, struct dma_buf *dbuf, + void *(*attach_dmabuf)(struct device *dev, + struct dma_buf *dbuf, unsigned long size, enum dma_data_direction dma_dir); void (*detach_dmabuf)(void *buf_priv); @@ -291,7 +294,7 @@ struct vb2_buffer { /** * struct vb2_ops - driver-specific callbacks * - * @queue_setup: called from %VIDIOC_REQBUFS and %VIDIOC_CREATE_BUFS + * @queue_setup: called from VIDIOC_REQBUFS() and VIDIOC_CREATE_BUFS() * handlers before memory allocation. It can be called * twice: if the original number of requested buffers * could not be allocated, then it will be called a @@ -302,11 +305,11 @@ struct vb2_buffer { * buffer in \*num_planes, the size of each plane should be * set in the sizes\[\] array and optional per-plane * allocator specific device in the alloc_devs\[\] array. - * When called from %VIDIOC_REQBUFS, \*num_planes == 0, the - * driver has to use the currently configured format to + * When called from VIDIOC_REQBUFS,() \*num_planes == 0, + * the driver has to use the currently configured format to * determine the plane sizes and \*num_buffers is the total * number of buffers that are being allocated. When called - * from %VIDIOC_CREATE_BUFS, \*num_planes != 0 and it + * from VIDIOC_CREATE_BUFS,() \*num_planes != 0 and it * describes the requested number of planes and sizes\[\] * contains the requested plane sizes. If either * \*num_planes or the requested sizes are invalid callback @@ -325,11 +328,11 @@ struct vb2_buffer { * initialization failure (return != 0) will prevent * queue setup from completing successfully; optional. * @buf_prepare: called every time the buffer is queued from userspace - * and from the %VIDIOC_PREPARE_BUF ioctl; drivers may + * and from the VIDIOC_PREPARE_BUF() ioctl; drivers may * perform any initialization required before each * hardware operation in this callback; drivers can * access/modify the buffer here as it is still synced for - * the CPU; drivers that support %VIDIOC_CREATE_BUFS must + * the CPU; drivers that support VIDIOC_CREATE_BUFS() must * also validate the buffer size; if an error is returned, * the buffer will not be queued in driver; optional. * @buf_finish: called before every dequeue of the buffer back to @@ -353,24 +356,25 @@ struct vb2_buffer { * driver can return an error if hardware fails, in that * case all buffers that have been already given by * the @buf_queue callback are to be returned by the driver - * by calling @vb2_buffer_done\(%VB2_BUF_STATE_QUEUED\). + * by calling vb2_buffer_done() with %VB2_BUF_STATE_QUEUED. * If you need a minimum number of buffers before you can * start streaming, then set @min_buffers_needed in the * vb2_queue structure. If that is non-zero then - * start_streaming won't be called until at least that + * @start_streaming won't be called until at least that * many buffers have been queued up by userspace. * @stop_streaming: called when 'streaming' state must be disabled; driver * should stop any DMA transactions or wait until they * finish and give back all buffers it got from &buf_queue - * callback by calling @vb2_buffer_done\(\) with either + * callback by calling vb2_buffer_done() with either * %VB2_BUF_STATE_DONE or %VB2_BUF_STATE_ERROR; may use * vb2_wait_for_all_buffers() function * @buf_queue: passes buffer vb to the driver; driver may start * hardware operation on this buffer; driver should give * the buffer back by calling vb2_buffer_done() function; - * it is allways called after calling %VIDIOC_STREAMON ioctl; - * might be called before start_streaming callback if user - * pre-queued buffers before calling %VIDIOC_STREAMON. + * it is allways called after calling VIDIOC_STREAMON() + * ioctl; might be called before @start_streaming callback + * if user pre-queued buffers before calling + * VIDIOC_STREAMON(). */ struct vb2_ops { int (*queue_setup)(struct vb2_queue *q, @@ -418,7 +422,7 @@ struct vb2_buf_ops { * * @type: private buffer type whose content is defined by the vb2-core * caller. For example, for V4L2, it should match - * the V4L2_BUF_TYPE_* in include/uapi/linux/videodev2.h + * the types defined on enum &v4l2_buf_type * @io_modes: supported io methods (see vb2_io_modes enum) * @dev: device to use for the default allocation context if the driver * doesn't fill in the @alloc_devs array. @@ -453,12 +457,12 @@ struct vb2_buf_ops { * Typically this is 0, but it may be e.g. GFP_DMA or __GFP_DMA32 * to force the buffer allocation to a specific memory zone. * @min_buffers_needed: the minimum number of buffers needed before - * start_streaming() can be called. Used when a DMA engine + * @start_streaming can be called. Used when a DMA engine * cannot be started unless at least this number of buffers * have been queued into the driver. */ /* - * Private elements (won't appear at the DocBook): + * Private elements (won't appear at the uAPI book): * @mmap_lock: private mutex used when buffers are allocated/freed/mmapped * @memory: current memory type used * @bufs: videobuf buffer structures @@ -471,7 +475,7 @@ struct vb2_buf_ops { * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued * @alloc_devs: memory type/allocator-specific per-plane device * @streaming: current streaming state - * @start_streaming_called: start_streaming() was called successfully and we + * @start_streaming_called: @start_streaming was called successfully and we * started streaming. * @error: a fatal error occurred on the queue * @waiting_for_buffers: used in poll() to check if vb2 is still waiting for @@ -576,17 +580,18 @@ void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no); /** * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished * @vb: vb2_buffer returned from the driver - * @state: either %VB2_BUF_STATE_DONE if the operation finished successfully, - * %VB2_BUF_STATE_ERROR if the operation finished with an error or - * %VB2_BUF_STATE_QUEUED if the driver wants to requeue buffers. - * If start_streaming fails then it should return buffers with state - * %VB2_BUF_STATE_QUEUED to put them back into the queue. + * @state: either %VB2_BUF_STATE_DONE if the operation finished + * successfully, %VB2_BUF_STATE_ERROR if the operation finished + * with an error or %VB2_BUF_STATE_QUEUED if the driver wants to + * requeue buffers. If start_streaming fails then it should return + * buffers with state %VB2_BUF_STATE_QUEUED to put them back into + * the queue. * * This function should be called by the driver after a hardware operation on * a buffer is finished and the buffer may be returned to userspace. The driver * cannot use this buffer anymore until it is queued back to it by videobuf - * by the means of buf_queue callback. Only buffers previously queued to the - * driver by buf_queue can be passed to this function. + * by the means of &vb2_ops->buf_queue callback. Only buffers previously queued + * to the driver by &vb2_ops->buf_queue can be passed to this function. * * While streaming a buffer can only be returned in state DONE or ERROR. * The start_streaming op can also return them in case the DMA engine cannot @@ -614,9 +619,9 @@ void vb2_discard_done(struct vb2_queue *q); * @q: videobuf2 queue * * This function will wait until all buffers that have been given to the driver - * by buf_queue() are given back to vb2 with vb2_buffer_done(). It doesn't call - * wait_prepare, wait_finish pair. It is intended to be called with all locks - * taken, for example from stop_streaming() callback. + * by &vb2_ops->buf_queue are given back to vb2 with vb2_buffer_done(). It + * doesn't call wait_prepare()/wait_finish() pair. It is intended to be called + * with all locks taken, for example from &vb2_ops->stop_streaming callback. */ int vb2_wait_for_all_buffers(struct vb2_queue *q); @@ -639,14 +644,16 @@ void vb2_core_querybuf(struct vb2_queue *q, unsigned int index, void *pb); * @count: requested buffer count * * Should be called from vidioc_reqbufs ioctl handler of a driver. + * * This function: - * 1) verifies streaming parameters passed from the userspace, - * 2) sets up the queue, - * 3) negotiates number of buffers and planes per buffer with the driver + * + * #) verifies streaming parameters passed from the userspace, + * #) sets up the queue, + * #) negotiates number of buffers and planes per buffer with the driver * to be used during streaming, - * 4) allocates internal buffer structures (struct vb2_buffer), according to + * #) allocates internal buffer structures (struct vb2_buffer), according to * the agreed parameters, - * 5) for MMAP memory type, allocates actual video memory, using the + * #) for MMAP memory type, allocates actual video memory, using the * memory handling/allocation routines provided during queue initialization * * If req->count is 0, all the memory will be freed instead. @@ -664,20 +671,22 @@ int vb2_core_reqbufs(struct vb2_queue *q, enum vb2_memory memory, * @q: videobuf2 queue * @memory: memory type * @count: requested buffer count - * @parg: parameter passed to device driver + * @requested_planes: number of planes requested + * @requested_sizes: array with the size of the planes * - * Should be called from vidioc_create_bufs ioctl handler of a driver. + * Should be called from VIDIOC_CREATE_BUFS() ioctl handler of a driver. * This function: - * 1) verifies parameter sanity - * 2) calls the .queue_setup() queue operation - * 3) performs any necessary memory allocations * - * The return values from this function are intended to be directly returned - * from vidioc_create_bufs handler in driver. + * #) verifies parameter sanity + * #) calls the .queue_setup() queue operation + * #) performs any necessary memory allocations + * + * Return: the return values from this function are intended to be directly + * returned from VIDIOC_CREATE_BUFS() handler in driver. */ int vb2_core_create_bufs(struct vb2_queue *q, enum vb2_memory memory, - unsigned int *count, unsigned requested_planes, - const unsigned int requested_sizes[]); + unsigned int *count, unsigned int requested_planes, + const unsigned int requested_sizes[]); /** * vb2_core_prepare_buf() - Pass ownership of a buffer from userspace @@ -699,6 +708,7 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); /** * vb2_core_qbuf() - Queue a buffer from userspace + * * @q: videobuf2 queue * @index: id number of the buffer * @pb: buffer structure passed from userspace to vidioc_qbuf handler @@ -706,11 +716,13 @@ int vb2_core_prepare_buf(struct vb2_queue *q, unsigned int index, void *pb); * * Should be called from vidioc_qbuf ioctl handler of a driver. * The passed buffer should have been verified. + * * This function: - * 1) if necessary, calls buf_prepare callback in the driver (if provided), in + * + * #) if necessary, calls buf_prepare callback in the driver (if provided), in * which driver-specific buffer initialization can be performed, - * 2) if streaming is on, queues the buffer in driver by the means of buf_queue - * callback for processing. + * #) if streaming is on, queues the buffer in driver by the means of + * &vb2_ops->buf_queue callback for processing. * * The return values from this function are intended to be directly returned * from vidioc_qbuf handler in driver. @@ -729,11 +741,13 @@ int vb2_core_qbuf(struct vb2_queue *q, unsigned int index, void *pb); * * Should be called from vidioc_dqbuf ioctl handler of a driver. * The passed buffer should have been verified. + * * This function: - * 1) calls buf_finish callback in the driver (if provided), in which + * + * #) calls buf_finish callback in the driver (if provided), in which * driver can perform any additional operations that may be required before * returning the buffer to userspace, such as cache sync, - * 2) the buffer struct members are filled with relevant information for + * #) the buffer struct members are filled with relevant information for * the userspace. * * The return values from this function are intended to be directly returned @@ -819,6 +833,7 @@ void vb2_queue_error(struct vb2_queue *q); * from the mmap handler in driver. */ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma); + #ifndef CONFIG_MMU unsigned long vb2_get_unmapped_area(struct vb2_queue *q, unsigned long addr, @@ -844,14 +859,18 @@ unsigned long vb2_get_unmapped_area(struct vb2_queue *q, * from poll handler in driver. */ unsigned int vb2_core_poll(struct vb2_queue *q, struct file *file, - poll_table *wait); + poll_table *wait); + size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count, loff_t *ppos, int nonblock); size_t vb2_write(struct vb2_queue *q, const char __user *data, size_t count, loff_t *ppos, int nonblock); -/* - * vb2_thread_fnc - callback function for use with vb2_thread +/** + * typedef vb2_thread_fnc - callback function for use with vb2_thread + * + * @vb: pointer to struct &vb2_buffer + * @priv: pointer to a private pointer * * This is called whenever a buffer is dequeued in the thread. */ @@ -867,9 +886,11 @@ typedef int (*vb2_thread_fnc)(struct vb2_buffer *vb, void *priv); * This starts a thread that will queue and dequeue until an error occurs * or @vb2_thread_stop is called. * - * This function should not be used for anything else but the videobuf2-dvb - * support. If you think you have another good use-case for this, then please - * contact the linux-media mailinglist first. + * .. attention:: + * + * This function should not be used for anything else but the videobuf2-dvb + * support. If you think you have another good use-case for this, then please + * contact the linux-media mailing list first. */ int vb2_thread_start(struct vb2_queue *q, vb2_thread_fnc fnc, void *priv, const char *thread_name); @@ -1000,6 +1021,12 @@ bool vb2_buffer_in_use(struct vb2_queue *q, struct vb2_buffer *vb); /** * vb2_verify_memory_type() - Check whether the memory type and buffer type * passed to a buffer operation are compatible with the queue. + * + * @q: videobuf queue + * @memory: memory model, as defined by enum &vb2_memory. + * @type: private buffer type whose content is defined by the vb2-core + * caller. For example, for V4L2, it should match + * the types defined on enum &v4l2_buf_type */ int vb2_verify_memory_type(struct vb2_queue *q, enum vb2_memory memory, unsigned int type); -- cgit v1.2.3-70-g09d2 From 24ade5b6de002c51d18722e996dd92e49ad88802 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 14:22:00 -0300 Subject: [media] videobuf2-v4l2.h: get kernel-doc tags from C file There are several functions documented at the C file. Move them to the header, as this is the one used to build the media books. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/videobuf2-v4l2.c | 142 ----------------------------- include/media/videobuf2-v4l2.h | 151 ++++++++++++++++++++++++++++++- 2 files changed, 150 insertions(+), 143 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/videobuf2-v4l2.c b/drivers/media/v4l2-core/videobuf2-v4l2.c index 9cfbb6e4bc28..52ef8833f6b6 100644 --- a/drivers/media/v4l2-core/videobuf2-v4l2.c +++ b/drivers/media/v4l2-core/videobuf2-v4l2.c @@ -483,13 +483,6 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b) } EXPORT_SYMBOL(vb2_querybuf); -/** - * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies - * the memory and type values. - * @q: videobuf2 queue - * @req: struct passed from userspace to vidioc_reqbufs handler - * in driver - */ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) { int ret = vb2_verify_memory_type(q, req->memory, req->type); @@ -498,21 +491,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) } EXPORT_SYMBOL_GPL(vb2_reqbufs); -/** - * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel - * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_prepare_buf - * handler in driver - * - * Should be called from vidioc_prepare_buf ioctl handler of a driver. - * This function: - * 1) verifies the passed buffer, - * 2) calls buf_prepare callback in the driver (if provided), in which - * driver-specific buffer initialization can be performed, - * - * The return values from this function are intended to be directly returned - * from vidioc_prepare_buf handler in driver. - */ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) { int ret; @@ -528,13 +506,6 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) } EXPORT_SYMBOL_GPL(vb2_prepare_buf); -/** - * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies - * the memory and type values. - * @q: videobuf2 queue - * @create: creation parameters, passed from userspace to vidioc_create_bufs - * handler in driver - */ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) { unsigned requested_planes = 1; @@ -586,23 +557,6 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create) } EXPORT_SYMBOL_GPL(vb2_create_bufs); -/** - * vb2_qbuf() - Queue a buffer from userspace - * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_qbuf handler - * in driver - * - * Should be called from vidioc_qbuf ioctl handler of a driver. - * This function: - * 1) verifies the passed buffer, - * 2) if necessary, calls buf_prepare callback in the driver (if provided), in - * which driver-specific buffer initialization can be performed, - * 3) if streaming is on, queues the buffer in driver by the means of buf_queue - * callback for processing. - * - * The return values from this function are intended to be directly returned - * from vidioc_qbuf handler in driver. - */ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) { int ret; @@ -617,27 +571,6 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) } EXPORT_SYMBOL_GPL(vb2_qbuf); -/** - * vb2_dqbuf() - Dequeue a buffer to the userspace - * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_dqbuf handler - * in driver - * @nonblocking: if true, this call will not sleep waiting for a buffer if no - * buffers ready for dequeuing are present. Normally the driver - * would be passing (file->f_flags & O_NONBLOCK) here - * - * Should be called from vidioc_dqbuf ioctl handler of a driver. - * This function: - * 1) verifies the passed buffer, - * 2) calls buf_finish callback in the driver (if provided), in which - * driver can perform any additional operations that may be required before - * returning the buffer to userspace, such as cache sync, - * 3) the buffer struct members are filled with relevant information for - * the userspace. - * - * The return values from this function are intended to be directly returned - * from vidioc_dqbuf handler in driver. - */ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) { int ret; @@ -664,19 +597,6 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking) } EXPORT_SYMBOL_GPL(vb2_dqbuf); -/** - * vb2_streamon - start streaming - * @q: videobuf2 queue - * @type: type argument passed from userspace to vidioc_streamon handler - * - * Should be called from vidioc_streamon handler of a driver. - * This function: - * 1) verifies current state - * 2) passes any previously queued buffers to the driver and starts streaming - * - * The return values from this function are intended to be directly returned - * from vidioc_streamon handler in the driver. - */ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) { if (vb2_fileio_is_active(q)) { @@ -687,21 +607,6 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type) } EXPORT_SYMBOL_GPL(vb2_streamon); -/** - * vb2_streamoff - stop streaming - * @q: videobuf2 queue - * @type: type argument passed from userspace to vidioc_streamoff handler - * - * Should be called from vidioc_streamoff handler of a driver. - * This function: - * 1) verifies current state, - * 2) stop streaming and dequeues any queued buffers, including those previously - * passed to the driver (after waiting for the driver to finish). - * - * This call can be used for pausing playback. - * The return values from this function are intended to be directly returned - * from vidioc_streamoff handler in the driver - */ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) { if (vb2_fileio_is_active(q)) { @@ -712,15 +617,6 @@ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type) } EXPORT_SYMBOL_GPL(vb2_streamoff); -/** - * vb2_expbuf() - Export a buffer as a file descriptor - * @q: videobuf2 queue - * @eb: export buffer structure passed from userspace to vidioc_expbuf - * handler in driver - * - * The return values from this function are intended to be directly returned - * from vidioc_expbuf handler in driver. - */ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) { return vb2_core_expbuf(q, &eb->fd, eb->type, eb->index, @@ -728,17 +624,6 @@ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb) } EXPORT_SYMBOL_GPL(vb2_expbuf); -/** - * vb2_queue_init() - initialize a videobuf2 queue - * @q: videobuf2 queue; this structure should be allocated in driver - * - * The vb2_queue structure should be allocated by the driver. The driver is - * responsible of clearing it's content and setting initial values for some - * required entries before calling this function. - * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer - * to the struct vb2_queue description in include/media/videobuf2-core.h - * for more information. - */ int vb2_queue_init(struct vb2_queue *q) { /* @@ -779,39 +664,12 @@ int vb2_queue_init(struct vb2_queue *q) } EXPORT_SYMBOL_GPL(vb2_queue_init); -/** - * vb2_queue_release() - stop streaming, release the queue and free memory - * @q: videobuf2 queue - * - * This function stops streaming and performs necessary clean ups, including - * freeing video buffer memory. The driver is responsible for freeing - * the vb2_queue structure itself. - */ void vb2_queue_release(struct vb2_queue *q) { vb2_core_queue_release(q); } EXPORT_SYMBOL_GPL(vb2_queue_release); -/** - * vb2_poll() - implements poll userspace operation - * @q: videobuf2 queue - * @file: file argument passed to the poll file operation handler - * @wait: wait argument passed to the poll file operation handler - * - * This function implements poll file operation handler for a driver. - * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will - * be informed that the file descriptor of a video device is available for - * reading. - * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor - * will be reported as available for writing. - * - * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any - * pending events. - * - * The return values from this function are intended to be directly returned - * from poll handler in driver. - */ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait) { struct video_device *vfd = video_devdata(file); diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 3cc836f76675..01b1b71fc6fd 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -49,22 +49,171 @@ struct vb2_v4l2_buffer { container_of(vb, struct vb2_v4l2_buffer, vb2_buf) int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); + +/** + * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies + * the memory and type values. + * @q: videobuf2 queue + * @req: struct passed from userspace to vidioc_reqbufs handler + * in driver + */ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); +/** + * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies + * the memory and type values. + * @q: videobuf2 queue + * @create: creation parameters, passed from userspace to vidioc_create_bufs + * handler in driver + */ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create); + +/** + * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel + * @q: videobuf2 queue + * @b: buffer structure passed from userspace to vidioc_prepare_buf + * handler in driver + * + * Should be called from vidioc_prepare_buf ioctl handler of a driver. + * This function: + * 1) verifies the passed buffer, + * 2) calls buf_prepare callback in the driver (if provided), in which + * driver-specific buffer initialization can be performed, + * + * The return values from this function are intended to be directly returned + * from vidioc_prepare_buf handler in driver. + */ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b); +/** + * vb2_qbuf() - Queue a buffer from userspace + * @q: videobuf2 queue + * @b: buffer structure passed from userspace to vidioc_qbuf handler + * in driver + * + * Should be called from vidioc_qbuf ioctl handler of a driver. + * This function: + * 1) verifies the passed buffer, + * 2) if necessary, calls buf_prepare callback in the driver (if provided), in + * which driver-specific buffer initialization can be performed, + * 3) if streaming is on, queues the buffer in driver by the means of buf_queue + * callback for processing. + * + * The return values from this function are intended to be directly returned + * from vidioc_qbuf handler in driver. + */ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b); + +/** + * vb2_expbuf() - Export a buffer as a file descriptor + * @q: videobuf2 queue + * @eb: export buffer structure passed from userspace to vidioc_expbuf + * handler in driver + * + * The return values from this function are intended to be directly returned + * from vidioc_expbuf handler in driver. + */ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb); + +/** + * vb2_dqbuf() - Dequeue a buffer to the userspace + * @q: videobuf2 queue + * @b: buffer structure passed from userspace to vidioc_dqbuf handler + * in driver + * @nonblocking: if true, this call will not sleep waiting for a buffer if no + * buffers ready for dequeuing are present. Normally the driver + * would be passing (file->f_flags & O_NONBLOCK) here + * + * Should be called from vidioc_dqbuf ioctl handler of a driver. + * This function: + * 1) verifies the passed buffer, + * 2) calls buf_finish callback in the driver (if provided), in which + * driver can perform any additional operations that may be required before + * returning the buffer to userspace, such as cache sync, + * 3) the buffer struct members are filled with relevant information for + * the userspace. + * + * The return values from this function are intended to be directly returned + * from vidioc_dqbuf handler in driver. + */ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking); +/** + * vb2_streamon - start streaming + * @q: videobuf2 queue + * @type: type argument passed from userspace to vidioc_streamon handler + * + * Should be called from vidioc_streamon handler of a driver. + * This function: + * 1) verifies current state + * 2) passes any previously queued buffers to the driver and starts streaming + * + * The return values from this function are intended to be directly returned + * from vidioc_streamon handler in the driver. + */ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type); + +/** + * vb2_streamoff - stop streaming + * @q: videobuf2 queue + * @type: type argument passed from userspace to vidioc_streamoff handler + * + * Should be called from vidioc_streamoff handler of a driver. + * This function: + * 1) verifies current state, + * 2) stop streaming and dequeues any queued buffers, including those previously + * passed to the driver (after waiting for the driver to finish). + * + * This call can be used for pausing playback. + * The return values from this function are intended to be directly returned + * from vidioc_streamoff handler in the driver + */ int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type); +/** + * vb2_queue_init() - initialize a videobuf2 queue + * @q: videobuf2 queue; this structure should be allocated in driver + * + * The vb2_queue structure should be allocated by the driver. The driver is + * responsible of clearing it's content and setting initial values for some + * required entries before calling this function. + * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer + * to the struct vb2_queue description in include/media/videobuf2-core.h + * for more information. + */ int __must_check vb2_queue_init(struct vb2_queue *q); + +/** + * vb2_queue_release() - stop streaming, release the queue and free memory + * @q: videobuf2 queue + * + * This function stops streaming and performs necessary clean ups, including + * freeing video buffer memory. The driver is responsible for freeing + * the vb2_queue structure itself. + */ void vb2_queue_release(struct vb2_queue *q); + +/** + * vb2_poll() - implements poll userspace operation + * @q: videobuf2 queue + * @file: file argument passed to the poll file operation handler + * @wait: wait argument passed to the poll file operation handler + * + * This function implements poll file operation handler for a driver. + * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will + * be informed that the file descriptor of a video device is available for + * reading. + * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor + * will be reported as available for writing. + * + * If the driver uses struct v4l2_fh, then vb2_poll() will also check for any + * pending events. + * + * The return values from this function are intended to be directly returned + * from poll handler in driver. + */ unsigned int vb2_poll(struct vb2_queue *q, struct file *file, - poll_table *wait); + poll_table *wait); /* * The following functions are not part of the vb2 core API, but are simple -- cgit v1.2.3-70-g09d2 From bf4404b482f927096ba3001d829a79f788d2265f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 18:01:44 -0300 Subject: [media] videobuf2-v4l2.h: improve documentation There are a few issues at the documentation: fields not documented, bad cross refrences, etc. Fix them. Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-v4l2.h | 52 +++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 01b1b71fc6fd..611d4f330a4c 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -25,11 +25,13 @@ /** * struct vb2_v4l2_buffer - video buffer information for v4l2 + * * @vb2_buf: video buffer 2 * @flags: buffer informational flags * @field: enum v4l2_field; field order of the image in the buffer * @timecode: frame timecode * @sequence: sequence count of this frame + * * Should contain enough information to be able to cover all the fields * of struct v4l2_buffer at videodev2.h */ @@ -53,6 +55,7 @@ int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b); /** * vb2_reqbufs() - Wrapper for vb2_core_reqbufs() that also verifies * the memory and type values. + * * @q: videobuf2 queue * @req: struct passed from userspace to vidioc_reqbufs handler * in driver @@ -62,6 +65,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req); /** * vb2_create_bufs() - Wrapper for vb2_core_create_bufs() that also verifies * the memory and type values. + * * @q: videobuf2 queue * @create: creation parameters, passed from userspace to vidioc_create_bufs * handler in driver @@ -70,15 +74,17 @@ int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create); /** * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel + * * @q: videobuf2 queue * @b: buffer structure passed from userspace to vidioc_prepare_buf * handler in driver * * Should be called from vidioc_prepare_buf ioctl handler of a driver. * This function: - * 1) verifies the passed buffer, - * 2) calls buf_prepare callback in the driver (if provided), in which - * driver-specific buffer initialization can be performed, + * + * #) verifies the passed buffer, + * #) calls buf_prepare callback in the driver (if provided), in which + * driver-specific buffer initialization can be performed. * * The return values from this function are intended to be directly returned * from vidioc_prepare_buf handler in driver. @@ -88,53 +94,57 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b); /** * vb2_qbuf() - Queue a buffer from userspace * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_qbuf handler + * @b: buffer structure passed from userspace to VIDIOC_QBUF() handler * in driver * - * Should be called from vidioc_qbuf ioctl handler of a driver. + * Should be called from VIDIOC_QBUF() ioctl handler of a driver. + * * This function: - * 1) verifies the passed buffer, - * 2) if necessary, calls buf_prepare callback in the driver (if provided), in + * + * #) verifies the passed buffer, + * #) if necessary, calls buf_prepare callback in the driver (if provided), in * which driver-specific buffer initialization can be performed, - * 3) if streaming is on, queues the buffer in driver by the means of buf_queue + * #) if streaming is on, queues the buffer in driver by the means of buf_queue * callback for processing. * * The return values from this function are intended to be directly returned - * from vidioc_qbuf handler in driver. + * from VIDIOC_QBUF() handler in driver. */ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b); /** * vb2_expbuf() - Export a buffer as a file descriptor * @q: videobuf2 queue - * @eb: export buffer structure passed from userspace to vidioc_expbuf + * @eb: export buffer structure passed from userspace to VIDIOC_EXPBUF() * handler in driver * * The return values from this function are intended to be directly returned - * from vidioc_expbuf handler in driver. + * from VIDIOC_EXPBUF() handler in driver. */ int vb2_expbuf(struct vb2_queue *q, struct v4l2_exportbuffer *eb); /** * vb2_dqbuf() - Dequeue a buffer to the userspace * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_dqbuf handler + * @b: buffer structure passed from userspace to VIDIOC_DQBUF() handler * in driver * @nonblocking: if true, this call will not sleep waiting for a buffer if no * buffers ready for dequeuing are present. Normally the driver * would be passing (file->f_flags & O_NONBLOCK) here * - * Should be called from vidioc_dqbuf ioctl handler of a driver. + * Should be called from VIDIOC_DQBUF() ioctl handler of a driver. + * * This function: - * 1) verifies the passed buffer, - * 2) calls buf_finish callback in the driver (if provided), in which + * + * #) verifies the passed buffer, + * #) calls buf_finish callback in the driver (if provided), in which * driver can perform any additional operations that may be required before * returning the buffer to userspace, such as cache sync, - * 3) the buffer struct members are filled with relevant information for + * #) the buffer struct members are filled with relevant information for * the userspace. * * The return values from this function are intended to be directly returned - * from vidioc_dqbuf handler in driver. + * from VIDIOC_DQBUF() handler in driver. */ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking); @@ -144,7 +154,9 @@ int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking); * @type: type argument passed from userspace to vidioc_streamon handler * * Should be called from vidioc_streamon handler of a driver. + * * This function: + * * 1) verifies current state * 2) passes any previously queued buffers to the driver and starts streaming * @@ -159,9 +171,11 @@ int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type); * @type: type argument passed from userspace to vidioc_streamoff handler * * Should be called from vidioc_streamoff handler of a driver. + * * This function: - * 1) verifies current state, - * 2) stop streaming and dequeues any queued buffers, including those previously + * + * #) verifies current state, + * #) stop streaming and dequeues any queued buffers, including those previously * passed to the driver (after waiting for the driver to finish). * * This call can be used for pausing playback. -- cgit v1.2.3-70-g09d2 From dba2d12ae49217254cfc0452c68f1a4e2d2f1e4b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 18:12:18 -0300 Subject: [media] videobuf2-v4l2: document two helper functions Document vb2_ops_wait_prepare() and vb2_ops_wait_finish(), in order to fix those two warnings: Documentation/media/kapi/v4l2-dev.rst:166: WARNING: c:func reference target not found: vb2_ops_wait_prepare Documentation/media/kapi/v4l2-dev.rst:166: WARNING: c:func reference target not found: vb2_ops_wait_finish Signed-off-by: Mauro Carvalho Chehab --- include/media/videobuf2-v4l2.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/videobuf2-v4l2.h b/include/media/videobuf2-v4l2.h index 611d4f330a4c..036127c54bbf 100644 --- a/include/media/videobuf2-v4l2.h +++ b/include/media/videobuf2-v4l2.h @@ -268,9 +268,22 @@ unsigned long vb2_fop_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags); #endif -/* struct vb2_ops helpers, only use if vq->lock is non-NULL. */ - +/** + * vb2_ops_wait_prepare - helper function to lock a struct &vb2_queue + * + * @vq: pointer to struct vb2_queue + * + * ..note:: only use if vq->lock is non-NULL. + */ void vb2_ops_wait_prepare(struct vb2_queue *vq); + +/** + * vb2_ops_wait_finish - helper function to unlock a struct &vb2_queue + * + * @vq: pointer to struct vb2_queue + * + * ..note:: only use if vq->lock is non-NULL. + */ void vb2_ops_wait_finish(struct vb2_queue *vq); #endif /* _MEDIA_VIDEOBUF2_V4L2_H */ -- cgit v1.2.3-70-g09d2 From 0d56015d80a2c187c107d7780b89712bda8eee2e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 18:23:35 -0300 Subject: [media] v4l2-flash-led-class.h: document v4l2_flash_ops Fix this warning: ./include/media/v4l2-flash-led-class.h:103: WARNING: c:type reference target not found: v4l2_flash_ops Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-flash-led-class.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-flash-led-class.h b/include/media/v4l2-flash-led-class.h index 3d184ab52274..b0fe4d6f4a5f 100644 --- a/include/media/v4l2-flash-led-class.h +++ b/include/media/v4l2-flash-led-class.h @@ -20,7 +20,7 @@ struct led_classdev; struct v4l2_flash; enum led_brightness; -/* +/** * struct v4l2_flash_ctrl_data - flash control initialization data, filled * basing on the features declared by the LED flash * class driver in the v4l2_flash_config @@ -33,14 +33,21 @@ struct v4l2_flash_ctrl_data { u32 cid; }; +/** + * struct v4l2_flash_ops - V4L2 flash operations + * + * @external_strobe_set: Setup strobing the flash by hardware pin state + * assertion. + * @intensity_to_led_brightness: Convert intensity to brightness in a device + * specific manner + * @led_brightness_to_intensity: convert brightness to intensity in a device + * specific manner. + */ struct v4l2_flash_ops { - /* setup strobing the flash by hardware pin state assertion */ int (*external_strobe_set)(struct v4l2_flash *v4l2_flash, bool enable); - /* convert intensity to brightness in a device specific manner */ enum led_brightness (*intensity_to_led_brightness) (struct v4l2_flash *v4l2_flash, s32 intensity); - /* convert brightness to intensity in a device specific manner */ s32 (*led_brightness_to_intensity) (struct v4l2_flash *v4l2_flash, enum led_brightness); }; -- cgit v1.2.3-70-g09d2 From cb8d67cf70b4bc7d60c356896823022717b70d1e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 8 Sep 2016 18:31:17 -0300 Subject: [media] v4l2-subdev: fix some references to v4l2_dev There is a warning there, because it was pointing to a different name. Fix it. While here, use struct &foo, instead of &struct foo. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 2c1e328ccb1d..e175c2c891a8 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -764,7 +764,7 @@ struct v4l2_subdev_platform_data { * @entity: pointer to &struct media_entity * @list: List of sub-devices * @owner: The owner is the same as the driver's &struct device owner. - * @owner_v4l2_dev: true if the &sd->owner matches the owner of &v4l2_dev->dev + * @owner_v4l2_dev: true if the &sd->owner matches the owner of @v4l2_dev->dev * ownner. Initialized by v4l2_device_register_subdev(). * @flags: subdev flags. Can be: * %V4L2_SUBDEV_FL_IS_I2C - Set this flag if this subdev is a i2c device; @@ -774,9 +774,9 @@ struct v4l2_subdev_platform_data { * %V4L2_SUBDEV_FL_HAS_EVENTS - Set this flag if this subdev generates * events. * - * @v4l2_dev: pointer to &struct v4l2_device - * @ops: pointer to &struct v4l2_subdev_ops - * @internal_ops: pointer to &struct v4l2_subdev_internal_ops. + * @v4l2_dev: pointer to struct &v4l2_device + * @ops: pointer to struct &v4l2_subdev_ops + * @internal_ops: pointer to struct &v4l2_subdev_internal_ops. * Never call these internal ops from within a driver! * @ctrl_handler: The control handler of this subdev. May be NULL. * @name: Name of the sub-device. Please notice that the name must be unique. -- cgit v1.2.3-70-g09d2 From 9ef0b3f3f88d2a177e3403dd57e373d97f1c389c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 9 Sep 2016 08:40:15 -0300 Subject: [media] v4l2-subdev.h: fix a typo at a kernel-doc markup One struct at the comment was not written well. Fix it. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index e175c2c891a8..863f92600607 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -421,7 +421,7 @@ struct v4l2_subdev_video_ops { * in video mode via the vbi device node. * * @decode_vbi_line: video decoders that support sliced VBI need to implement - * this ioctl. Field p of the &struct v4l2_sliced_vbi_line is set to the + * this ioctl. Field p of the &struct v4l2_decode_vbi_line is set to the * start of the VBI data that was generated by the decoder. The driver * then parses the sliced VBI data and sets the other fields in the * struct accordingly. The pointer p is updated to point to the start of -- cgit v1.2.3-70-g09d2 From 283e4a82999f48c61495436b9bbd0357a3268f9d Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 6 Sep 2016 06:04:20 -0300 Subject: [media] media: platform: pxa_camera: make a standalone v4l2 device This patch removes the soc_camera API dependency from pxa_camera. In the current status : - all previously captures are working the same on pxa270 - the s_crop() call was removed, judged not working (see what happens soc_camera_s_crop() when get_crop() == NULL) - if the pixel clock is provided by then sensor, ie. not MCLK, the dual stage change is not handled yet. => there is no in-tree user of this, so I'll let it that way - the MCLK is not yet finished, it's as in the legacy way, ie. activated at video device opening and closed at video device closing. In a subsequence patch pxa_camera_mclk_ops should be used, and platform data MCLK ignored. It will be the sensor's duty to request the clock and enable it, which will end in pxa_camera_mclk_ops. Signed-off-by: Robert Jarzmik Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/soc_camera/Kconfig | 2 +- drivers/media/platform/soc_camera/pxa_camera.c | 753 +++++++++++++++++-------- include/linux/platform_data/media/camera-pxa.h | 2 + 3 files changed, 518 insertions(+), 239 deletions(-) (limited to 'include') diff --git a/drivers/media/platform/soc_camera/Kconfig b/drivers/media/platform/soc_camera/Kconfig index de1767899ddc..6b87b3a9d546 100644 --- a/drivers/media/platform/soc_camera/Kconfig +++ b/drivers/media/platform/soc_camera/Kconfig @@ -19,7 +19,7 @@ config SOC_CAMERA_PLATFORM config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" - depends on VIDEO_DEV && PXA27x && SOC_CAMERA && HAS_DMA + depends on VIDEO_DEV && PXA27x && HAS_DMA select VIDEOBUF2_DMA_SG select SG_SPLIT ---help--- diff --git a/drivers/media/platform/soc_camera/pxa_camera.c b/drivers/media/platform/soc_camera/pxa_camera.c index 8f329d0b2cda..395cd398c32b 100644 --- a/drivers/media/platform/soc_camera/pxa_camera.c +++ b/drivers/media/platform/soc_camera/pxa_camera.c @@ -3,6 +3,7 @@ * * Copyright (C) 2006, Sascha Hauer, Pengutronix * Copyright (C) 2008, Guennadi Liakhovetski + * Copyright (C) 2016, Robert Jarzmik * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -22,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -32,13 +35,16 @@ #include #include +#include +#include #include -#include -#include -#include -#include +#include +#include #include +#include +#include + #include #include @@ -46,6 +52,9 @@ #define PXA_CAM_VERSION "0.0.6" #define PXA_CAM_DRV_NAME "pxa27x-camera" +#define DEFAULT_WIDTH 640 +#define DEFAULT_HEIGHT 480 + /* Camera Interface */ #define CICR0 0x0000 #define CICR1 0x0004 @@ -169,7 +178,25 @@ CICR0_EOFM | CICR0_FOM) #define sensor_call(cam, o, f, args...) \ - v4l2_subdev_call(sd, o, f, ##args) + v4l2_subdev_call(cam->sensor, o, f, ##args) + +/* + * Format handling + */ +/** + * struct soc_camera_format_xlate - match between host and sensor formats + * @code: code of a sensor provided format + * @host_fmt: host format after host translation from code + * + * Host and sensor translation structure. Used in table of host and sensor + * formats matchings in soc_camera_device. A host can override the generic list + * generation by implementing get_formats(), and use it for format checks and + * format setup. + */ +struct soc_camera_format_xlate { + u32 code; + const struct soc_mbus_pixelfmt *host_fmt; +}; /* * Structures @@ -198,7 +225,18 @@ struct pxa_buffer { }; struct pxa_camera_dev { - struct soc_camera_host soc_host; + struct v4l2_device v4l2_dev; + struct video_device vdev; + struct v4l2_async_notifier notifier; + struct vb2_queue vb2_vq; + struct v4l2_subdev *sensor; + struct soc_camera_format_xlate *user_formats; + const struct soc_camera_format_xlate *current_fmt; + struct v4l2_pix_format current_pix; + + struct v4l2_async_subdev asd; + struct v4l2_async_subdev *asds[1]; + /* * PXA27x is only supposed to handle one camera on its Quick Capture * interface. If anyone ever builds hardware to enable more than @@ -218,11 +256,13 @@ struct pxa_camera_dev { unsigned long ciclk; unsigned long mclk; u32 mclk_divisor; + struct v4l2_clk *mclk_clk; u16 width_flags; /* max 10 bits */ struct list_head capture; spinlock_t lock; + struct mutex mlock; unsigned int buf_sequence; struct pxa_buffer *active; @@ -237,12 +277,69 @@ struct pxa_cam { static const char *pxa_cam_driver_description = "PXA_Camera"; -static struct pxa_camera_dev *icd_to_pcdev(struct soc_camera_device *icd) +/* + * Format translation functions + */ +const struct soc_camera_format_xlate *soc_mbus_xlate_by_fourcc( + struct soc_camera_format_xlate *user_formats, unsigned int fourcc) +{ + unsigned int i; + + for (i = 0; user_formats[i].code; i++) + if (user_formats[i].host_fmt->fourcc == fourcc) + return user_formats + i; + return NULL; +} + +static struct soc_camera_format_xlate *soc_mbus_build_fmts_xlate( + struct v4l2_device *v4l2_dev, struct v4l2_subdev *subdev, + int (*get_formats)(struct v4l2_device *, unsigned int, + struct soc_camera_format_xlate *xlate)) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct pxa_camera_dev *pcdev = ici->priv; + unsigned int i, fmts = 0, raw_fmts = 0; + int ret; + struct v4l2_subdev_mbus_code_enum code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct soc_camera_format_xlate *user_formats; + + while (!v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) { + raw_fmts++; + code.index++; + } + + /* + * First pass - only count formats this host-sensor + * configuration can provide + */ + for (i = 0; i < raw_fmts; i++) { + ret = get_formats(v4l2_dev, i, NULL); + if (ret < 0) + return ERR_PTR(ret); + fmts += ret; + } + + if (!fmts) + return ERR_PTR(-ENXIO); - return pcdev; + user_formats = kcalloc(fmts + 1, sizeof(*user_formats), GFP_KERNEL); + if (!user_formats) + return ERR_PTR(-ENOMEM); + + /* Second pass - actually fill data formats */ + fmts = 0; + for (i = 0; i < raw_fmts; i++) { + ret = get_formats(v4l2_dev, i, user_formats + fmts); + if (ret < 0) + goto egfmt; + fmts += ret; + } + user_formats[fmts].code = 0; + + return user_formats; +egfmt: + kfree(user_formats); + return ERR_PTR(ret); } /* @@ -257,7 +354,12 @@ static struct pxa_buffer *vb2_to_pxa_buffer(struct vb2_buffer *vb) static struct device *pcdev_to_dev(struct pxa_camera_dev *pcdev) { - return pcdev->soc_host.v4l2_dev.dev; + return pcdev->v4l2_dev.dev; +} + +static struct pxa_camera_dev *v4l2_dev_to_pcdev(struct v4l2_device *v4l2_dev) +{ + return container_of(v4l2_dev, struct pxa_camera_dev, v4l2_dev); } static void pxa_camera_dma_irq(struct pxa_camera_dev *pcdev, @@ -338,7 +440,7 @@ static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev, struct pxa_buffer *buf) { buf->active_dma = DMA_Y; - if (pcdev->channels == 3) + if (buf->nb_planes == 3) buf->active_dma |= DMA_U | DMA_V; } @@ -671,51 +773,6 @@ static irqreturn_t pxa_camera_irq(int irq, void *data) return IRQ_HANDLED; } -static int pxa_camera_add_device(struct soc_camera_device *icd) -{ - struct pxa_camera_dev *pcdev = icd_to_pcdev(icd); - - dev_info(pcdev_to_dev(pcdev), "PXA Camera driver attached to camera %d\n", - icd->devnum); - - return 0; -} - -static void pxa_camera_remove_device(struct soc_camera_device *icd) -{ - struct pxa_camera_dev *pcdev = icd_to_pcdev(icd); - - dev_info(pcdev_to_dev(pcdev), "PXA Camera driver detached from camera %d\n", - icd->devnum); -} - -/* - * The following two functions absolutely depend on the fact, that - * there can be only one camera on PXA quick capture interface - * Called with .host_lock held - */ -static int pxa_camera_clock_start(struct soc_camera_host *ici) -{ - struct pxa_camera_dev *pcdev = ici->priv; - - pxa_camera_activate(pcdev); - - return 0; -} - -/* Called with .host_lock held */ -static void pxa_camera_clock_stop(struct soc_camera_host *ici) -{ - struct pxa_camera_dev *pcdev = ici->priv; - - /* disable capture, disable interrupts */ - __raw_writel(0x3ff, pcdev->base + CICR0); - - /* Stop DMA engine */ - pxa_dma_stop_channels(pcdev); - pxa_camera_deactivate(pcdev); -} - static int test_platform_param(struct pxa_camera_dev *pcdev, unsigned char buswidth, unsigned long *flags) { @@ -741,12 +798,9 @@ static int test_platform_param(struct pxa_camera_dev *pcdev, return -EINVAL; } -static void pxa_camera_setup_cicr(struct soc_camera_device *icd, +static void pxa_camera_setup_cicr(struct pxa_camera_dev *pcdev, unsigned long flags, __u32 pixfmt) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct pxa_camera_dev *pcdev = ici->priv; - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); unsigned long dw, bpp; u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0, y_skip_top; int ret = sensor_call(pcdev, sensor, g_skip_top_lines, &y_skip_top); @@ -758,7 +812,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, * Datawidth is now guaranteed to be equal to one of the three values. * We fix bit-per-pixel equal to data-width... */ - switch (icd->current_fmt->host_fmt->bits_per_sample) { + switch (pcdev->current_fmt->host_fmt->bits_per_sample) { case 10: dw = 4; bpp = 0x40; @@ -792,7 +846,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, if (cicr0 & CICR0_ENB) __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0); - cicr1 = CICR1_PPL_VAL(icd->user_width - 1) | bpp | dw; + cicr1 = CICR1_PPL_VAL(pcdev->current_pix.width - 1) | bpp | dw; switch (pixfmt) { case V4L2_PIX_FMT_YUV422P: @@ -821,7 +875,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd, } cicr2 = 0; - cicr3 = CICR3_LPF_VAL(icd->user_height - 1) | + cicr3 = CICR3_LPF_VAL(pcdev->current_pix.height - 1) | CICR3_BFW_VAL(min((u32)255, y_skip_top)); cicr4 |= pcdev->mclk_divisor; @@ -933,13 +987,12 @@ static int pxac_vb2_prepare(struct vb2_buffer *vb) { struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vb->vb2_queue); struct pxa_buffer *buf = vb2_to_pxa_buffer(vb); - struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue); int ret = 0; switch (pcdev->channels) { case 1: case 3: - vb2_set_plane_payload(vb, 0, icd->sizeimage); + vb2_set_plane_payload(vb, 0, pcdev->current_pix.sizeimage); break; default: return -EINVAL; @@ -949,7 +1002,7 @@ static int pxac_vb2_prepare(struct vb2_buffer *vb) "%s (vb=%p) nb_channels=%d size=%lu\n", __func__, vb, pcdev->channels, vb2_get_plane_payload(vb, 0)); - WARN_ON(!icd->current_fmt); + WARN_ON(!pcdev->current_fmt); #ifdef DEBUG /* @@ -989,8 +1042,7 @@ static int pxac_vb2_queue_setup(struct vb2_queue *vq, struct device *alloc_devs[]) { struct pxa_camera_dev *pcdev = vb2_get_drv_priv(vq); - struct soc_camera_device *icd = soc_camera_from_vb2q(vq); - int size = icd->sizeimage; + int size = pcdev->current_pix.sizeimage; dev_dbg(pcdev_to_dev(pcdev), "%s(vq=%p nbufs=%d num_planes=%d size=%d)\n", @@ -1050,21 +1102,22 @@ static struct vb2_ops pxac_vb2_ops = { .wait_finish = vb2_ops_wait_finish, }; -static int pxa_camera_init_videobuf2(struct vb2_queue *vq, - struct soc_camera_device *icd) +static int pxa_camera_init_videobuf2(struct pxa_camera_dev *pcdev) { - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct pxa_camera_dev *pcdev = ici->priv; int ret; + struct vb2_queue *vq = &pcdev->vb2_vq; + memset(vq, 0, sizeof(*vq)); vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; vq->drv_priv = pcdev; vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; vq->buf_struct_size = sizeof(struct pxa_buffer); + vq->dev = pcdev->v4l2_dev.dev; vq->ops = &pxac_vb2_ops; vq->mem_ops = &vb2_dma_sg_memops; + vq->lock = &pcdev->mlock; ret = vb2_queue_init(vq); dev_dbg(pcdev_to_dev(pcdev), @@ -1076,18 +1129,15 @@ static int pxa_camera_init_videobuf2(struct vb2_queue *vq, /* * Video ioctls section */ -static int pxa_camera_set_bus_param(struct soc_camera_device *icd) +static int pxa_camera_set_bus_param(struct pxa_camera_dev *pcdev) { - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct pxa_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; - u32 pixfmt = icd->current_fmt->host_fmt->fourcc; + u32 pixfmt = pcdev->current_fmt->host_fmt->fourcc; unsigned long bus_flags, common_flags; int ret; - struct pxa_cam *cam = icd->host_priv; - ret = test_platform_param(pcdev, icd->current_fmt->host_fmt->bits_per_sample, + ret = test_platform_param(pcdev, + pcdev->current_fmt->host_fmt->bits_per_sample, &bus_flags); if (ret < 0) return ret; @@ -1138,24 +1188,20 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd) cfg.flags = common_flags; ret = sensor_call(pcdev, video, s_mbus_config, &cfg); if (ret < 0 && ret != -ENOIOCTLCMD) { - dev_dbg(pcdev_to_dev(pcdev), "camera s_mbus_config(0x%lx) returned %d\n", + dev_dbg(pcdev_to_dev(pcdev), + "camera s_mbus_config(0x%lx) returned %d\n", common_flags, ret); return ret; } - cam->flags = common_flags; - - pxa_camera_setup_cicr(icd, common_flags, pixfmt); + pxa_camera_setup_cicr(pcdev, common_flags, pixfmt); return 0; } -static int pxa_camera_try_bus_param(struct soc_camera_device *icd, +static int pxa_camera_try_bus_param(struct pxa_camera_dev *pcdev, unsigned char buswidth) { - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct soc_camera_host *ici = to_soc_camera_host(icd->parent); - struct pxa_camera_dev *pcdev = ici->priv; struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,}; unsigned long bus_flags, common_flags; int ret = test_platform_param(pcdev, buswidth, &bus_flags); @@ -1201,13 +1247,12 @@ static bool pxa_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt) fmt->packing == SOC_MBUS_PACKING_EXTEND16); } -static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int idx, +static int pxa_camera_get_formats(struct v4l2_device *v4l2_dev, + unsigned int idx, struct soc_camera_format_xlate *xlate) { - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct pxa_camera_dev *pcdev = icd_to_pcdev(icd); + struct pxa_camera_dev *pcdev = v4l2_dev_to_pcdev(v4l2_dev); int formats = 0, ret; - struct pxa_cam *cam; struct v4l2_subdev_mbus_code_enum code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, .index = idx, @@ -1221,25 +1266,16 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id fmt = soc_mbus_get_fmtdesc(code.code); if (!fmt) { - dev_err(pcdev_to_dev(pcdev), "Invalid format code #%u: %d\n", idx, code.code); + dev_err(pcdev_to_dev(pcdev), + "Invalid format code #%u: %d\n", idx, code.code); return 0; } /* This also checks support for the requested bits-per-sample */ - ret = pxa_camera_try_bus_param(icd, fmt->bits_per_sample); + ret = pxa_camera_try_bus_param(pcdev, fmt->bits_per_sample); if (ret < 0) return 0; - if (!icd->host_priv) { - cam = kzalloc(sizeof(*cam), GFP_KERNEL); - if (!cam) - return -ENOMEM; - - icd->host_priv = cam; - } else { - cam = icd->host_priv; - } - switch (code.code) { case MEDIA_BUS_FMT_UYVY8_2X8: formats++; @@ -1281,10 +1317,22 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, unsigned int id return formats; } -static void pxa_camera_put_formats(struct soc_camera_device *icd) +static int pxa_camera_build_formats(struct pxa_camera_dev *pcdev) +{ + struct soc_camera_format_xlate *xlate; + + xlate = soc_mbus_build_fmts_xlate(&pcdev->v4l2_dev, pcdev->sensor, + pxa_camera_get_formats); + if (IS_ERR(xlate)) + return PTR_ERR(xlate); + + pcdev->user_formats = xlate; + return 0; +} + +static void pxa_camera_destroy_formats(struct pxa_camera_dev *pcdev) { - kfree(icd->host_priv); - icd->host_priv = NULL; + kfree(pcdev->user_formats); } static int pxa_camera_check_frame(u32 width, u32 height) @@ -1294,86 +1342,44 @@ static int pxa_camera_check_frame(u32 width, u32 height) (width & 0x01); } -static int pxa_camera_set_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) +static int pxac_vidioc_enum_fmt_vid_cap(struct file *filp, void *priv, + struct v4l2_fmtdesc *f) { - struct device *dev = icd->parent; - struct soc_camera_host *ici = to_soc_camera_host(dev); - struct pxa_camera_dev *pcdev = ici->priv; - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - const struct soc_camera_format_xlate *xlate = NULL; - struct soc_camera_sense sense = { - .master_clock = pcdev->mclk, - .pixel_clock_max = pcdev->ciclk / 4, - }; - struct v4l2_pix_format *pix = &f->fmt.pix; - struct v4l2_subdev_format format = { - .which = V4L2_SUBDEV_FORMAT_ACTIVE, - }; - struct v4l2_mbus_framefmt *mf = &format.format; - int ret; - - xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); - if (!xlate) { - dev_warn(pcdev_to_dev(pcdev), - "Format %x not found\n", pix->pixelformat); - return -EINVAL; - } - - /* If PCLK is used to latch data from the sensor, check sense */ - if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) - /* The caller holds a mutex. */ - icd->sense = &sense; - - mf->width = pix->width; - mf->height = pix->height; - mf->field = pix->field; - mf->colorspace = pix->colorspace; - mf->code = xlate->code; + struct pxa_camera_dev *pcdev = video_drvdata(filp); + const struct soc_mbus_pixelfmt *format; + unsigned int idx; - ret = sensor_call(pcdev, pad, set_fmt, NULL, &format); - - if (mf->code != xlate->code) + for (idx = 0; pcdev->user_formats[idx].code; idx++); + if (f->index >= idx) return -EINVAL; - icd->sense = NULL; - - if (ret < 0) { - dev_warn(pcdev_to_dev(pcdev), - "Failed to configure for format %x\n", - pix->pixelformat); - } else if (pxa_camera_check_frame(mf->width, mf->height)) { - dev_warn(pcdev_to_dev(pcdev), - "Camera driver produced an unsupported frame %dx%d\n", - mf->width, mf->height); - ret = -EINVAL; - } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { - if (sense.pixel_clock > sense.pixel_clock_max) { - dev_err(pcdev_to_dev(pcdev), - "pixel clock %lu set by the camera too high!", - sense.pixel_clock); - return -EIO; - } - recalculate_fifo_timeout(pcdev, sense.pixel_clock); - } - - if (ret < 0) - return ret; + format = pcdev->user_formats[f->index].host_fmt; + f->pixelformat = format->fourcc; + return 0; +} - pix->width = mf->width; - pix->height = mf->height; - pix->field = mf->field; - pix->colorspace = mf->colorspace; - icd->current_fmt = xlate; +static int pxac_vidioc_g_fmt_vid_cap(struct file *filp, void *priv, + struct v4l2_format *f) +{ + struct pxa_camera_dev *pcdev = video_drvdata(filp); + struct v4l2_pix_format *pix = &f->fmt.pix; - return ret; + pix->width = pcdev->current_pix.width; + pix->height = pcdev->current_pix.height; + pix->bytesperline = pcdev->current_pix.bytesperline; + pix->sizeimage = pcdev->current_pix.sizeimage; + pix->field = pcdev->current_pix.field; + pix->pixelformat = pcdev->current_fmt->host_fmt->fourcc; + pix->colorspace = pcdev->current_pix.colorspace; + dev_dbg(pcdev_to_dev(pcdev), "current_fmt->fourcc: 0x%08x\n", + pcdev->current_fmt->host_fmt->fourcc); + return 0; } -static int pxa_camera_try_fmt(struct soc_camera_device *icd, - struct v4l2_format *f) +static int pxac_vidioc_try_fmt_vid_cap(struct file *filp, void *priv, + struct v4l2_format *f) { - struct v4l2_subdev *sd = soc_camera_to_subdev(icd); - struct pxa_camera_dev *pcdev = icd_to_pcdev(icd); + struct pxa_camera_dev *pcdev = video_drvdata(filp); const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; struct v4l2_subdev_pad_config pad_cfg; @@ -1384,7 +1390,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, __u32 pixfmt = pix->pixelformat; int ret; - xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + xlate = soc_mbus_xlate_by_fourcc(pcdev->user_formats, pixfmt); if (!xlate) { dev_warn(pcdev_to_dev(pcdev), "Format %x not found\n", pixfmt); return -EINVAL; @@ -1400,26 +1406,18 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, &pix->height, 32, 2048, 0, pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0); - /* limit to sensor capabilities */ - mf->width = pix->width; - mf->height = pix->height; - /* Only progressive video supported so far */ - mf->field = V4L2_FIELD_NONE; - mf->colorspace = pix->colorspace; - mf->code = xlate->code; - + v4l2_fill_mbus_format(mf, pix, xlate->code); ret = sensor_call(pcdev, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; - pix->width = mf->width; - pix->height = mf->height; - pix->colorspace = mf->colorspace; + v4l2_fill_pix_format(pix, mf); + /* Only progressive video supported so far */ switch (mf->field) { case V4L2_FIELD_ANY: case V4L2_FIELD_NONE: - pix->field = V4L2_FIELD_NONE; + pix->field = V4L2_FIELD_NONE; break; default: /* TODO: support interlaced at least in pass-through mode */ @@ -1428,20 +1426,74 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd, return -EINVAL; } - return ret; + ret = soc_mbus_bytes_per_line(pix->width, xlate->host_fmt); + if (ret < 0) + return ret; + + pix->bytesperline = ret; + ret = soc_mbus_image_size(xlate->host_fmt, pix->bytesperline, + pix->height); + if (ret < 0) + return ret; + + pix->sizeimage = ret; + return 0; } -static unsigned int pxa_camera_poll(struct file *file, poll_table *pt) +static int pxac_vidioc_s_fmt_vid_cap(struct file *filp, void *priv, + struct v4l2_format *f) { - struct soc_camera_device *icd = file->private_data; + struct pxa_camera_dev *pcdev = video_drvdata(filp); + const struct soc_camera_format_xlate *xlate; + struct v4l2_pix_format *pix = &f->fmt.pix; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + unsigned long flags; + int ret, is_busy; + + dev_dbg(pcdev_to_dev(pcdev), + "s_fmt_vid_cap(pix=%dx%d:%x)\n", + pix->width, pix->height, pix->pixelformat); + + spin_lock_irqsave(&pcdev->lock, flags); + is_busy = pcdev->active || vb2_is_busy(&pcdev->vb2_vq); + spin_unlock_irqrestore(&pcdev->lock, flags); + + if (is_busy) + return -EBUSY; + + ret = pxac_vidioc_try_fmt_vid_cap(filp, priv, f); + if (ret) + return ret; + + xlate = soc_mbus_xlate_by_fourcc(pcdev->user_formats, + pix->pixelformat); + v4l2_fill_mbus_format(&format.format, pix, xlate->code); + ret = sensor_call(pcdev, pad, set_fmt, NULL, &format); + if (ret < 0) { + dev_warn(pcdev_to_dev(pcdev), + "Failed to configure for format %x\n", + pix->pixelformat); + } else if (pxa_camera_check_frame(pix->width, pix->height)) { + dev_warn(pcdev_to_dev(pcdev), + "Camera driver produced an unsupported frame %dx%d\n", + pix->width, pix->height); + return -EINVAL; + } + + pcdev->current_fmt = xlate; + pcdev->current_pix = *pix; - return vb2_poll(&icd->vb2_vidq, file, pt); + ret = pxa_camera_set_bus_param(pcdev); + return ret; } -static int pxa_camera_querycap(struct soc_camera_host *ici, - struct v4l2_capability *cap) +static int pxac_vidioc_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) { - /* cap->name is set by the firendly caller:-> */ + strlcpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info)); + strlcpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver)); strlcpy(cap->card, pxa_cam_driver_description, sizeof(cap->card)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; @@ -1449,13 +1501,212 @@ static int pxa_camera_querycap(struct soc_camera_host *ici, return 0; } +static int pxac_vidioc_enum_input(struct file *file, void *priv, + struct v4l2_input *i) +{ + if (i->index > 0) + return -EINVAL; + + i->type = V4L2_INPUT_TYPE_CAMERA; + strlcpy(i->name, "Camera", sizeof(i->name)); + + return 0; +} + +static int pxac_vidioc_g_input(struct file *file, void *priv, unsigned int *i) +{ + *i = 0; + + return 0; +} + +static int pxac_vidioc_s_input(struct file *file, void *priv, unsigned int i) +{ + if (i > 0) + return -EINVAL; + + return 0; +} + +static int pxac_fops_camera_open(struct file *filp) +{ + struct pxa_camera_dev *pcdev = video_drvdata(filp); + int ret; + + mutex_lock(&pcdev->mlock); + ret = v4l2_fh_open(filp); + if (ret < 0) + goto out; + + ret = sensor_call(pcdev, core, s_power, 1); + if (ret) + v4l2_fh_release(filp); +out: + mutex_unlock(&pcdev->mlock); + return ret; +} + +static int pxac_fops_camera_release(struct file *filp) +{ + struct pxa_camera_dev *pcdev = video_drvdata(filp); + int ret; + + ret = vb2_fop_release(filp); + if (ret < 0) + return ret; + + mutex_lock(&pcdev->mlock); + ret = sensor_call(pcdev, core, s_power, 0); + mutex_unlock(&pcdev->mlock); + + return ret; +} + +static const struct v4l2_file_operations pxa_camera_fops = { + .owner = THIS_MODULE, + .open = pxac_fops_camera_open, + .release = pxac_fops_camera_release, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .unlocked_ioctl = video_ioctl2, +}; + +static const struct v4l2_ioctl_ops pxa_camera_ioctl_ops = { + .vidioc_querycap = pxac_vidioc_querycap, + + .vidioc_enum_input = pxac_vidioc_enum_input, + .vidioc_g_input = pxac_vidioc_g_input, + .vidioc_s_input = pxac_vidioc_s_input, + + .vidioc_enum_fmt_vid_cap = pxac_vidioc_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap = pxac_vidioc_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap = pxac_vidioc_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap = pxac_vidioc_try_fmt_vid_cap, + + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_qbuf = vb2_ioctl_qbuf, + .vidioc_dqbuf = vb2_ioctl_dqbuf, + .vidioc_expbuf = vb2_ioctl_expbuf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, +}; + +static struct v4l2_clk_ops pxa_camera_mclk_ops = { +}; + +static const struct video_device pxa_camera_videodev_template = { + .name = "pxa-camera", + .minor = -1, + .fops = &pxa_camera_fops, + .ioctl_ops = &pxa_camera_ioctl_ops, + .release = video_device_release_empty, + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING, +}; + +static int pxa_camera_sensor_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + int err; + struct v4l2_device *v4l2_dev = notifier->v4l2_dev; + struct pxa_camera_dev *pcdev = v4l2_dev_to_pcdev(v4l2_dev); + struct video_device *vdev = &pcdev->vdev; + struct v4l2_pix_format *pix = &pcdev->current_pix; + struct v4l2_subdev_format format = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; + struct v4l2_mbus_framefmt *mf = &format.format; + + dev_info(pcdev_to_dev(pcdev), "%s(): trying to bind a device\n", + __func__); + mutex_lock(&pcdev->mlock); + *vdev = pxa_camera_videodev_template; + vdev->v4l2_dev = v4l2_dev; + vdev->lock = &pcdev->mlock; + pcdev->sensor = subdev; + pcdev->vdev.queue = &pcdev->vb2_vq; + pcdev->vdev.v4l2_dev = &pcdev->v4l2_dev; + pcdev->vdev.ctrl_handler = subdev->ctrl_handler; + video_set_drvdata(&pcdev->vdev, pcdev); + + err = pxa_camera_build_formats(pcdev); + if (err) { + dev_err(pcdev_to_dev(pcdev), "building formats failed: %d\n", + err); + goto out; + } + + pcdev->current_fmt = pcdev->user_formats; + pix->field = V4L2_FIELD_NONE; + pix->width = DEFAULT_WIDTH; + pix->height = DEFAULT_HEIGHT; + pix->bytesperline = + soc_mbus_bytes_per_line(pix->width, + pcdev->current_fmt->host_fmt); + pix->sizeimage = + soc_mbus_image_size(pcdev->current_fmt->host_fmt, + pix->bytesperline, pix->height); + pix->pixelformat = pcdev->current_fmt->host_fmt->fourcc; + v4l2_fill_mbus_format(mf, pix, pcdev->current_fmt->code); + err = sensor_call(pcdev, pad, set_fmt, NULL, &format); + if (err) + goto out; + + v4l2_fill_pix_format(pix, mf); + pr_info("%s(): colorspace=0x%x pixfmt=0x%x\n", + __func__, pix->colorspace, pix->pixelformat); + + err = pxa_camera_init_videobuf2(pcdev); + if (err) + goto out; + + err = video_register_device(&pcdev->vdev, VFL_TYPE_GRABBER, -1); + if (err) { + v4l2_err(v4l2_dev, "register video device failed: %d\n", err); + pcdev->sensor = NULL; + } else { + dev_info(pcdev_to_dev(pcdev), + "PXA Camera driver attached to camera %s\n", + subdev->name); + } +out: + mutex_unlock(&pcdev->mlock); + return err; +} + +static void pxa_camera_sensor_unbind(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct pxa_camera_dev *pcdev = v4l2_dev_to_pcdev(notifier->v4l2_dev); + + mutex_lock(&pcdev->mlock); + dev_info(pcdev_to_dev(pcdev), + "PXA Camera driver detached from camera %s\n", + subdev->name); + + /* disable capture, disable interrupts */ + __raw_writel(0x3ff, pcdev->base + CICR0); + + /* Stop DMA engine */ + pxa_dma_stop_channels(pcdev); + + pxa_camera_destroy_formats(pcdev); + video_unregister_device(&pcdev->vdev); + pcdev->sensor = NULL; + + mutex_unlock(&pcdev->mlock); +} + /* * Driver probe, remove, suspend and resume operations */ static int pxa_camera_suspend(struct device *dev) { - struct soc_camera_host *ici = to_soc_camera_host(dev); - struct pxa_camera_dev *pcdev = ici->priv; + struct pxa_camera_dev *pcdev = dev_get_drvdata(dev); int i = 0, ret = 0; pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR0); @@ -1464,8 +1715,7 @@ static int pxa_camera_suspend(struct device *dev) pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR3); pcdev->save_cicr[i++] = __raw_readl(pcdev->base + CICR4); - if (pcdev->soc_host.icd) { - struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd); + if (pcdev->sensor) { ret = sensor_call(pcdev, core, s_power, 0); if (ret == -ENOIOCTLCMD) ret = 0; @@ -1476,8 +1726,7 @@ static int pxa_camera_suspend(struct device *dev) static int pxa_camera_resume(struct device *dev) { - struct soc_camera_host *ici = to_soc_camera_host(dev); - struct pxa_camera_dev *pcdev = ici->priv; + struct pxa_camera_dev *pcdev = dev_get_drvdata(dev); int i = 0, ret = 0; __raw_writel(pcdev->save_cicr[i++] & ~CICR0_ENB, pcdev->base + CICR0); @@ -1486,8 +1735,7 @@ static int pxa_camera_resume(struct device *dev) __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR3); __raw_writel(pcdev->save_cicr[i++], pcdev->base + CICR4); - if (pcdev->soc_host.icd) { - struct v4l2_subdev *sd = soc_camera_to_subdev(pcdev->soc_host.icd); + if (pcdev->sensor) { ret = sensor_call(pcdev, core, s_power, 1); if (ret == -ENOIOCTLCMD) ret = 0; @@ -1500,27 +1748,12 @@ static int pxa_camera_resume(struct device *dev) return ret; } -static struct soc_camera_host_ops pxa_soc_camera_host_ops = { - .owner = THIS_MODULE, - .add = pxa_camera_add_device, - .remove = pxa_camera_remove_device, - .clock_start = pxa_camera_clock_start, - .clock_stop = pxa_camera_clock_stop, - .get_formats = pxa_camera_get_formats, - .put_formats = pxa_camera_put_formats, - .set_fmt = pxa_camera_set_fmt, - .try_fmt = pxa_camera_try_fmt, - .init_videobuf2 = pxa_camera_init_videobuf2, - .poll = pxa_camera_poll, - .querycap = pxa_camera_querycap, - .set_bus_param = pxa_camera_set_bus_param, -}; - static int pxa_camera_pdata_from_dt(struct device *dev, - struct pxa_camera_dev *pcdev) + struct pxa_camera_dev *pcdev, + struct v4l2_async_subdev *asd) { u32 mclk_rate; - struct device_node *np = dev->of_node; + struct device_node *remote, *np = dev->of_node; struct v4l2_of_endpoint ep; int err = of_property_read_u32(np, "clock-frequency", &mclk_rate); @@ -1531,13 +1764,13 @@ static int pxa_camera_pdata_from_dt(struct device *dev, np = of_graph_get_next_endpoint(np, NULL); if (!np) { - dev_err(pcdev_to_dev(pcdev), "could not find endpoint\n"); + dev_err(dev, "could not find endpoint\n"); return -EINVAL; } err = v4l2_of_parse_endpoint(np, &ep); if (err) { - dev_err(pcdev_to_dev(pcdev), "could not parse endpoint\n"); + dev_err(dev, "could not parse endpoint\n"); goto out; } @@ -1572,6 +1805,15 @@ static int pxa_camera_pdata_from_dt(struct device *dev, if (ep.bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) pcdev->platform_flags |= PXA_CAMERA_PCLK_EN; + asd->match_type = V4L2_ASYNC_MATCH_OF; + remote = of_graph_get_remote_port(np); + if (remote) { + asd->match.of.node = remote; + of_node_put(remote); + } else { + dev_notice(dev, "no remote for %s\n", of_node_full_name(np)); + } + out: of_node_put(np); @@ -1590,6 +1832,7 @@ static int pxa_camera_probe(struct platform_device *pdev) }; dma_cap_mask_t mask; struct pxad_param params; + char clk_name[V4L2_CLK_NAME_SIZE]; int irq; int err = 0, i; @@ -1612,10 +1855,14 @@ static int pxa_camera_probe(struct platform_device *pdev) pcdev->pdata = pdev->dev.platform_data; if (&pdev->dev.of_node && !pcdev->pdata) { - err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev); + err = pxa_camera_pdata_from_dt(&pdev->dev, pcdev, &pcdev->asd); } else { pcdev->platform_flags = pcdev->pdata->flags; pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; + pcdev->asd.match_type = V4L2_ASYNC_MATCH_I2C; + pcdev->asd.match.i2c.adapter_id = + pcdev->pdata->sensor_i2c_adapter_id; + pcdev->asd.match.i2c.address = pcdev->pdata->sensor_i2c_address; } if (err < 0) return err; @@ -1647,6 +1894,7 @@ static int pxa_camera_probe(struct platform_device *pdev) INIT_LIST_HEAD(&pcdev->capture); spin_lock_init(&pcdev->lock); + mutex_init(&pcdev->mlock); /* * Request the regions. @@ -1709,19 +1957,48 @@ static int pxa_camera_probe(struct platform_device *pdev) goto exit_free_dma; } - pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME; - pcdev->soc_host.ops = &pxa_soc_camera_host_ops; - pcdev->soc_host.priv = pcdev; - pcdev->soc_host.v4l2_dev.dev = &pdev->dev; - pcdev->soc_host.nr = pdev->id; tasklet_init(&pcdev->task_eof, pxa_camera_eof, (unsigned long)pcdev); - err = soc_camera_host_register(&pcdev->soc_host); + pxa_camera_activate(pcdev); + + dev_set_drvdata(&pdev->dev, pcdev); + err = v4l2_device_register(&pdev->dev, &pcdev->v4l2_dev); if (err) goto exit_free_dma; - return 0; + pcdev->asds[0] = &pcdev->asd; + pcdev->notifier.subdevs = pcdev->asds; + pcdev->notifier.num_subdevs = 1; + pcdev->notifier.bound = pxa_camera_sensor_bound; + pcdev->notifier.unbind = pxa_camera_sensor_unbind; + + if (!of_have_populated_dt()) + pcdev->asd.match_type = V4L2_ASYNC_MATCH_I2C; + + err = pxa_camera_init_videobuf2(pcdev); + if (err) + goto exit_free_v4l2dev; + if (pcdev->mclk) { + v4l2_clk_name_i2c(clk_name, sizeof(clk_name), + pcdev->asd.match.i2c.adapter_id, + pcdev->asd.match.i2c.address); + + pcdev->mclk_clk = v4l2_clk_register(&pxa_camera_mclk_ops, + clk_name, NULL); + if (IS_ERR(pcdev->mclk_clk)) + return PTR_ERR(pcdev->mclk_clk); + } + + err = v4l2_async_notifier_register(&pcdev->v4l2_dev, &pcdev->notifier); + if (err) + goto exit_free_clk; + + return 0; +exit_free_clk: + v4l2_clk_unregister(pcdev->mclk_clk); +exit_free_v4l2dev: + v4l2_device_unregister(&pcdev->v4l2_dev); exit_free_dma: dma_release_channel(pcdev->dma_chans[2]); exit_free_dma_u: @@ -1733,15 +2010,15 @@ exit_free_dma_y: static int pxa_camera_remove(struct platform_device *pdev) { - struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); - struct pxa_camera_dev *pcdev = container_of(soc_host, - struct pxa_camera_dev, soc_host); + struct pxa_camera_dev *pcdev = dev_get_drvdata(&pdev->dev); + pxa_camera_deactivate(pcdev); dma_release_channel(pcdev->dma_chans[0]); dma_release_channel(pcdev->dma_chans[1]); dma_release_channel(pcdev->dma_chans[2]); - soc_camera_host_unregister(soc_host); + v4l2_clk_unregister(pcdev->mclk_clk); + v4l2_device_unregister(&pcdev->v4l2_dev); dev_info(&pdev->dev, "PXA Camera driver unloaded\n"); diff --git a/include/linux/platform_data/media/camera-pxa.h b/include/linux/platform_data/media/camera-pxa.h index 6709b1cd7c77..ce5d90e1a6e4 100644 --- a/include/linux/platform_data/media/camera-pxa.h +++ b/include/linux/platform_data/media/camera-pxa.h @@ -37,6 +37,8 @@ struct pxacamera_platform_data { unsigned long flags; unsigned long mclk_10khz; + int sensor_i2c_adapter_id; + int sensor_i2c_address; }; extern void pxa_set_camera_info(struct pxacamera_platform_data *); -- cgit v1.2.3-70-g09d2 From cfe41359942b933ee0058c73df7dcc00dae64885 Mon Sep 17 00:00:00 2001 From: Jouni Ukkonen Date: Mon, 25 Apr 2016 09:19:10 -0300 Subject: [media] media: Add 1X14 14-bit raw bayer media bus code definitions The codes will be called: MEDIA_BUS_FMT_SBGGR14_1X14 MEDIA_BUS_FMT_SGBRG14_1X14 MEDIA_BUS_FMT_SGRBG14_1X14 MEDIA_BUS_FMT_SRGGB14_1X14 Signed-off-by: Jouni Ukkonen Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/subdev-formats.rst | 258 +++++++++++++++++++++++- include/uapi/linux/media-bus-format.h | 6 +- 2 files changed, 262 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 568d5dd56561..273ca484983d 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -2812,7 +2812,7 @@ organization is given as an example for the first pixel only. - Code - - - :cspan:`11` Data organization + - :cspan:`13` Data organization - .. row 2 @@ -2820,6 +2820,10 @@ organization is given as an example for the first pixel only. - - Bit + - 13 + + - 12 + - 11 - 10 @@ -2859,6 +2863,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -2890,6 +2898,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -2921,6 +2933,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -2952,6 +2968,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - r\ :sub:`7` - r\ :sub:`6` @@ -2983,6 +3003,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3014,6 +3038,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3045,6 +3073,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3076,6 +3108,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - r\ :sub:`7` - r\ :sub:`6` @@ -3107,6 +3143,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3138,6 +3178,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3169,6 +3213,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3200,6 +3248,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - r\ :sub:`7` - r\ :sub:`6` @@ -3231,6 +3283,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - 0 - 0 @@ -3260,6 +3316,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3291,6 +3351,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3320,6 +3384,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - 0 - 0 @@ -3351,6 +3419,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`9` - b\ :sub:`8` @@ -3380,6 +3452,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`1` - b\ :sub:`0` @@ -3411,6 +3487,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`1` - b\ :sub:`0` @@ -3440,6 +3520,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`9` - b\ :sub:`8` @@ -3467,6 +3551,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - b\ :sub:`9` - b\ :sub:`8` @@ -3498,6 +3586,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`9` - g\ :sub:`8` @@ -3529,6 +3621,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - g\ :sub:`9` - g\ :sub:`8` @@ -3560,6 +3656,10 @@ organization is given as an example for the first pixel only. - + - - + + - - + - r\ :sub:`9` - r\ :sub:`8` @@ -3587,6 +3687,10 @@ organization is given as an example for the first pixel only. - 0x3008 - + - - + + - - + - b\ :sub:`11` - b\ :sub:`10` @@ -3618,6 +3722,10 @@ organization is given as an example for the first pixel only. - 0x3010 - + - - + + - - + - g\ :sub:`11` - g\ :sub:`10` @@ -3649,6 +3757,10 @@ organization is given as an example for the first pixel only. - 0x3011 - + - - + + - - + - g\ :sub:`11` - g\ :sub:`10` @@ -3680,6 +3792,150 @@ organization is given as an example for the first pixel only. - 0x3012 - + - - + + - - + + - r\ :sub:`11` + + - r\ :sub:`10` + + - r\ :sub:`9` + + - r\ :sub:`8` + + - r\ :sub:`7` + + - r\ :sub:`6` + + - r\ :sub:`5` + + - r\ :sub:`4` + + - r\ :sub:`3` + + - r\ :sub:`2` + + - r\ :sub:`1` + + - r\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SBGGR14-1X14: + + - MEDIA_BUS_FMT_SBGGR14_1X14 + + - 0x3019 + + - + - b\ :sub:`13` + + - b\ :sub:`12` + + - b\ :sub:`11` + + - b\ :sub:`10` + + - b\ :sub:`9` + + - b\ :sub:`8` + + - b\ :sub:`7` + + - b\ :sub:`6` + + - b\ :sub:`5` + + - b\ :sub:`4` + + - b\ :sub:`3` + + - b\ :sub:`2` + + - b\ :sub:`1` + + - b\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SGBRG14-1X14: + + - MEDIA_BUS_FMT_SGBRG14_1X14 + + - 0x301a + + - + - g\ :sub:`13` + + - g\ :sub:`12` + + - g\ :sub:`11` + + - g\ :sub:`10` + + - g\ :sub:`9` + + - g\ :sub:`8` + + - g\ :sub:`7` + + - g\ :sub:`6` + + - g\ :sub:`5` + + - g\ :sub:`4` + + - g\ :sub:`3` + + - g\ :sub:`2` + + - g\ :sub:`1` + + - g\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SGRBG14-1X14: + + - MEDIA_BUS_FMT_SGRBG14_1X14 + + - 0x301b + + - + - g\ :sub:`13` + + - g\ :sub:`12` + + - g\ :sub:`11` + + - g\ :sub:`10` + + - g\ :sub:`9` + + - g\ :sub:`8` + + - g\ :sub:`7` + + - g\ :sub:`6` + + - g\ :sub:`5` + + - g\ :sub:`4` + + - g\ :sub:`3` + + - g\ :sub:`2` + + - g\ :sub:`1` + + - g\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SRGGB14-1X14: + + - MEDIA_BUS_FMT_SRGGB14_1X14 + + - 0x301c + + - + - r\ :sub:`13` + + - r\ :sub:`12` + - r\ :sub:`11` - r\ :sub:`10` diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 190d491d5b13..1dff459ab6ff 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -97,7 +97,7 @@ #define MEDIA_BUS_FMT_YUV10_1X30 0x2016 #define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 -/* Bayer - next is 0x3019 */ +/* Bayer - next is 0x301d */ #define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 #define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013 #define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002 @@ -122,6 +122,10 @@ #define MEDIA_BUS_FMT_SGBRG12_1X12 0x3010 #define MEDIA_BUS_FMT_SGRBG12_1X12 0x3011 #define MEDIA_BUS_FMT_SRGGB12_1X12 0x3012 +#define MEDIA_BUS_FMT_SBGGR14_1X14 0x3019 +#define MEDIA_BUS_FMT_SGBRG14_1X14 0x301a +#define MEDIA_BUS_FMT_SGRBG14_1X14 0x301b +#define MEDIA_BUS_FMT_SRGGB14_1X14 0x301c /* JPEG compressed formats - next is 0x4002 */ #define MEDIA_BUS_FMT_JPEG_1X8 0x4001 -- cgit v1.2.3-70-g09d2 From 82dec0a7db16f7691470b58c28e79a2f65e829c4 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Mon, 27 Jun 2016 11:15:57 -0300 Subject: [media] media: Add 1X16 16-bit raw bayer media bus code definitions The codes will be called: MEDIA_BUS_FMT_SBGGR16_1X16 MEDIA_BUS_FMT_SGBRG16_1X16 MEDIA_BUS_FMT_SGRBG16_1X16 MEDIA_BUS_FMT_SRGGB16_1X16 Signed-off-by: Sakari Ailus Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/uapi/v4l/subdev-formats.rst | 290 +++++++++++++++++++++++- include/uapi/linux/media-bus-format.h | 6 +- 2 files changed, 294 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/Documentation/media/uapi/v4l/subdev-formats.rst b/Documentation/media/uapi/v4l/subdev-formats.rst index 273ca484983d..08d6532b0a26 100644 --- a/Documentation/media/uapi/v4l/subdev-formats.rst +++ b/Documentation/media/uapi/v4l/subdev-formats.rst @@ -2812,7 +2812,7 @@ organization is given as an example for the first pixel only. - Code - - - :cspan:`13` Data organization + - :cspan:`15` Data organization - .. row 2 @@ -2820,6 +2820,10 @@ organization is given as an example for the first pixel only. - - Bit + - 15 + + - 14 + - 13 - 12 @@ -2867,6 +2871,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -2902,6 +2910,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -2937,6 +2949,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -2972,6 +2988,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - r\ :sub:`7` - r\ :sub:`6` @@ -3007,6 +3027,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3042,6 +3066,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3077,6 +3105,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3112,6 +3144,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - r\ :sub:`7` - r\ :sub:`6` @@ -3147,6 +3183,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3182,6 +3222,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3217,6 +3261,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`7` - g\ :sub:`6` @@ -3252,6 +3300,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - r\ :sub:`7` - r\ :sub:`6` @@ -3287,6 +3339,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - 0 - 0 @@ -3320,6 +3376,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3355,6 +3415,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`7` - b\ :sub:`6` @@ -3388,6 +3452,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - 0 - 0 @@ -3423,6 +3491,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`9` - b\ :sub:`8` @@ -3456,6 +3528,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`1` - b\ :sub:`0` @@ -3491,6 +3567,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`1` - b\ :sub:`0` @@ -3524,6 +3604,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`9` - b\ :sub:`8` @@ -3555,6 +3639,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`9` - b\ :sub:`8` @@ -3590,6 +3678,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`9` - g\ :sub:`8` @@ -3625,6 +3717,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`9` - g\ :sub:`8` @@ -3660,6 +3756,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - r\ :sub:`9` - r\ :sub:`8` @@ -3691,6 +3791,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - b\ :sub:`11` - b\ :sub:`10` @@ -3726,6 +3830,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`11` - g\ :sub:`10` @@ -3761,6 +3869,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - g\ :sub:`11` - g\ :sub:`10` @@ -3796,6 +3908,10 @@ organization is given as an example for the first pixel only. - - + - - + + - - + - r\ :sub:`11` - r\ :sub:`10` @@ -3827,6 +3943,10 @@ organization is given as an example for the first pixel only. - 0x3019 - + - - + + - - + - b\ :sub:`13` - b\ :sub:`12` @@ -3862,6 +3982,10 @@ organization is given as an example for the first pixel only. - 0x301a - + - - + + - - + - g\ :sub:`13` - g\ :sub:`12` @@ -3897,6 +4021,10 @@ organization is given as an example for the first pixel only. - 0x301b - + - - + + - - + - g\ :sub:`13` - g\ :sub:`12` @@ -3932,6 +4060,166 @@ organization is given as an example for the first pixel only. - 0x301c - + - - + + - - + + - r\ :sub:`13` + + - r\ :sub:`12` + + - r\ :sub:`11` + + - r\ :sub:`10` + + - r\ :sub:`9` + + - r\ :sub:`8` + + - r\ :sub:`7` + + - r\ :sub:`6` + + - r\ :sub:`5` + + - r\ :sub:`4` + + - r\ :sub:`3` + + - r\ :sub:`2` + + - r\ :sub:`1` + + - r\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SBGGR16-1X16: + + - MEDIA_BUS_FMT_SBGGR16_1X16 + + - 0x301d + + - + - b\ :sub:`15` + + - b\ :sub:`14` + + - b\ :sub:`13` + + - b\ :sub:`12` + + - b\ :sub:`11` + + - b\ :sub:`10` + + - b\ :sub:`9` + + - b\ :sub:`8` + + - b\ :sub:`7` + + - b\ :sub:`6` + + - b\ :sub:`5` + + - b\ :sub:`4` + + - b\ :sub:`3` + + - b\ :sub:`2` + + - b\ :sub:`1` + + - b\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SGBRG16-1X16: + + - MEDIA_BUS_FMT_SGBRG16_1X16 + + - 0x301e + + - + - g\ :sub:`15` + + - g\ :sub:`14` + + - g\ :sub:`13` + + - g\ :sub:`12` + + - g\ :sub:`11` + + - g\ :sub:`10` + + - g\ :sub:`9` + + - g\ :sub:`8` + + - g\ :sub:`7` + + - g\ :sub:`6` + + - g\ :sub:`5` + + - g\ :sub:`4` + + - g\ :sub:`3` + + - g\ :sub:`2` + + - g\ :sub:`1` + + - g\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SGRBG16-1X16: + + - MEDIA_BUS_FMT_SGRBG16_1X16 + + - 0x301f + + - + - g\ :sub:`15` + + - g\ :sub:`14` + + - g\ :sub:`13` + + - g\ :sub:`12` + + - g\ :sub:`11` + + - g\ :sub:`10` + + - g\ :sub:`9` + + - g\ :sub:`8` + + - g\ :sub:`7` + + - g\ :sub:`6` + + - g\ :sub:`5` + + - g\ :sub:`4` + + - g\ :sub:`3` + + - g\ :sub:`2` + + - g\ :sub:`1` + + - g\ :sub:`0` + + - .. _MEDIA-BUS-FMT-SRGGB16-1X16: + + - MEDIA_BUS_FMT_SRGGB16_1X16 + + - 0x3020 + + - + - r\ :sub:`15` + + - r\ :sub:`14` + - r\ :sub:`13` - r\ :sub:`12` diff --git a/include/uapi/linux/media-bus-format.h b/include/uapi/linux/media-bus-format.h index 1dff459ab6ff..2168759c1287 100644 --- a/include/uapi/linux/media-bus-format.h +++ b/include/uapi/linux/media-bus-format.h @@ -97,7 +97,7 @@ #define MEDIA_BUS_FMT_YUV10_1X30 0x2016 #define MEDIA_BUS_FMT_AYUV8_1X32 0x2017 -/* Bayer - next is 0x301d */ +/* Bayer - next is 0x3021 */ #define MEDIA_BUS_FMT_SBGGR8_1X8 0x3001 #define MEDIA_BUS_FMT_SGBRG8_1X8 0x3013 #define MEDIA_BUS_FMT_SGRBG8_1X8 0x3002 @@ -126,6 +126,10 @@ #define MEDIA_BUS_FMT_SGBRG14_1X14 0x301a #define MEDIA_BUS_FMT_SGRBG14_1X14 0x301b #define MEDIA_BUS_FMT_SRGGB14_1X14 0x301c +#define MEDIA_BUS_FMT_SBGGR16_1X16 0x301d +#define MEDIA_BUS_FMT_SGBRG16_1X16 0x301e +#define MEDIA_BUS_FMT_SGRBG16_1X16 0x301f +#define MEDIA_BUS_FMT_SRGGB16_1X16 0x3020 /* JPEG compressed formats - next is 0x4002 */ #define MEDIA_BUS_FMT_JPEG_1X8 0x4001 -- cgit v1.2.3-70-g09d2 From 68429f50ab60074e58b98010103fcc5bac4afd54 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 3 Nov 2015 00:27:51 -0200 Subject: [media] media: Move media_device link_notify operation to an ops structure This will allow adding new operations without increasing the media_device structure size for drivers that don't implement any media device operation. Signed-off-by: Laurent Pinchart Signed-off-by: Sakari Ailus Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/media-entity.c | 11 ++++++----- drivers/media/platform/exynos4-is/media-dev.c | 6 +++++- drivers/media/platform/omap3isp/isp.c | 6 +++++- drivers/staging/media/omap4iss/iss.c | 6 +++++- include/media/media-device.h | 16 ++++++++++++---- 5 files changed, 33 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 9014362e904d..c68239e60487 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -808,17 +808,18 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) mdev = source->graph_obj.mdev; - if (mdev->link_notify) { - ret = mdev->link_notify(link, flags, - MEDIA_DEV_NOTIFY_PRE_LINK_CH); + if (mdev->ops && mdev->ops->link_notify) { + ret = mdev->ops->link_notify(link, flags, + MEDIA_DEV_NOTIFY_PRE_LINK_CH); if (ret < 0) return ret; } ret = __media_entity_setup_link_notify(link, flags); - if (mdev->link_notify) - mdev->link_notify(link, flags, MEDIA_DEV_NOTIFY_POST_LINK_CH); + if (mdev->ops && mdev->ops->link_notify) + mdev->ops->link_notify(link, flags, + MEDIA_DEV_NOTIFY_POST_LINK_CH); return ret; } diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 891625e77ef5..1a1154a9dfa4 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1190,6 +1190,10 @@ static int fimc_md_link_notify(struct media_link *link, unsigned int flags, return ret ? -EPIPE : 0; } +static const struct media_device_ops fimc_md_ops = { + .link_notify = fimc_md_link_notify, +}; + static ssize_t fimc_md_sysfs_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1416,7 +1420,7 @@ static int fimc_md_probe(struct platform_device *pdev) strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", sizeof(fmd->media_dev.model)); - fmd->media_dev.link_notify = fimc_md_link_notify; + fmd->media_dev.ops = &fimc_md_ops; fmd->media_dev.dev = dev; v4l2_dev = &fmd->v4l2_dev; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 5d54e2c6c16b..0321d84addc7 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -657,6 +657,10 @@ static irqreturn_t isp_isr(int irq, void *_isp) return IRQ_HANDLED; } +static const struct media_device_ops isp_media_ops = { + .link_notify = v4l2_pipeline_link_notify, +}; + /* ----------------------------------------------------------------------------- * Pipeline stream management */ @@ -1680,7 +1684,7 @@ static int isp_register_entities(struct isp_device *isp) strlcpy(isp->media_dev.model, "TI OMAP3 ISP", sizeof(isp->media_dev.model)); isp->media_dev.hw_revision = isp->revision; - isp->media_dev.link_notify = v4l2_pipeline_link_notify; + isp->media_dev.ops = &isp_media_ops; media_device_init(&isp->media_dev); isp->v4l2_dev.mdev = &isp->media_dev; diff --git a/drivers/staging/media/omap4iss/iss.c b/drivers/staging/media/omap4iss/iss.c index 6ceb4eb00493..ffc4900da961 100644 --- a/drivers/staging/media/omap4iss/iss.c +++ b/drivers/staging/media/omap4iss/iss.c @@ -362,6 +362,10 @@ static irqreturn_t iss_isr(int irq, void *_iss) return IRQ_HANDLED; } +static const struct media_device_ops iss_media_ops = { + .link_notify = v4l2_pipeline_link_notify, +}; + /* ----------------------------------------------------------------------------- * Pipeline stream management */ @@ -988,7 +992,7 @@ static int iss_register_entities(struct iss_device *iss) strlcpy(iss->media_dev.model, "TI OMAP4 ISS", sizeof(iss->media_dev.model)); iss->media_dev.hw_revision = iss->revision; - iss->media_dev.link_notify = v4l2_pipeline_link_notify; + iss->media_dev.ops = &iss_media_ops; ret = media_device_register(&iss->media_dev); if (ret < 0) { dev_err(iss->dev, "Media device registration failed (%d)\n", diff --git a/include/media/media-device.h b/include/media/media-device.h index 481dd6c672cb..ef93e21335df 100644 --- a/include/media/media-device.h +++ b/include/media/media-device.h @@ -48,6 +48,16 @@ struct media_entity_notify { void (*notify)(struct media_entity *entity, void *notify_data); }; +/** + * struct media_device_ops - Media device operations + * @link_notify: Link state change notification callback. This callback is + * called with the graph_mutex held. + */ +struct media_device_ops { + int (*link_notify)(struct media_link *link, u32 flags, + unsigned int notification); +}; + /** * struct media_device - Media device * @dev: Parent device @@ -80,8 +90,7 @@ struct media_entity_notify { * @enable_source: Enable Source Handler function pointer * @disable_source: Disable Source Handler function pointer * - * @link_notify: Link state change notification callback. This callback is - * called with the graph_mutex held. + * @ops: Operation handler callbacks * * This structure represents an abstract high-level media device. It allows easy * access to entities and provides basic media device-level support. The @@ -150,8 +159,7 @@ struct media_device { struct media_pipeline *pipe); void (*disable_source)(struct media_entity *entity); - int (*link_notify)(struct media_link *link, u32 flags, - unsigned int notification); + const struct media_device_ops *ops; }; /* We don't need to include pci.h or usb.h here */ -- cgit v1.2.3-70-g09d2 From fd44aa9a254b18176ec3792a18e7de6977030ca8 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 17 Aug 2016 09:57:37 -0300 Subject: [media] v4l: rcar-fcp: Don't force users to check for disabled FCP support The rcar_fcp_enable() function immediately returns successfully when the FCP device pointer is NULL to avoid forcing the users to check the FCP device manually before every call. However, the stub version of the function used when the FCP driver is disabled returns -ENOSYS unconditionally, resulting in a different API contract for the two versions of the function. As a user that requires FCP support will fail at probe time when calling rcar_fcp_get() if the FCP driver is disabled, the stub version of the rcar_fcp_enable() function will only be called with a NULL FCP device. We can thus return 0 unconditionally to align the behaviour with the normal version of the function. Reported-by: Sergei Shtylyov Signed-off-by: Laurent Pinchart Reviewed-by: Geert Uytterhoeven Signed-off-by: Mauro Carvalho Chehab --- include/media/rcar-fcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h index 4c7fc77eaf29..8723f05c6321 100644 --- a/include/media/rcar-fcp.h +++ b/include/media/rcar-fcp.h @@ -29,7 +29,7 @@ static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np) static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { } static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp) { - return -ENOSYS; + return 0; } static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { } #endif -- cgit v1.2.3-70-g09d2 From bffba4737bf39542c4cb4d276f4bf18cfa0ffa21 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Aug 2016 10:16:17 -0300 Subject: [media] v4l: vsp1: Fix tri-planar format support through DRM API The vsp1 driver supports tri-planar formats, but the DRM API only passes two memory addresses. Add a third one. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- drivers/media/platform/vsp1/vsp1_drm.c | 6 +++--- include/media/vsp1.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/media/platform/vsp1/vsp1_drm.c b/drivers/media/platform/vsp1/vsp1_drm.c index fe9665e57b3b..06972f612263 100644 --- a/drivers/media/platform/vsp1/vsp1_drm.c +++ b/drivers/media/platform/vsp1/vsp1_drm.c @@ -276,12 +276,12 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index, } dev_dbg(vsp1->dev, - "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad } zpos %u\n", + "%s: RPF%u: (%u,%u)/%ux%u -> (%u,%u)/%ux%u (%08x), pitch %u dma { %pad, %pad, %pad } zpos %u\n", __func__, rpf_index, cfg->src.left, cfg->src.top, cfg->src.width, cfg->src.height, cfg->dst.left, cfg->dst.top, cfg->dst.width, cfg->dst.height, cfg->pixelformat, cfg->pitch, &cfg->mem[0], &cfg->mem[1], - cfg->zpos); + &cfg->mem[2], cfg->zpos); /* Store the format, stride, memory buffer address, crop and compose * rectangles and Z-order position and for the input. @@ -301,7 +301,7 @@ int vsp1_du_atomic_update(struct device *dev, unsigned int rpf_index, rpf->mem.addr[0] = cfg->mem[0]; rpf->mem.addr[1] = cfg->mem[1]; - rpf->mem.addr[2] = 0; + rpf->mem.addr[2] = cfg->mem[2]; vsp1->drm->inputs[rpf_index].crop = cfg->src; vsp1->drm->inputs[rpf_index].compose = cfg->dst; diff --git a/include/media/vsp1.h b/include/media/vsp1.h index 9322d9775fb7..458b400373d4 100644 --- a/include/media/vsp1.h +++ b/include/media/vsp1.h @@ -26,7 +26,7 @@ int vsp1_du_setup_lif(struct device *dev, unsigned int width, struct vsp1_du_atomic_config { u32 pixelformat; unsigned int pitch; - dma_addr_t mem[2]; + dma_addr_t mem[3]; struct v4l2_rect src; struct v4l2_rect dst; unsigned int alpha; -- cgit v1.2.3-70-g09d2 From 7389e6ef347443ac90116c2208bbdfb4f9d135ba Mon Sep 17 00:00:00 2001 From: Charles-Antoine Couret Date: Thu, 15 Sep 2016 12:29:50 -0300 Subject: [media] SDI: add flag for SDI formats and SMPTE 125M definition Adding others generic flags, which could be used by many components like GS1662. Signed-off-by: Charles-Antoine Couret Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/v4l2-core/v4l2-dv-timings.c | 11 +++++++---- include/uapi/linux/v4l2-dv-timings.h | 12 ++++++++++++ include/uapi/linux/videodev2.h | 8 ++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/media/v4l2-core/v4l2-dv-timings.c b/drivers/media/v4l2-core/v4l2-dv-timings.c index 889de0a32152..730a7c392c1d 100644 --- a/drivers/media/v4l2-core/v4l2-dv-timings.c +++ b/drivers/media/v4l2-core/v4l2-dv-timings.c @@ -306,7 +306,7 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, (bt->polarities & V4L2_DV_VSYNC_POS_POL) ? "+" : "-", bt->il_vsync, bt->il_vbackporch); pr_info("%s: pixelclock: %llu\n", dev_prefix, bt->pixelclock); - pr_info("%s: flags (0x%x):%s%s%s%s%s%s\n", dev_prefix, bt->flags, + pr_info("%s: flags (0x%x):%s%s%s%s%s%s%s\n", dev_prefix, bt->flags, (bt->flags & V4L2_DV_FL_REDUCED_BLANKING) ? " REDUCED_BLANKING" : "", ((bt->flags & V4L2_DV_FL_REDUCED_BLANKING) && @@ -318,12 +318,15 @@ void v4l2_print_dv_timings(const char *dev_prefix, const char *prefix, (bt->flags & V4L2_DV_FL_HALF_LINE) ? " HALF_LINE" : "", (bt->flags & V4L2_DV_FL_IS_CE_VIDEO) ? - " CE_VIDEO" : ""); - pr_info("%s: standards (0x%x):%s%s%s%s\n", dev_prefix, bt->standards, + " CE_VIDEO" : "", + (bt->flags & V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE) ? + " FIRST_FIELD_EXTRA_LINE" : ""); + pr_info("%s: standards (0x%x):%s%s%s%s%s\n", dev_prefix, bt->standards, (bt->standards & V4L2_DV_BT_STD_CEA861) ? " CEA" : "", (bt->standards & V4L2_DV_BT_STD_DMT) ? " DMT" : "", (bt->standards & V4L2_DV_BT_STD_CVT) ? " CVT" : "", - (bt->standards & V4L2_DV_BT_STD_GTF) ? " GTF" : ""); + (bt->standards & V4L2_DV_BT_STD_GTF) ? " GTF" : "", + (bt->standards & V4L2_DV_BT_STD_SDI) ? " SDI" : ""); } EXPORT_SYMBOL_GPL(v4l2_print_dv_timings); diff --git a/include/uapi/linux/v4l2-dv-timings.h b/include/uapi/linux/v4l2-dv-timings.h index 086168e18ca8..f31957166337 100644 --- a/include/uapi/linux/v4l2-dv-timings.h +++ b/include/uapi/linux/v4l2-dv-timings.h @@ -934,4 +934,16 @@ V4L2_DV_FL_REDUCED_BLANKING) \ } +/* SDI timings definitions */ + +/* SMPTE-125M */ +#define V4L2_DV_BT_SDI_720X487I60 { \ + .type = V4L2_DV_BT_656_1120, \ + V4L2_INIT_BT_TIMINGS(720, 487, 1, \ + V4L2_DV_HSYNC_POS_POL, \ + 13500000, 16, 121, 0, 0, 19, 0, 0, 19, 0, \ + V4L2_DV_BT_STD_SDI, \ + V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE) \ +} + #endif diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h index 5529741202b5..94f123f3e04e 100644 --- a/include/uapi/linux/videodev2.h +++ b/include/uapi/linux/videodev2.h @@ -1274,6 +1274,7 @@ struct v4l2_bt_timings { #define V4L2_DV_BT_STD_DMT (1 << 1) /* VESA Discrete Monitor Timings */ #define V4L2_DV_BT_STD_CVT (1 << 2) /* VESA Coordinated Video Timings */ #define V4L2_DV_BT_STD_GTF (1 << 3) /* VESA Generalized Timings Formula */ +#define V4L2_DV_BT_STD_SDI (1 << 4) /* SDI Timings */ /* Flags */ @@ -1305,6 +1306,11 @@ struct v4l2_bt_timings { * use the range 16-235) as opposed to 0-255. All formats defined in CEA-861 * except for the 640x480 format are CE formats. */ #define V4L2_DV_FL_IS_CE_VIDEO (1 << 4) +/* Some formats like SMPTE-125M have an interlaced signal with a odd + * total height. For these formats, if this flag is set, the first + * field has the extra line. If not, it is the second field. + */ +#define V4L2_DV_FL_FIRST_FIELD_EXTRA_LINE (1 << 5) /* A few useful defines to calculate the total blanking and frame sizes */ #define V4L2_DV_BT_BLANKING_WIDTH(bt) \ @@ -1429,6 +1435,8 @@ struct v4l2_input { /* field 'status' - analog */ #define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */ #define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */ +#define V4L2_IN_ST_NO_V_LOCK 0x00000400 /* No vertical sync lock */ +#define V4L2_IN_ST_NO_STD_LOCK 0x00000800 /* No standard format lock */ /* field 'status' - digital */ #define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */ -- cgit v1.2.3-70-g09d2 From e383ce0736f5ce74bbc0e989c6d044e29fefb9dc Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 22 Sep 2016 07:59:03 -0300 Subject: [media] get rid of a number of problems at the cross references As warned by linuxdoc[1] tool, using: $ for i in $(git grep kernel-doc Documentation/media/kapi/|cut -d: -f4); do kernel-lintdoc --sloppy $i; done include/media/v4l2-dev.h:118 :WARN: function name from comment differs: v4l2_prio_close <--> v4l2_prio_check include/media/v4l2-mc.h:56 [kernel-doc WARN] : enum name from comment differs: if_vid_dec_index <--> if_vid_dec_pad_index include/media/v4l2-mc.h:71 [kernel-doc WARN] : enum name from comment differs: if_aud_dec_index <--> if_aud_dec_pad_index include/media/v4l2-mem2mem.h:396 [kernel-doc WARN] : function name from comment differs: v4l2_m2m_num_src_bufs_ready <--> v4l2_m2m_num_dst_bufs_ready drivers/media/dvb-core/dvb_math.h:28 [kernel-doc WARN] : function name from comment differs: cintlog2 <--> intlog2 include/media/v4l2-subdev.h:215 [kernel-doc WARN] : struct name from comment differs: s_radio <--> v4l2_subdev_tuner_ops include/media/v4l2-subdev.h:890 [kernel-doc WARN] : function name from comment differs: v4l2_set_subdevdata <--> v4l2_set_subdev_hostdata include/media/v4l2-subdev.h:901 [kernel-doc WARN] : function name from comment differs: v4l2_get_subdevdata <--> v4l2_get_subdev_hostdata drivers/media/dvb-core/dvb_ringbuffer.h:196 [kernel-doc WARN] : function name from comment differs: dvb_ringbuffer_writeuser <--> dvb_ringbuffer_write_user include/media/videobuf2-core.h:399 [kernel-doc WARN] : struct name from comment differs: vb2_ops <--> vb2_buf_ops include/media/media-entity.h:132 [kernel-doc ERROR] : duplicate parameter definition 'source' include/media/media-entity.h:477 [kernel-doc WARN] : function name from comment differs: media_entity_enum_test <--> media_entity_enum_test_and_set include/media/media-entity.h:535 [kernel-doc WARN] : function name from comment differs: gobj_to_entity <--> gobj_to_pad include/media/media-entity.h:544 [kernel-doc WARN] : function name from comment differs: gobj_to_entity <--> gobj_to_link include/media/media-entity.h:553 [kernel-doc WARN] : function name from comment differs: gobj_to_entity <--> gobj_to_intf include/media/media-entity.h:562 [kernel-doc WARN] : function name from comment differs: gobj_to_entity <--> intf_to_devnode include/media/rc-core.h:234 [kernel-doc WARN] : function name from comment differs: rc_open <--> rc_close include/media/v4l2-ctrls.h:397 [kernel-doc WARN] : missing initial short description of 'v4l2_ctrl_handler_init' include/media/v4l2-dev.h:118 [kernel-doc WARN] : function name from comment differs: v4l2_prio_close <--> v4l2_prio_check include/media/v4l2-event.h:225 [kernel-doc WARN] : missing initial short description of 'v4l2_src_change_event_subscribe' [1] https://return42.github.io/linuxdoc/linux.html The above are real issues at the documentation. On several cases, caused by cut-and-paste. Fix them. Signed-off-by: Mauro Carvalho Chehab --- Documentation/media/kapi/v4l2-dev.rst | 2 +- drivers/media/dvb-core/dvb_math.h | 2 +- drivers/media/dvb-core/dvb_ringbuffer.h | 2 +- include/media/media-entity.h | 13 +++++++------ include/media/rc-core.h | 2 +- include/media/v4l2-ctrls.h | 3 ++- include/media/v4l2-dev.h | 2 +- include/media/v4l2-event.h | 3 ++- include/media/v4l2-mc.h | 4 ++-- include/media/v4l2-mem2mem.h | 2 +- include/media/v4l2-subdev.h | 7 ++++--- include/media/videobuf2-core.h | 2 +- 12 files changed, 24 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/Documentation/media/kapi/v4l2-dev.rst b/Documentation/media/kapi/v4l2-dev.rst index 0a3b4503a89f..b29aa616c267 100644 --- a/Documentation/media/kapi/v4l2-dev.rst +++ b/Documentation/media/kapi/v4l2-dev.rst @@ -173,7 +173,7 @@ The implementation of a hotplug disconnect should also take the lock from using :c:type:`video_device`->queue->lock, then you have to first lock :c:type:`video_device`->queue->lock followed by :c:type:`video_device`->lock. That way you can be sure no ioctl is running when you call -:c:type:`v4l2_device_disconnect`. +:c:func:`v4l2_device_disconnect`. Video device registration ------------------------- diff --git a/drivers/media/dvb-core/dvb_math.h b/drivers/media/dvb-core/dvb_math.h index 2f0326674ca6..4d11d3529c14 100644 --- a/drivers/media/dvb-core/dvb_math.h +++ b/drivers/media/dvb-core/dvb_math.h @@ -25,7 +25,7 @@ #include /** - * cintlog2 - computes log2 of a value; the result is shifted left by 24 bits + * intlog2 - computes log2 of a value; the result is shifted left by 24 bits * * @value: The value (must be != 0) * diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h index eae3f091b6a0..bbe94873d44d 100644 --- a/drivers/media/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb-core/dvb_ringbuffer.h @@ -193,7 +193,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len); /** - * dvb_ringbuffer_writeuser - Writes a buffer received via an user pointer + * dvb_ringbuffer_write_user - Writes a buffer received via an user pointer * * @rbuf: pointer to struct dvb_ringbuffer * @buf: pointer to the buffer where the data will be read diff --git a/include/media/media-entity.h b/include/media/media-entity.h index e21958c7c5d9..b2203ee7a4c1 100644 --- a/include/media/media-entity.h +++ b/include/media/media-entity.h @@ -129,7 +129,7 @@ struct media_pipeline { * an interface. * @gobj1: Part of a union. Used to get the pointer for the second * graph_object of the link. - * @source: Part of a union. Used only if the second object (gobj1) is + * @sink: Part of a union. Used only if the second object (gobj1) is * a pad. In that case, it represents the sink pad. * @entity: Part of a union. Used only if the second object (gobj1) is * an entity. @@ -474,7 +474,8 @@ static inline bool media_entity_enum_test(struct media_entity_enum *ent_enum, } /** - * media_entity_enum_test - Test whether the entity is marked, and mark it + * media_entity_enum_test_and_set - Test whether the entity is marked, + * and mark it * * @ent_enum: Entity enumeration * @entity: Entity to be tested @@ -532,7 +533,7 @@ static inline bool media_entity_enum_intersects( container_of(gobj, struct media_entity, graph_obj) /** - * gobj_to_entity - returns the struct &media_pad pointer from the + * gobj_to_pad - returns the struct &media_pad pointer from the * @gobj contained on it. * * @gobj: Pointer to the struct &media_gobj graph object @@ -541,7 +542,7 @@ static inline bool media_entity_enum_intersects( container_of(gobj, struct media_pad, graph_obj) /** - * gobj_to_entity - returns the struct &media_link pointer from the + * gobj_to_link - returns the struct &media_link pointer from the * @gobj contained on it. * * @gobj: Pointer to the struct &media_gobj graph object @@ -550,7 +551,7 @@ static inline bool media_entity_enum_intersects( container_of(gobj, struct media_link, graph_obj) /** - * gobj_to_entity - returns the struct &media_interface pointer from the + * gobj_to_intf - returns the struct &media_interface pointer from the * @gobj contained on it. * * @gobj: Pointer to the struct &media_gobj graph object @@ -559,7 +560,7 @@ static inline bool media_entity_enum_intersects( container_of(gobj, struct media_interface, graph_obj) /** - * gobj_to_entity - returns the struct media_intf_devnode pointer from the + * intf_to_devnode - returns the struct media_intf_devnode pointer from the * @intf contained on it. * * @intf: Pointer to struct &media_intf_devnode diff --git a/include/media/rc-core.h b/include/media/rc-core.h index 10908e356b23..40188d362486 100644 --- a/include/media/rc-core.h +++ b/include/media/rc-core.h @@ -231,7 +231,7 @@ void rc_unregister_device(struct rc_dev *dev); int rc_open(struct rc_dev *rdev); /** - * rc_open - Closes a RC device + * rc_close - Closes a RC device * * @rdev: pointer to struct rc_dev. */ diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index beea0a2c0894..e1006b391cdc 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -394,7 +394,8 @@ int v4l2_ctrl_handler_init_class(struct v4l2_ctrl_handler *hdl, #ifdef CONFIG_LOCKDEP /** - * v4l2_ctrl_handler_init - + * v4l2_ctrl_handler_init - helper function to create a static struct + * &lock_class_key and calls v4l2_ctrl_handler_init_class() * * @hdl: The control handler. * @nr_of_controls_hint: A hint of how many controls this handler is diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index 477e90d89a04..e657614521e3 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -115,7 +115,7 @@ void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local); enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global); /** - * v4l2_prio_close - Implements the priority logic for a file handler close + * v4l2_prio_check - Implements the priority logic for a file handler close * * @global: pointer to the &struct v4l2_prio_state of the device node. * @local: desired priority, as defined by enum &v4l2_priority local diff --git a/include/media/v4l2-event.h b/include/media/v4l2-event.h index ca854203b8b9..a700285c64a9 100644 --- a/include/media/v4l2-event.h +++ b/include/media/v4l2-event.h @@ -222,7 +222,8 @@ int v4l2_event_subdev_unsubscribe(struct v4l2_subdev *sd, struct v4l2_fh *fh, struct v4l2_event_subscription *sub); /** - * v4l2_src_change_event_subscribe - + * v4l2_src_change_event_subscribe - helper function that calls + * v4l2_event_subscribe() if the event is %V4L2_EVENT_SOURCE_CHANGE. * * @fh: pointer to struct v4l2_fh * @sub: pointer to &struct v4l2_event_subscription diff --git a/include/media/v4l2-mc.h b/include/media/v4l2-mc.h index 28c3f9d9c209..2634d9dc9916 100644 --- a/include/media/v4l2-mc.h +++ b/include/media/v4l2-mc.h @@ -53,7 +53,7 @@ enum tuner_pad_index { }; /** - * enum if_vid_dec_index - video IF-PLL pad index for + * enum if_vid_dec_pad_index - video IF-PLL pad index for * MEDIA_ENT_F_IF_VID_DECODER * * @IF_VID_DEC_PAD_IF_INPUT: video Intermediate Frequency (IF) sink pad @@ -68,7 +68,7 @@ enum if_vid_dec_pad_index { }; /** - * enum if_aud_dec_index - audio/sound IF-PLL pad index for + * enum if_aud_dec_pad_index - audio/sound IF-PLL pad index for * MEDIA_ENT_F_IF_AUD_DECODER * * @IF_AUD_DEC_PAD_IF_INPUT: audio Intermediate Frequency (IF) sink pad diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h index 498c99baf8ac..1b355344c804 100644 --- a/include/media/v4l2-mem2mem.h +++ b/include/media/v4l2-mem2mem.h @@ -393,7 +393,7 @@ unsigned int v4l2_m2m_num_src_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx) } /** - * v4l2_m2m_num_src_bufs_ready() - return the number of destination buffers + * v4l2_m2m_num_dst_bufs_ready() - return the number of destination buffers * ready for use * * @m2m_ctx: m2m context assigned to the instance given by struct &v4l2_m2m_ctx diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 863f92600607..cf778c5dca18 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -212,7 +212,8 @@ struct v4l2_subdev_core_ops { }; /** - * struct s_radio - Callbacks used when v4l device was opened in radio mode. + * struct v4l2_subdev_tuner_ops - Callbacks used when v4l device was opened + * in radio mode. * * @s_radio: callback for %VIDIOC_S_RADIO ioctl handler code. * @@ -887,7 +888,7 @@ static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) } /** - * v4l2_set_subdevdata - Sets V4L2 dev private host data + * v4l2_set_subdev_hostdata - Sets V4L2 dev private host data * * @sd: pointer to &struct v4l2_subdev * @p: pointer to the private data to be stored. @@ -898,7 +899,7 @@ static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p) } /** - * v4l2_get_subdevdata - Gets V4L2 dev private data + * v4l2_get_subdev_hostdata - Gets V4L2 dev private data * * @sd: pointer to &struct v4l2_subdev * diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h index 9a144f2d9083..ac5898a55fd9 100644 --- a/include/media/videobuf2-core.h +++ b/include/media/videobuf2-core.h @@ -396,7 +396,7 @@ struct vb2_ops { }; /** - * struct vb2_ops - driver-specific callbacks + * struct vb2_buf_ops - driver-specific callbacks * * @verify_planes_array: Verify that a given user space structure contains * enough planes for the buffer. This is called -- cgit v1.2.3-70-g09d2 From 2ceeca0499d745213306ecd785af17adb2321b6a Mon Sep 17 00:00:00 2001 From: Sean Young Date: Wed, 21 Sep 2016 06:54:19 -0300 Subject: [media] rc: split nec protocol into its three variants Currently we do not know what variant (bit length) of the nec protocol is used, other than from guessing from the length of the scancode. Now nec will be handled the same way as the sony protocol or the rc6 protocol; one variant per bit length. In the future we might want to expose the rc protocol type to userspace and we don't want to be introducing this world of pain into userspace too. Signed-off-by: Sean Young Signed-off-by: Mauro Carvalho Chehab --- drivers/media/pci/cx23885/cx23885-input.c | 2 +- drivers/media/pci/cx88/cx88-input.c | 5 +++-- drivers/media/pci/saa7134/saa7134-input.c | 4 ++-- drivers/media/rc/igorplugusb.c | 3 ++- drivers/media/rc/img-ir/img-ir-nec.c | 6 ++++-- drivers/media/rc/ir-nec-decoder.c | 8 ++++++-- drivers/media/rc/rc-main.c | 4 +++- drivers/media/usb/au0828/au0828-input.c | 3 ++- drivers/media/usb/dvb-usb-v2/af9015.c | 8 ++++++-- drivers/media/usb/dvb-usb-v2/af9035.c | 9 +++++++-- drivers/media/usb/dvb-usb-v2/az6007.c | 13 +++++++++---- drivers/media/usb/dvb-usb-v2/lmedm04.c | 5 +++-- drivers/media/usb/dvb-usb-v2/rtl28xxu.c | 9 +++++++-- drivers/media/usb/dvb-usb/dib0700_core.c | 4 +++- drivers/media/usb/dvb-usb/dtt200u.c | 5 ++++- include/media/rc-map.h | 31 +++++++++++++++++++------------ 16 files changed, 81 insertions(+), 38 deletions(-) (limited to 'include') diff --git a/drivers/media/pci/cx23885/cx23885-input.c b/drivers/media/pci/cx23885/cx23885-input.c index 64328d08ac2f..410c3141c163 100644 --- a/drivers/media/pci/cx23885/cx23885-input.c +++ b/drivers/media/pci/cx23885/cx23885-input.c @@ -293,7 +293,7 @@ int cx23885_input_init(struct cx23885_dev *dev) case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: /* Integrated CX23885 IR controller */ driver_type = RC_DRIVER_IR_RAW; - allowed_protos = RC_BIT_NEC; + allowed_protos = RC_BIT_ALL; /* The grey Terratec remote with orange buttons */ rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS; break; diff --git a/drivers/media/pci/cx88/cx88-input.c b/drivers/media/pci/cx88/cx88-input.c index 21d029b2bbb3..cd7687183381 100644 --- a/drivers/media/pci/cx88/cx88-input.c +++ b/drivers/media/pci/cx88/cx88-input.c @@ -144,7 +144,8 @@ static void cx88_ir_handle_key(struct cx88_IR *ir) scancode = RC_SCANCODE_NECX(addr, cmd); if (0 == (gpio & ir->mask_keyup)) - rc_keydown_notimeout(ir->dev, RC_TYPE_NEC, scancode, 0); + rc_keydown_notimeout(ir->dev, RC_TYPE_NECX, scancode, + 0); else rc_keyup(ir->dev); @@ -345,7 +346,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) * 002-T mini RC, provided with newer PV hardware */ ir_codes = RC_MAP_PIXELVIEW_MK12; - rc_type = RC_BIT_NEC; + rc_type = RC_BIT_NECX; ir->gpio_addr = MO_GP1_IO; ir->mask_keyup = 0x80; ir->polling = 10; /* ms */ diff --git a/drivers/media/pci/saa7134/saa7134-input.c b/drivers/media/pci/saa7134/saa7134-input.c index c8042c3888cd..eff52bbbfd66 100644 --- a/drivers/media/pci/saa7134/saa7134-input.c +++ b/drivers/media/pci/saa7134/saa7134-input.c @@ -345,7 +345,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, enum rc_type *protocol, if (data[9] != (unsigned char)(~data[8])) return 0; - *protocol = RC_TYPE_NEC; + *protocol = RC_TYPE_NECX; *scancode = RC_SCANCODE_NECX(data[11] << 8 | data[10], data[9]); *toggle = 0; return 1; @@ -1035,7 +1035,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev) dev->init_data.name = "BeholdTV"; dev->init_data.get_key = get_key_beholdm6xx; dev->init_data.ir_codes = RC_MAP_BEHOLD; - dev->init_data.type = RC_BIT_NEC; + dev->init_data.type = RC_BIT_NECX; info.addr = 0x2d; break; case SAA7134_BOARD_AVERMEDIA_CARDBUS_501: diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c index e0c531fa01da..5cf983be07a2 100644 --- a/drivers/media/rc/igorplugusb.c +++ b/drivers/media/rc/igorplugusb.c @@ -203,7 +203,8 @@ static int igorplugusb_probe(struct usb_interface *intf, * This device can only store 36 pulses + spaces, which is not enough * for the NEC protocol and many others. */ - rc->allowed_protocols = RC_BIT_ALL & ~(RC_BIT_NEC | RC_BIT_RC6_6A_20 | + rc->allowed_protocols = RC_BIT_ALL & ~(RC_BIT_NEC | RC_BIT_NECX | + RC_BIT_NEC32 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SONY20 | RC_BIT_MCE_KBD | RC_BIT_SANYO); diff --git a/drivers/media/rc/img-ir/img-ir-nec.c b/drivers/media/rc/img-ir/img-ir-nec.c index 27a7ea8f1260..09314933ea08 100644 --- a/drivers/media/rc/img-ir/img-ir-nec.c +++ b/drivers/media/rc/img-ir/img-ir-nec.c @@ -34,19 +34,21 @@ static int img_ir_nec_scancode(int len, u64 raw, u64 enabled_protocols, bitrev8(addr_inv) << 16 | bitrev8(data) << 8 | bitrev8(data_inv); + request->protocol = RC_TYPE_NEC32; } else if ((addr_inv ^ addr) != 0xff) { /* Extended NEC */ /* scan encoding: AAaaDD */ request->scancode = addr << 16 | addr_inv << 8 | data; + request->protocol = RC_TYPE_NECX; } else { /* Normal NEC */ /* scan encoding: AADD */ request->scancode = addr << 8 | data; + request->protocol = RC_TYPE_NEC; } - request->protocol = RC_TYPE_NEC; return IMG_IR_SCANCODE; } @@ -109,7 +111,7 @@ static int img_ir_nec_filter(const struct rc_scancode_filter *in, * http://wiki.altium.com/display/ADOH/NEC+Infrared+Transmission+Protocol */ struct img_ir_decoder img_ir_nec = { - .type = RC_BIT_NEC, + .type = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32, .control = { .decoden = 1, .code_type = IMG_IR_CODETYPE_PULSEDIST, diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c index bea0d1eedee0..2a9d155548ab 100644 --- a/drivers/media/rc/ir-nec-decoder.c +++ b/drivers/media/rc/ir-nec-decoder.c @@ -49,6 +49,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) { struct nec_dec *data = &dev->raw->nec; u32 scancode; + enum rc_type rc_type; u8 address, not_address, command, not_command; bool send_32bits = false; @@ -171,22 +172,25 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) * least Apple and TiVo remotes */ scancode = data->bits; IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode); + rc_type = RC_TYPE_NEC32; } else if ((address ^ not_address) != 0xff) { /* Extended NEC */ scancode = address << 16 | not_address << 8 | command; IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); + rc_type = RC_TYPE_NECX; } else { /* Normal NEC */ scancode = address << 8 | command; IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); + rc_type = RC_TYPE_NEC; } if (data->is_nec_x) data->necx_repeat = true; - rc_keydown(dev, RC_TYPE_NEC, scancode, 0); + rc_keydown(dev, rc_type, scancode, 0); data->state = STATE_INACTIVE; return 0; } @@ -198,7 +202,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev) } static struct ir_raw_handler nec_handler = { - .protocols = RC_BIT_NEC, + .protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32, .decode = ir_nec_decode, }; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index 26fd63bdf8e8..d9c1f2ff7119 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -795,7 +795,9 @@ static const struct { { RC_BIT_UNKNOWN, "unknown", NULL }, { RC_BIT_RC5 | RC_BIT_RC5X, "rc-5", "ir-rc5-decoder" }, - { RC_BIT_NEC, "nec", "ir-nec-decoder" }, + { RC_BIT_NEC | + RC_BIT_NECX | + RC_BIT_NEC32, "nec", "ir-nec-decoder" }, { RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | diff --git a/drivers/media/usb/au0828/au0828-input.c b/drivers/media/usb/au0828/au0828-input.c index 3d6687f0407d..1e66e7828d8f 100644 --- a/drivers/media/usb/au0828/au0828-input.c +++ b/drivers/media/usb/au0828/au0828-input.c @@ -344,7 +344,8 @@ int au0828_rc_register(struct au0828_dev *dev) rc->dev.parent = &dev->usbdev->dev; rc->driver_name = "au0828-input"; rc->driver_type = RC_DRIVER_IR_RAW; - rc->allowed_protocols = RC_BIT_NEC | RC_BIT_RC5; + rc->allowed_protocols = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | + RC_BIT_RC5; /* all done */ err = rc_register_device(rc); diff --git a/drivers/media/usb/dvb-usb-v2/af9015.c b/drivers/media/usb/dvb-usb-v2/af9015.c index 09e0f58f6bb7..941ceff9b268 100644 --- a/drivers/media/usb/dvb-usb-v2/af9015.c +++ b/drivers/media/usb/dvb-usb-v2/af9015.c @@ -1222,6 +1222,7 @@ static int af9015_rc_query(struct dvb_usb_device *d) /* Only process key if canary killed */ if (buf[16] != 0xff && buf[0] != 0x01) { + enum rc_type proto; dev_dbg(&d->udev->dev, "%s: key pressed %*ph\n", __func__, 4, buf + 12); @@ -1237,11 +1238,13 @@ static int af9015_rc_query(struct dvb_usb_device *d) /* NEC */ state->rc_keycode = RC_SCANCODE_NEC(buf[12], buf[14]); + proto = RC_TYPE_NEC; } else { /* NEC extended*/ state->rc_keycode = RC_SCANCODE_NECX(buf[12] << 8 | buf[13], buf[14]); + proto = RC_TYPE_NECX; } } else { /* 32 bit NEC */ @@ -1249,8 +1252,9 @@ static int af9015_rc_query(struct dvb_usb_device *d) buf[13] << 16 | buf[14] << 8 | buf[15]); + proto = RC_TYPE_NEC32; } - rc_keydown(d->rc_dev, RC_TYPE_NEC, state->rc_keycode, 0); + rc_keydown(d->rc_dev, proto, state->rc_keycode, 0); } else { dev_dbg(&d->udev->dev, "%s: no key press\n", __func__); /* Invalidate last keypress */ @@ -1317,7 +1321,7 @@ static int af9015_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) if (!rc->map_name) rc->map_name = RC_MAP_EMPTY; - rc->allowed_protos = RC_BIT_NEC; + rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; rc->query = af9015_rc_query; rc->interval = 500; diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c index ca018cd3fcd4..8961dd732522 100644 --- a/drivers/media/usb/dvb-usb-v2/af9035.c +++ b/drivers/media/usb/dvb-usb-v2/af9035.c @@ -1828,6 +1828,7 @@ static int af9035_rc_query(struct dvb_usb_device *d) { struct usb_interface *intf = d->intf; int ret; + enum rc_type proto; u32 key; u8 buf[4]; struct usb_req req = { CMD_IR_GET, 0, 0, NULL, 4, buf }; @@ -1842,19 +1843,22 @@ static int af9035_rc_query(struct dvb_usb_device *d) if ((buf[0] + buf[1]) == 0xff) { /* NEC standard 16bit */ key = RC_SCANCODE_NEC(buf[0], buf[2]); + proto = RC_TYPE_NEC; } else { /* NEC extended 24bit */ key = RC_SCANCODE_NECX(buf[0] << 8 | buf[1], buf[2]); + proto = RC_TYPE_NECX; } } else { /* NEC full code 32bit */ key = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]); + proto = RC_TYPE_NEC32; } dev_dbg(&intf->dev, "%*ph\n", 4, buf); - rc_keydown(d->rc_dev, RC_TYPE_NEC, key, 0); + rc_keydown(d->rc_dev, proto, key, 0); return 0; @@ -1889,7 +1893,8 @@ static int af9035_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) switch (tmp) { case 0: /* NEC */ default: - rc->allowed_protos = RC_BIT_NEC; + rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | + RC_BIT_NEC32; break; case 1: /* RC6 */ rc->allowed_protos = RC_BIT_RC6_MCE; diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c index 935dbaa80ef0..50c07fe7dacb 100644 --- a/drivers/media/usb/dvb-usb-v2/az6007.c +++ b/drivers/media/usb/dvb-usb-v2/az6007.c @@ -208,6 +208,7 @@ static int az6007_rc_query(struct dvb_usb_device *d) { struct az6007_device_state *st = d_to_priv(d); unsigned code; + enum rc_type proto; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); @@ -215,19 +216,23 @@ static int az6007_rc_query(struct dvb_usb_device *d) return 0; if ((st->data[3] ^ st->data[4]) == 0xff) { - if ((st->data[1] ^ st->data[2]) == 0xff) + if ((st->data[1] ^ st->data[2]) == 0xff) { code = RC_SCANCODE_NEC(st->data[1], st->data[3]); - else + proto = RC_TYPE_NEC; + } else { code = RC_SCANCODE_NECX(st->data[1] << 8 | st->data[2], st->data[3]); + proto = RC_TYPE_NECX; + } } else { code = RC_SCANCODE_NEC32(st->data[1] << 24 | st->data[2] << 16 | st->data[3] << 8 | st->data[4]); + proto = RC_TYPE_NEC32; } - rc_keydown(d->rc_dev, RC_TYPE_NEC, code, st->data[5]); + rc_keydown(d->rc_dev, proto, code, st->data[5]); return 0; } @@ -236,7 +241,7 @@ static int az6007_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { pr_debug("Getting az6007 Remote Control properties\n"); - rc->allowed_protos = RC_BIT_NEC; + rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; rc->query = az6007_rc_query; rc->interval = 400; diff --git a/drivers/media/usb/dvb-usb-v2/lmedm04.c b/drivers/media/usb/dvb-usb-v2/lmedm04.c index 3721ee63b8fb..0e8fb89896c4 100644 --- a/drivers/media/usb/dvb-usb-v2/lmedm04.c +++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c @@ -357,7 +357,8 @@ static void lme2510_int_response(struct urb *lme_urb) ibuf[5]); deb_info(1, "INT Key = 0x%08x", key); - rc_keydown(adap_to_d(adap)->rc_dev, RC_TYPE_NEC, key, 0); + rc_keydown(adap_to_d(adap)->rc_dev, RC_TYPE_NEC32, key, + 0); break; case 0xbb: switch (st->tuner_config) { @@ -1242,7 +1243,7 @@ static int lme2510_get_stream_config(struct dvb_frontend *fe, u8 *ts_type, static int lme2510_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { - rc->allowed_protos = RC_BIT_NEC; + rc->allowed_protos = RC_BIT_NEC32; return 0; } diff --git a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c index 6643762a9ff7..c583c638e468 100644 --- a/drivers/media/usb/dvb-usb-v2/rtl28xxu.c +++ b/drivers/media/usb/dvb-usb-v2/rtl28xxu.c @@ -1631,22 +1631,27 @@ static int rtl2831u_rc_query(struct dvb_usb_device *d) goto err; if (buf[4] & 0x01) { + enum rc_type proto; + if (buf[2] == (u8) ~buf[3]) { if (buf[0] == (u8) ~buf[1]) { /* NEC standard (16 bit) */ rc_code = RC_SCANCODE_NEC(buf[0], buf[2]); + proto = RC_TYPE_NEC; } else { /* NEC extended (24 bit) */ rc_code = RC_SCANCODE_NECX(buf[0] << 8 | buf[1], buf[2]); + proto = RC_TYPE_NECX; } } else { /* NEC full (32 bit) */ rc_code = RC_SCANCODE_NEC32(buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]); + proto = RC_TYPE_NEC32; } - rc_keydown(d->rc_dev, RC_TYPE_NEC, rc_code, 0); + rc_keydown(d->rc_dev, proto, rc_code, 0); ret = rtl28xxu_wr_reg(d, SYS_IRRC_SR, 1); if (ret) @@ -1668,7 +1673,7 @@ static int rtl2831u_get_rc_config(struct dvb_usb_device *d, struct dvb_usb_rc *rc) { rc->map_name = RC_MAP_EMPTY; - rc->allowed_protos = RC_BIT_NEC; + rc->allowed_protos = RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32; rc->query = rtl2831u_rc_query; rc->interval = 400; diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c index 26797979ebce..f3196658fb70 100644 --- a/drivers/media/usb/dvb-usb/dib0700_core.c +++ b/drivers/media/usb/dvb-usb/dib0700_core.c @@ -710,7 +710,6 @@ static void dib0700_rc_urb_completion(struct urb *purb) switch (d->props.rc.core.protocol) { case RC_BIT_NEC: - protocol = RC_TYPE_NEC; toggle = 0; /* NEC protocol sends repeat code as 0 0 0 FF */ @@ -728,16 +727,19 @@ static void dib0700_rc_urb_completion(struct urb *purb) poll_reply->nec.not_system << 16 | poll_reply->nec.data << 8 | poll_reply->nec.not_data); + protocol = RC_TYPE_NEC32; } else if ((poll_reply->nec.system ^ poll_reply->nec.not_system) != 0xff) { deb_data("NEC extended protocol\n"); keycode = RC_SCANCODE_NECX(poll_reply->nec.system << 8 | poll_reply->nec.not_system, poll_reply->nec.data); + protocol = RC_TYPE_NECX; } else { deb_data("NEC normal protocol\n"); keycode = RC_SCANCODE_NEC(poll_reply->nec.system, poll_reply->nec.data); + protocol = RC_TYPE_NEC; } break; diff --git a/drivers/media/usb/dvb-usb/dtt200u.c b/drivers/media/usb/dvb-usb/dtt200u.c index be633ece4194..d2a01b50af0d 100644 --- a/drivers/media/usb/dvb-usb/dtt200u.c +++ b/drivers/media/usb/dvb-usb/dtt200u.c @@ -62,18 +62,21 @@ static int dtt200u_rc_query(struct dvb_usb_device *d) dvb_usb_generic_rw(d,&cmd,1,key,5,0); if (key[0] == 1) { + enum rc_type proto = RC_TYPE_NEC; + scancode = key[1]; if ((u8) ~key[1] != key[2]) { /* Extended NEC */ scancode = scancode << 8; scancode |= key[2]; + proto = RC_TYPE_NECX; } scancode = scancode << 8; scancode |= key[3]; /* Check command checksum is ok */ if ((u8) ~key[3] == key[4]) - rc_keydown(d->rc_dev, RC_TYPE_NEC, scancode, 0); + rc_keydown(d->rc_dev, proto, scancode, 0); else rc_keyup(d->rc_dev); } else if (key[0] == 2) { diff --git a/include/media/rc-map.h b/include/media/rc-map.h index 3c8edb34f84a..e1cc14cba391 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -24,6 +24,8 @@ * @RC_TYPE_SONY15: Sony 15 bit protocol * @RC_TYPE_SONY20: Sony 20 bit protocol * @RC_TYPE_NEC: NEC protocol + * @RC_TYPE_NECX: Extended NEC protocol + * @RC_TYPE_NEC32: NEC 32 bit protocol * @RC_TYPE_SANYO: Sanyo protocol * @RC_TYPE_MCE_KBD: RC6-ish MCE keyboard/mouse * @RC_TYPE_RC6_0: Philips RC6-0-16 protocol @@ -46,16 +48,18 @@ enum rc_type { RC_TYPE_SONY15 = 7, RC_TYPE_SONY20 = 8, RC_TYPE_NEC = 9, - RC_TYPE_SANYO = 10, - RC_TYPE_MCE_KBD = 11, - RC_TYPE_RC6_0 = 12, - RC_TYPE_RC6_6A_20 = 13, - RC_TYPE_RC6_6A_24 = 14, - RC_TYPE_RC6_6A_32 = 15, - RC_TYPE_RC6_MCE = 16, - RC_TYPE_SHARP = 17, - RC_TYPE_XMP = 18, - RC_TYPE_CEC = 19, + RC_TYPE_NECX = 10, + RC_TYPE_NEC32 = 11, + RC_TYPE_SANYO = 12, + RC_TYPE_MCE_KBD = 13, + RC_TYPE_RC6_0 = 14, + RC_TYPE_RC6_6A_20 = 15, + RC_TYPE_RC6_6A_24 = 16, + RC_TYPE_RC6_6A_32 = 17, + RC_TYPE_RC6_MCE = 18, + RC_TYPE_SHARP = 19, + RC_TYPE_XMP = 20, + RC_TYPE_CEC = 21, }; #define RC_BIT_NONE 0ULL @@ -69,6 +73,8 @@ enum rc_type { #define RC_BIT_SONY15 (1ULL << RC_TYPE_SONY15) #define RC_BIT_SONY20 (1ULL << RC_TYPE_SONY20) #define RC_BIT_NEC (1ULL << RC_TYPE_NEC) +#define RC_BIT_NECX (1ULL << RC_TYPE_NECX) +#define RC_BIT_NEC32 (1ULL << RC_TYPE_NEC32) #define RC_BIT_SANYO (1ULL << RC_TYPE_SANYO) #define RC_BIT_MCE_KBD (1ULL << RC_TYPE_MCE_KBD) #define RC_BIT_RC6_0 (1ULL << RC_TYPE_RC6_0) @@ -84,8 +90,9 @@ enum rc_type { RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ | \ RC_BIT_JVC | \ RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20 | \ - RC_BIT_NEC | RC_BIT_SANYO | RC_BIT_MCE_KBD | \ - RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ + RC_BIT_NEC | RC_BIT_NECX | RC_BIT_NEC32 | \ + RC_BIT_SANYO | RC_BIT_MCE_KBD | RC_BIT_RC6_0 | \ + RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | \ RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE | RC_BIT_SHARP | \ RC_BIT_XMP | RC_BIT_CEC) -- cgit v1.2.3-70-g09d2