diff options
author | Linus Torvalds | 2019-09-17 17:55:23 -0700 |
---|---|---|
committer | Linus Torvalds | 2019-09-17 17:55:23 -0700 |
commit | e7345f92c27af003f219ad026d0e629a50b41e5c (patch) | |
tree | e4a68d230e460d25e340128e60a7e7efe4165244 /drivers/media/platform | |
parent | 6ab8ad31601f29470eb895fd95e5c963e125aa1b (diff) | |
parent | 6f51fdfd8229d5358c2d6e272cf73478866e8ddc (diff) |
Merge tag 'media/v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab:
- a new sensor driver for ov5675
- a new platform driver for Allwinner A10 sensor interface
- some new remote controller keymaps
- some cosmetic changes at V4L2 core in order to avoid #ifdefs and to
merge two core modules into one
- removal of bcm2048 radio driver from staging
- removal of davinci_vpfe video driver from staging
- regression fix since Kernel 5.1 at the legacy VideoBuffer version 1
core
- added some documentation for remote controller protocols
- pixel format documentation was split on two files
- lots of other driver improvements and cleanups
* tag 'media/v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (321 commits)
media: videobuf-core.c: poll_wait needs a non-NULL buf pointer
media: sun4i: Make sun4i_csi_formats static
media: imx: remove unused including <linux/version.h>
media: stm32-dcmi: Delete an unnecessary of_node_put() call in dcmi_probe()
media: pvrusb2: qctrl.flag will be uninitlaized if cx2341x_ctrl_query() returns error code
media: em28xx: Fix exception handling in em28xx_alloc_urbs()
media: don't do a 31 bit shift on a signed int
media: use the BIT() macro
media: ov9650: add a sanity check
media: aspeed-video: address a protential usage of an unitialized var
media: vicodec: make life easier for static analyzers
media: remove include stdarg.h from some drivers
v4l2-core: fix coding style for the two new c files
media: v4l2-core: Remove BUG() from i2c and spi helpers
media: v4l2-core: introduce a helper to unregister a i2c subdev
media: v4l2-core: introduce a helper to unregister a spi subdev
media: v4l2-core: move i2c helpers out of v4l2-common.c
media: v4l2-core: move spi helpers out of v4l2-common.c
media: v4l2-core: Module re-organization
media: usbvision: Remove dead code
...
Diffstat (limited to 'drivers/media/platform')
137 files changed, 4995 insertions, 3464 deletions
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 8a19654b393a..83a785010753 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -16,7 +16,7 @@ source "drivers/media/platform/marvell-ccic/Kconfig" config VIDEO_VIA_CAMERA tristate "VIAFB camera controller support" depends on FB_VIA - select VIDEOBUF_DMA_SG + select VIDEOBUF2_DMA_SG select VIDEO_OV7670 help Driver support for the integrated camera controller in VIA @@ -121,7 +121,7 @@ config VIDEO_S3C_CAMIF config VIDEO_STM32_DCMI tristate "STM32 Digital Camera Memory Interface (DCMI) support" - depends on VIDEO_V4L2 && OF + depends on VIDEO_V4L2 && OF && MEDIA_CONTROLLER depends on ARCH_STM32 || COMPILE_TEST select VIDEOBUF2_DMA_CONTIG select V4L2_FWNODE @@ -146,7 +146,7 @@ source "drivers/media/platform/am437x/Kconfig" source "drivers/media/platform/xilinx/Kconfig" source "drivers/media/platform/rcar-vin/Kconfig" source "drivers/media/platform/atmel/Kconfig" -source "drivers/media/platform/sunxi/sun6i-csi/Kconfig" +source "drivers/media/platform/sunxi/Kconfig" config VIDEO_TI_CAL tristate "TI CAL (Camera Adaptation Layer) driver" diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index 7cbbd925124c..6ee7eb0d36f4 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -100,4 +100,4 @@ obj-y += meson/ obj-y += cros-ec-cec/ -obj-$(CONFIG_VIDEO_SUN6I_CSI) += sunxi/sun6i-csi/ +obj-y += sunxi/ diff --git a/drivers/media/platform/am437x/am437x-vpfe.c b/drivers/media/platform/am437x/am437x-vpfe.c index fe7b937eb5f2..2b42ba1f5949 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.c +++ b/drivers/media/platform/am437x/am437x-vpfe.c @@ -76,7 +76,6 @@ struct bus_format { /* * struct vpfe_fmt - VPFE media bus format information - * @name: V4L2 format description * @code: V4L2 media bus format code * @shifted: V4L2 media bus format code for the same pixel layout but * shifted to be 8 bits per pixel. =0 if format is not shiftable. @@ -86,7 +85,6 @@ struct bus_format { * @supported: Indicates format supported by subdev */ struct vpfe_fmt { - const char *name; u32 fourcc; u32 code; struct bus_format l; @@ -97,7 +95,6 @@ struct vpfe_fmt { static struct vpfe_fmt formats[] = { { - .name = "YUV 4:2:2 packed, YCbYCr", .fourcc = V4L2_PIX_FMT_YUYV, .code = MEDIA_BUS_FMT_YUYV8_2X8, .l.width = 10, @@ -106,7 +103,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 2, .supported = false, }, { - .name = "YUV 4:2:2 packed, CbYCrY", .fourcc = V4L2_PIX_FMT_UYVY, .code = MEDIA_BUS_FMT_UYVY8_2X8, .l.width = 10, @@ -115,7 +111,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 2, .supported = false, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_YVYU, .code = MEDIA_BUS_FMT_YVYU8_2X8, .l.width = 10, @@ -124,7 +119,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 2, .supported = false, }, { - .name = "YUV 4:2:2 packed, CrYCbY", .fourcc = V4L2_PIX_FMT_VYUY, .code = MEDIA_BUS_FMT_VYUY8_2X8, .l.width = 10, @@ -133,7 +127,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 2, .supported = false, }, { - .name = "RAW8 BGGR", .fourcc = V4L2_PIX_FMT_SBGGR8, .code = MEDIA_BUS_FMT_SBGGR8_1X8, .l.width = 10, @@ -142,7 +135,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 1, .supported = false, }, { - .name = "RAW8 GBRG", .fourcc = V4L2_PIX_FMT_SGBRG8, .code = MEDIA_BUS_FMT_SGBRG8_1X8, .l.width = 10, @@ -151,7 +143,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 1, .supported = false, }, { - .name = "RAW8 GRBG", .fourcc = V4L2_PIX_FMT_SGRBG8, .code = MEDIA_BUS_FMT_SGRBG8_1X8, .l.width = 10, @@ -160,7 +151,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 1, .supported = false, }, { - .name = "RAW8 RGGB", .fourcc = V4L2_PIX_FMT_SRGGB8, .code = MEDIA_BUS_FMT_SRGGB8_1X8, .l.width = 10, @@ -169,7 +159,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 1, .supported = false, }, { - .name = "RGB565 (LE)", .fourcc = V4L2_PIX_FMT_RGB565, .code = MEDIA_BUS_FMT_RGB565_2X8_LE, .l.width = 10, @@ -178,7 +167,6 @@ static struct vpfe_fmt formats[] = { .s.bpp = 2, .supported = false, }, { - .name = "RGB565 (BE)", .fourcc = V4L2_PIX_FMT_RGB565X, .code = MEDIA_BUS_FMT_RGB565_2X8_BE, .l.width = 10, @@ -1412,10 +1400,6 @@ static int vpfe_querycap(struct file *file, void *priv, strscpy(cap->card, "TI AM437x VPFE", sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", vpfe->v4l2_dev.name); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; } @@ -1540,12 +1524,10 @@ static int vpfe_enum_fmt(struct file *file, void *priv, if (!fmt) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; - f->type = vpfe->fmt.type; - vpfe_dbg(1, vpfe, "vpfe_enum_format: mbus index: %d code: %x pixelformat: %s [%s]\n", - f->index, fmt->code, print_fourcc(fmt->fourcc), fmt->name); + vpfe_dbg(1, vpfe, "vpfe_enum_format: mbus index: %d code: %x pixelformat: %s\n", + f->index, fmt->code, print_fourcc(fmt->fourcc)); return 0; } @@ -2393,6 +2375,8 @@ static int vpfe_probe_complete(struct vpfe_device *vpfe) vdev->vfl_dir = VFL_DIR_RX; vdev->queue = q; vdev->lock = &vpfe->lock; + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; video_set_drvdata(vdev, vpfe); err = video_register_device(&vpfe->video_dev, VFL_TYPE_GRABBER, -1); if (err) { @@ -2505,10 +2489,9 @@ vpfe_get_pdata(struct vpfe_device *vpfe) pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev( &vpfe->notifier, of_fwnode_handle(rem), sizeof(struct v4l2_async_subdev)); - if (IS_ERR(pdata->asd[i])) { - of_node_put(rem); + of_node_put(rem); + if (IS_ERR(pdata->asd[i])) goto cleanup; - } } of_node_put(endpoint); @@ -2557,7 +2540,6 @@ static int vpfe_probe(struct platform_device *pdev) ret = platform_get_irq(pdev, 0); if (ret <= 0) { - dev_err(&pdev->dev, "No IRQ resource\n"); ret = -ENODEV; goto probe_out_cleanup; } diff --git a/drivers/media/platform/am437x/am437x-vpfe.h b/drivers/media/platform/am437x/am437x-vpfe.h index 17d7aa426788..4678285f34c6 100644 --- a/drivers/media/platform/am437x/am437x-vpfe.h +++ b/drivers/media/platform/am437x/am437x-vpfe.h @@ -65,12 +65,6 @@ struct vpfe_hw_if_param { #define VPFE_MAX_SUBDEV 1 #define VPFE_MAX_INPUTS 1 -struct vpfe_pixel_format { - struct v4l2_fmtdesc fmtdesc; - /* bytes per pixel */ - int bpp; -}; - struct vpfe_std_info { int active_pixels; int active_lines; diff --git a/drivers/media/platform/am437x/am437x-vpfe_regs.h b/drivers/media/platform/am437x/am437x-vpfe_regs.h index 4a0ed29723e8..0746c48ec23f 100644 --- a/drivers/media/platform/am437x/am437x-vpfe_regs.h +++ b/drivers/media/platform/am437x/am437x-vpfe_regs.h @@ -66,13 +66,13 @@ #define VPFE_PIX_FMT_MASK 3 #define VPFE_PIX_FMT_SHIFT 12 #define VPFE_VP2SDR_DISABLE 0xfffbffff -#define VPFE_WEN_ENABLE (1 << 17) +#define VPFE_WEN_ENABLE BIT(17) #define VPFE_SDR2RSZ_DISABLE 0xfff7ffff -#define VPFE_VDHDEN_ENABLE (1 << 16) -#define VPFE_LPF_ENABLE (1 << 14) -#define VPFE_ALAW_ENABLE (1 << 3) +#define VPFE_VDHDEN_ENABLE BIT(16) +#define VPFE_LPF_ENABLE BIT(14) +#define VPFE_ALAW_ENABLE BIT(3) #define VPFE_ALAW_GAMMA_WD_MASK 7 -#define VPFE_BLK_CLAMP_ENABLE (1 << 31) +#define VPFE_BLK_CLAMP_ENABLE BIT(31) #define VPFE_BLK_SGAIN_MASK 0x1f #define VPFE_BLK_ST_PXL_MASK 0x7fff #define VPFE_BLK_ST_PXL_SHIFT 10 @@ -85,8 +85,8 @@ #define VPFE_BLK_COMP_GB_COMP_SHIFT 8 #define VPFE_BLK_COMP_GR_COMP_SHIFT 16 #define VPFE_BLK_COMP_R_COMP_SHIFT 24 -#define VPFE_LATCH_ON_VSYNC_DISABLE (1 << 15) -#define VPFE_DATA_PACK_ENABLE (1 << 11) +#define VPFE_LATCH_ON_VSYNC_DISABLE BIT(15) +#define VPFE_DATA_PACK_ENABLE BIT(11) #define VPFE_HORZ_INFO_SPH_SHIFT 16 #define VPFE_VERT_START_SLV0_SHIFT 16 #define VPFE_VDINT_VDINT0_SHIFT 16 @@ -114,15 +114,15 @@ #define VPFE_SYN_FLDMODE_MASK 1 #define VPFE_SYN_FLDMODE_SHIFT 7 #define VPFE_REC656IF_BT656_EN 3 -#define VPFE_SYN_MODE_VD_POL_NEGATIVE (1 << 2) +#define VPFE_SYN_MODE_VD_POL_NEGATIVE BIT(2) #define VPFE_CCDCFG_Y8POS_SHIFT 11 -#define VPFE_CCDCFG_BW656_10BIT (1 << 5) +#define VPFE_CCDCFG_BW656_10BIT BIT(5) #define VPFE_SDOFST_FIELD_INTERLEAVED 0x249 #define VPFE_NO_CULLING 0xffff00ff -#define VPFE_VDINT0 (1 << 0) -#define VPFE_VDINT1 (1 << 1) -#define VPFE_VDINT2 (1 << 2) -#define VPFE_DMA_CNTL_OVERFLOW (1 << 31) +#define VPFE_VDINT0 BIT(0) +#define VPFE_VDINT1 BIT(1) +#define VPFE_VDINT2 BIT(2) +#define VPFE_DMA_CNTL_OVERFLOW BIT(31) #define VPFE_CONFIG_PCLK_INV_SHIFT 0 #define VPFE_CONFIG_PCLK_INV_MASK 1 diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c index f899ac3b4a61..eb12f3793062 100644 --- a/drivers/media/platform/aspeed-video.c +++ b/drivers/media/platform/aspeed-video.c @@ -630,7 +630,7 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video) } if (hsync_counter < 0 || vsync_counter < 0) { - u32 ctrl; + u32 ctrl = 0; if (hsync_counter < 0) { ctrl = VE_CTRL_HSYNC_POL; @@ -650,7 +650,8 @@ static void aspeed_video_check_and_set_polarity(struct aspeed_video *video) V4L2_DV_VSYNC_POS_POL; } - aspeed_video_update(video, VE_CTRL, 0, ctrl); + if (ctrl) + aspeed_video_update(video, VE_CTRL, 0, ctrl); } } @@ -1624,6 +1625,7 @@ static int aspeed_video_init(struct aspeed_video *video) if (!aspeed_video_alloc_buf(video, &video->jpeg, VE_JPEG_HEADER_SIZE)) { dev_err(dev, "Failed to allocate DMA for JPEG header\n"); + rc = -ENOMEM; goto err_release_reserved_mem; } diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c index d7d94c1a39d3..428f117caa59 100644 --- a/drivers/media/platform/atmel/atmel-isi.c +++ b/drivers/media/platform/atmel/atmel-isi.c @@ -493,7 +493,7 @@ static void stop_streaming(struct vb2_queue *vq) spin_unlock_irq(&isi->irqlock); if (!isi->enable_preview_path) { - timeout = jiffies + FRAME_INTERVAL_MILLI_SEC * HZ; + timeout = jiffies + (FRAME_INTERVAL_MILLI_SEC * HZ) / 1000; /* Wait until the end of the current frame. */ while ((isi_readl(isi, ISI_STATUS) & ISI_CTRL_CDC) && time_before(jiffies, timeout)) diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c index 266df14da2d5..78381651238d 100644 --- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c +++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c @@ -160,11 +160,8 @@ static int atmel_isc_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - ret = irq; - dev_err(dev, "failed to get irq: %d\n", ret); - return ret; - } + if (irq < 0) + return irq; ret = devm_request_irq(dev, irq, isc_interrupt, 0, ATMEL_ISC_NAME, isc); diff --git a/drivers/media/platform/cadence/cdns-csi2tx.c b/drivers/media/platform/cadence/cdns-csi2tx.c index 5042d053b94e..e4d08acfbb49 100644 --- a/drivers/media/platform/cadence/cdns-csi2tx.c +++ b/drivers/media/platform/cadence/cdns-csi2tx.c @@ -2,7 +2,7 @@ /* * Driver for Cadence MIPI-CSI2 TX Controller * - * Copyright (C) 2017-2018 Cadence Design Systems Inc. + * Copyright (C) 2017-2019 Cadence Design Systems Inc. */ #include <linux/clk.h> @@ -52,6 +52,17 @@ #define CSI2TX_STREAM_IF_CFG_REG(n) (0x100 + (n) * 4) #define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n) ((n) & 0x1f) +/* CSI2TX V2 Registers */ +#define CSI2TX_V2_DPHY_CFG_REG 0x28 +#define CSI2TX_V2_DPHY_CFG_RESET BIT(16) +#define CSI2TX_V2_DPHY_CFG_CLOCK_MODE BIT(10) +#define CSI2TX_V2_DPHY_CFG_MODE_MASK GENMASK(9, 8) +#define CSI2TX_V2_DPHY_CFG_MODE_LPDT (2 << 8) +#define CSI2TX_V2_DPHY_CFG_MODE_HS (1 << 8) +#define CSI2TX_V2_DPHY_CFG_MODE_ULPS (0 << 8) +#define CSI2TX_V2_DPHY_CFG_CLK_ENABLE BIT(4) +#define CSI2TX_V2_DPHY_CFG_LANE_ENABLE(n) BIT(n) + #define CSI2TX_LANES_MAX 4 #define CSI2TX_STREAMS_MAX 4 @@ -70,6 +81,13 @@ struct csi2tx_fmt { u32 bpp; }; +struct csi2tx_priv; + +/* CSI2TX Variant Operations */ +struct csi2tx_vops { + void (*dphy_setup)(struct csi2tx_priv *csi2tx); +}; + struct csi2tx_priv { struct device *dev; unsigned int count; @@ -82,6 +100,8 @@ struct csi2tx_priv { void __iomem *base; + struct csi2tx_vops *vops; + struct clk *esc_clk; struct clk *p_clk; struct clk *pixel_clk[CSI2TX_STREAMS_MAX]; @@ -209,53 +229,92 @@ static const struct v4l2_subdev_pad_ops csi2tx_pad_ops = { .set_fmt = csi2tx_set_pad_format, }; -static void csi2tx_reset(struct csi2tx_priv *csi2tx) +/* Set Wake Up value in the D-PHY */ +static void csi2tx_dphy_set_wakeup(struct csi2tx_priv *csi2tx) { - writel(CSI2TX_CONFIG_SRST_REQ, csi2tx->base + CSI2TX_CONFIG_REG); - - udelay(10); + writel(CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(32), + csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG); } -static int csi2tx_start(struct csi2tx_priv *csi2tx) +/* + * Finishes the D-PHY initialization + * reg dphy cfg value to be used + */ +static void csi2tx_dphy_init_finish(struct csi2tx_priv *csi2tx, u32 reg) { - struct media_entity *entity = &csi2tx->subdev.entity; - struct media_link *link; unsigned int i; - u32 reg; - csi2tx_reset(csi2tx); + udelay(10); - writel(CSI2TX_CONFIG_CFG_REQ, csi2tx->base + CSI2TX_CONFIG_REG); + /* Enable our (clock and data) lanes */ + reg |= CSI2TX_DPHY_CFG_CLK_ENABLE; + for (i = 0; i < csi2tx->num_lanes; i++) + reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i] - 1); + writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); udelay(10); - /* Configure our PPI interface with the D-PHY */ - writel(CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(32), - csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG); + /* Switch to HS mode */ + reg &= ~CSI2TX_DPHY_CFG_MODE_MASK; + writel(reg | CSI2TX_DPHY_CFG_MODE_HS, + csi2tx->base + CSI2TX_DPHY_CFG_REG); +} + +/* Configures D-PHY in CSIv1.3 */ +static void csi2tx_dphy_setup(struct csi2tx_priv *csi2tx) +{ + u32 reg; + unsigned int i; + + csi2tx_dphy_set_wakeup(csi2tx); /* Put our lanes (clock and data) out of reset */ reg = CSI2TX_DPHY_CFG_CLK_RESET | CSI2TX_DPHY_CFG_MODE_LPDT; for (i = 0; i < csi2tx->num_lanes; i++) - reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i]); + reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i] - 1); writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); - udelay(10); + csi2tx_dphy_init_finish(csi2tx, reg); +} - /* Enable our (clock and data) lanes */ - reg |= CSI2TX_DPHY_CFG_CLK_ENABLE; - for (i = 0; i < csi2tx->num_lanes; i++) - reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i]); - writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); +/* Configures D-PHY in CSIv2 */ +static void csi2tx_v2_dphy_setup(struct csi2tx_priv *csi2tx) +{ + u32 reg; + + csi2tx_dphy_set_wakeup(csi2tx); + + /* Put our lanes (clock and data) out of reset */ + reg = CSI2TX_V2_DPHY_CFG_RESET | CSI2TX_V2_DPHY_CFG_MODE_LPDT; + writel(reg, csi2tx->base + CSI2TX_V2_DPHY_CFG_REG); + + csi2tx_dphy_init_finish(csi2tx, reg); +} + +static void csi2tx_reset(struct csi2tx_priv *csi2tx) +{ + writel(CSI2TX_CONFIG_SRST_REQ, csi2tx->base + CSI2TX_CONFIG_REG); udelay(10); +} - /* Switch to HS mode */ - reg &= ~CSI2TX_DPHY_CFG_MODE_MASK; - writel(reg | CSI2TX_DPHY_CFG_MODE_HS, - csi2tx->base + CSI2TX_DPHY_CFG_REG); +static int csi2tx_start(struct csi2tx_priv *csi2tx) +{ + struct media_entity *entity = &csi2tx->subdev.entity; + struct media_link *link; + unsigned int i; + + csi2tx_reset(csi2tx); + + writel(CSI2TX_CONFIG_CFG_REQ, csi2tx->base + CSI2TX_CONFIG_REG); udelay(10); + if (csi2tx->vops && csi2tx->vops->dphy_setup) { + csi2tx->vops->dphy_setup(csi2tx); + udelay(10); + } + /* * Create a static mapping between the CSI virtual channels * and the input streams. @@ -434,7 +493,7 @@ static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) { struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 }; struct device_node *ep; - int ret; + int ret, i; ep = of_graph_get_endpoint_by_regs(csi2tx->dev->of_node, 0, 0); if (!ep) @@ -461,6 +520,15 @@ static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) goto out; } + for (i = 0; i < csi2tx->num_lanes; i++) { + if (v4l2_ep.bus.mipi_csi2.data_lanes[i] < 1) { + dev_err(csi2tx->dev, "Invalid lane[%d] number: %u\n", + i, v4l2_ep.bus.mipi_csi2.data_lanes[i]); + ret = -EINVAL; + goto out; + } + } + memcpy(csi2tx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes, sizeof(csi2tx->lanes)); @@ -469,9 +537,35 @@ out: return ret; } +static const struct csi2tx_vops csi2tx_vops = { + .dphy_setup = csi2tx_dphy_setup, +}; + +static const struct csi2tx_vops csi2tx_v2_vops = { + .dphy_setup = csi2tx_v2_dphy_setup, +}; + +static const struct of_device_id csi2tx_of_table[] = { + { + .compatible = "cdns,csi2tx", + .data = &csi2tx_vops + }, + { + .compatible = "cdns,csi2tx-1.3", + .data = &csi2tx_vops + }, + { + .compatible = "cdns,csi2tx-2.1", + .data = &csi2tx_v2_vops + }, + { } +}; +MODULE_DEVICE_TABLE(of, csi2tx_of_table); + static int csi2tx_probe(struct platform_device *pdev) { struct csi2tx_priv *csi2tx; + const struct of_device_id *of_id; unsigned int i; int ret; @@ -486,6 +580,9 @@ static int csi2tx_probe(struct platform_device *pdev) if (ret) goto err_free_priv; + of_id = of_match_node(csi2tx_of_table, pdev->dev.of_node); + csi2tx->vops = (struct csi2tx_vops *)of_id->data; + v4l2_subdev_init(&csi2tx->subdev, &csi2tx_subdev_ops); csi2tx->subdev.owner = THIS_MODULE; csi2tx->subdev.dev = &pdev->dev; @@ -543,12 +640,6 @@ static int csi2tx_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id csi2tx_of_table[] = { - { .compatible = "cdns,csi2tx" }, - { }, -}; -MODULE_DEVICE_TABLE(of, csi2tx_of_table); - static struct platform_driver csi2tx_driver = { .probe = csi2tx_probe, .remove = csi2tx_remove, diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 01428de2596e..73222c0615c0 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -390,9 +390,6 @@ static int coda_querycap(struct file *file, void *priv, strscpy(cap->card, coda_product_name(ctx->dev->devtype->product), sizeof(cap->card)); strscpy(cap->bus_info, "platform:" CODA_NAME, sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; } @@ -2699,6 +2696,7 @@ static int coda_register_device(struct coda_dev *dev, int i) vfd->lock = &dev->dev_mutex; vfd->v4l2_dev = &dev->v4l2_dev; vfd->vfl_dir = VFL_DIR_M2M; + vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; video_set_drvdata(vfd, dev); /* Not applicable, use the selection API instead */ diff --git a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c index 068df9888dbf..76ab83f55cc0 100644 --- a/drivers/media/platform/cros-ec-cec/cros-ec-cec.c +++ b/drivers/media/platform/cros-ec-cec/cros-ec-cec.c @@ -206,10 +206,10 @@ static SIMPLE_DEV_PM_OPS(cros_ec_cec_pm_ops, */ struct cec_dmi_match { - char *sys_vendor; - char *product_name; - char *devname; - char *conn; + const char *sys_vendor; + const char *product_name; + const char *devname; + const char *conn; }; static const struct cec_dmi_match cec_dmi_match_table[] = { @@ -217,8 +217,8 @@ static const struct cec_dmi_match cec_dmi_match_table[] = { { "Google", "Fizz", "0000:00:02.0", "Port B" }, }; -static int cros_ec_cec_get_notifier(struct device *dev, - struct cec_notifier **notify) +static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev, + const char **conn) { int i; @@ -233,26 +233,25 @@ static int cros_ec_cec_get_notifier(struct device *dev, d = bus_find_device_by_name(&pci_bus_type, NULL, m->devname); if (!d) - return -EPROBE_DEFER; - - *notify = cec_notifier_get_conn(d, m->conn); + return ERR_PTR(-EPROBE_DEFER); put_device(d); - return 0; + *conn = m->conn; + return d; } } /* Hardware support must be added in the cec_dmi_match_table */ dev_warn(dev, "CEC notifier not configured for this hardware\n"); - return -ENODEV; + return ERR_PTR(-ENODEV); } #else -static int cros_ec_cec_get_notifier(struct device *dev, - struct cec_notifier **notify) +static struct device *cros_ec_cec_find_hdmi_dev(struct device *dev, + const char **conn) { - return -ENODEV; + return ERR_PTR(-ENODEV); } #endif @@ -262,8 +261,14 @@ static int cros_ec_cec_probe(struct platform_device *pdev) struct cros_ec_dev *ec_dev = dev_get_drvdata(pdev->dev.parent); struct cros_ec_device *cros_ec = ec_dev->ec_dev; struct cros_ec_cec *cros_ec_cec; + struct device *hdmi_dev; + const char *conn = NULL; int ret; + hdmi_dev = cros_ec_cec_find_hdmi_dev(&pdev->dev, &conn); + if (IS_ERR(hdmi_dev)) + return PTR_ERR(hdmi_dev); + cros_ec_cec = devm_kzalloc(&pdev->dev, sizeof(*cros_ec_cec), GFP_KERNEL); if (!cros_ec_cec) @@ -272,10 +277,6 @@ static int cros_ec_cec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, cros_ec_cec); cros_ec_cec->cros_ec = cros_ec; - ret = cros_ec_cec_get_notifier(&pdev->dev, &cros_ec_cec->notify); - if (ret) - return ret; - ret = device_init_wakeup(&pdev->dev, 1); if (ret) { dev_err(&pdev->dev, "failed to initialize wakeup\n"); @@ -283,29 +284,39 @@ static int cros_ec_cec_probe(struct platform_device *pdev) } cros_ec_cec->adap = cec_allocate_adapter(&cros_ec_cec_ops, cros_ec_cec, - DRV_NAME, CEC_CAP_DEFAULTS, 1); + DRV_NAME, + CEC_CAP_DEFAULTS | + CEC_CAP_CONNECTOR_INFO, 1); if (IS_ERR(cros_ec_cec->adap)) return PTR_ERR(cros_ec_cec->adap); + cros_ec_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, conn, + cros_ec_cec->adap); + if (!cros_ec_cec->notify) { + ret = -ENOMEM; + goto out_probe_adapter; + } + /* Get CEC events from the EC. */ cros_ec_cec->notifier.notifier_call = cros_ec_cec_event; ret = blocking_notifier_chain_register(&cros_ec->event_notifier, &cros_ec_cec->notifier); if (ret) { dev_err(&pdev->dev, "failed to register notifier\n"); - cec_delete_adapter(cros_ec_cec->adap); - return ret; + goto out_probe_notify; } ret = cec_register_adapter(cros_ec_cec->adap, &pdev->dev); - if (ret < 0) { - cec_delete_adapter(cros_ec_cec->adap); - return ret; - } - - cec_register_cec_notifier(cros_ec_cec->adap, cros_ec_cec->notify); + if (ret < 0) + goto out_probe_notify; return 0; + +out_probe_notify: + cec_notifier_cec_adap_unregister(cros_ec_cec->notify); +out_probe_adapter: + cec_delete_adapter(cros_ec_cec->adap); + return ret; } static int cros_ec_cec_remove(struct platform_device *pdev) @@ -323,11 +334,9 @@ static int cros_ec_cec_remove(struct platform_device *pdev) return ret; } + cec_notifier_cec_adap_unregister(cros_ec_cec->notify); cec_unregister_adapter(cros_ec_cec->adap); - if (cros_ec_cec->notify) - cec_notifier_put(cros_ec_cec->notify); - return 0; } diff --git a/drivers/media/platform/davinci/dm644x_ccdc_regs.h b/drivers/media/platform/davinci/dm644x_ccdc_regs.h index 3ae301320313..c4894f6a254e 100644 --- a/drivers/media/platform/davinci/dm644x_ccdc_regs.h +++ b/drivers/media/platform/davinci/dm644x_ccdc_regs.h @@ -66,13 +66,13 @@ #define CCDC_PIX_FMT_MASK 3 #define CCDC_PIX_FMT_SHIFT 12 #define CCDC_VP2SDR_DISABLE 0xFFFBFFFF -#define CCDC_WEN_ENABLE (1 << 17) +#define CCDC_WEN_ENABLE BIT(17) #define CCDC_SDR2RSZ_DISABLE 0xFFF7FFFF -#define CCDC_VDHDEN_ENABLE (1 << 16) -#define CCDC_LPF_ENABLE (1 << 14) -#define CCDC_ALAW_ENABLE (1 << 3) +#define CCDC_VDHDEN_ENABLE BIT(16) +#define CCDC_LPF_ENABLE BIT(14) +#define CCDC_ALAW_ENABLE BIT(3) #define CCDC_ALAW_GAMMA_WD_MASK 7 -#define CCDC_BLK_CLAMP_ENABLE (1 << 31) +#define CCDC_BLK_CLAMP_ENABLE BIT(31) #define CCDC_BLK_SGAIN_MASK 0x1F #define CCDC_BLK_ST_PXL_MASK 0x7FFF #define CCDC_BLK_ST_PXL_SHIFT 10 @@ -85,11 +85,11 @@ #define CCDC_BLK_COMP_GB_COMP_SHIFT 8 #define CCDC_BLK_COMP_GR_COMP_SHIFT 16 #define CCDC_BLK_COMP_R_COMP_SHIFT 24 -#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15) -#define CCDC_FPC_ENABLE (1 << 15) +#define CCDC_LATCH_ON_VSYNC_DISABLE BIT(15) +#define CCDC_FPC_ENABLE BIT(15) #define CCDC_FPC_DISABLE 0 #define CCDC_FPC_FPC_NUM_MASK 0x7FFF -#define CCDC_DATA_PACK_ENABLE (1 << 11) +#define CCDC_DATA_PACK_ENABLE BIT(11) #define CCDC_FMTCFG_VPIN_MASK 7 #define CCDC_FMTCFG_VPIN_SHIFT 12 #define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF @@ -132,9 +132,9 @@ #define CCDC_SYN_FLDMODE_MASK 1 #define CCDC_SYN_FLDMODE_SHIFT 7 #define CCDC_REC656IF_BT656_EN 3 -#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2) +#define CCDC_SYN_MODE_VD_POL_NEGATIVE BIT(2) #define CCDC_CCDCFG_Y8POS_SHIFT 11 -#define CCDC_CCDCFG_BW656_10BIT (1 << 5) +#define CCDC_CCDCFG_BW656_10BIT BIT(5) #define CCDC_SDOFST_FIELD_INTERLEAVED 0x249 #define CCDC_NO_CULLING 0xffff00ff #endif diff --git a/drivers/media/platform/davinci/vpbe_display.c b/drivers/media/platform/davinci/vpbe_display.c index 000b191c42d8..ae419958e420 100644 --- a/drivers/media/platform/davinci/vpbe_display.c +++ b/drivers/media/platform/davinci/vpbe_display.c @@ -19,10 +19,6 @@ #include <asm/pgtable.h> -#ifdef CONFIG_ARCH_DAVINCI -#include <mach/cputype.h> -#endif - #include <media/v4l2-dev.h> #include <media/v4l2-common.h> #include <media/v4l2-ioctl.h> @@ -633,8 +629,6 @@ static int vpbe_display_querycap(struct file *file, void *priv, struct vpbe_layer *layer = video_drvdata(file); struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; snprintf(cap->driver, sizeof(cap->driver), "%s", dev_name(vpbe_dev->pdev)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", @@ -792,7 +786,6 @@ static int vpbe_display_enum_fmt(struct file *file, void *priv, { struct vpbe_layer *layer = video_drvdata(file); struct vpbe_device *vpbe_dev = layer->disp_dev->vpbe_dev; - unsigned int index = 0; v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_FMT, layer id = %d\n", @@ -803,19 +796,10 @@ static int vpbe_display_enum_fmt(struct file *file, void *priv, } /* Fill in the information about format */ - index = fmt->index; - memset(fmt, 0, sizeof(*fmt)); - fmt->index = index; - fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - if (index == 0) { - strscpy(fmt->description, "YUV 4:2:2 - UYVY", - sizeof(fmt->description)); + if (fmt->index == 0) fmt->pixelformat = V4L2_PIX_FMT_UYVY; - } else { - strscpy(fmt->description, "Y/CbCr 4:2:0", - sizeof(fmt->description)); + else fmt->pixelformat = V4L2_PIX_FMT_NV12; - } return 0; } @@ -1319,6 +1303,7 @@ static int init_vpbe_layer(int i, struct vpbe_display *disp_dev, vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev; vbd->lock = &vpbe_display_layer->opslock; vbd->vfl_dir = VFL_DIR_TX; + vbd->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; if (disp_dev->vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) diff --git a/drivers/media/platform/davinci/vpbe_osd.c b/drivers/media/platform/davinci/vpbe_osd.c index 491842ef33c5..91b571a0ac2c 100644 --- a/drivers/media/platform/davinci/vpbe_osd.c +++ b/drivers/media/platform/davinci/vpbe_osd.c @@ -16,11 +16,6 @@ #include <linux/clk.h> #include <linux/slab.h> -#ifdef CONFIG_ARCH_DAVINCI -#include <mach/cputype.h> -#include <mach/hardware.h> -#endif - #include <media/davinci/vpss.h> #include <media/v4l2-device.h> #include <media/davinci/vpbe_types.h> diff --git a/drivers/media/platform/davinci/vpbe_venc.c b/drivers/media/platform/davinci/vpbe_venc.c index 425f91f07165..8caa084e5704 100644 --- a/drivers/media/platform/davinci/vpbe_venc.c +++ b/drivers/media/platform/davinci/vpbe_venc.c @@ -14,11 +14,6 @@ #include <linux/videodev2.h> #include <linux/slab.h> -#ifdef CONFIG_ARCH_DAVINCI -#include <mach/hardware.h> -#include <mach/mux.h> -#endif - #include <linux/platform_data/i2c-davinci.h> #include <linux/io.h> diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c index 295fbf1a49cf..916ed743d716 100644 --- a/drivers/media/platform/davinci/vpfe_capture.c +++ b/drivers/media/platform/davinci/vpfe_capture.c @@ -119,57 +119,27 @@ static const struct vpfe_standard vpfe_standards[] = { /* Used when raw Bayer image from ccdc is directly captured to SDRAM */ static const struct vpfe_pixel_format vpfe_pix_fmts[] = { { - .fmtdesc = { - .index = 0, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "Bayer GrRBGb 8bit A-Law compr.", - .pixelformat = V4L2_PIX_FMT_SBGGR8, - }, + .pixelformat = V4L2_PIX_FMT_SBGGR8, .bpp = 1, }, { - .fmtdesc = { - .index = 1, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "Bayer GrRBGb - 16bit", - .pixelformat = V4L2_PIX_FMT_SBGGR16, - }, + .pixelformat = V4L2_PIX_FMT_SBGGR16, .bpp = 2, }, { - .fmtdesc = { - .index = 2, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "Bayer GrRBGb 8bit DPCM compr.", - .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, - }, + .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, .bpp = 1, }, { - .fmtdesc = { - .index = 3, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "YCbCr 4:2:2 Interleaved UYVY", - .pixelformat = V4L2_PIX_FMT_UYVY, - }, + .pixelformat = V4L2_PIX_FMT_UYVY, .bpp = 2, }, { - .fmtdesc = { - .index = 4, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "YCbCr 4:2:2 Interleaved YUYV", - .pixelformat = V4L2_PIX_FMT_YUYV, - }, + .pixelformat = V4L2_PIX_FMT_YUYV, .bpp = 2, }, { - .fmtdesc = { - .index = 5, - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, - .description = "Y/CbCr 4:2:0 - Semi planar", - .pixelformat = V4L2_PIX_FMT_NV12, - }, + .pixelformat = V4L2_PIX_FMT_NV12, .bpp = 1, }, }; @@ -183,7 +153,7 @@ static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format) int i; for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) { - if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat) + if (pix_format == vpfe_pix_fmts[i].pixelformat) return &vpfe_pix_fmts[i]; } return NULL; @@ -782,7 +752,7 @@ static const struct vpfe_pixel_format * temp = 0; found = 0; while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) { - if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) { + if (vpfe_pix_fmt->pixelformat == pix) { found = 1; break; } @@ -877,8 +847,6 @@ static int vpfe_querycap(struct file *file, void *priv, v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n"); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; strscpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver)); strscpy(cap->bus_info, "VPFE", sizeof(cap->bus_info)); strscpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card)); @@ -901,7 +869,6 @@ static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv, { struct vpfe_device *vpfe_dev = video_drvdata(file); const struct vpfe_pixel_format *pix_fmt; - int temp_index; u32 pix; v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n"); @@ -912,9 +879,7 @@ static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv, /* Fill in the information about format */ pix_fmt = vpfe_lookup_pix_format(pix); if (pix_fmt) { - temp_index = fmt->index; - *fmt = pix_fmt->fmtdesc; - fmt->index = temp_index; + fmt->pixelformat = fmt->pixelformat; return 0; } return -EINVAL; @@ -1785,6 +1750,7 @@ static int vpfe_probe(struct platform_device *pdev) vfd->ioctl_ops = &vpfe_ioctl_ops; vfd->tvnorms = 0; vfd->v4l2_dev = &vpfe_dev->v4l2_dev; + vfd->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; snprintf(vfd->name, sizeof(vfd->name), "%s_V%d.%d.%d", CAPTURE_DRV_NAME, diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c index f0f7ef638c56..71f4fe882d13 100644 --- a/drivers/media/platform/davinci/vpif_capture.c +++ b/drivers/media/platform/davinci/vpif_capture.c @@ -938,17 +938,10 @@ static int vpif_enum_fmt_vid_cap(struct file *file, void *priv, } /* Fill in the information about format */ - if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) { - fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strscpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb", - sizeof(fmt->description)); + if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) fmt->pixelformat = V4L2_PIX_FMT_SBGGR8; - } else { - fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - strscpy(fmt->description, "YCbCr4:2:2 Semi-Planar", - sizeof(fmt->description)); + else fmt->pixelformat = V4L2_PIX_FMT_NV16; - } return 0; } @@ -979,7 +972,6 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv, pixfmt->bytesperline = common->fmt.fmt.pix.width * 2; pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; } - pixfmt->priv = 0; dev_dbg(vpif_dev, "%s: %d x %d; pitch=%d pixelformat=0x%08x, field=%d, size=%d\n", __func__, pixfmt->width, pixfmt->height, @@ -1085,8 +1077,6 @@ static int vpif_querycap(struct file *file, void *priv, { struct vpif_capture_config *config = vpif_dev->platform_data; - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(vpif_dev)); @@ -1473,6 +1463,7 @@ static int vpif_probe_complete(void) vdev->vfl_dir = VFL_DIR_RX; vdev->queue = q; vdev->lock = &common->lock; + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; video_set_drvdata(&ch->video_dev, ch); err = video_register_device(vdev, VFL_TYPE_GRABBER, (j ? 1 : 0)); @@ -1511,6 +1502,7 @@ static struct vpif_capture_config * vpif_capture_get_pdata(struct platform_device *pdev) { struct device_node *endpoint = NULL; + struct device_node *rem = NULL; struct vpif_capture_config *pdata; struct vpif_subdev_info *sdinfo; struct vpif_capture_chan_config *chan; @@ -1541,7 +1533,6 @@ vpif_capture_get_pdata(struct platform_device *pdev) for (i = 0; i < VPIF_CAPTURE_NUM_CHANNELS; i++) { struct v4l2_fwnode_endpoint bus_cfg = { .bus_type = 0 }; - struct device_node *rem; unsigned int flags; int err; @@ -1554,7 +1545,6 @@ vpif_capture_get_pdata(struct platform_device *pdev) if (!rem) { dev_dbg(&pdev->dev, "Remote device at %pOF not found\n", endpoint); - of_node_put(endpoint); goto done; } @@ -1564,11 +1554,8 @@ vpif_capture_get_pdata(struct platform_device *pdev) VPIF_CAPTURE_NUM_CHANNELS, sizeof(*chan->inputs), GFP_KERNEL); - if (!chan->inputs) { - of_node_put(rem); - of_node_put(endpoint); + if (!chan->inputs) goto err_cleanup; - } chan->input_count++; chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA; @@ -1577,7 +1564,6 @@ vpif_capture_get_pdata(struct platform_device *pdev) err = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &bus_cfg); - of_node_put(endpoint); if (err) { dev_err(&pdev->dev, "Could not parse the endpoint\n"); of_node_put(rem); @@ -1601,13 +1587,14 @@ vpif_capture_get_pdata(struct platform_device *pdev) pdata->asd[i] = v4l2_async_notifier_add_fwnode_subdev( &vpif_obj.notifier, of_fwnode_handle(rem), sizeof(struct v4l2_async_subdev)); - if (IS_ERR(pdata->asd[i])) { - of_node_put(rem); + if (IS_ERR(pdata->asd[i])) goto err_cleanup; - } + + of_node_put(rem); } done: + of_node_put(endpoint); pdata->asd_sizes[0] = i; pdata->subdev_count = i; pdata->card_name = "DA850/OMAP-L138 Video Capture"; @@ -1615,6 +1602,8 @@ done: return pdata; err_cleanup: + of_node_put(rem); + of_node_put(endpoint); v4l2_async_notifier_cleanup(&vpif_obj.notifier); return NULL; diff --git a/drivers/media/platform/davinci/vpif_display.c b/drivers/media/platform/davinci/vpif_display.c index a69897c68a50..abbdbac08e6f 100644 --- a/drivers/media/platform/davinci/vpif_display.c +++ b/drivers/media/platform/davinci/vpif_display.c @@ -584,8 +584,6 @@ static int vpif_querycap(struct file *file, void *priv, { struct vpif_display_config *config = vpif_dev->platform_data; - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; strscpy(cap->driver, VPIF_DRIVER_NAME, sizeof(cap->driver)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(vpif_dev)); @@ -601,11 +599,7 @@ static int vpif_enum_fmt_vid_out(struct file *file, void *priv, return -EINVAL; /* Fill in the information about format */ - fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - strscpy(fmt->description, "YCbCr4:2:2 YC Planar", - sizeof(fmt->description)); fmt->pixelformat = V4L2_PIX_FMT_YUV422P; - fmt->flags = 0; return 0; } @@ -1218,6 +1212,7 @@ static int vpif_probe_complete(void) vdev->vfl_dir = VFL_DIR_TX; vdev->queue = q; vdev->lock = &common->lock; + vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; video_set_drvdata(&ch->video_dev, ch); err = video_register_device(vdev, VFL_TYPE_GRABBER, (j ? 3 : 2)); diff --git a/drivers/media/platform/exynos-gsc/gsc-core.c b/drivers/media/platform/exynos-gsc/gsc-core.c index 854869f0024e..f6650b45bc3d 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.c +++ b/drivers/media/platform/exynos-gsc/gsc-core.c @@ -27,21 +27,18 @@ static const struct gsc_fmt gsc_formats[] = { { - .name = "RGB565", .pixelformat = V4L2_PIX_FMT_RGB565X, .depth = { 16 }, .color = GSC_RGB, .num_planes = 1, .num_comp = 1, }, { - .name = "BGRX-8-8-8-8, 32 bpp", .pixelformat = V4L2_PIX_FMT_BGR32, .depth = { 32 }, .color = GSC_RGB, .num_planes = 1, .num_comp = 1, }, { - .name = "YUV 4:2:2 packed, YCbYCr", .pixelformat = V4L2_PIX_FMT_YUYV, .depth = { 16 }, .color = GSC_YUV422, @@ -51,7 +48,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_comp = 1, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, }, { - .name = "YUV 4:2:2 packed, CbYCrY", .pixelformat = V4L2_PIX_FMT_UYVY, .depth = { 16 }, .color = GSC_YUV422, @@ -61,7 +57,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_comp = 1, .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, }, { - .name = "YUV 4:2:2 packed, CrYCbY", .pixelformat = V4L2_PIX_FMT_VYUY, .depth = { 16 }, .color = GSC_YUV422, @@ -71,7 +66,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_comp = 1, .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .pixelformat = V4L2_PIX_FMT_YVYU, .depth = { 16 }, .color = GSC_YUV422, @@ -81,7 +75,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_comp = 1, .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, }, { - .name = "YUV 4:4:4 planar, YCbYCr", .pixelformat = V4L2_PIX_FMT_YUV32, .depth = { 32 }, .color = GSC_YUV444, @@ -90,7 +83,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 1, }, { - .name = "YUV 4:2:2 planar, Y/Cb/Cr", .pixelformat = V4L2_PIX_FMT_YUV422P, .depth = { 16 }, .color = GSC_YUV422, @@ -99,7 +91,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 3, }, { - .name = "YUV 4:2:2 planar, Y/CbCr", .pixelformat = V4L2_PIX_FMT_NV16, .depth = { 16 }, .color = GSC_YUV422, @@ -108,7 +99,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 2, }, { - .name = "YUV 4:2:2 non-contig, Y/CbCr", .pixelformat = V4L2_PIX_FMT_NV16M, .depth = { 8, 8 }, .color = GSC_YUV422, @@ -117,7 +107,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 2, .num_comp = 2, }, { - .name = "YUV 4:2:2 planar, Y/CrCb", .pixelformat = V4L2_PIX_FMT_NV61, .depth = { 16 }, .color = GSC_YUV422, @@ -126,7 +115,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 2, }, { - .name = "YUV 4:2:2 non-contig, Y/CrCb", .pixelformat = V4L2_PIX_FMT_NV61M, .depth = { 8, 8 }, .color = GSC_YUV422, @@ -135,7 +123,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 2, .num_comp = 2, }, { - .name = "YUV 4:2:0 planar, YCbCr", .pixelformat = V4L2_PIX_FMT_YUV420, .depth = { 12 }, .color = GSC_YUV420, @@ -144,7 +131,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 3, }, { - .name = "YUV 4:2:0 planar, YCrCb", .pixelformat = V4L2_PIX_FMT_YVU420, .depth = { 12 }, .color = GSC_YUV420, @@ -154,7 +140,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_comp = 3, }, { - .name = "YUV 4:2:0 planar, Y/CbCr", .pixelformat = V4L2_PIX_FMT_NV12, .depth = { 12 }, .color = GSC_YUV420, @@ -163,7 +148,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 2, }, { - .name = "YUV 4:2:0 planar, Y/CrCb", .pixelformat = V4L2_PIX_FMT_NV21, .depth = { 12 }, .color = GSC_YUV420, @@ -172,7 +156,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 1, .num_comp = 2, }, { - .name = "YUV 4:2:0 non-contig. 2p, Y/CrCb", .pixelformat = V4L2_PIX_FMT_NV21M, .depth = { 8, 4 }, .color = GSC_YUV420, @@ -181,7 +164,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 2, .num_comp = 2, }, { - .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr", .pixelformat = V4L2_PIX_FMT_NV12M, .depth = { 8, 4 }, .color = GSC_YUV420, @@ -190,7 +172,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 2, .num_comp = 2, }, { - .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr", .pixelformat = V4L2_PIX_FMT_YUV420M, .depth = { 8, 2, 2 }, .color = GSC_YUV420, @@ -199,7 +180,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 3, .num_comp = 3, }, { - .name = "YUV 4:2:0 non-contig. 3p, Y/Cr/Cb", .pixelformat = V4L2_PIX_FMT_YVU420M, .depth = { 8, 2, 2 }, .color = GSC_YUV420, @@ -208,7 +188,6 @@ static const struct gsc_fmt gsc_formats[] = { .num_planes = 3, .num_comp = 3, }, { - .name = "YUV 4:2:0 n.c. 2p, Y/CbCr tiled", .pixelformat = V4L2_PIX_FMT_NV12MT_16X16, .depth = { 8, 4 }, .color = GSC_YUV420, @@ -335,7 +314,6 @@ int gsc_enum_fmt(struct v4l2_fmtdesc *f) if (!fmt) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->pixelformat; return 0; diff --git a/drivers/media/platform/exynos-gsc/gsc-core.h b/drivers/media/platform/exynos-gsc/gsc-core.h index 772183b090c2..8e5a9acb78aa 100644 --- a/drivers/media/platform/exynos-gsc/gsc-core.h +++ b/drivers/media/platform/exynos-gsc/gsc-core.h @@ -103,7 +103,6 @@ enum gsc_yuv_fmt { /** * struct gsc_fmt - the driver's internal color format data * @mbus_code: Media Bus pixel code, -1 if not applicable - * @name: format description * @pixelformat: the fourcc code for this format, 0 if not applicable * @yorder: Y/C order * @corder: Chrominance order control @@ -114,7 +113,6 @@ enum gsc_yuv_fmt { */ struct gsc_fmt { u32 mbus_code; - char *name; u32 pixelformat; u32 color; u32 yorder; diff --git a/drivers/media/platform/exynos4-is/fimc-capture.c b/drivers/media/platform/exynos4-is/fimc-capture.c index 66510365dd5d..121d609ff856 100644 --- a/drivers/media/platform/exynos4-is/fimc-capture.c +++ b/drivers/media/platform/exynos4-is/fimc-capture.c @@ -738,10 +738,7 @@ static int fimc_cap_enum_fmt(struct file *file, void *priv, f->index); if (!fmt) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; - if (fmt->fourcc == MEDIA_BUS_FMT_JPEG_1X8) - f->flags |= V4L2_FMT_FLAG_COMPRESSED; return 0; } diff --git a/drivers/media/platform/exynos4-is/fimc-core.c b/drivers/media/platform/exynos4-is/fimc-core.c index 7006f54bfee2..cde60fbb23a8 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.c +++ b/drivers/media/platform/exynos4-is/fimc-core.c @@ -36,7 +36,6 @@ static char *fimc_clocks[MAX_FIMC_CLOCKS] = { static struct fimc_fmt fimc_formats[] = { { - .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565, .depth = { 16 }, .color = FIMC_FMT_RGB565, @@ -44,7 +43,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 1, .flags = FMT_FLAGS_M2M, }, { - .name = "BGR666", .fourcc = V4L2_PIX_FMT_BGR666, .depth = { 32 }, .color = FIMC_FMT_RGB666, @@ -52,7 +50,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 1, .flags = FMT_FLAGS_M2M, }, { - .name = "BGRA8888, 32 bpp", .fourcc = V4L2_PIX_FMT_BGR32, .depth = { 32 }, .color = FIMC_FMT_RGB888, @@ -60,7 +57,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 1, .flags = FMT_FLAGS_M2M | FMT_HAS_ALPHA, }, { - .name = "ARGB1555", .fourcc = V4L2_PIX_FMT_RGB555, .depth = { 16 }, .color = FIMC_FMT_RGB555, @@ -68,7 +64,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 1, .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA, }, { - .name = "ARGB4444", .fourcc = V4L2_PIX_FMT_RGB444, .depth = { 16 }, .color = FIMC_FMT_RGB444, @@ -76,11 +71,9 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 1, .flags = FMT_FLAGS_M2M_OUT | FMT_HAS_ALPHA, }, { - .name = "YUV 4:4:4", .mbus_code = MEDIA_BUS_FMT_YUV10_1X30, .flags = FMT_FLAGS_WRITEBACK, }, { - .name = "YUV 4:2:2 packed, YCbYCr", .fourcc = V4L2_PIX_FMT_YUYV, .depth = { 16 }, .color = FIMC_FMT_YCBYCR422, @@ -89,7 +82,6 @@ static struct fimc_fmt fimc_formats[] = { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { - .name = "YUV 4:2:2 packed, CbYCrY", .fourcc = V4L2_PIX_FMT_UYVY, .depth = { 16 }, .color = FIMC_FMT_CBYCRY422, @@ -98,7 +90,6 @@ static struct fimc_fmt fimc_formats[] = { .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { - .name = "YUV 4:2:2 packed, CrYCbY", .fourcc = V4L2_PIX_FMT_VYUY, .depth = { 16 }, .color = FIMC_FMT_CRYCBY422, @@ -107,7 +98,6 @@ static struct fimc_fmt fimc_formats[] = { .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_YVYU, .depth = { 16 }, .color = FIMC_FMT_YCRYCB422, @@ -116,7 +106,6 @@ static struct fimc_fmt fimc_formats[] = { .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, }, { - .name = "YUV 4:2:2 planar, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV422P, .depth = { 16 }, .color = FIMC_FMT_YCBYCR422, @@ -124,7 +113,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 3, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:2 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV16, .depth = { 16 }, .color = FIMC_FMT_YCBYCR422, @@ -132,7 +120,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:2 planar, Y/CrCb", .fourcc = V4L2_PIX_FMT_NV61, .depth = { 16 }, .color = FIMC_FMT_YCRYCB422, @@ -140,7 +127,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 planar, YCbCr", .fourcc = V4L2_PIX_FMT_YUV420, .depth = { 12 }, .color = FIMC_FMT_YCBCR420, @@ -148,7 +134,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 3, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12, .depth = { 12 }, .color = FIMC_FMT_YCBCR420, @@ -156,7 +141,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contig. 2p, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -164,7 +148,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contig. 3p, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420M, .color = FIMC_FMT_YCBCR420, .depth = { 8, 2, 2 }, @@ -172,7 +155,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 3, .flags = FMT_FLAGS_M2M, }, { - .name = "YUV 4:2:0 non-contig. 2p, tiled", .fourcc = V4L2_PIX_FMT_NV12MT, .color = FIMC_FMT_YCBCR420, .depth = { 8, 4 }, @@ -180,7 +162,6 @@ static struct fimc_fmt fimc_formats[] = { .colplanes = 2, .flags = FMT_FLAGS_M2M, }, { - .name = "JPEG encoded data", .fourcc = V4L2_PIX_FMT_JPEG, .color = FIMC_FMT_JPEG, .depth = { 8 }, @@ -189,7 +170,6 @@ static struct fimc_fmt fimc_formats[] = { .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, .flags = FMT_FLAGS_CAM | FMT_FLAGS_COMPRESSED, }, { - .name = "S5C73MX interleaved UYVY/JPEG", .fourcc = V4L2_PIX_FMT_S5C_UYVY_JPG, .color = FIMC_FMT_YUYV_JPEG, .depth = { 8 }, diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index e043d55133a3..64148b7e0d98 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -341,7 +341,6 @@ static int fimc_is_alloc_cpu_memory(struct fimc_is *is) return -ENOMEM; is->memory.size = FIMC_IS_CPU_MEM_SIZE; - memset(is->memory.vaddr, 0, is->memory.size); dev_info(dev, "FIMC-IS CPU memory base: %#x\n", (u32)is->memory.paddr); @@ -806,6 +805,7 @@ static int fimc_is_probe(struct platform_device *pdev) return -ENODEV; is->pmu_regs = of_iomap(node, 0); + of_node_put(node); if (!is->pmu_regs) return -ENOMEM; diff --git a/drivers/media/platform/exynos4-is/fimc-isp-video.c b/drivers/media/platform/exynos4-is/fimc-isp-video.c index a75f932a289a..378cc302e1f8 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp-video.c +++ b/drivers/media/platform/exynos4-is/fimc-isp-video.c @@ -362,7 +362,6 @@ static int isp_video_enum_fmt(struct file *file, void *priv, if (WARN_ON(fmt == NULL)) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index 907b83e6649d..cde0d254ec1c 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -33,21 +33,18 @@ module_param_named(debug_isp, fimc_isp_debug, int, S_IRUGO | S_IWUSR); static const struct fimc_fmt fimc_isp_formats[FIMC_ISP_NUM_FORMATS] = { { - .name = "RAW8 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG8, .depth = { 8 }, .color = FIMC_FMT_RAW8, .memplanes = 1, .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, }, { - .name = "RAW10 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG10, .depth = { 10 }, .color = FIMC_FMT_RAW10, .memplanes = 1, .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, }, { - .name = "RAW12 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG12, .depth = { 12 }, .color = FIMC_FMT_RAW12, diff --git a/drivers/media/platform/exynos4-is/fimc-lite-reg.h b/drivers/media/platform/exynos4-is/fimc-lite-reg.h index 48f2cf1148b8..c5656e902750 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite-reg.h +++ b/drivers/media/platform/exynos4-is/fimc-lite-reg.h @@ -6,6 +6,8 @@ #ifndef FIMC_LITE_REG_H_ #define FIMC_LITE_REG_H_ +#include <linux/bitops.h> + #include "fimc-lite.h" /* Camera Source size */ @@ -27,27 +29,27 @@ /* User defined formats. x = 0...15 */ #define FLITE_REG_CIGCTRL_USER(x) ((0x30 + x - 1) << 24) #define FLITE_REG_CIGCTRL_FMT_MASK (0x3f << 24) -#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE (1 << 21) -#define FLITE_REG_CIGCTRL_ODMA_DISABLE (1 << 20) -#define FLITE_REG_CIGCTRL_SWRST_REQ (1 << 19) -#define FLITE_REG_CIGCTRL_SWRST_RDY (1 << 18) -#define FLITE_REG_CIGCTRL_SWRST (1 << 17) -#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR (1 << 15) -#define FLITE_REG_CIGCTRL_INVPOLPCLK (1 << 14) -#define FLITE_REG_CIGCTRL_INVPOLVSYNC (1 << 13) -#define FLITE_REG_CIGCTRL_INVPOLHREF (1 << 12) +#define FLITE_REG_CIGCTRL_SHADOWMASK_DISABLE BIT(21) +#define FLITE_REG_CIGCTRL_ODMA_DISABLE BIT(20) +#define FLITE_REG_CIGCTRL_SWRST_REQ BIT(19) +#define FLITE_REG_CIGCTRL_SWRST_RDY BIT(18) +#define FLITE_REG_CIGCTRL_SWRST BIT(17) +#define FLITE_REG_CIGCTRL_TEST_PATTERN_COLORBAR BIT(15) +#define FLITE_REG_CIGCTRL_INVPOLPCLK BIT(14) +#define FLITE_REG_CIGCTRL_INVPOLVSYNC BIT(13) +#define FLITE_REG_CIGCTRL_INVPOLHREF BIT(12) /* Interrupts mask bits (1 disables an interrupt) */ -#define FLITE_REG_CIGCTRL_IRQ_LASTEN (1 << 8) -#define FLITE_REG_CIGCTRL_IRQ_ENDEN (1 << 7) -#define FLITE_REG_CIGCTRL_IRQ_STARTEN (1 << 6) -#define FLITE_REG_CIGCTRL_IRQ_OVFEN (1 << 5) +#define FLITE_REG_CIGCTRL_IRQ_LASTEN BIT(8) +#define FLITE_REG_CIGCTRL_IRQ_ENDEN BIT(7) +#define FLITE_REG_CIGCTRL_IRQ_STARTEN BIT(6) +#define FLITE_REG_CIGCTRL_IRQ_OVFEN BIT(5) #define FLITE_REG_CIGCTRL_IRQ_DISABLE_MASK (0xf << 5) -#define FLITE_REG_CIGCTRL_SELCAM_MIPI (1 << 3) +#define FLITE_REG_CIGCTRL_SELCAM_MIPI BIT(3) /* Image Capture Enable */ #define FLITE_REG_CIIMGCPT 0x08 -#define FLITE_REG_CIIMGCPT_IMGCPTEN (1 << 31) -#define FLITE_REG_CIIMGCPT_CPT_FREN (1 << 25) +#define FLITE_REG_CIIMGCPT_IMGCPTEN BIT(31) +#define FLITE_REG_CIIMGCPT_CPT_FREN BIT(25) #define FLITE_REG_CIIMGCPT_CPT_MOD_FRCNT (1 << 18) #define FLITE_REG_CIIMGCPT_CPT_MOD_FREN (0 << 18) @@ -56,10 +58,10 @@ /* Camera Window Offset */ #define FLITE_REG_CIWDOFST 0x10 -#define FLITE_REG_CIWDOFST_WINOFSEN (1 << 31) -#define FLITE_REG_CIWDOFST_CLROVIY (1 << 31) -#define FLITE_REG_CIWDOFST_CLROVFICB (1 << 15) -#define FLITE_REG_CIWDOFST_CLROVFICR (1 << 14) +#define FLITE_REG_CIWDOFST_WINOFSEN BIT(31) +#define FLITE_REG_CIWDOFST_CLROVIY BIT(31) +#define FLITE_REG_CIWDOFST_CLROVFICB BIT(15) +#define FLITE_REG_CIWDOFST_CLROVFICR BIT(14) #define FLITE_REG_CIWDOFST_OFST_MASK ((0x1fff << 16) | 0x1fff) /* Camera Window Offset2 */ @@ -67,8 +69,8 @@ /* Camera Output DMA Format */ #define FLITE_REG_CIODMAFMT 0x18 -#define FLITE_REG_CIODMAFMT_RAW_CON (1 << 15) -#define FLITE_REG_CIODMAFMT_PACK12 (1 << 14) +#define FLITE_REG_CIODMAFMT_RAW_CON BIT(15) +#define FLITE_REG_CIODMAFMT_PACK12 BIT(14) #define FLITE_REG_CIODMAFMT_YCBYCR (0 << 4) #define FLITE_REG_CIODMAFMT_YCRYCB (1 << 4) #define FLITE_REG_CIODMAFMT_CBYCRY (2 << 4) @@ -88,34 +90,34 @@ /* Camera Status */ #define FLITE_REG_CISTATUS 0x40 -#define FLITE_REG_CISTATUS_MIPI_VVALID (1 << 22) -#define FLITE_REG_CISTATUS_MIPI_HVALID (1 << 21) -#define FLITE_REG_CISTATUS_MIPI_DVALID (1 << 20) -#define FLITE_REG_CISTATUS_ITU_VSYNC (1 << 14) -#define FLITE_REG_CISTATUS_ITU_HREFF (1 << 13) -#define FLITE_REG_CISTATUS_OVFIY (1 << 10) -#define FLITE_REG_CISTATUS_OVFICB (1 << 9) -#define FLITE_REG_CISTATUS_OVFICR (1 << 8) -#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW (1 << 7) -#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND (1 << 6) -#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART (1 << 5) -#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND (1 << 4) -#define FLITE_REG_CISTATUS_IRQ_CAM (1 << 0) +#define FLITE_REG_CISTATUS_MIPI_VVALID BIT(22) +#define FLITE_REG_CISTATUS_MIPI_HVALID BIT(21) +#define FLITE_REG_CISTATUS_MIPI_DVALID BIT(20) +#define FLITE_REG_CISTATUS_ITU_VSYNC BIT(14) +#define FLITE_REG_CISTATUS_ITU_HREFF BIT(13) +#define FLITE_REG_CISTATUS_OVFIY BIT(10) +#define FLITE_REG_CISTATUS_OVFICB BIT(9) +#define FLITE_REG_CISTATUS_OVFICR BIT(8) +#define FLITE_REG_CISTATUS_IRQ_SRC_OVERFLOW BIT(7) +#define FLITE_REG_CISTATUS_IRQ_SRC_LASTCAPEND BIT(6) +#define FLITE_REG_CISTATUS_IRQ_SRC_FRMSTART BIT(5) +#define FLITE_REG_CISTATUS_IRQ_SRC_FRMEND BIT(4) +#define FLITE_REG_CISTATUS_IRQ_CAM BIT(0) #define FLITE_REG_CISTATUS_IRQ_MASK (0xf << 4) /* Camera Status2 */ #define FLITE_REG_CISTATUS2 0x44 -#define FLITE_REG_CISTATUS2_LASTCAPEND (1 << 1) -#define FLITE_REG_CISTATUS2_FRMEND (1 << 0) +#define FLITE_REG_CISTATUS2_LASTCAPEND BIT(1) +#define FLITE_REG_CISTATUS2_FRMEND BIT(0) /* Qos Threshold */ #define FLITE_REG_CITHOLD 0xf0 -#define FLITE_REG_CITHOLD_W_QOS_EN (1 << 30) +#define FLITE_REG_CITHOLD_W_QOS_EN BIT(30) /* Camera General Purpose */ #define FLITE_REG_CIGENERAL 0xfc /* b0: 1 - camera B, 0 - camera A */ -#define FLITE_REG_CIGENERAL_CAM_B (1 << 0) +#define FLITE_REG_CIGENERAL_CAM_B BIT(0) #define FLITE_REG_CIFCNTSEQ 0x100 #define FLITE_REG_CIOSAN(x) (0x200 + (4 * (x))) diff --git a/drivers/media/platform/exynos4-is/fimc-lite.c b/drivers/media/platform/exynos4-is/fimc-lite.c index c1f0aee02e5e..e87c6a09205b 100644 --- a/drivers/media/platform/exynos4-is/fimc-lite.c +++ b/drivers/media/platform/exynos4-is/fimc-lite.c @@ -39,7 +39,6 @@ module_param(debug, int, 0644); static const struct fimc_fmt fimc_lite_formats[] = { { - .name = "YUV 4:2:2 packed, YCbYCr", .fourcc = V4L2_PIX_FMT_YUYV, .colorspace = V4L2_COLORSPACE_JPEG, .depth = { 16 }, @@ -48,7 +47,6 @@ static const struct fimc_fmt fimc_lite_formats[] = { .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .flags = FMT_FLAGS_YUV, }, { - .name = "YUV 4:2:2 packed, CbYCrY", .fourcc = V4L2_PIX_FMT_UYVY, .colorspace = V4L2_COLORSPACE_JPEG, .depth = { 16 }, @@ -57,7 +55,6 @@ static const struct fimc_fmt fimc_lite_formats[] = { .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8, .flags = FMT_FLAGS_YUV, }, { - .name = "YUV 4:2:2 packed, CrYCbY", .fourcc = V4L2_PIX_FMT_VYUY, .colorspace = V4L2_COLORSPACE_JPEG, .depth = { 16 }, @@ -66,7 +63,6 @@ static const struct fimc_fmt fimc_lite_formats[] = { .mbus_code = MEDIA_BUS_FMT_VYUY8_2X8, .flags = FMT_FLAGS_YUV, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_YVYU, .colorspace = V4L2_COLORSPACE_JPEG, .depth = { 16 }, @@ -75,7 +71,6 @@ static const struct fimc_fmt fimc_lite_formats[] = { .mbus_code = MEDIA_BUS_FMT_YVYU8_2X8, .flags = FMT_FLAGS_YUV, }, { - .name = "RAW8 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG8, .colorspace = V4L2_COLORSPACE_SRGB, .depth = { 8 }, @@ -84,7 +79,6 @@ static const struct fimc_fmt fimc_lite_formats[] = { .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, .flags = FMT_FLAGS_RAW_BAYER, }, { - .name = "RAW10 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG10, .colorspace = V4L2_COLORSPACE_SRGB, .depth = { 16 }, @@ -93,7 +87,6 @@ static const struct fimc_fmt fimc_lite_formats[] = { .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, .flags = FMT_FLAGS_RAW_BAYER, }, { - .name = "RAW12 (GRBG)", .fourcc = V4L2_PIX_FMT_SGRBG12, .colorspace = V4L2_COLORSPACE_SRGB, .depth = { 16 }, @@ -667,7 +660,6 @@ static int fimc_lite_enum_fmt(struct file *file, void *priv, return -EINVAL; fmt = &fimc_lite_formats[f->index]; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 62e876fc3555..c70c2cbe3eb1 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -247,7 +247,6 @@ static int fimc_m2m_enum_fmt(struct file *file, void *priv, if (!fmt) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } diff --git a/drivers/media/platform/exynos4-is/fimc-reg.h b/drivers/media/platform/exynos4-is/fimc-reg.h index 03ba6c2bc84b..b81826d04936 100644 --- a/drivers/media/platform/exynos4-is/fimc-reg.h +++ b/drivers/media/platform/exynos4-is/fimc-reg.h @@ -8,12 +8,14 @@ #ifndef FIMC_REG_H_ #define FIMC_REG_H_ +#include <linux/bitops.h> + #include "fimc-core.h" /* Input source format */ #define FIMC_REG_CISRCFMT 0x00 -#define FIMC_REG_CISRCFMT_ITU601_8BIT (1 << 31) -#define FIMC_REG_CISRCFMT_ITU601_16BIT (1 << 29) +#define FIMC_REG_CISRCFMT_ITU601_8BIT BIT(31) +#define FIMC_REG_CISRCFMT_ITU601_16BIT BIT(29) #define FIMC_REG_CISRCFMT_ORDER422_YCBYCR (0 << 14) #define FIMC_REG_CISRCFMT_ORDER422_YCRYCB (1 << 14) #define FIMC_REG_CISRCFMT_ORDER422_CBYCRY (2 << 14) @@ -21,45 +23,45 @@ /* Window offset */ #define FIMC_REG_CIWDOFST 0x04 -#define FIMC_REG_CIWDOFST_OFF_EN (1 << 31) -#define FIMC_REG_CIWDOFST_CLROVFIY (1 << 30) -#define FIMC_REG_CIWDOFST_CLROVRLB (1 << 29) +#define FIMC_REG_CIWDOFST_OFF_EN BIT(31) +#define FIMC_REG_CIWDOFST_CLROVFIY BIT(30) +#define FIMC_REG_CIWDOFST_CLROVRLB BIT(29) #define FIMC_REG_CIWDOFST_HOROFF_MASK (0x7ff << 16) -#define FIMC_REG_CIWDOFST_CLROVFICB (1 << 15) -#define FIMC_REG_CIWDOFST_CLROVFICR (1 << 14) +#define FIMC_REG_CIWDOFST_CLROVFICB BIT(15) +#define FIMC_REG_CIWDOFST_CLROVFICR BIT(14) #define FIMC_REG_CIWDOFST_VEROFF_MASK (0xfff << 0) /* Global control */ #define FIMC_REG_CIGCTRL 0x08 -#define FIMC_REG_CIGCTRL_SWRST (1 << 31) -#define FIMC_REG_CIGCTRL_CAMRST_A (1 << 30) -#define FIMC_REG_CIGCTRL_SELCAM_ITU_A (1 << 29) +#define FIMC_REG_CIGCTRL_SWRST BIT(31) +#define FIMC_REG_CIGCTRL_CAMRST_A BIT(30) +#define FIMC_REG_CIGCTRL_SELCAM_ITU_A BIT(29) #define FIMC_REG_CIGCTRL_TESTPAT_NORMAL (0 << 27) #define FIMC_REG_CIGCTRL_TESTPAT_COLOR_BAR (1 << 27) #define FIMC_REG_CIGCTRL_TESTPAT_HOR_INC (2 << 27) #define FIMC_REG_CIGCTRL_TESTPAT_VER_INC (3 << 27) #define FIMC_REG_CIGCTRL_TESTPAT_MASK (3 << 27) #define FIMC_REG_CIGCTRL_TESTPAT_SHIFT 27 -#define FIMC_REG_CIGCTRL_INVPOLPCLK (1 << 26) -#define FIMC_REG_CIGCTRL_INVPOLVSYNC (1 << 25) -#define FIMC_REG_CIGCTRL_INVPOLHREF (1 << 24) -#define FIMC_REG_CIGCTRL_IRQ_OVFEN (1 << 22) -#define FIMC_REG_CIGCTRL_HREF_MASK (1 << 21) -#define FIMC_REG_CIGCTRL_IRQ_LEVEL (1 << 20) -#define FIMC_REG_CIGCTRL_IRQ_CLR (1 << 19) -#define FIMC_REG_CIGCTRL_IRQ_ENABLE (1 << 16) -#define FIMC_REG_CIGCTRL_SHDW_DISABLE (1 << 12) +#define FIMC_REG_CIGCTRL_INVPOLPCLK BIT(26) +#define FIMC_REG_CIGCTRL_INVPOLVSYNC BIT(25) +#define FIMC_REG_CIGCTRL_INVPOLHREF BIT(24) +#define FIMC_REG_CIGCTRL_IRQ_OVFEN BIT(22) +#define FIMC_REG_CIGCTRL_HREF_MASK BIT(21) +#define FIMC_REG_CIGCTRL_IRQ_LEVEL BIT(20) +#define FIMC_REG_CIGCTRL_IRQ_CLR BIT(19) +#define FIMC_REG_CIGCTRL_IRQ_ENABLE BIT(16) +#define FIMC_REG_CIGCTRL_SHDW_DISABLE BIT(12) /* 0 - selects Writeback A (LCD), 1 - selects Writeback B (LCD/ISP) */ -#define FIMC_REG_CIGCTRL_SELWB_A (1 << 10) -#define FIMC_REG_CIGCTRL_CAM_JPEG (1 << 8) -#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A (1 << 7) -#define FIMC_REG_CIGCTRL_CAMIF_SELWB (1 << 6) +#define FIMC_REG_CIGCTRL_SELWB_A BIT(10) +#define FIMC_REG_CIGCTRL_CAM_JPEG BIT(8) +#define FIMC_REG_CIGCTRL_SELCAM_MIPI_A BIT(7) +#define FIMC_REG_CIGCTRL_CAMIF_SELWB BIT(6) /* 0 - ITU601; 1 - ITU709 */ -#define FIMC_REG_CIGCTRL_CSC_ITU601_709 (1 << 5) -#define FIMC_REG_CIGCTRL_INVPOLHSYNC (1 << 4) -#define FIMC_REG_CIGCTRL_SELCAM_MIPI (1 << 3) -#define FIMC_REG_CIGCTRL_INVPOLFIELD (1 << 1) -#define FIMC_REG_CIGCTRL_INTERLACE (1 << 0) +#define FIMC_REG_CIGCTRL_CSC_ITU601_709 BIT(5) +#define FIMC_REG_CIGCTRL_INVPOLHSYNC BIT(4) +#define FIMC_REG_CIGCTRL_SELCAM_MIPI BIT(3) +#define FIMC_REG_CIGCTRL_INVPOLFIELD BIT(1) +#define FIMC_REG_CIGCTRL_INTERLACE BIT(0) /* Window offset 2 */ #define FIMC_REG_CIWDOFST2 0x14 @@ -73,7 +75,7 @@ /* Target image format */ #define FIMC_REG_CITRGFMT 0x48 -#define FIMC_REG_CITRGFMT_INROT90 (1 << 31) +#define FIMC_REG_CITRGFMT_INROT90 BIT(31) #define FIMC_REG_CITRGFMT_YCBCR420 (0 << 29) #define FIMC_REG_CITRGFMT_YCBCR422 (1 << 29) #define FIMC_REG_CITRGFMT_YCBCR422_1P (2 << 29) @@ -86,7 +88,7 @@ #define FIMC_REG_CITRGFMT_FLIP_Y_MIRROR (2 << 14) #define FIMC_REG_CITRGFMT_FLIP_180 (3 << 14) #define FIMC_REG_CITRGFMT_FLIP_MASK (3 << 14) -#define FIMC_REG_CITRGFMT_OUTROT90 (1 << 13) +#define FIMC_REG_CITRGFMT_OUTROT90 BIT(13) #define FIMC_REG_CITRGFMT_VSIZE_MASK (0xfff << 0) /* Output DMA control */ @@ -96,7 +98,7 @@ #define FIMC_REG_CIOCTRL_ORDER422_YCRYCB (1 << 0) #define FIMC_REG_CIOCTRL_ORDER422_CBYCRY (2 << 0) #define FIMC_REG_CIOCTRL_ORDER422_CRYCBY (3 << 0) -#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE (1 << 2) +#define FIMC_REG_CIOCTRL_LASTIRQ_ENABLE BIT(2) #define FIMC_REG_CIOCTRL_YCBCR_3PLANE (0 << 3) #define FIMC_REG_CIOCTRL_YCBCR_2PLANE (1 << 3) #define FIMC_REG_CIOCTRL_YCBCR_PLANE_MASK (1 << 3) @@ -116,14 +118,14 @@ /* Main scaler control */ #define FIMC_REG_CISCCTRL 0x58 -#define FIMC_REG_CISCCTRL_SCALERBYPASS (1 << 31) -#define FIMC_REG_CISCCTRL_SCALEUP_H (1 << 30) -#define FIMC_REG_CISCCTRL_SCALEUP_V (1 << 29) -#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE (1 << 28) -#define FIMC_REG_CISCCTRL_CSCY2R_WIDE (1 << 27) -#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO (1 << 26) -#define FIMC_REG_CISCCTRL_INTERLACE (1 << 25) -#define FIMC_REG_CISCCTRL_SCALERSTART (1 << 15) +#define FIMC_REG_CISCCTRL_SCALERBYPASS BIT(31) +#define FIMC_REG_CISCCTRL_SCALEUP_H BIT(30) +#define FIMC_REG_CISCCTRL_SCALEUP_V BIT(29) +#define FIMC_REG_CISCCTRL_CSCR2Y_WIDE BIT(28) +#define FIMC_REG_CISCCTRL_CSCY2R_WIDE BIT(27) +#define FIMC_REG_CISCCTRL_LCDPATHEN_FIFO BIT(26) +#define FIMC_REG_CISCCTRL_INTERLACE BIT(25) +#define FIMC_REG_CISCCTRL_SCALERSTART BIT(15) #define FIMC_REG_CISCCTRL_INRGB_FMT_RGB565 (0 << 13) #define FIMC_REG_CISCCTRL_INRGB_FMT_RGB666 (1 << 13) #define FIMC_REG_CISCCTRL_INRGB_FMT_RGB888 (2 << 13) @@ -132,8 +134,8 @@ #define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11) #define FIMC_REG_CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11) #define FIMC_REG_CISCCTRL_OUTRGB_FMT_MASK (3 << 11) -#define FIMC_REG_CISCCTRL_RGB_EXT (1 << 10) -#define FIMC_REG_CISCCTRL_ONE2ONE (1 << 9) +#define FIMC_REG_CISCCTRL_RGB_EXT BIT(10) +#define FIMC_REG_CISCCTRL_ONE2ONE BIT(9) #define FIMC_REG_CISCCTRL_MHRATIO(x) ((x) << 16) #define FIMC_REG_CISCCTRL_MVRATIO(x) ((x) << 0) #define FIMC_REG_CISCCTRL_MHRATIO_MASK (0x1ff << 16) @@ -147,39 +149,39 @@ /* General status */ #define FIMC_REG_CISTATUS 0x64 -#define FIMC_REG_CISTATUS_OVFIY (1 << 31) -#define FIMC_REG_CISTATUS_OVFICB (1 << 30) -#define FIMC_REG_CISTATUS_OVFICR (1 << 29) -#define FIMC_REG_CISTATUS_VSYNC (1 << 28) +#define FIMC_REG_CISTATUS_OVFIY BIT(31) +#define FIMC_REG_CISTATUS_OVFICB BIT(30) +#define FIMC_REG_CISTATUS_OVFICR BIT(29) +#define FIMC_REG_CISTATUS_VSYNC BIT(28) #define FIMC_REG_CISTATUS_FRAMECNT_MASK (3 << 26) #define FIMC_REG_CISTATUS_FRAMECNT_SHIFT 26 -#define FIMC_REG_CISTATUS_WINOFF_EN (1 << 25) -#define FIMC_REG_CISTATUS_IMGCPT_EN (1 << 22) -#define FIMC_REG_CISTATUS_IMGCPT_SCEN (1 << 21) -#define FIMC_REG_CISTATUS_VSYNC_A (1 << 20) -#define FIMC_REG_CISTATUS_VSYNC_B (1 << 19) -#define FIMC_REG_CISTATUS_OVRLB (1 << 18) -#define FIMC_REG_CISTATUS_FRAME_END (1 << 17) -#define FIMC_REG_CISTATUS_LASTCAPT_END (1 << 16) -#define FIMC_REG_CISTATUS_VVALID_A (1 << 15) -#define FIMC_REG_CISTATUS_VVALID_B (1 << 14) +#define FIMC_REG_CISTATUS_WINOFF_EN BIT(25) +#define FIMC_REG_CISTATUS_IMGCPT_EN BIT(22) +#define FIMC_REG_CISTATUS_IMGCPT_SCEN BIT(21) +#define FIMC_REG_CISTATUS_VSYNC_A BIT(20) +#define FIMC_REG_CISTATUS_VSYNC_B BIT(19) +#define FIMC_REG_CISTATUS_OVRLB BIT(18) +#define FIMC_REG_CISTATUS_FRAME_END BIT(17) +#define FIMC_REG_CISTATUS_LASTCAPT_END BIT(16) +#define FIMC_REG_CISTATUS_VVALID_A BIT(15) +#define FIMC_REG_CISTATUS_VVALID_B BIT(14) /* Indexes to the last and the currently processed buffer. */ #define FIMC_REG_CISTATUS2 0x68 /* Image capture control */ #define FIMC_REG_CIIMGCPT 0xc0 -#define FIMC_REG_CIIMGCPT_IMGCPTEN (1 << 31) -#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC (1 << 30) -#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE (1 << 25) -#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT (1 << 18) +#define FIMC_REG_CIIMGCPT_IMGCPTEN BIT(31) +#define FIMC_REG_CIIMGCPT_IMGCPTEN_SC BIT(30) +#define FIMC_REG_CIIMGCPT_CPT_FREN_ENABLE BIT(25) +#define FIMC_REG_CIIMGCPT_CPT_FRMOD_CNT BIT(18) /* Frame capture sequence */ #define FIMC_REG_CICPTSEQ 0xc4 /* Image effect */ #define FIMC_REG_CIIMGEFF 0xd0 -#define FIMC_REG_CIIMGEFF_IE_ENABLE (1 << 30) +#define FIMC_REG_CIIMGEFF_IE_ENABLE BIT(30) #define FIMC_REG_CIIMGEFF_IE_SC_BEFORE (0 << 29) #define FIMC_REG_CIIMGEFF_IE_SC_AFTER (1 << 29) #define FIMC_REG_CIIMGEFF_FIN_BYPASS (0 << 26) @@ -198,8 +200,8 @@ /* Real input DMA image size */ #define FIMC_REG_CIREAL_ISIZE 0xf8 -#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN (1 << 31) -#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS (1 << 30) +#define FIMC_REG_CIREAL_ISIZE_AUTOLOAD_EN BIT(31) +#define FIMC_REG_CIREAL_ISIZE_ADDR_CH_DIS BIT(30) /* Input DMA control */ #define FIMC_REG_MSCTRL 0xfc @@ -215,7 +217,7 @@ #define FIMC_REG_MSCTRL_FLIP_X_MIRROR (1 << 13) #define FIMC_REG_MSCTRL_FLIP_Y_MIRROR (2 << 13) #define FIMC_REG_MSCTRL_FLIP_180 (3 << 13) -#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL (1 << 12) +#define FIMC_REG_MSCTRL_FIFO_CTRL_FULL BIT(12) #define FIMC_REG_MSCTRL_ORDER422_SHIFT 4 #define FIMC_REG_MSCTRL_ORDER422_CRYCBY (0 << 4) #define FIMC_REG_MSCTRL_ORDER422_YCRYCB (1 << 4) @@ -223,14 +225,14 @@ #define FIMC_REG_MSCTRL_ORDER422_YCBYCR (3 << 4) #define FIMC_REG_MSCTRL_ORDER422_MASK (3 << 4) #define FIMC_REG_MSCTRL_INPUT_EXTCAM (0 << 3) -#define FIMC_REG_MSCTRL_INPUT_MEMORY (1 << 3) -#define FIMC_REG_MSCTRL_INPUT_MASK (1 << 3) +#define FIMC_REG_MSCTRL_INPUT_MEMORY BIT(3) +#define FIMC_REG_MSCTRL_INPUT_MASK BIT(3) #define FIMC_REG_MSCTRL_INFORMAT_YCBCR420 (0 << 1) #define FIMC_REG_MSCTRL_INFORMAT_YCBCR422 (1 << 1) #define FIMC_REG_MSCTRL_INFORMAT_YCBCR422_1P (2 << 1) #define FIMC_REG_MSCTRL_INFORMAT_RGB (3 << 1) #define FIMC_REG_MSCTRL_INFORMAT_MASK (3 << 1) -#define FIMC_REG_MSCTRL_ENVID (1 << 0) +#define FIMC_REG_MSCTRL_ENVID BIT(0) #define FIMC_REG_MSCTRL_IN_BURST_COUNT(x) ((x) << 24) /* Output DMA Y/Cb/Cr offset */ @@ -277,10 +279,10 @@ /* SYSREG ISP Writeback register address offsets */ #define SYSREG_ISPBLK 0x020c -#define SYSREG_ISPBLK_FIFORST_CAM_BLK (1 << 7) +#define SYSREG_ISPBLK_FIFORST_CAM_BLK BIT(7) #define SYSREG_CAMBLK 0x0218 -#define SYSREG_CAMBLK_FIFORST_ISP (1 << 15) +#define SYSREG_CAMBLK_FIFORST_ISP BIT(15) #define SYSREG_CAMBLK_ISPWB_FULL_EN (7 << 20) /* diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index d53427a8db11..a838189d4490 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -501,6 +501,7 @@ static int fimc_md_register_sensor_entities(struct fimc_md *fmd) continue; ret = fimc_md_parse_port_node(fmd, port, index); + of_node_put(port); if (ret < 0) { of_node_put(node); goto cleanup; @@ -542,6 +543,7 @@ static int __of_get_csis_id(struct device_node *np) if (!np) return -EINVAL; of_property_read_u32(np, "reg", ®); + of_node_put(np); return reg - FIMC_INPUT_MIPI_CSI2_0; } diff --git a/drivers/media/platform/exynos4-is/mipi-csis.c b/drivers/media/platform/exynos4-is/mipi-csis.c index 3e9ac6066cf6..540151bbf58f 100644 --- a/drivers/media/platform/exynos4-is/mipi-csis.c +++ b/drivers/media/platform/exynos4-is/mipi-csis.c @@ -41,7 +41,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); /* CSIS global control */ #define S5PCSIS_CTRL 0x00 #define S5PCSIS_CTRL_DPDN_DEFAULT (0 << 31) -#define S5PCSIS_CTRL_DPDN_SWAP (1 << 31) +#define S5PCSIS_CTRL_DPDN_SWAP (1UL << 31) #define S5PCSIS_CTRL_ALIGN_32BIT (1 << 20) #define S5PCSIS_CTRL_UPDATE_SHADOW (1 << 16) #define S5PCSIS_CTRL_WCLK_EXTCLK (1 << 8) @@ -65,7 +65,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); /* Interrupt mask */ #define S5PCSIS_INTMSK 0x10 -#define S5PCSIS_INTMSK_EVEN_BEFORE (1 << 31) +#define S5PCSIS_INTMSK_EVEN_BEFORE (1UL << 31) #define S5PCSIS_INTMSK_EVEN_AFTER (1 << 30) #define S5PCSIS_INTMSK_ODD_BEFORE (1 << 29) #define S5PCSIS_INTMSK_ODD_AFTER (1 << 28) @@ -83,7 +83,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-2)"); /* Interrupt source */ #define S5PCSIS_INTSRC 0x14 -#define S5PCSIS_INTSRC_EVEN_BEFORE (1 << 31) +#define S5PCSIS_INTSRC_EVEN_BEFORE (1UL << 31) #define S5PCSIS_INTSRC_EVEN_AFTER (1 << 30) #define S5PCSIS_INTSRC_EVEN (0x3 << 30) #define S5PCSIS_INTSRC_ODD_BEFORE (1 << 29) @@ -803,10 +803,8 @@ static int s5pcsis_probe(struct platform_device *pdev) return PTR_ERR(state->regs); state->irq = platform_get_irq(pdev, 0); - if (state->irq < 0) { - dev_err(dev, "Failed to get irq\n"); + if (state->irq < 0) return state->irq; - } for (i = 0; i < CSIS_NUM_SUPPLIES; i++) state->supplies[i].supply = csis_supply_name[i]; diff --git a/drivers/media/platform/fsl-viu.c b/drivers/media/platform/fsl-viu.c index 691be788e38b..81a8faedbba6 100644 --- a/drivers/media/platform/fsl-viu.c +++ b/drivers/media/platform/fsl-viu.c @@ -32,7 +32,7 @@ #define VIU_VERSION "0.5.1" /* Allow building this driver with COMPILE_TEST */ -#ifndef CONFIG_PPC +#if !defined(CONFIG_PPC) && !defined(CONFIG_MICROBLAZE) #define out_be32(v, a) iowrite32be(a, (void __iomem *)v) #define in_be32(a) ioread32be((void __iomem *)a) #endif @@ -214,7 +214,7 @@ enum status_config { FIELD_NO = 0x01 << 28, /* Field number */ DITHER_ON = 0x01 << 29, /* Dithering is on */ ROUND_ON = 0x01 << 30, /* Round is on */ - MODE_32BIT = 0x01 << 31, /* Data in RGBa888, + MODE_32BIT = 1UL << 31, /* Data in RGBa888, * 0 in RGB565 */ }; @@ -563,11 +563,6 @@ static int vidioc_querycap(struct file *file, void *priv, strscpy(cap->driver, "viu", sizeof(cap->driver)); strscpy(cap->card, "viu", sizeof(cap->card)); strscpy(cap->bus_info, "platform:viu", sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING | - V4L2_CAP_VIDEO_OVERLAY | - V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -1380,6 +1375,8 @@ static const struct video_device viu_template = { .release = video_device_release, .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL, + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_READWRITE, }; static int viu_of_probe(struct platform_device *op) diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c index 8e7ef23b9a7e..38d942322302 100644 --- a/drivers/media/platform/imx-pxp.c +++ b/drivers/media/platform/imx-pxp.c @@ -1661,10 +1661,8 @@ static int pxp_probe(struct platform_device *pdev) } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "Failed to get irq resource: %d\n", irq); + if (irq < 0) return irq; - } ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler, IRQF_ONESHOT, dev_name(&pdev->dev), dev); diff --git a/drivers/media/platform/m2m-deinterlace.c b/drivers/media/platform/m2m-deinterlace.c index beb7fd7442fb..9ad24c86c5ab 100644 --- a/drivers/media/platform/m2m-deinterlace.c +++ b/drivers/media/platform/m2m-deinterlace.c @@ -37,7 +37,6 @@ module_param(debug, bool, 0644); v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg) struct deinterlace_fmt { - char *name; u32 fourcc; /* Types the format can be used for */ u32 types; @@ -45,12 +44,10 @@ struct deinterlace_fmt { static struct deinterlace_fmt formats[] = { { - .name = "YUV 4:2:0 Planar", .fourcc = V4L2_PIX_FMT_YUV420, .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, }, { - .name = "YUYV 4:2:2", .fourcc = V4L2_PIX_FMT_YUYV, .types = MEM2MEM_CAPTURE | MEM2MEM_OUTPUT, }, @@ -135,13 +132,13 @@ struct deinterlace_dev { }; struct deinterlace_ctx { + struct v4l2_fh fh; struct deinterlace_dev *dev; /* Abort requested by m2m */ int aborting; enum v4l2_colorspace colorspace; dma_cookie_t cookie; - struct v4l2_m2m_ctx *m2m_ctx; struct dma_interleaved_template *xt; }; @@ -153,9 +150,9 @@ static int deinterlace_job_ready(void *priv) struct deinterlace_ctx *ctx = priv; struct deinterlace_dev *pcdev = ctx->dev; - if ((v4l2_m2m_num_src_bufs_ready(ctx->m2m_ctx) > 0) - && (v4l2_m2m_num_dst_bufs_ready(ctx->m2m_ctx) > 0) - && (atomic_read(&ctx->dev->busy) == 0)) { + if (v4l2_m2m_num_src_bufs_ready(ctx->fh.m2m_ctx) > 0 && + v4l2_m2m_num_dst_bufs_ready(ctx->fh.m2m_ctx) > 0 && + !atomic_read(&ctx->dev->busy)) { dprintk(pcdev, "Task ready\n"); return 1; } @@ -174,7 +171,7 @@ static void deinterlace_job_abort(void *priv) dprintk(pcdev, "Aborting task\n"); - v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx); + v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->fh.m2m_ctx); } static void dma_callback(void *data) @@ -185,8 +182,8 @@ static void dma_callback(void *data) atomic_set(&pcdev->busy, 0); - src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); - dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); + src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); + dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp; dst_vb->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK; @@ -197,7 +194,7 @@ static void dma_callback(void *data) v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE); v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE); - v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx); + v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->fh.m2m_ctx); dprintk(pcdev, "dma transfers completed.\n"); } @@ -216,8 +213,8 @@ static void deinterlace_issue_dma(struct deinterlace_ctx *ctx, int op, dma_addr_t p_in, p_out; enum dma_ctrl_flags flags; - src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); - dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); s_q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT); s_width = s_q_data->width; @@ -436,16 +433,7 @@ static int vidioc_querycap(struct file *file, void *priv, { strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); - strscpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->card)); - /* - * This is only a mem-to-mem video device. The capture and output - * device capability flags are left only for backward compatibility - * and are scheduled for removal. - */ - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | - V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - + strscpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); return 0; } @@ -470,7 +458,6 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) if (i < NUM_FORMATS) { /* Format found */ fmt = &formats[i]; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } @@ -496,7 +483,7 @@ static int vidioc_g_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f) struct vb2_queue *vq; struct deinterlace_q_data *q_data; - vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (!vq) return -EINVAL; @@ -593,7 +580,7 @@ static int vidioc_s_fmt(struct deinterlace_ctx *ctx, struct v4l2_format *f) struct deinterlace_q_data *q_data; struct vb2_queue *vq; - vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (!vq) return -EINVAL; @@ -666,36 +653,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, return ret; } -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *reqbufs) -{ - struct deinterlace_ctx *ctx = priv; - - return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct deinterlace_ctx *ctx = priv; - - return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); -} - -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct deinterlace_ctx *ctx = priv; - - return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct deinterlace_ctx *ctx = priv; - - return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); -} - static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { @@ -736,15 +693,7 @@ static int vidioc_streamon(struct file *file, void *priv, return -EINVAL; } - return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); -} - -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct deinterlace_ctx *ctx = priv; - - return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); + return v4l2_m2m_streamon(file, ctx->fh.m2m_ctx, type); } static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = { @@ -760,14 +709,15 @@ static const struct v4l2_ioctl_ops deinterlace_ioctl_ops = { .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, }; @@ -831,7 +781,7 @@ static void deinterlace_buf_queue(struct vb2_buffer *vb) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct deinterlace_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf); + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); } static const struct vb2_ops deinterlace_qops = { @@ -849,7 +799,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, int ret; src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - src_vq->io_modes = VB2_MMAP | VB2_USERPTR; + src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); src_vq->ops = &deinterlace_qops; @@ -868,7 +818,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, return ret; dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); dst_vq->ops = &deinterlace_qops; @@ -897,12 +847,13 @@ static int deinterlace_open(struct file *file) if (!ctx) return -ENOMEM; - file->private_data = ctx; + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; ctx->dev = pcdev; - ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init); - if (IS_ERR(ctx->m2m_ctx)) { - int ret = PTR_ERR(ctx->m2m_ctx); + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init); + if (IS_ERR(ctx->fh.m2m_ctx)) { + int ret = PTR_ERR(ctx->fh.m2m_ctx); kfree(ctx); return ret; @@ -916,8 +867,10 @@ static int deinterlace_open(struct file *file) } ctx->colorspace = V4L2_COLORSPACE_REC709; + v4l2_fh_add(&ctx->fh); - dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx); + dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", + ctx, ctx->fh.m2m_ctx); return 0; } @@ -929,40 +882,22 @@ static int deinterlace_release(struct file *file) dprintk(pcdev, "Releasing instance %p\n", ctx); - v4l2_m2m_ctx_release(ctx->m2m_ctx); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); kfree(ctx->xt); kfree(ctx); return 0; } -static __poll_t deinterlace_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct deinterlace_ctx *ctx = file->private_data; - __poll_t ret; - - mutex_lock(&ctx->dev->dev_mutex); - ret = v4l2_m2m_poll(file, ctx->m2m_ctx, wait); - mutex_unlock(&ctx->dev->dev_mutex); - - return ret; -} - -static int deinterlace_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct deinterlace_ctx *ctx = file->private_data; - - return v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); -} - static const struct v4l2_file_operations deinterlace_fops = { .owner = THIS_MODULE, .open = deinterlace_open, .release = deinterlace_release, - .poll = deinterlace_poll, + .poll = v4l2_m2m_fop_poll, .unlocked_ioctl = video_ioctl2, - .mmap = deinterlace_mmap, + .mmap = v4l2_m2m_fop_mmap, }; static const struct video_device deinterlace_videodev = { @@ -972,6 +907,7 @@ static const struct video_device deinterlace_videodev = { .minor = -1, .release = video_device_release_empty, .vfl_dir = VFL_DIR_M2M, + .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, }; static const struct v4l2_m2m_ops m2m_ops = { diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c index dc30c48d4671..803baf97f06e 100644 --- a/drivers/media/platform/marvell-ccic/mcam-core.c +++ b/drivers/media/platform/marvell-ccic/mcam-core.c @@ -98,56 +98,48 @@ MODULE_PARM_DESC(buffer_mode, container_of(notifier, struct mcam_camera, notifier) static struct mcam_format_struct { - __u8 *desc; __u32 pixelformat; int bpp; /* Bytes per pixel */ bool planar; u32 mbus_code; } mcam_formats[] = { { - .desc = "YUYV 4:2:2", .pixelformat = V4L2_PIX_FMT_YUYV, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, }, { - .desc = "YVYU 4:2:2", .pixelformat = V4L2_PIX_FMT_YVYU, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, .planar = false, }, { - .desc = "YUV 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YUV420, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 1, .planar = true, }, { - .desc = "YVU 4:2:0 PLANAR", .pixelformat = V4L2_PIX_FMT_YVU420, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 1, .planar = true, }, { - .desc = "XRGB 444", .pixelformat = V4L2_PIX_FMT_XRGB444, .mbus_code = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, .bpp = 2, .planar = false, }, { - .desc = "RGB 565", .pixelformat = V4L2_PIX_FMT_RGB565, .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, .bpp = 2, .planar = false, }, { - .desc = "Raw RGB Bayer", .pixelformat = V4L2_PIX_FMT_SBGGR8, .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, .bpp = 1, @@ -1357,9 +1349,6 @@ static int mcam_vidioc_querycap(struct file *file, void *priv, strscpy(cap->driver, "marvell_ccic", sizeof(cap->driver)); strscpy(cap->card, "marvell_ccic", sizeof(cap->card)); strscpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -1369,8 +1358,6 @@ static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp, { if (fmt->index >= N_MCAM_FMTS) return -EINVAL; - strscpy(fmt->description, mcam_formats[fmt->index].desc, - sizeof(fmt->description)); fmt->pixelformat = mcam_formats[fmt->index].pixelformat; return 0; } @@ -1698,6 +1685,8 @@ static const struct video_device mcam_v4l_template = { .fops = &mcam_v4l_fops, .ioctl_ops = &mcam_v4l_ioctl_ops, .release = video_device_release_empty, + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING, }; /* ---------------------------------------------------------------------- */ diff --git a/drivers/media/platform/marvell-ccic/mmp-driver.c b/drivers/media/platform/marvell-ccic/mmp-driver.c index 10559492e09e..92b92255dac6 100644 --- a/drivers/media/platform/marvell-ccic/mmp-driver.c +++ b/drivers/media/platform/marvell-ccic/mmp-driver.c @@ -372,6 +372,7 @@ static const struct of_device_id mmpcam_of_match[] = { { .compatible = "marvell,mmp2-ccic", }, {}, }; +MODULE_DEVICE_TABLE(of, mmpcam_of_match); static struct platform_driver mmpcam_driver = { .probe = mmpcam_probe, diff --git a/drivers/media/platform/meson/ao-cec-g12a.c b/drivers/media/platform/meson/ao-cec-g12a.c index fb52e5dd044a..3b39e875292e 100644 --- a/drivers/media/platform/meson/ao-cec-g12a.c +++ b/drivers/media/platform/meson/ao-cec-g12a.c @@ -121,6 +121,9 @@ #define CECB_CTRL_TYPE_NEXT 2 #define CECB_CTRL2 0x01 + +#define CECB_CTRL2_RISE_DEL_MAX GENMASK(4, 0) + #define CECB_INTR_MASK 0x02 #define CECB_LADD_LOW 0x05 #define CECB_LADD_HIGH 0x06 @@ -165,6 +168,11 @@ #define CECB_WAKEUPCTRL 0x31 +struct meson_ao_cec_g12a_data { + /* Setup the internal CECB_CTRL2 register */ + bool ctrl2_setup; +}; + struct meson_ao_cec_g12a_device { struct platform_device *pdev; struct regmap *regmap; @@ -175,6 +183,7 @@ struct meson_ao_cec_g12a_device { struct cec_msg rx_msg; struct clk *oscin; struct clk *core; + const struct meson_ao_cec_g12a_data *data; }; static const struct regmap_config meson_ao_cec_g12a_regmap_conf = { @@ -605,6 +614,10 @@ static int meson_ao_cec_g12a_adap_enable(struct cec_adapter *adap, bool enable) regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET, 0); + if (ao_cec->data->ctrl2_setup) + regmap_write(ao_cec->regmap_cec, CECB_CTRL2, + FIELD_PREP(CECB_CTRL2_RISE_DEL_MAX, 2)); + meson_ao_cec_g12a_irq_setup(ao_cec, true); return 0; @@ -632,20 +645,28 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev) if (!ao_cec) return -ENOMEM; + ao_cec->data = of_device_get_match_data(&pdev->dev); + if (!ao_cec->data) { + dev_err(&pdev->dev, "failed to get match data\n"); + return -ENODEV; + } + spin_lock_init(&ao_cec->cec_reg_lock); ao_cec->pdev = pdev; - ao_cec->notify = cec_notifier_get(hdmi_dev); - if (!ao_cec->notify) - return -ENOMEM; - ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_g12a_ops, ao_cec, "meson_g12a_ao_cec", - CEC_CAP_DEFAULTS, + CEC_CAP_DEFAULTS | + CEC_CAP_CONNECTOR_INFO, CEC_MAX_LOG_ADDRS); - if (IS_ERR(ao_cec->adap)) { - ret = PTR_ERR(ao_cec->adap); - goto out_probe_notify; + if (IS_ERR(ao_cec->adap)) + return PTR_ERR(ao_cec->adap); + + ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL, + ao_cec->adap); + if (!ao_cec->notify) { + ret = -ENOMEM; + goto out_probe_adapter; } ao_cec->adap->owner = THIS_MODULE; @@ -654,21 +675,21 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev) base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(base)) { ret = PTR_ERR(base); - goto out_probe_adapter; + goto out_probe_notify; } ao_cec->regmap = devm_regmap_init_mmio(&pdev->dev, base, &meson_ao_cec_g12a_regmap_conf); if (IS_ERR(ao_cec->regmap)) { ret = PTR_ERR(ao_cec->regmap); - goto out_probe_adapter; + goto out_probe_notify; } ao_cec->regmap_cec = devm_regmap_init(&pdev->dev, NULL, ao_cec, &meson_ao_cec_g12a_cec_regmap_conf); if (IS_ERR(ao_cec->regmap_cec)) { ret = PTR_ERR(ao_cec->regmap_cec); - goto out_probe_adapter; + goto out_probe_notify; } irq = platform_get_irq(pdev, 0); @@ -678,24 +699,24 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev) 0, NULL, ao_cec); if (ret) { dev_err(&pdev->dev, "irq request failed\n"); - goto out_probe_adapter; + goto out_probe_notify; } ao_cec->oscin = devm_clk_get(&pdev->dev, "oscin"); if (IS_ERR(ao_cec->oscin)) { dev_err(&pdev->dev, "oscin clock request failed\n"); ret = PTR_ERR(ao_cec->oscin); - goto out_probe_adapter; + goto out_probe_notify; } ret = meson_ao_cec_g12a_setup_clk(ao_cec); if (ret) - goto out_probe_adapter; + goto out_probe_notify; ret = clk_prepare_enable(ao_cec->core); if (ret) { dev_err(&pdev->dev, "core clock enable failed\n"); - goto out_probe_adapter; + goto out_probe_notify; } device_reset_optional(&pdev->dev); @@ -703,27 +724,23 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ao_cec); ret = cec_register_adapter(ao_cec->adap, &pdev->dev); - if (ret < 0) { - cec_notifier_put(ao_cec->notify); + if (ret < 0) goto out_probe_core_clk; - } /* Setup Hardware */ regmap_write(ao_cec->regmap, CECB_GEN_CNTL_REG, CECB_GEN_CNTL_RESET); - cec_register_cec_notifier(ao_cec->adap, ao_cec->notify); - return 0; out_probe_core_clk: clk_disable_unprepare(ao_cec->core); +out_probe_notify: + cec_notifier_cec_adap_unregister(ao_cec->notify); + out_probe_adapter: cec_delete_adapter(ao_cec->adap); -out_probe_notify: - cec_notifier_put(ao_cec->notify); - dev_err(&pdev->dev, "CEC controller registration failed\n"); return ret; @@ -735,15 +752,30 @@ static int meson_ao_cec_g12a_remove(struct platform_device *pdev) clk_disable_unprepare(ao_cec->core); - cec_unregister_adapter(ao_cec->adap); + cec_notifier_cec_adap_unregister(ao_cec->notify); - cec_notifier_put(ao_cec->notify); + cec_unregister_adapter(ao_cec->adap); return 0; } +static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = { + .ctrl2_setup = false, +}; + +static const struct meson_ao_cec_g12a_data ao_cec_sm1_data = { + .ctrl2_setup = true, +}; + static const struct of_device_id meson_ao_cec_g12a_of_match[] = { - { .compatible = "amlogic,meson-g12a-ao-cec", }, + { + .compatible = "amlogic,meson-g12a-ao-cec", + .data = &ao_cec_g12a_data, + }, + { + .compatible = "amlogic,meson-sm1-ao-cec", + .data = &ao_cec_sm1_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match); diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c index facf9b029e79..64ed549bf012 100644 --- a/drivers/media/platform/meson/ao-cec.c +++ b/drivers/media/platform/meson/ao-cec.c @@ -616,20 +616,19 @@ static int meson_ao_cec_probe(struct platform_device *pdev) spin_lock_init(&ao_cec->cec_reg_lock); - ao_cec->notify = cec_notifier_get(hdmi_dev); - if (!ao_cec->notify) - return -ENOMEM; - ao_cec->adap = cec_allocate_adapter(&meson_ao_cec_ops, ao_cec, "meson_ao_cec", - CEC_CAP_LOG_ADDRS | - CEC_CAP_TRANSMIT | - CEC_CAP_RC | - CEC_CAP_PASSTHROUGH, + CEC_CAP_DEFAULTS | + CEC_CAP_CONNECTOR_INFO, 1); /* Use 1 for now */ - if (IS_ERR(ao_cec->adap)) { - ret = PTR_ERR(ao_cec->adap); - goto out_probe_notify; + if (IS_ERR(ao_cec->adap)) + return PTR_ERR(ao_cec->adap); + + ao_cec->notify = cec_notifier_cec_adap_register(hdmi_dev, NULL, + ao_cec->adap); + if (!ao_cec->notify) { + ret = -ENOMEM; + goto out_probe_adapter; } ao_cec->adap->owner = THIS_MODULE; @@ -638,7 +637,7 @@ static int meson_ao_cec_probe(struct platform_device *pdev) ao_cec->base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(ao_cec->base)) { ret = PTR_ERR(ao_cec->base); - goto out_probe_adapter; + goto out_probe_notify; } irq = platform_get_irq(pdev, 0); @@ -648,20 +647,20 @@ static int meson_ao_cec_probe(struct platform_device *pdev) 0, NULL, ao_cec); if (ret) { dev_err(&pdev->dev, "irq request failed\n"); - goto out_probe_adapter; + goto out_probe_notify; } ao_cec->core = devm_clk_get(&pdev->dev, "core"); if (IS_ERR(ao_cec->core)) { dev_err(&pdev->dev, "core clock request failed\n"); ret = PTR_ERR(ao_cec->core); - goto out_probe_adapter; + goto out_probe_notify; } ret = clk_prepare_enable(ao_cec->core); if (ret) { dev_err(&pdev->dev, "core clock enable failed\n"); - goto out_probe_adapter; + goto out_probe_notify; } ret = clk_set_rate(ao_cec->core, CEC_CLK_RATE); @@ -676,28 +675,24 @@ static int meson_ao_cec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, ao_cec); ret = cec_register_adapter(ao_cec->adap, &pdev->dev); - if (ret < 0) { - cec_notifier_put(ao_cec->notify); + if (ret < 0) goto out_probe_clk; - } /* Setup Hardware */ writel_relaxed(CEC_GEN_CNTL_RESET, ao_cec->base + CEC_GEN_CNTL_REG); - cec_register_cec_notifier(ao_cec->adap, ao_cec->notify); - return 0; out_probe_clk: clk_disable_unprepare(ao_cec->core); +out_probe_notify: + cec_notifier_cec_adap_unregister(ao_cec->notify); + out_probe_adapter: cec_delete_adapter(ao_cec->adap); -out_probe_notify: - cec_notifier_put(ao_cec->notify); - dev_err(&pdev->dev, "CEC controller registration failed\n"); return ret; @@ -709,10 +704,9 @@ static int meson_ao_cec_remove(struct platform_device *pdev) clk_disable_unprepare(ao_cec->core); + cec_notifier_cec_adap_unregister(ao_cec->notify); cec_unregister_adapter(ao_cec->adap); - cec_notifier_put(ao_cec->notify); - return 0; } diff --git a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c index fc9faec85edb..c1e29a46ae69 100644 --- a/drivers/media/platform/mtk-mdp/mtk_mdp_core.c +++ b/drivers/media/platform/mtk-mdp/mtk_mdp_core.c @@ -110,7 +110,9 @@ static int mtk_mdp_probe(struct platform_device *pdev) mutex_init(&mdp->vpulock); /* Old dts had the components as child nodes */ - if (of_get_next_child(dev->of_node, NULL)) { + node = of_get_next_child(dev->of_node, NULL); + if (node) { + of_node_put(node); parent = dev->of_node; dev_warn(dev, "device tree is out of date\n"); } else { @@ -145,13 +147,16 @@ static int mtk_mdp_probe(struct platform_device *pdev) comp = devm_kzalloc(dev, sizeof(*comp), GFP_KERNEL); if (!comp) { ret = -ENOMEM; + of_node_put(node); goto err_comp; } mdp->comp[comp_id] = comp; ret = mtk_mdp_comp_init(dev, node, comp, comp_id); - if (ret) + if (ret) { + of_node_put(node); goto err_comp; + } } mdp->job_wq = create_singlethread_workqueue(MTK_MDP_MODULE_NAME); diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c index 90d1a67db7e5..26a55c3e807e 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_dec.c @@ -29,16 +29,19 @@ static const struct mtk_video_fmt mtk_video_formats[] = { .fourcc = V4L2_PIX_FMT_H264, .type = MTK_FMT_DEC, .num_planes = 1, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .fourcc = V4L2_PIX_FMT_VP8, .type = MTK_FMT_DEC, .num_planes = 1, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .fourcc = V4L2_PIX_FMT_VP9, .type = MTK_FMT_DEC, .num_planes = 1, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .fourcc = V4L2_PIX_FMT_MT21C, @@ -948,6 +951,7 @@ static int vidioc_enum_fmt(struct v4l2_fmtdesc *f, bool output_queue) fmt = &mtk_video_formats[i]; f->pixelformat = fmt->fourcc; + f->flags = fmt->flags; return 0; } diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h index c95de5d08dda..9fd56dee7fd1 100644 --- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h +++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_drv.h @@ -99,6 +99,7 @@ struct mtk_video_fmt { u32 fourcc; enum mtk_fmt_type type; u32 num_planes; + u32 flags; }; /** diff --git a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c index c5f8f1fca44c..49aa85a9bb5a 100644 --- a/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c +++ b/drivers/media/platform/mtk-vcodec/vdec/vdec_h264_if.c @@ -29,6 +29,9 @@ #define H264_MAX_FB_NUM 17 #define HDR_PARSING_BUF_SZ 1024 +#define DEC_ERR_RET(ret) ((ret) >> 16) +#define H264_ERR_NOT_VALID 3 + /** * struct h264_fb - h264 decode frame buffer information * @vdec_fb_va : virtual address of struct vdec_fb @@ -357,8 +360,11 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, buf = (unsigned char *)bs->va; buf_sz = bs->size; nal_start_idx = find_start_code(buf, buf_sz); - if (nal_start_idx < 0) + if (nal_start_idx < 0) { + mtk_vcodec_err(inst, "invalid nal start code"); + err = -EIO; goto err_free_fb_out; + } nal_start = buf[nal_start_idx]; nal_type = NAL_TYPE(buf[nal_start_idx]); @@ -382,8 +388,14 @@ static int vdec_h264_decode(void *h_vdec, struct mtk_vcodec_mem *bs, data[0] = buf_sz; data[1] = nal_start; err = vpu_dec_start(vpu, data, 2); - if (err) + if (err) { + if (err > 0 && (DEC_ERR_RET(err) == H264_ERR_NOT_VALID)) { + mtk_vcodec_err(inst, "- error bitstream - err = %d -", + err); + err = -EIO; + } goto err_free_fb_out; + } *res_chg = inst->vsi->dec.resolution_changed; if (*res_chg) { diff --git a/drivers/media/platform/mx2_emmaprp.c b/drivers/media/platform/mx2_emmaprp.c index 333324c75027..27779b75df54 100644 --- a/drivers/media/platform/mx2_emmaprp.c +++ b/drivers/media/platform/mx2_emmaprp.c @@ -120,7 +120,7 @@ module_param(debug, bool, 0644); #define PRP_CNTL_RZ_FIFO_LEVEL(x) ((x) << 27) #define PRP_CNTL_CH2B1EN (1 << 29) #define PRP_CNTL_CH2B2EN (1 << 30) -#define PRP_CNTL_CH2FEN (1 << 31) +#define PRP_CNTL_CH2FEN (1UL << 31) #define PRP_SIZE_HEIGHT(x) (x) #define PRP_SIZE_WIDTH(x) ((x) << 16) @@ -145,7 +145,6 @@ module_param(debug, bool, 0644); #define PRP_INTR_ST_CH2OVF (1 << 8) struct emmaprp_fmt { - char *name; u32 fourcc; /* Types the format can be used for */ u32 types; @@ -153,12 +152,10 @@ struct emmaprp_fmt { static struct emmaprp_fmt formats[] = { { - .name = "YUV 4:2:0 Planar", .fourcc = V4L2_PIX_FMT_YUV420, .types = MEM2MEM_CAPTURE, }, { - .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .types = MEM2MEM_OUTPUT, }, @@ -210,11 +207,11 @@ struct emmaprp_dev { }; struct emmaprp_ctx { + struct v4l2_fh fh; struct emmaprp_dev *dev; /* Abort requested by m2m */ int aborting; struct emmaprp_q_data q_data[2]; - struct v4l2_m2m_ctx *m2m_ctx; }; static struct emmaprp_q_data *get_q_data(struct emmaprp_ctx *ctx, @@ -243,7 +240,7 @@ static void emmaprp_job_abort(void *priv) dprintk(pcdev, "Aborting task\n"); - v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->m2m_ctx); + v4l2_m2m_job_finish(pcdev->m2m_dev, ctx->fh.m2m_ctx); } static inline void emmaprp_dump_regs(struct emmaprp_dev *pcdev) @@ -278,8 +275,8 @@ static void emmaprp_device_run(void *priv) dma_addr_t p_in, p_out; u32 tmp; - src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); - dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); s_q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); s_width = s_q_data->width; @@ -353,8 +350,8 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data) pr_err("PrP bus error occurred, this transfer is probably corrupted\n"); writel(PRP_CNTL_SWRST, pcdev->base_emma + PRP_CNTL); } else if (irqst & PRP_INTR_ST_CH2B1CI) { /* buffer ready */ - src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); - dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); + src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); + dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); dst_vb->vb2_buf.timestamp = src_vb->vb2_buf.timestamp; dst_vb->flags &= @@ -371,7 +368,7 @@ static irqreturn_t emmaprp_irq(int irq_emma, void *data) } } - v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->m2m_ctx); + v4l2_m2m_job_finish(pcdev->m2m_dev, curr_ctx->fh.m2m_ctx); return IRQ_HANDLED; } @@ -383,8 +380,6 @@ static int vidioc_querycap(struct file *file, void *priv, { strscpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver)); strscpy(cap->card, MEM2MEM_NAME, sizeof(cap->card)); - cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -409,7 +404,6 @@ static int enum_fmt(struct v4l2_fmtdesc *f, u32 type) if (i < NUM_FORMATS) { /* Format found */ fmt = &formats[i]; - strscpy(f->description, fmt->name, sizeof(f->description) - 1); f->pixelformat = fmt->fourcc; return 0; } @@ -435,7 +429,7 @@ static int vidioc_g_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f) struct vb2_queue *vq; struct emmaprp_q_data *q_data; - vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (!vq) return -EINVAL; @@ -540,7 +534,7 @@ static int vidioc_s_fmt(struct emmaprp_ctx *ctx, struct v4l2_format *f) struct vb2_queue *vq; int ret; - vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); + vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); if (!vq) return -EINVAL; @@ -596,52 +590,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *priv, return vidioc_s_fmt(priv, f); } -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *reqbufs) -{ - struct emmaprp_ctx *ctx = priv; - - return v4l2_m2m_reqbufs(file, ctx->m2m_ctx, reqbufs); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *buf) -{ - struct emmaprp_ctx *ctx = priv; - - return v4l2_m2m_querybuf(file, ctx->m2m_ctx, buf); -} - -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct emmaprp_ctx *ctx = priv; - - return v4l2_m2m_qbuf(file, ctx->m2m_ctx, buf); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf) -{ - struct emmaprp_ctx *ctx = priv; - - return v4l2_m2m_dqbuf(file, ctx->m2m_ctx, buf); -} - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct emmaprp_ctx *ctx = priv; - - return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); -} - -static int vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type type) -{ - struct emmaprp_ctx *ctx = priv; - - return v4l2_m2m_streamoff(file, ctx->m2m_ctx, type); -} - static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = { .vidioc_querycap = vidioc_querycap, @@ -655,14 +603,14 @@ static const struct v4l2_ioctl_ops emmaprp_ioctl_ops = { .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out, .vidioc_s_fmt_vid_out = vidioc_s_fmt_vid_out, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs, + .vidioc_querybuf = v4l2_m2m_ioctl_querybuf, + .vidioc_qbuf = v4l2_m2m_ioctl_qbuf, + .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf, + .vidioc_prepare_buf = v4l2_m2m_ioctl_prepare_buf, + .vidioc_expbuf = v4l2_m2m_ioctl_expbuf, + .vidioc_streamon = v4l2_m2m_ioctl_streamon, + .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, }; @@ -722,7 +670,7 @@ static void emmaprp_buf_queue(struct vb2_buffer *vb) { struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); struct emmaprp_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); - v4l2_m2m_buf_queue(ctx->m2m_ctx, vbuf); + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf); } static const struct vb2_ops emmaprp_qops = { @@ -740,7 +688,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, int ret; src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - src_vq->io_modes = VB2_MMAP | VB2_USERPTR; + src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; src_vq->drv_priv = ctx; src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); src_vq->ops = &emmaprp_qops; @@ -754,7 +702,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq, return ret; dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - dst_vq->io_modes = VB2_MMAP | VB2_USERPTR; + dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; dst_vq->drv_priv = ctx; dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); dst_vq->ops = &emmaprp_qops; @@ -778,7 +726,8 @@ static int emmaprp_open(struct file *file) if (!ctx) return -ENOMEM; - file->private_data = ctx; + v4l2_fh_init(&ctx->fh, video_devdata(file)); + file->private_data = &ctx->fh; ctx->dev = pcdev; if (mutex_lock_interruptible(&pcdev->dev_mutex)) { @@ -786,10 +735,10 @@ static int emmaprp_open(struct file *file) return -ERESTARTSYS; } - ctx->m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init); + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(pcdev->m2m_dev, ctx, &queue_init); - if (IS_ERR(ctx->m2m_ctx)) { - int ret = PTR_ERR(ctx->m2m_ctx); + if (IS_ERR(ctx->fh.m2m_ctx)) { + int ret = PTR_ERR(ctx->fh.m2m_ctx); mutex_unlock(&pcdev->dev_mutex); kfree(ctx); @@ -800,9 +749,10 @@ static int emmaprp_open(struct file *file) clk_prepare_enable(pcdev->clk_emma_ahb); ctx->q_data[V4L2_M2M_SRC].fmt = &formats[1]; ctx->q_data[V4L2_M2M_DST].fmt = &formats[0]; + v4l2_fh_add(&ctx->fh); mutex_unlock(&pcdev->dev_mutex); - dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->m2m_ctx); + dprintk(pcdev, "Created instance %p, m2m_ctx: %p\n", ctx, ctx->fh.m2m_ctx); return 0; } @@ -817,46 +767,22 @@ static int emmaprp_release(struct file *file) mutex_lock(&pcdev->dev_mutex); clk_disable_unprepare(pcdev->clk_emma_ahb); clk_disable_unprepare(pcdev->clk_emma_ipg); - v4l2_m2m_ctx_release(ctx->m2m_ctx); + v4l2_fh_del(&ctx->fh); + v4l2_fh_exit(&ctx->fh); + v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); mutex_unlock(&pcdev->dev_mutex); kfree(ctx); return 0; } -static __poll_t emmaprp_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct emmaprp_dev *pcdev = video_drvdata(file); - struct emmaprp_ctx *ctx = file->private_data; - __poll_t res; - - mutex_lock(&pcdev->dev_mutex); - res = v4l2_m2m_poll(file, ctx->m2m_ctx, wait); - mutex_unlock(&pcdev->dev_mutex); - return res; -} - -static int emmaprp_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct emmaprp_dev *pcdev = video_drvdata(file); - struct emmaprp_ctx *ctx = file->private_data; - int ret; - - if (mutex_lock_interruptible(&pcdev->dev_mutex)) - return -ERESTARTSYS; - ret = v4l2_m2m_mmap(file, ctx->m2m_ctx, vma); - mutex_unlock(&pcdev->dev_mutex); - return ret; -} - static const struct v4l2_file_operations emmaprp_fops = { .owner = THIS_MODULE, .open = emmaprp_open, .release = emmaprp_release, - .poll = emmaprp_poll, + .poll = v4l2_m2m_fop_poll, .unlocked_ioctl = video_ioctl2, - .mmap = emmaprp_mmap, + .mmap = v4l2_m2m_fop_mmap, }; static const struct video_device emmaprp_videodev = { @@ -866,6 +792,7 @@ static const struct video_device emmaprp_videodev = { .minor = -1, .release = video_device_release, .vfl_dir = VFL_DIR_M2M, + .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, }; static const struct v4l2_m2m_ops m2m_ops = { diff --git a/drivers/media/platform/omap/Kconfig b/drivers/media/platform/omap/Kconfig index 1a99dff21ca0..f73b5893220d 100644 --- a/drivers/media/platform/omap/Kconfig +++ b/drivers/media/platform/omap/Kconfig @@ -10,8 +10,7 @@ config VIDEO_OMAP2_VOUT depends on FB_OMAP2 || (COMPILE_TEST && FB_OMAP2=n) depends on ARCH_OMAP2 || ARCH_OMAP3 || COMPILE_TEST depends on VIDEO_V4L2 - select VIDEOBUF_GEN - select VIDEOBUF_DMA_CONTIG + select VIDEOBUF2_DMA_CONTIG select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 select FRAME_VECTOR help diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index cb6a9e3946b6..513b99bf963b 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -40,9 +40,9 @@ #include <linux/dma-mapping.h> #include <linux/slab.h> -#include <media/videobuf-dma-contig.h> #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> +#include <media/v4l2-event.h> #include <video/omapvrfb.h> #include <video/omapfb_dss.h> @@ -63,33 +63,12 @@ enum omap_vout_channels { OMAP_VIDEO2, }; -static struct videobuf_queue_ops video_vbq_ops; /* Variables configurable through module params*/ -static u32 video1_numbuffers = 3; -static u32 video2_numbuffers = 3; -static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE; -static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE; static bool vid1_static_vrfb_alloc; static bool vid2_static_vrfb_alloc; static bool debug; /* Module parameters */ -module_param(video1_numbuffers, uint, S_IRUGO); -MODULE_PARM_DESC(video1_numbuffers, - "Number of buffers to be allocated at init time for Video1 device."); - -module_param(video2_numbuffers, uint, S_IRUGO); -MODULE_PARM_DESC(video2_numbuffers, - "Number of buffers to be allocated at init time for Video2 device."); - -module_param(video1_bufsize, uint, S_IRUGO); -MODULE_PARM_DESC(video1_bufsize, - "Size of the buffer to be allocated for video1 device"); - -module_param(video2_bufsize, uint, S_IRUGO); -MODULE_PARM_DESC(video2_bufsize, - "Size of the buffer to be allocated for video2 device"); - module_param(vid1_static_vrfb_alloc, bool, S_IRUGO); MODULE_PARM_DESC(vid1_static_vrfb_alloc, "Static allocation of the VRFB buffer for video1 device"); @@ -114,14 +93,12 @@ static const struct v4l2_fmtdesc omap_formats[] = { * Byte 0 Byte 1 * g2 g1 g0 b4 b3 b2 b1 b0 r4 r3 r2 r1 r0 g5 g4 g3 */ - .description = "RGB565, le", .pixelformat = V4L2_PIX_FMT_RGB565, }, { /* Note: V4L2 defines RGB32 as: RGB-8-8-8-8 we use * this for RGB24 unpack mode, the last 8 bits are ignored * */ - .description = "RGB32, le", .pixelformat = V4L2_PIX_FMT_RGB32, }, { @@ -129,15 +106,12 @@ static const struct v4l2_fmtdesc omap_formats[] = { * this for RGB24 packed mode * */ - .description = "RGB24, le", .pixelformat = V4L2_PIX_FMT_RGB24, }, { - .description = "YUYV (YUV 4:2:2), packed", .pixelformat = V4L2_PIX_FMT_YUYV, }, { - .description = "UYVY, packed", .pixelformat = V4L2_PIX_FMT_UYVY, }, }; @@ -164,13 +138,13 @@ static int omap_vout_try_format(struct v4l2_pix_format *pix) ifmt = 0; pix->pixelformat = omap_formats[ifmt].pixelformat; - pix->field = V4L2_FIELD_ANY; + pix->field = V4L2_FIELD_NONE; switch (pix->pixelformat) { case V4L2_PIX_FMT_YUYV: case V4L2_PIX_FMT_UYVY: default: - pix->colorspace = V4L2_COLORSPACE_JPEG; + pix->colorspace = V4L2_COLORSPACE_SRGB; bpp = YUYV_BPP; break; case V4L2_PIX_FMT_RGB565: @@ -195,56 +169,6 @@ static int omap_vout_try_format(struct v4l2_pix_format *pix) } /* - * omap_vout_get_userptr: Convert user space virtual address to physical - * address. - */ -static int omap_vout_get_userptr(struct videobuf_buffer *vb, long virtp, - u32 *physp) -{ - struct frame_vector *vec; - int ret; - - /* For kernel direct-mapped memory, take the easy way */ - if (virtp >= PAGE_OFFSET) { - *physp = virt_to_phys((void *)virtp); - return 0; - } - - vec = frame_vector_create(1); - if (!vec) - return -ENOMEM; - - ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec); - if (ret != 1) { - frame_vector_destroy(vec); - return -EINVAL; - } - *physp = __pfn_to_phys(frame_vector_pfns(vec)[0]); - vb->priv = vec; - - return 0; -} - -/* - * Free the V4L2 buffers - */ -void omap_vout_free_buffers(struct omap_vout_device *vout) -{ - int i, numbuffers; - - /* Allocate memory for the buffers */ - numbuffers = (vout->vid) ? video2_numbuffers : video1_numbuffers; - vout->buffer_size = (vout->vid) ? video2_bufsize : video1_bufsize; - - for (i = 0; i < numbuffers; i++) { - omap_vout_free_buffer(vout->buf_virt_addr[i], - vout->buffer_size); - vout->buf_phy_addr[i] = 0; - vout->buf_virt_addr[i] = 0; - } -} - -/* * Convert V4L2 rotation to DSS rotation * V4L2 understand 0, 90, 180, 270. * Convert to 0, 1, 2 and 3 respectively for DSS @@ -537,9 +461,9 @@ static int omapvid_handle_interlace_display(struct omap_vout_device *vout, if (vout->cur_frm == vout->next_frm) goto err; - vout->cur_frm->ts = ts; - vout->cur_frm->state = VIDEOBUF_DONE; - wake_up_interruptible(&vout->cur_frm->done); + vout->cur_frm->vbuf.vb2_buf.timestamp = ts; + vout->cur_frm->vbuf.sequence = vout->sequence++; + vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE); vout->cur_frm = vout->next_frm; } else { if (list_empty(&vout->dma_queue) || @@ -562,9 +486,6 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) struct omap_dss_device *cur_display; struct omap_vout_device *vout = (struct omap_vout_device *)arg; - if (!vout->streaming) - return; - ovid = &vout->vid_info; ovl = ovid->overlays[0]; @@ -608,9 +529,9 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) } if (!vout->first_int && (vout->cur_frm != vout->next_frm)) { - vout->cur_frm->ts = ts; - vout->cur_frm->state = VIDEOBUF_DONE; - wake_up_interruptible(&vout->cur_frm->done); + vout->cur_frm->vbuf.vb2_buf.timestamp = ts; + vout->cur_frm->vbuf.sequence = vout->sequence++; + vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_DONE); vout->cur_frm = vout->next_frm; } @@ -619,12 +540,10 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) goto vout_isr_err; vout->next_frm = list_entry(vout->dma_queue.next, - struct videobuf_buffer, queue); + struct omap_vout_buffer, queue); list_del(&vout->next_frm->queue); - vout->next_frm->state = VIDEOBUF_ACTIVE; - - addr = (unsigned long) vout->queued_buf_addr[vout->next_frm->i] + addr = (unsigned long)vout->queued_buf_addr[vout->next_frm->vbuf.vb2_buf.index] + vout->cropped_offset; /* First save the configuration in ovelray structure */ @@ -644,394 +563,6 @@ vout_isr_err: spin_unlock(&vout->vbq_lock); } -/* Video buffer call backs */ - -/* - * Buffer setup function is called by videobuf layer when REQBUF ioctl is - * called. This is used to setup buffers and return size and count of - * buffers allocated. After the call to this buffer, videobuf layer will - * setup buffer queue depending on the size and count of buffers - */ -static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, - unsigned int *size) -{ - int startindex = 0, i, j; - u32 phy_addr = 0, virt_addr = 0; - struct omap_vout_device *vout = q->priv_data; - struct omapvideo_info *ovid = &vout->vid_info; - int vid_max_buf_size; - - if (!vout) - return -EINVAL; - - vid_max_buf_size = vout->vid == OMAP_VIDEO1 ? video1_bufsize : - video2_bufsize; - - if (V4L2_BUF_TYPE_VIDEO_OUTPUT != q->type) - return -EINVAL; - - startindex = (vout->vid == OMAP_VIDEO1) ? - video1_numbuffers : video2_numbuffers; - if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex) - *count = startindex; - - if (ovid->rotation_type == VOUT_ROT_VRFB) { - if (omap_vout_vrfb_buffer_setup(vout, count, startindex)) - return -ENOMEM; - } - - if (V4L2_MEMORY_MMAP != vout->memory) - return 0; - - /* Now allocated the V4L2 buffers */ - *size = PAGE_ALIGN(vout->pix.width * vout->pix.height * vout->bpp); - startindex = (vout->vid == OMAP_VIDEO1) ? - video1_numbuffers : video2_numbuffers; - - /* Check the size of the buffer */ - if (*size > vid_max_buf_size) { - v4l2_err(&vout->vid_dev->v4l2_dev, - "buffer allocation mismatch [%u] [%u]\n", - *size, vout->buffer_size); - return -ENOMEM; - } - - for (i = startindex; i < *count; i++) { - vout->buffer_size = *size; - - virt_addr = omap_vout_alloc_buffer(vout->buffer_size, - &phy_addr); - if (!virt_addr) { - if (ovid->rotation_type == VOUT_ROT_NONE) - break; - - if (!is_rotation_enabled(vout)) - break; - - /* Free the VRFB buffers if no space for V4L2 buffers */ - for (j = i; j < *count; j++) { - omap_vout_free_buffer(vout->smsshado_virt_addr[j], - vout->smsshado_size); - vout->smsshado_virt_addr[j] = 0; - vout->smsshado_phy_addr[j] = 0; - } - } - vout->buf_virt_addr[i] = virt_addr; - vout->buf_phy_addr[i] = phy_addr; - } - *count = vout->buffer_allocated = i; - - return 0; -} - -/* - * Free the V4L2 buffers additionally allocated than default - * number of buffers - */ -static void omap_vout_free_extra_buffers(struct omap_vout_device *vout) -{ - int num_buffers = 0, i; - - num_buffers = (vout->vid == OMAP_VIDEO1) ? - video1_numbuffers : video2_numbuffers; - - for (i = num_buffers; i < vout->buffer_allocated; i++) { - if (vout->buf_virt_addr[i]) - omap_vout_free_buffer(vout->buf_virt_addr[i], - vout->buffer_size); - - vout->buf_virt_addr[i] = 0; - vout->buf_phy_addr[i] = 0; - } - vout->buffer_allocated = num_buffers; -} - -/* - * This function will be called when VIDIOC_QBUF ioctl is called. - * It prepare buffers before give out for the display. This function - * converts user space virtual address into physical address if userptr memory - * exchange mechanism is used. If rotation is enabled, it copies entire - * buffer into VRFB memory space before giving it to the DSS. - */ -static int omap_vout_buffer_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct omap_vout_device *vout = q->priv_data; - struct omapvideo_info *ovid = &vout->vid_info; - - if (VIDEOBUF_NEEDS_INIT == vb->state) { - vb->width = vout->pix.width; - vb->height = vout->pix.height; - vb->size = vb->width * vb->height * vout->bpp; - vb->field = field; - } - vb->state = VIDEOBUF_PREPARED; - /* if user pointer memory mechanism is used, get the physical - * address of the buffer - */ - if (V4L2_MEMORY_USERPTR == vb->memory) { - int ret; - - if (0 == vb->baddr) - return -EINVAL; - /* Physical address */ - ret = omap_vout_get_userptr(vb, vb->baddr, - (u32 *)&vout->queued_buf_addr[vb->i]); - if (ret < 0) - return ret; - } else { - unsigned long addr, dma_addr; - unsigned long size; - - addr = (unsigned long) vout->buf_virt_addr[vb->i]; - size = (unsigned long) vb->size; - - dma_addr = dma_map_single(vout->vid_dev->v4l2_dev.dev, (void *) addr, - size, DMA_TO_DEVICE); - if (dma_mapping_error(vout->vid_dev->v4l2_dev.dev, dma_addr)) - v4l2_err(&vout->vid_dev->v4l2_dev, - "dma_map_single failed\n"); - - vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb->i]; - } - - if (ovid->rotation_type == VOUT_ROT_VRFB) - return omap_vout_prepare_vrfb(vout, vb); - else - return 0; -} - -/* - * Buffer queue function will be called from the videobuf layer when _QBUF - * ioctl is called. It is used to enqueue buffer, which is ready to be - * displayed. - */ -static void omap_vout_buffer_queue(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - struct omap_vout_device *vout = q->priv_data; - - /* Driver is also maintainig a queue. So enqueue buffer in the driver - * queue */ - list_add_tail(&vb->queue, &vout->dma_queue); - - vb->state = VIDEOBUF_QUEUED; -} - -/* - * Buffer release function is called from videobuf layer to release buffer - * which are already allocated - */ -static void omap_vout_buffer_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - vb->state = VIDEOBUF_NEEDS_INIT; - if (vb->memory == V4L2_MEMORY_USERPTR && vb->priv) { - struct frame_vector *vec = vb->priv; - - put_vaddr_frames(vec); - frame_vector_destroy(vec); - } -} - -/* - * File operations - */ -static __poll_t omap_vout_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct omap_vout_device *vout = file->private_data; - struct videobuf_queue *q = &vout->vbq; - - return videobuf_poll_stream(file, q, wait); -} - -static void omap_vout_vm_open(struct vm_area_struct *vma) -{ - struct omap_vout_device *vout = vma->vm_private_data; - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, - "vm_open [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end); - vout->mmap_count++; -} - -static void omap_vout_vm_close(struct vm_area_struct *vma) -{ - struct omap_vout_device *vout = vma->vm_private_data; - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, - "vm_close [vma=%08lx-%08lx]\n", vma->vm_start, vma->vm_end); - vout->mmap_count--; -} - -static const struct vm_operations_struct omap_vout_vm_ops = { - .open = omap_vout_vm_open, - .close = omap_vout_vm_close, -}; - -static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) -{ - int i; - void *pos; - unsigned long start = vma->vm_start; - unsigned long size = (vma->vm_end - vma->vm_start); - struct omap_vout_device *vout = file->private_data; - struct videobuf_queue *q = &vout->vbq; - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, - " %s pgoff=0x%lx, start=0x%lx, end=0x%lx\n", __func__, - vma->vm_pgoff, vma->vm_start, vma->vm_end); - - /* look for the buffer to map */ - for (i = 0; i < VIDEO_MAX_FRAME; i++) { - if (NULL == q->bufs[i]) - continue; - if (V4L2_MEMORY_MMAP != q->bufs[i]->memory) - continue; - if (q->bufs[i]->boff == (vma->vm_pgoff << PAGE_SHIFT)) - break; - } - - if (VIDEO_MAX_FRAME == i) { - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, - "offset invalid [offset=0x%lx]\n", - (vma->vm_pgoff << PAGE_SHIFT)); - return -EINVAL; - } - /* Check the size of the buffer */ - if (size > vout->buffer_size) { - v4l2_err(&vout->vid_dev->v4l2_dev, - "insufficient memory [%lu] [%u]\n", - size, vout->buffer_size); - return -ENOMEM; - } - - q->bufs[i]->baddr = vma->vm_start; - - vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP; - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - vma->vm_ops = &omap_vout_vm_ops; - vma->vm_private_data = (void *) vout; - pos = (void *)vout->buf_virt_addr[i]; - vma->vm_pgoff = virt_to_phys((void *)pos) >> PAGE_SHIFT; - while (size > 0) { - unsigned long pfn; - pfn = virt_to_phys((void *) pos) >> PAGE_SHIFT; - if (remap_pfn_range(vma, start, pfn, PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - start += PAGE_SIZE; - pos += PAGE_SIZE; - size -= PAGE_SIZE; - } - vout->mmap_count++; - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); - - return 0; -} - -static int omap_vout_release(struct file *file) -{ - unsigned int ret, i; - struct videobuf_queue *q; - struct omapvideo_info *ovid; - struct omap_vout_device *vout = file->private_data; - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); - ovid = &vout->vid_info; - - if (!vout) - return 0; - - q = &vout->vbq; - /* Disable all the overlay managers connected with this interface */ - for (i = 0; i < ovid->num_overlays; i++) { - struct omap_overlay *ovl = ovid->overlays[i]; - struct omap_dss_device *dssdev = ovl->get_device(ovl); - - if (dssdev) - ovl->disable(ovl); - } - /* Turn off the pipeline */ - ret = omapvid_apply_changes(vout); - if (ret) - v4l2_warn(&vout->vid_dev->v4l2_dev, - "Unable to apply changes\n"); - - /* Free all buffers */ - omap_vout_free_extra_buffers(vout); - - /* Free the VRFB buffers only if they are allocated - * during reqbufs. Don't free if init time allocated - */ - if (ovid->rotation_type == VOUT_ROT_VRFB) { - if (!vout->vrfb_static_allocation) - omap_vout_free_vrfb_buffers(vout); - } - videobuf_mmap_free(q); - - /* Even if apply changes fails we should continue - freeing allocated memory */ - if (vout->streaming) { - u32 mask = 0; - - mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | - DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2; - omap_dispc_unregister_isr(omap_vout_isr, vout, mask); - vout->streaming = false; - - videobuf_streamoff(q); - videobuf_queue_cancel(q); - } - - if (vout->mmap_count != 0) - vout->mmap_count = 0; - - vout->opened -= 1; - file->private_data = NULL; - - if (vout->buffer_allocated) - videobuf_mmap_free(q); - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); - return ret; -} - -static int omap_vout_open(struct file *file) -{ - struct videobuf_queue *q; - struct omap_vout_device *vout = NULL; - - vout = video_drvdata(file); - - if (vout == NULL) - return -ENODEV; - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Entering %s\n", __func__); - - /* for now, we only support single open */ - if (vout->opened) - return -EBUSY; - - vout->opened += 1; - - file->private_data = vout; - vout->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - - q = &vout->vbq; - video_vbq_ops.buf_setup = omap_vout_buffer_setup; - video_vbq_ops.buf_prepare = omap_vout_buffer_prepare; - video_vbq_ops.buf_release = omap_vout_buffer_release; - video_vbq_ops.buf_queue = omap_vout_buffer_queue; - spin_lock_init(&vout->vbq_lock); - - videobuf_queue_dma_contig_init(q, &video_vbq_ops, q->dev, - &vout->vbq_lock, vout->type, V4L2_FIELD_NONE, - sizeof(struct videobuf_buffer), vout, NULL); - - v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, "Exiting %s\n", __func__); - return 0; -} /* * V4L2 ioctls @@ -1039,15 +570,12 @@ static int omap_vout_open(struct file *file) static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); strscpy(cap->driver, VOUT_NAME, sizeof(cap->driver)); strscpy(cap->card, vout->vfd->name, sizeof(cap->card)); - cap->bus_info[0] = '\0'; - cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | - V4L2_CAP_VIDEO_OUTPUT_OVERLAY; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - + snprintf(cap->bus_info, sizeof(cap->bus_info), + "platform:%s.%d", VOUT_NAME, vout->vid); return 0; } @@ -1060,8 +588,6 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *fh, return -EINVAL; fmt->flags = omap_formats[index].flags; - strscpy(fmt->description, omap_formats[index].description, - sizeof(fmt->description)); fmt->pixelformat = omap_formats[index].pixelformat; return 0; @@ -1070,7 +596,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *fh, static int vidioc_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f) { - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); f->fmt.pix = vout->pix; return 0; @@ -1083,7 +609,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh, struct omap_overlay *ovl; struct omapvideo_info *ovid; struct omap_video_timings *timing; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct omap_dss_device *dssdev; ovid = &vout->vid_info; @@ -1110,14 +636,12 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, struct omap_overlay *ovl; struct omapvideo_info *ovid; struct omap_video_timings *timing; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct omap_dss_device *dssdev; - if (vout->streaming) + if (vb2_is_busy(&vout->vq)) return -EBUSY; - mutex_lock(&vout->lock); - ovid = &vout->vid_info; ovl = ovid->overlays[0]; dssdev = ovl->get_device(ovl); @@ -1168,7 +692,6 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, ret = 0; s_fmt_vid_out_exit: - mutex_unlock(&vout->lock); return ret; } @@ -1176,7 +699,7 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) { int ret = 0; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct omap_overlay *ovl; struct omapvideo_info *ovid; struct v4l2_window *win = &f->fmt.win; @@ -1186,12 +709,8 @@ static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, ret = omap_vout_try_window(&vout->fbuf, win); - if (!ret) { - if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) - win->global_alpha = 255; - else - win->global_alpha = f->fmt.win.global_alpha; - } + if (!ret && !(ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA)) + win->global_alpha = 0; return ret; } @@ -1202,35 +721,53 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *fh, int ret = 0; struct omap_overlay *ovl; struct omapvideo_info *ovid; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct v4l2_window *win = &f->fmt.win; - mutex_lock(&vout->lock); ovid = &vout->vid_info; ovl = ovid->overlays[0]; ret = omap_vout_new_window(&vout->crop, &vout->win, &vout->fbuf, win); if (!ret) { + enum omap_dss_trans_key_type key_type = + OMAP_DSS_COLOR_KEY_GFX_DST; + int enable; + /* Video1 plane does not support global alpha on OMAP3 */ - if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) == 0) - vout->win.global_alpha = 255; + if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) + vout->win.global_alpha = win->global_alpha; + else + win->global_alpha = 0; + if (vout->fbuf.flags & (V4L2_FBUF_FLAG_CHROMAKEY | + V4L2_FBUF_FLAG_SRC_CHROMAKEY)) + enable = 1; else - vout->win.global_alpha = f->fmt.win.global_alpha; + enable = 0; + if (vout->fbuf.flags & V4L2_FBUF_FLAG_SRC_CHROMAKEY) + key_type = OMAP_DSS_COLOR_KEY_VID_SRC; + + if (ovl->manager && ovl->manager->get_manager_info && + ovl->manager->set_manager_info) { + struct omap_overlay_manager_info info; - vout->win.chromakey = f->fmt.win.chromakey; + ovl->manager->get_manager_info(ovl->manager, &info); + info.trans_enabled = enable; + info.trans_key_type = key_type; + info.trans_key = vout->win.chromakey; + + if (ovl->manager->set_manager_info(ovl->manager, &info)) + return -EINVAL; + } } - mutex_unlock(&vout->lock); return ret; } static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) { - u32 key_value = 0; struct omap_overlay *ovl; struct omapvideo_info *ovid; - struct omap_vout_device *vout = fh; - struct omap_overlay_manager_info info; + struct omap_vout_device *vout = video_drvdata(file); struct v4l2_window *win = &f->fmt.win; ovid = &vout->vid_info; @@ -1238,19 +775,20 @@ static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, win->w = vout->win.w; win->field = vout->win.field; - win->global_alpha = vout->win.global_alpha; - - if (ovl->manager && ovl->manager->get_manager_info) { - ovl->manager->get_manager_info(ovl->manager, &info); - key_value = info.trans_key; - } - win->chromakey = key_value; + win->chromakey = vout->win.chromakey; + if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) + win->global_alpha = vout->win.global_alpha; + else + win->global_alpha = 0; + win->clips = NULL; + win->clipcount = 0; + win->bitmap = NULL; return 0; } static int vidioc_g_selection(struct file *file, void *fh, struct v4l2_selection *sel) { - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct v4l2_pix_format *pix = &vout->pix; if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) @@ -1277,7 +815,7 @@ static int vidioc_g_selection(struct file *file, void *fh, struct v4l2_selection static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection *sel) { int ret = -EINVAL; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct omapvideo_info *ovid; struct omap_overlay *ovl; struct omap_video_timings *timing; @@ -1289,10 +827,9 @@ static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection if (sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - if (vout->streaming) + if (vb2_is_busy(&vout->vq)) return -EBUSY; - mutex_lock(&vout->lock); ovid = &vout->vid_info; ovl = ovid->overlays[0]; /* get the display device attached to the overlay */ @@ -1317,7 +854,6 @@ static int vidioc_s_selection(struct file *file, void *fh, struct v4l2_selection &vout->fbuf, &sel->r); s_crop_err: - mutex_unlock(&vout->lock); return ret; } @@ -1334,26 +870,21 @@ static int omap_vout_s_ctrl(struct v4l2_ctrl *ctrl) ovid = &vout->vid_info; - mutex_lock(&vout->lock); if (rotation && ovid->rotation_type == VOUT_ROT_NONE) { - mutex_unlock(&vout->lock); ret = -ERANGE; break; } if (rotation && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { - mutex_unlock(&vout->lock); ret = -EINVAL; break; } if (v4l2_rot_to_dss_rot(rotation, &vout->rotation, vout->mirror)) { - mutex_unlock(&vout->lock); ret = -EINVAL; break; } - mutex_unlock(&vout->lock); break; } case V4L2_CID_BG_COLOR: @@ -1364,9 +895,7 @@ static int omap_vout_s_ctrl(struct v4l2_ctrl *ctrl) ovl = vout->vid_info.overlays[0]; - mutex_lock(&vout->lock); if (!ovl->manager || !ovl->manager->get_manager_info) { - mutex_unlock(&vout->lock); ret = -EINVAL; break; } @@ -1374,11 +903,9 @@ static int omap_vout_s_ctrl(struct v4l2_ctrl *ctrl) ovl->manager->get_manager_info(ovl->manager, &info); info.default_color = color; if (ovl->manager->set_manager_info(ovl->manager, &info)) { - mutex_unlock(&vout->lock); ret = -EINVAL; break; } - mutex_unlock(&vout->lock); break; } case V4L2_CID_VFLIP: @@ -1388,20 +915,16 @@ static int omap_vout_s_ctrl(struct v4l2_ctrl *ctrl) ovid = &vout->vid_info; - mutex_lock(&vout->lock); if (mirror && ovid->rotation_type == VOUT_ROT_NONE) { - mutex_unlock(&vout->lock); ret = -ERANGE; break; } if (mirror && vout->pix.pixelformat == V4L2_PIX_FMT_RGB24) { - mutex_unlock(&vout->lock); ret = -EINVAL; break; } vout->mirror = mirror; - mutex_unlock(&vout->lock); break; } default: @@ -1414,185 +937,94 @@ static const struct v4l2_ctrl_ops omap_vout_ctrl_ops = { .s_ctrl = omap_vout_s_ctrl, }; -static int vidioc_reqbufs(struct file *file, void *fh, - struct v4l2_requestbuffers *req) +static int omap_vout_vb2_queue_setup(struct vb2_queue *vq, + unsigned int *nbufs, + unsigned int *num_planes, unsigned int sizes[], + struct device *alloc_devs[]) { - int ret = 0; - unsigned int i, num_buffers = 0; - struct omap_vout_device *vout = fh; - struct videobuf_queue *q = &vout->vbq; - - if (req->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) - return -EINVAL; - /* if memory is not mmp or userptr - return error */ - if ((V4L2_MEMORY_MMAP != req->memory) && - (V4L2_MEMORY_USERPTR != req->memory)) - return -EINVAL; - - mutex_lock(&vout->lock); - /* Cannot be requested when streaming is on */ - if (vout->streaming) { - ret = -EBUSY; - goto reqbuf_err; - } + struct omap_vout_device *vout = vb2_get_drv_priv(vq); + int size = vout->pix.sizeimage; - /* If buffers are already allocated free them */ - if (q->bufs[0] && (V4L2_MEMORY_MMAP == q->bufs[0]->memory)) { - if (vout->mmap_count) { - ret = -EBUSY; - goto reqbuf_err; - } - num_buffers = (vout->vid == OMAP_VIDEO1) ? - video1_numbuffers : video2_numbuffers; - for (i = num_buffers; i < vout->buffer_allocated; i++) { - omap_vout_free_buffer(vout->buf_virt_addr[i], - vout->buffer_size); - vout->buf_virt_addr[i] = 0; - vout->buf_phy_addr[i] = 0; - } - vout->buffer_allocated = num_buffers; - videobuf_mmap_free(q); - } else if (q->bufs[0] && (V4L2_MEMORY_USERPTR == q->bufs[0]->memory)) { - if (vout->buffer_allocated) { - videobuf_mmap_free(q); - for (i = 0; i < vout->buffer_allocated; i++) { - kfree(q->bufs[i]); - q->bufs[i] = NULL; - } - vout->buffer_allocated = 0; - } + if (is_rotation_enabled(vout) && vq->num_buffers + *nbufs > VRFB_NUM_BUFS) { + *nbufs = VRFB_NUM_BUFS - vq->num_buffers; + if (*nbufs == 0) + return -EINVAL; } - /*store the memory type in data structure */ - vout->memory = req->memory; - - INIT_LIST_HEAD(&vout->dma_queue); - - /* call videobuf_reqbufs api */ - ret = videobuf_reqbufs(q, req); - if (ret < 0) - goto reqbuf_err; - - vout->buffer_allocated = req->count; - -reqbuf_err: - mutex_unlock(&vout->lock); - return ret; -} - -static int vidioc_querybuf(struct file *file, void *fh, - struct v4l2_buffer *b) -{ - struct omap_vout_device *vout = fh; + if (*num_planes) + return sizes[0] < size ? -EINVAL : 0; - return videobuf_querybuf(&vout->vbq, b); + *num_planes = 1; + sizes[0] = size; + return 0; } -static int vidioc_qbuf(struct file *file, void *fh, - struct v4l2_buffer *buffer) +static int omap_vout_vb2_prepare(struct vb2_buffer *vb) { - struct omap_vout_device *vout = fh; - struct videobuf_queue *q = &vout->vbq; + struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue); + struct omapvideo_info *ovid = &vout->vid_info; + struct omap_vout_buffer *voutbuf = vb2_to_omap_vout_buffer(vb); + dma_addr_t buf_phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); - if ((V4L2_BUF_TYPE_VIDEO_OUTPUT != buffer->type) || - (buffer->index >= vout->buffer_allocated) || - (q->bufs[buffer->index]->memory != buffer->memory)) { + if (vb2_plane_size(vb, 0) < vout->pix.sizeimage) { + v4l2_dbg(1, debug, &vout->vid_dev->v4l2_dev, + "%s data will not fit into plane (%lu < %u)\n", + __func__, vb2_plane_size(vb, 0), vout->pix.sizeimage); return -EINVAL; } - if (V4L2_MEMORY_USERPTR == buffer->memory) { - if ((buffer->length < vout->pix.sizeimage) || - (0 == buffer->m.userptr)) { - return -EINVAL; - } - } - if ((is_rotation_enabled(vout)) && - vout->vrfb_dma_tx.req_status == DMA_CHAN_NOT_ALLOTED) { - v4l2_warn(&vout->vid_dev->v4l2_dev, - "DMA Channel not allocated for Rotation\n"); - return -EINVAL; - } + vb2_set_plane_payload(vb, 0, vout->pix.sizeimage); + voutbuf->vbuf.field = V4L2_FIELD_NONE; - return videobuf_qbuf(q, buffer); + vout->queued_buf_addr[vb->index] = (u8 *)buf_phy_addr; + if (ovid->rotation_type == VOUT_ROT_VRFB) + return omap_vout_prepare_vrfb(vout, vb); + return 0; } -static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) +static void omap_vout_vb2_queue(struct vb2_buffer *vb) { - struct omap_vout_device *vout = fh; - struct videobuf_queue *q = &vout->vbq; + struct omap_vout_device *vout = vb2_get_drv_priv(vb->vb2_queue); + struct omap_vout_buffer *voutbuf = vb2_to_omap_vout_buffer(vb); - int ret; - u32 addr; - unsigned long size; - struct videobuf_buffer *vb; - - if (!vout->streaming) - return -EINVAL; - - ret = videobuf_dqbuf(q, b, !!(file->f_flags & O_NONBLOCK)); - if (ret) - return ret; - - vb = q->bufs[b->index]; - - addr = (unsigned long) vout->buf_phy_addr[vb->i]; - size = (unsigned long) vb->size; - dma_unmap_single(vout->vid_dev->v4l2_dev.dev, addr, - size, DMA_TO_DEVICE); - return 0; + list_add_tail(&voutbuf->queue, &vout->dma_queue); } -static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) +static int omap_vout_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) { - int ret = 0, j; - u32 addr = 0, mask = 0; - struct omap_vout_device *vout = fh; - struct videobuf_queue *q = &vout->vbq; + struct omap_vout_device *vout = vb2_get_drv_priv(vq); struct omapvideo_info *ovid = &vout->vid_info; - - mutex_lock(&vout->lock); - - if (vout->streaming) { - ret = -EBUSY; - goto streamon_err; - } - - ret = videobuf_streamon(q); - if (ret) - goto streamon_err; - - if (list_empty(&vout->dma_queue)) { - ret = -EIO; - goto streamon_err1; - } + struct omap_vout_buffer *buf, *tmp; + u32 addr = 0, mask = 0; + int ret, j; /* Get the next frame from the buffer queue */ vout->next_frm = vout->cur_frm = list_entry(vout->dma_queue.next, - struct videobuf_buffer, queue); + struct omap_vout_buffer, queue); /* Remove buffer from the buffer queue */ list_del(&vout->cur_frm->queue); - /* Mark state of the current frame to active */ - vout->cur_frm->state = VIDEOBUF_ACTIVE; /* Initialize field_id and started member */ vout->field_id = 0; - - /* set flag here. Next QBUF will start DMA */ - vout->streaming = true; - vout->first_int = 1; + vout->sequence = 0; if (omap_vout_calculate_offset(vout)) { ret = -EINVAL; - goto streamon_err1; + goto out; } - addr = (unsigned long) vout->queued_buf_addr[vout->cur_frm->i] + if (ovid->rotation_type == VOUT_ROT_VRFB) + if (omap_vout_vrfb_buffer_setup(vout, &count, 0)) { + ret = -ENOMEM; + goto out; + } + + addr = (unsigned long)vout->queued_buf_addr[vout->cur_frm->vbuf.vb2_buf.index] + vout->cropped_offset; mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2; - /* First save the configuration in ovelray structure */ + /* First save the configuration in overlay structure */ ret = omapvid_init(vout, addr); if (ret) { v4l2_err(&vout->vid_dev->v4l2_dev, @@ -1617,28 +1049,43 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) goto streamon_err1; } } - - ret = 0; + return 0; streamon_err1: - if (ret) - ret = videobuf_streamoff(q); -streamon_err: - mutex_unlock(&vout->lock); + mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD + | DISPC_IRQ_VSYNC2; + + omap_dispc_unregister_isr(omap_vout_isr, vout, mask); + + for (j = 0; j < ovid->num_overlays; j++) { + struct omap_overlay *ovl = ovid->overlays[j]; + struct omap_dss_device *dssdev = ovl->get_device(ovl); + + if (dssdev) + ovl->disable(ovl); + } + /* Turn of the pipeline */ + if (omapvid_apply_changes(vout)) + v4l2_err(&vout->vid_dev->v4l2_dev, + "failed to change mode in streamoff\n"); + +out: + vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); + list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) { + list_del(&buf->queue); + vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); + } return ret; } -static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) +static void omap_vout_vb2_stop_streaming(struct vb2_queue *vq) { - u32 mask = 0; - int ret = 0, j; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = vb2_get_drv_priv(vq); struct omapvideo_info *ovid = &vout->vid_info; + struct omap_vout_buffer *buf, *tmp; + u32 mask = 0; + int j; - if (!vout->streaming) - return -EINVAL; - - vout->streaming = false; mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_VSYNC2; @@ -1651,17 +1098,18 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) if (dssdev) ovl->disable(ovl); } - /* Turn of the pipeline */ - ret = omapvid_apply_changes(vout); - if (ret) + if (omapvid_apply_changes(vout)) v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode in streamoff\n"); - INIT_LIST_HEAD(&vout->dma_queue); - ret = videobuf_streamoff(&vout->vbq); - - return ret; + if (vout->next_frm != vout->cur_frm) + vb2_buffer_done(&vout->next_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); + vb2_buffer_done(&vout->cur_frm->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); + list_for_each_entry_safe(buf, tmp, &vout->dma_queue, queue) { + list_del(&buf->queue); + vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); + } } static int vidioc_s_fbuf(struct file *file, void *fh, @@ -1670,7 +1118,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, int enable = 0; struct omap_overlay *ovl; struct omapvideo_info *ovid; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct omap_overlay_manager_info info; enum omap_dss_trans_key_type key_type = OMAP_DSS_COLOR_KEY_GFX_DST; @@ -1741,17 +1189,36 @@ static int vidioc_g_fbuf(struct file *file, void *fh, { struct omap_overlay *ovl; struct omapvideo_info *ovid; - struct omap_vout_device *vout = fh; + struct omap_vout_device *vout = video_drvdata(file); struct omap_overlay_manager_info info; + struct omap_video_timings *timing; + struct omap_dss_device *dssdev; ovid = &vout->vid_info; ovl = ovid->overlays[0]; + /* get the display device attached to the overlay */ + dssdev = ovl->get_device(ovl); + + if (!dssdev) + return -EINVAL; + + timing = &dssdev->panel.timings; - /* The video overlay must stay within the framebuffer and can't be - positioned independently. */ - a->flags = V4L2_FBUF_FLAG_OVERLAY; - a->capability = V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_CHROMAKEY - | V4L2_FBUF_CAP_SRC_CHROMAKEY; + vout->fbuf.fmt.height = timing->y_res; + vout->fbuf.fmt.width = timing->x_res; + a->fmt.field = V4L2_FIELD_NONE; + a->fmt.colorspace = V4L2_COLORSPACE_SRGB; + a->fmt.pixelformat = V4L2_PIX_FMT_RGBA32; + a->fmt.height = vout->fbuf.fmt.height; + a->fmt.width = vout->fbuf.fmt.width; + a->fmt.bytesperline = vout->fbuf.fmt.width * 4; + a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline; + a->base = vout->fbuf.base; + + a->flags = vout->fbuf.flags; + a->capability = vout->fbuf.capability; + a->flags &= ~(V4L2_FBUF_FLAG_SRC_CHROMAKEY | V4L2_FBUF_FLAG_CHROMAKEY | + V4L2_FBUF_FLAG_LOCAL_ALPHA); if (ovl->manager && ovl->manager->get_manager_info) { ovl->manager->get_manager_info(ovl->manager, &info); @@ -1759,9 +1226,6 @@ static int vidioc_g_fbuf(struct file *file, void *fh, a->flags |= V4L2_FBUF_FLAG_SRC_CHROMAKEY; if (info.trans_key_type == OMAP_DSS_COLOR_KEY_GFX_DST) a->flags |= V4L2_FBUF_FLAG_CHROMAKEY; - } - if (ovl->manager && ovl->manager->get_manager_info) { - ovl->manager->get_manager_info(ovl->manager, &info); if (info.partial_alpha_enabled) a->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; } @@ -1769,6 +1233,27 @@ static int vidioc_g_fbuf(struct file *file, void *fh, return 0; } +static int vidioc_enum_output(struct file *file, void *priv_fh, + struct v4l2_output *out) +{ + if (out->index) + return -EINVAL; + snprintf(out->name, sizeof(out->name), "Overlay"); + out->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY; + return 0; +} + +static int vidioc_g_output(struct file *file, void *priv_fh, unsigned int *i) +{ + *i = 0; + return 0; +} + +static int vidioc_s_output(struct file *file, void *priv_fh, unsigned int i) +{ + return i ? -EINVAL : 0; +} + static const struct v4l2_ioctl_ops vout_ioctl_ops = { .vidioc_querycap = vidioc_querycap, .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out, @@ -1782,21 +1267,38 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = { .vidioc_g_fmt_vid_out_overlay = vidioc_g_fmt_vid_overlay, .vidioc_g_selection = vidioc_g_selection, .vidioc_s_selection = vidioc_s_selection, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, + .vidioc_enum_output = vidioc_enum_output, + .vidioc_g_output = vidioc_g_output, + .vidioc_s_output = vidioc_s_output, + .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, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static const struct v4l2_file_operations omap_vout_fops = { .owner = THIS_MODULE, - .poll = omap_vout_poll, .unlocked_ioctl = video_ioctl2, - .mmap = omap_vout_mmap, - .open = omap_vout_open, - .release = omap_vout_release, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .open = v4l2_fh_open, + .release = vb2_fop_release, +}; + +static const struct vb2_ops omap_vout_vb2_ops = { + .queue_setup = omap_vout_vb2_queue_setup, + .buf_queue = omap_vout_vb2_queue, + .buf_prepare = omap_vout_vb2_prepare, + .start_streaming = omap_vout_vb2_start_streaming, + .stop_streaming = omap_vout_vb2_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* Init functions used during driver initialization */ @@ -1808,6 +1310,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) struct omap_overlay *ovl = vout->vid_info.overlays[0]; struct omap_dss_device *display = ovl->get_device(ovl); struct v4l2_ctrl_handler *hdl; + struct vb2_queue *vq; + int ret; /* set the default pix */ pix = &vout->pix; @@ -1818,37 +1322,48 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) /* Default pixel format is RGB 5-6-5 */ pix->pixelformat = V4L2_PIX_FMT_RGB565; - pix->field = V4L2_FIELD_ANY; + pix->field = V4L2_FIELD_NONE; pix->bytesperline = pix->width * 2; pix->sizeimage = pix->bytesperline * pix->height; - pix->colorspace = V4L2_COLORSPACE_JPEG; + pix->colorspace = V4L2_COLORSPACE_SRGB; vout->bpp = RGB565_BPP; vout->fbuf.fmt.width = display->panel.timings.x_res; vout->fbuf.fmt.height = display->panel.timings.y_res; + vout->cropped_offset = 0; /* Set the data structures for the overlay parameters*/ - vout->win.global_alpha = 255; - vout->fbuf.flags = 0; + vout->fbuf.flags = V4L2_FBUF_FLAG_OVERLAY; vout->fbuf.capability = V4L2_FBUF_CAP_LOCAL_ALPHA | - V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY; - vout->win.chromakey = 0; + V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_CHROMAKEY | + V4L2_FBUF_CAP_EXTERNOVERLAY; + if (ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) { + vout->win.global_alpha = 255; + vout->fbuf.capability |= V4L2_FBUF_CAP_GLOBAL_ALPHA; + vout->fbuf.flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; + } else { + vout->win.global_alpha = 0; + } + vout->win.field = V4L2_FIELD_NONE; omap_vout_new_format(pix, &vout->fbuf, &vout->crop, &vout->win); hdl = &vout->ctrl_handler; v4l2_ctrl_handler_init(hdl, 3); - v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops, - V4L2_CID_ROTATE, 0, 270, 90, 0); + if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) { + v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops, + V4L2_CID_ROTATE, 0, 270, 90, 0); + v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops, + V4L2_CID_VFLIP, 0, 1, 1, 0); + } v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops, V4L2_CID_BG_COLOR, 0, 0xffffff, 1, 0); - v4l2_ctrl_new_std(hdl, &omap_vout_ctrl_ops, - V4L2_CID_VFLIP, 0, 1, 1, 0); if (hdl->error) return hdl->error; vout->rotation = 0; vout->mirror = false; + INIT_LIST_HEAD(&vout->dma_queue); if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) vout->vrfb_bpp = 2; @@ -1870,63 +1385,54 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) vfd->fops = &omap_vout_fops; vfd->v4l2_dev = &vout->vid_dev->v4l2_dev; vfd->vfl_dir = VFL_DIR_TX; - mutex_init(&vout->lock); - vfd->minor = -1; - return 0; + vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT | + V4L2_CAP_VIDEO_OUTPUT_OVERLAY; + mutex_init(&vout->lock); + vq = &vout->vq; + vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; + vq->io_modes = VB2_MMAP | VB2_DMABUF; + vq->drv_priv = vout; + vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + vq->buf_struct_size = sizeof(struct omap_vout_buffer); + vq->dev = vfd->v4l2_dev->dev; + + vq->ops = &omap_vout_vb2_ops; + vq->mem_ops = &vb2_dma_contig_memops; + vq->lock = &vout->lock; + vq->min_buffers_needed = 1; + vfd->queue = vq; + + ret = vb2_queue_init(vq); + if (ret) { + v4l2_ctrl_handler_free(hdl); + video_device_release(vfd); + } + return ret; } /* Setup video buffers */ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev, int vid_num) { - u32 numbuffers; - int ret = 0, i; struct omapvideo_info *ovid; struct omap_vout_device *vout; struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); struct omap2video_device *vid_dev = container_of(v4l2_dev, struct omap2video_device, v4l2_dev); + int ret = 0; vout = vid_dev->vouts[vid_num]; ovid = &vout->vid_info; - numbuffers = (vid_num == 0) ? video1_numbuffers : video2_numbuffers; - vout->buffer_size = (vid_num == 0) ? video1_bufsize : video2_bufsize; - dev_info(&pdev->dev, "Buffer Size = %d\n", vout->buffer_size); - - for (i = 0; i < numbuffers; i++) { - vout->buf_virt_addr[i] = - omap_vout_alloc_buffer(vout->buffer_size, - (u32 *) &vout->buf_phy_addr[i]); - if (!vout->buf_virt_addr[i]) { - numbuffers = i; - ret = -ENOMEM; - goto free_buffers; - } - } - - vout->cropped_offset = 0; - if (ovid->rotation_type == VOUT_ROT_VRFB) { bool static_vrfb_allocation = (vid_num == 0) ? vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; ret = omap_vout_setup_vrfb_bufs(pdev, vid_num, static_vrfb_allocation); } - - return ret; - -free_buffers: - for (i = 0; i < numbuffers; i++) { - omap_vout_free_buffer(vout->buf_virt_addr[i], - vout->buffer_size); - vout->buf_virt_addr[i] = 0; - vout->buf_phy_addr[i] = 0; - } return ret; - } /* Create video out devices */ @@ -1938,6 +1444,10 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev); struct omap2video_device *vid_dev = container_of(v4l2_dev, struct omap2video_device, v4l2_dev); + struct omap_overlay *ovl = vid_dev->overlays[0]; + struct omap_overlay_info info; + + ovl->get_overlay_info(ovl, &info); for (k = 0; k < pdev->num_resources; k++) { @@ -1958,6 +1468,15 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) vout->vid_info.overlays[0] = vid_dev->overlays[k + 1]; vout->vid_info.num_overlays = 1; vout->vid_info.id = k + 1; + spin_lock_init(&vout->vbq_lock); + /* + * Set the framebuffer base, this allows applications to find + * the fb corresponding to this overlay. + * + * To be precise: fbuf.base should match smem_start of + * struct fb_fix_screeninfo. + */ + vout->fbuf.base = (void *)info.paddr; /* Set VRFB as rotation_type for omap2 and omap3 */ if (omap_vout_dss_omap24xx() || omap_vout_dss_omap34xx()) @@ -2000,7 +1519,6 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) error2: if (vout->vid_info.rotation_type == VOUT_ROT_VRFB) omap_vout_release_vrfb(vout); - omap_vout_free_buffers(vout); error1: video_device_release(vfd); error: @@ -2045,7 +1563,6 @@ static void omap_vout_cleanup_device(struct omap_vout_device *vout) if (vout->vrfb_static_allocation) omap_vout_free_vrfb_buffers(vout); } - omap_vout_free_buffers(vout); kfree(vout); } diff --git a/drivers/media/platform/omap/omap_vout_vrfb.c b/drivers/media/platform/omap/omap_vout_vrfb.c index 11ec048929e8..6bd672cbdb62 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.c +++ b/drivers/media/platform/omap/omap_vout_vrfb.c @@ -14,7 +14,6 @@ #include <linux/videodev2.h> #include <linux/slab.h> -#include <media/videobuf-dma-contig.h> #include <media/v4l2-device.h> #include <video/omapvrfb.h> @@ -40,7 +39,7 @@ static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout, &vout->smsshado_phy_addr[i]); } if (!vout->smsshado_virt_addr[i] && startindex != -1) { - if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex) + if (vout->vq.memory == V4L2_MEMORY_MMAP && i >= startindex) break; } if (!vout->smsshado_virt_addr[i]) { @@ -109,8 +108,7 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, dev_info(&pdev->dev, ": VRFB allocation failed\n"); for (j = 0; j < i; j++) omap_vrfb_release_ctx(&vout->vrfb_context[j]); - ret = -ENOMEM; - goto free_buffers; + return -ENOMEM; } } @@ -155,8 +153,10 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, init_waitqueue_head(&vout->vrfb_dma_tx.wait); - /* statically allocated the VRFB buffer is done through - commands line aruments */ + /* + * statically allocated the VRFB buffer is done through + * command line arguments + */ if (static_vrfb_allocation) { if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) { ret = -ENOMEM; @@ -169,9 +169,6 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num, release_vrfb_ctx: for (j = 0; j < VRFB_NUM_BUFS; j++) omap_vrfb_release_ctx(&vout->vrfb_context[j]); -free_buffers: - omap_vout_free_buffers(vout); - return ret; } @@ -231,13 +228,14 @@ int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, } int omap_vout_prepare_vrfb(struct omap_vout_device *vout, - struct videobuf_buffer *vb) + struct vb2_buffer *vb) { struct dma_async_tx_descriptor *tx; enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; struct dma_chan *chan = vout->vrfb_dma_tx.chan; struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; dma_cookie_t cookie; + dma_addr_t buf_phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0); enum dma_status status; enum dss_rotation rotation; size_t dst_icg; @@ -255,8 +253,8 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, pixsize = vout->bpp * vout->vrfb_bpp; dst_icg = MAX_PIXELS_PER_LINE * pixsize - vout->pix.width * vout->bpp; - xt->src_start = vout->buf_phy_addr[vb->i]; - xt->dst_start = vout->vrfb_context[vb->i].paddr[0]; + xt->src_start = buf_phy_addr; + xt->dst_start = vout->vrfb_context[vb->index].paddr[0]; xt->numf = vout->pix.height; xt->frame_size = 1; @@ -307,8 +305,8 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout, /* Store buffers physical address into an array. Addresses * from this array will be used to configure DSS */ rotation = calc_rotation(vout); - vout->queued_buf_addr[vb->i] = (u8 *) - vout->vrfb_context[vb->i].paddr[rotation]; + vout->queued_buf_addr[vb->index] = (u8 *) + vout->vrfb_context[vb->index].paddr[rotation]; return 0; } diff --git a/drivers/media/platform/omap/omap_vout_vrfb.h b/drivers/media/platform/omap/omap_vout_vrfb.h index c976975024df..40bc9e54ecc6 100644 --- a/drivers/media/platform/omap/omap_vout_vrfb.h +++ b/drivers/media/platform/omap/omap_vout_vrfb.h @@ -20,7 +20,7 @@ void omap_vout_release_vrfb(struct omap_vout_device *vout); int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, unsigned int *count, unsigned int startindex); int omap_vout_prepare_vrfb(struct omap_vout_device *vout, - struct videobuf_buffer *vb); + struct vb2_buffer *vb); void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout); #else static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }; @@ -32,7 +32,7 @@ static inline int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, unsigned int *count, unsigned int startindex) { return 0; }; static inline int omap_vout_prepare_vrfb(struct omap_vout_device *vout, - struct videobuf_buffer *vb) + struct vb2_buffer *vb) { return 0; }; static inline void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout) { }; #endif diff --git a/drivers/media/platform/omap/omap_voutdef.h b/drivers/media/platform/omap/omap_voutdef.h index c740393c8509..1cff6dea1879 100644 --- a/drivers/media/platform/omap/omap_voutdef.h +++ b/drivers/media/platform/omap/omap_voutdef.h @@ -11,6 +11,7 @@ #ifndef OMAP_VOUTDEF_H #define OMAP_VOUTDEF_H +#include <media/videobuf2-dma-contig.h> #include <media/v4l2-ctrls.h> #include <video/omapfb_dss.h> #include <video/omapvrfb.h> @@ -113,6 +114,20 @@ struct omap2video_device { struct omap_overlay_manager *managers[MAX_MANAGERS]; }; +/* buffer for one video frame */ +struct omap_vout_buffer { + /* common v4l buffer stuff -- must be first */ + struct vb2_v4l2_buffer vbuf; + struct list_head queue; +}; + +static inline struct omap_vout_buffer *vb2_to_omap_vout_buffer(struct vb2_buffer *vb) +{ + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + + return container_of(vbuf, struct omap_vout_buffer, vbuf); +} + /* per-device data structure */ struct omap_vout_device { @@ -121,29 +136,12 @@ struct omap_vout_device { struct omap2video_device *vid_dev; struct v4l2_ctrl_handler ctrl_handler; int vid; - int opened; - /* we don't allow to change image fmt/size once buffer has - * been allocated - */ - int buffer_allocated; /* allow to reuse previously allocated buffer which is big enough */ int buffer_size; - /* keep buffer info across opens */ - unsigned long buf_virt_addr[VIDEO_MAX_FRAME]; - unsigned long buf_phy_addr[VIDEO_MAX_FRAME]; enum omap_color_mode dss_mode; - /* we don't allow to request new buffer when old buffers are - * still mmapped - */ - int mmap_count; - - spinlock_t vbq_lock; /* spinlock for videobuf queues */ - unsigned long field_count; /* field counter for videobuf_buffer */ - - /* non-NULL means streaming is in progress. */ - bool streaming; + u32 sequence; struct v4l2_pix_format pix; struct v4l2_rect crop; @@ -169,19 +167,14 @@ struct omap_vout_device { unsigned char pos; int ps, vr_ps, line_length, first_int, field_id; - enum v4l2_memory memory; - struct videobuf_buffer *cur_frm, *next_frm; + struct omap_vout_buffer *cur_frm, *next_frm; + spinlock_t vbq_lock; /* spinlock for dma_queue */ struct list_head dma_queue; u8 *queued_buf_addr[VIDEO_MAX_FRAME]; u32 cropped_offset; s32 tv_field1_offset; void *isr_handle; - - /* Buffer queue variables */ - struct omap_vout_device *vout; - enum v4l2_buf_type type; - struct videobuf_queue vbq; - int io_allowed; + struct vb2_queue vq; }; diff --git a/drivers/media/platform/omap/omap_voutlib.c b/drivers/media/platform/omap/omap_voutlib.c index 58a25fdf0cce..480a7e95533d 100644 --- a/drivers/media/platform/omap/omap_voutlib.c +++ b/drivers/media/platform/omap/omap_voutlib.c @@ -95,7 +95,11 @@ int omap_vout_try_window(struct v4l2_framebuffer *fbuf, /* We now have a valid preview window, so go with it */ new_win->w = try_win; - new_win->field = V4L2_FIELD_ANY; + new_win->field = V4L2_FIELD_NONE; + new_win->clips = NULL; + new_win->clipcount = 0; + new_win->bitmap = NULL; + return 0; } EXPORT_SYMBOL_GPL(omap_vout_try_window); diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 83216fc7156b..327c5716922a 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -719,6 +719,10 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe, s_stream, mode); pipe->do_propagation = true; } + + /* Stop at the first external sub-device. */ + if (subdev->dev != isp->dev) + break; } return 0; @@ -833,6 +837,10 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) &subdev->entity); failure = -ETIMEDOUT; } + + /* Stop at the first external sub-device. */ + if (subdev->dev != isp->dev) + break; } return failure; @@ -2014,136 +2022,6 @@ enum isp_of_phy { ISP_OF_PHY_CSIPHY2, }; -static int isp_fwnode_parse(struct device *dev, - struct v4l2_fwnode_endpoint *vep, - struct v4l2_async_subdev *asd) -{ - struct isp_async_subdev *isd = - container_of(asd, struct isp_async_subdev, asd); - struct isp_bus_cfg *buscfg = &isd->bus; - bool csi1 = false; - unsigned int i; - - dev_dbg(dev, "parsing endpoint %pOF, interface %u\n", - to_of_node(vep->base.local_fwnode), vep->base.port); - - switch (vep->base.port) { - case ISP_OF_PHY_PARALLEL: - buscfg->interface = ISP_INTERFACE_PARALLEL; - buscfg->bus.parallel.data_lane_shift = - vep->bus.parallel.data_shift; - buscfg->bus.parallel.clk_pol = - !!(vep->bus.parallel.flags - & V4L2_MBUS_PCLK_SAMPLE_FALLING); - buscfg->bus.parallel.hs_pol = - !!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW); - buscfg->bus.parallel.vs_pol = - !!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW); - buscfg->bus.parallel.fld_pol = - !!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW); - buscfg->bus.parallel.data_pol = - !!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW); - buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656; - break; - - case ISP_OF_PHY_CSIPHY1: - case ISP_OF_PHY_CSIPHY2: - switch (vep->bus_type) { - case V4L2_MBUS_CCP2: - case V4L2_MBUS_CSI1: - dev_dbg(dev, "CSI-1/CCP-2 configuration\n"); - csi1 = true; - break; - case V4L2_MBUS_CSI2_DPHY: - dev_dbg(dev, "CSI-2 configuration\n"); - csi1 = false; - break; - default: - dev_err(dev, "unsupported bus type %u\n", - vep->bus_type); - return -EINVAL; - } - - switch (vep->base.port) { - case ISP_OF_PHY_CSIPHY1: - if (csi1) - buscfg->interface = ISP_INTERFACE_CCP2B_PHY1; - else - buscfg->interface = ISP_INTERFACE_CSI2C_PHY1; - break; - case ISP_OF_PHY_CSIPHY2: - if (csi1) - buscfg->interface = ISP_INTERFACE_CCP2B_PHY2; - else - buscfg->interface = ISP_INTERFACE_CSI2A_PHY2; - break; - } - if (csi1) { - buscfg->bus.ccp2.lanecfg.clk.pos = - vep->bus.mipi_csi1.clock_lane; - buscfg->bus.ccp2.lanecfg.clk.pol = - vep->bus.mipi_csi1.lane_polarity[0]; - dev_dbg(dev, "clock lane polarity %u, pos %u\n", - buscfg->bus.ccp2.lanecfg.clk.pol, - buscfg->bus.ccp2.lanecfg.clk.pos); - - buscfg->bus.ccp2.lanecfg.data[0].pos = - vep->bus.mipi_csi1.data_lane; - buscfg->bus.ccp2.lanecfg.data[0].pol = - vep->bus.mipi_csi1.lane_polarity[1]; - - dev_dbg(dev, "data lane polarity %u, pos %u\n", - buscfg->bus.ccp2.lanecfg.data[0].pol, - buscfg->bus.ccp2.lanecfg.data[0].pos); - - buscfg->bus.ccp2.strobe_clk_pol = - vep->bus.mipi_csi1.clock_inv; - buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe; - buscfg->bus.ccp2.ccp2_mode = - vep->bus_type == V4L2_MBUS_CCP2; - buscfg->bus.ccp2.vp_clk_pol = 1; - - buscfg->bus.ccp2.crc = 1; - } else { - buscfg->bus.csi2.lanecfg.clk.pos = - vep->bus.mipi_csi2.clock_lane; - buscfg->bus.csi2.lanecfg.clk.pol = - vep->bus.mipi_csi2.lane_polarities[0]; - dev_dbg(dev, "clock lane polarity %u, pos %u\n", - buscfg->bus.csi2.lanecfg.clk.pol, - buscfg->bus.csi2.lanecfg.clk.pos); - - buscfg->bus.csi2.num_data_lanes = - vep->bus.mipi_csi2.num_data_lanes; - - for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) { - buscfg->bus.csi2.lanecfg.data[i].pos = - vep->bus.mipi_csi2.data_lanes[i]; - buscfg->bus.csi2.lanecfg.data[i].pol = - vep->bus.mipi_csi2.lane_polarities[i + 1]; - dev_dbg(dev, - "data lane %u polarity %u, pos %u\n", i, - buscfg->bus.csi2.lanecfg.data[i].pol, - buscfg->bus.csi2.lanecfg.data[i].pos); - } - /* - * FIXME: now we assume the CRC is always there. - * Implement a way to obtain this information from the - * sensor. Frame descriptors, perhaps? - */ - buscfg->bus.csi2.crc = 1; - } - break; - - default: - dev_warn(dev, "%pOF: invalid interface %u\n", - to_of_node(vep->base.local_fwnode), vep->base.port); - return -EINVAL; - } - - return 0; -} - static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) { struct isp_device *isp = container_of(async, struct isp_device, @@ -2173,6 +2051,201 @@ static int isp_subdev_notifier_complete(struct v4l2_async_notifier *async) return media_device_register(&isp->media_dev); } +static void isp_parse_of_parallel_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct isp_bus_cfg *buscfg) +{ + buscfg->interface = ISP_INTERFACE_PARALLEL; + buscfg->bus.parallel.data_lane_shift = vep->bus.parallel.data_shift; + buscfg->bus.parallel.clk_pol = + !!(vep->bus.parallel.flags & V4L2_MBUS_PCLK_SAMPLE_FALLING); + buscfg->bus.parallel.hs_pol = + !!(vep->bus.parallel.flags & V4L2_MBUS_VSYNC_ACTIVE_LOW); + buscfg->bus.parallel.vs_pol = + !!(vep->bus.parallel.flags & V4L2_MBUS_HSYNC_ACTIVE_LOW); + buscfg->bus.parallel.fld_pol = + !!(vep->bus.parallel.flags & V4L2_MBUS_FIELD_EVEN_LOW); + buscfg->bus.parallel.data_pol = + !!(vep->bus.parallel.flags & V4L2_MBUS_DATA_ACTIVE_LOW); + buscfg->bus.parallel.bt656 = vep->bus_type == V4L2_MBUS_BT656; +} + +static void isp_parse_of_csi2_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct isp_bus_cfg *buscfg) +{ + unsigned int i; + + buscfg->bus.csi2.lanecfg.clk.pos = vep->bus.mipi_csi2.clock_lane; + buscfg->bus.csi2.lanecfg.clk.pol = + vep->bus.mipi_csi2.lane_polarities[0]; + dev_dbg(dev, "clock lane polarity %u, pos %u\n", + buscfg->bus.csi2.lanecfg.clk.pol, + buscfg->bus.csi2.lanecfg.clk.pos); + + buscfg->bus.csi2.num_data_lanes = vep->bus.mipi_csi2.num_data_lanes; + + for (i = 0; i < buscfg->bus.csi2.num_data_lanes; i++) { + buscfg->bus.csi2.lanecfg.data[i].pos = + vep->bus.mipi_csi2.data_lanes[i]; + buscfg->bus.csi2.lanecfg.data[i].pol = + vep->bus.mipi_csi2.lane_polarities[i + 1]; + dev_dbg(dev, + "data lane %u polarity %u, pos %u\n", i, + buscfg->bus.csi2.lanecfg.data[i].pol, + buscfg->bus.csi2.lanecfg.data[i].pos); + } + /* + * FIXME: now we assume the CRC is always there. Implement a way to + * obtain this information from the sensor. Frame descriptors, perhaps? + */ + buscfg->bus.csi2.crc = 1; +} + +static void isp_parse_of_csi1_endpoint(struct device *dev, + struct v4l2_fwnode_endpoint *vep, + struct isp_bus_cfg *buscfg) +{ + buscfg->bus.ccp2.lanecfg.clk.pos = vep->bus.mipi_csi1.clock_lane; + buscfg->bus.ccp2.lanecfg.clk.pol = vep->bus.mipi_csi1.lane_polarity[0]; + dev_dbg(dev, "clock lane polarity %u, pos %u\n", + buscfg->bus.ccp2.lanecfg.clk.pol, + buscfg->bus.ccp2.lanecfg.clk.pos); + + buscfg->bus.ccp2.lanecfg.data[0].pos = vep->bus.mipi_csi1.data_lane; + buscfg->bus.ccp2.lanecfg.data[0].pol = + vep->bus.mipi_csi1.lane_polarity[1]; + + dev_dbg(dev, "data lane polarity %u, pos %u\n", + buscfg->bus.ccp2.lanecfg.data[0].pol, + buscfg->bus.ccp2.lanecfg.data[0].pos); + + buscfg->bus.ccp2.strobe_clk_pol = vep->bus.mipi_csi1.clock_inv; + buscfg->bus.ccp2.phy_layer = vep->bus.mipi_csi1.strobe; + buscfg->bus.ccp2.ccp2_mode = vep->bus_type == V4L2_MBUS_CCP2; + buscfg->bus.ccp2.vp_clk_pol = 1; + + buscfg->bus.ccp2.crc = 1; +} + +static int isp_alloc_isd(struct isp_async_subdev **isd, + struct isp_bus_cfg **buscfg) +{ + struct isp_async_subdev *__isd; + + __isd = kzalloc(sizeof(*__isd), GFP_KERNEL); + if (!__isd) + return -ENOMEM; + + *isd = __isd; + *buscfg = &__isd->bus; + + return 0; +} + +static struct { + u32 phy; + u32 csi2_if; + u32 csi1_if; +} isp_bus_interfaces[2] = { + { ISP_OF_PHY_CSIPHY1, + ISP_INTERFACE_CSI2C_PHY1, ISP_INTERFACE_CCP2B_PHY1 }, + { ISP_OF_PHY_CSIPHY2, + ISP_INTERFACE_CSI2A_PHY2, ISP_INTERFACE_CCP2B_PHY2 }, +}; + +static int isp_parse_of_endpoints(struct isp_device *isp) +{ + struct fwnode_handle *ep; + struct isp_async_subdev *isd = NULL; + struct isp_bus_cfg *buscfg; + unsigned int i; + + ep = fwnode_graph_get_endpoint_by_id( + dev_fwnode(isp->dev), ISP_OF_PHY_PARALLEL, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + + if (ep) { + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_PARALLEL + }; + int ret; + + dev_dbg(isp->dev, "parsing parallel interface\n"); + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + + if (!ret) { + ret = isp_alloc_isd(&isd, &buscfg); + if (ret) + return ret; + } + + if (!ret) { + isp_parse_of_parallel_endpoint(isp->dev, &vep, buscfg); + ret = v4l2_async_notifier_add_fwnode_remote_subdev( + &isp->notifier, ep, &isd->asd); + } + + fwnode_handle_put(ep); + if (ret) + kfree(isd); + } + + for (i = 0; i < ARRAY_SIZE(isp_bus_interfaces); i++) { + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_CSI2_DPHY + }; + int ret; + + ep = fwnode_graph_get_endpoint_by_id( + dev_fwnode(isp->dev), isp_bus_interfaces[i].phy, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + + if (!ep) + continue; + + dev_dbg(isp->dev, "parsing serial interface %u, node %pOF\n", i, + to_of_node(ep)); + + ret = isp_alloc_isd(&isd, &buscfg); + if (ret) + return ret; + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + if (!ret) { + buscfg->interface = isp_bus_interfaces[i].csi2_if; + isp_parse_of_csi2_endpoint(isp->dev, &vep, buscfg); + } else if (ret == -ENXIO) { + vep = (struct v4l2_fwnode_endpoint) + { .bus_type = V4L2_MBUS_CSI1 }; + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + + if (ret == -ENXIO) { + vep = (struct v4l2_fwnode_endpoint) + { .bus_type = V4L2_MBUS_CCP2 }; + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + } + if (!ret) { + buscfg->interface = + isp_bus_interfaces[i].csi1_if; + isp_parse_of_csi1_endpoint(isp->dev, &vep, + buscfg); + } + } + + if (!ret) + ret = v4l2_async_notifier_add_fwnode_remote_subdev( + &isp->notifier, ep, &isd->asd); + + fwnode_handle_put(ep); + if (ret) + kfree(isd); + } + + return 0; +} + static const struct v4l2_async_notifier_operations isp_subdev_notifier_ops = { .complete = isp_subdev_notifier_complete, }; @@ -2223,14 +2296,12 @@ static int isp_probe(struct platform_device *pdev) mutex_init(&isp->isp_mutex); spin_lock_init(&isp->stat_lock); v4l2_async_notifier_init(&isp->notifier); + isp->dev = &pdev->dev; - ret = v4l2_async_notifier_parse_fwnode_endpoints( - &pdev->dev, &isp->notifier, sizeof(struct isp_async_subdev), - isp_fwnode_parse); + ret = isp_parse_of_endpoints(isp); if (ret < 0) goto error; - isp->dev = &pdev->dev; isp->ref_count = 0; ret = dma_coerce_mask_and_coherent(isp->dev, DMA_BIT_MASK(32)); @@ -2324,7 +2395,6 @@ static int isp_probe(struct platform_device *pdev) /* Interrupt */ ret = platform_get_irq(pdev, 0); if (ret <= 0) { - dev_err(isp->dev, "No IRQ resource\n"); ret = -ENODEV; goto error_iommu; } diff --git a/drivers/media/platform/omap3isp/ispccdc.c b/drivers/media/platform/omap3isp/ispccdc.c index 1ba8a5ba343f..e2f336c715a4 100644 --- a/drivers/media/platform/omap3isp/ispccdc.c +++ b/drivers/media/platform/omap3isp/ispccdc.c @@ -2602,6 +2602,7 @@ int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc, int ret; /* Register the subdev and video node. */ + ccdc->subdev.dev = vdev->mdev->dev; ret = v4l2_device_register_subdev(vdev, &ccdc->subdev); if (ret < 0) goto error; diff --git a/drivers/media/platform/omap3isp/ispccp2.c b/drivers/media/platform/omap3isp/ispccp2.c index efca45bb02c8..d0a49cdfd22d 100644 --- a/drivers/media/platform/omap3isp/ispccp2.c +++ b/drivers/media/platform/omap3isp/ispccp2.c @@ -1031,6 +1031,7 @@ int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2, int ret; /* Register the subdev and video nodes. */ + ccp2->subdev.dev = vdev->mdev->dev; ret = v4l2_device_register_subdev(vdev, &ccp2->subdev); if (ret < 0) goto error; diff --git a/drivers/media/platform/omap3isp/ispcsi2.c b/drivers/media/platform/omap3isp/ispcsi2.c index e85917f4a50c..fd493c5e4e24 100644 --- a/drivers/media/platform/omap3isp/ispcsi2.c +++ b/drivers/media/platform/omap3isp/ispcsi2.c @@ -1198,6 +1198,7 @@ int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2, int ret; /* Register the subdev and video nodes. */ + csi2->subdev.dev = vdev->mdev->dev; ret = v4l2_device_register_subdev(vdev, &csi2->subdev); if (ret < 0) goto error; diff --git a/drivers/media/platform/omap3isp/isppreview.c b/drivers/media/platform/omap3isp/isppreview.c index 40e22400cf5e..97d660606d98 100644 --- a/drivers/media/platform/omap3isp/isppreview.c +++ b/drivers/media/platform/omap3isp/isppreview.c @@ -2225,6 +2225,7 @@ int omap3isp_preview_register_entities(struct isp_prev_device *prev, int ret; /* Register the subdev and video nodes. */ + prev->subdev.dev = vdev->mdev->dev; ret = v4l2_device_register_subdev(vdev, &prev->subdev); if (ret < 0) goto error; diff --git a/drivers/media/platform/omap3isp/ispreg.h b/drivers/media/platform/omap3isp/ispreg.h index 38e2b99b3f10..86b6ebb0438d 100644 --- a/drivers/media/platform/omap3isp/ispreg.h +++ b/drivers/media/platform/omap3isp/ispreg.h @@ -45,7 +45,7 @@ #define ISPCCP2_REVISION (0x000) #define ISPCCP2_SYSCONFIG (0x004) -#define ISPCCP2_SYSCONFIG_SOFT_RESET (1 << 1) +#define ISPCCP2_SYSCONFIG_SOFT_RESET BIT(1) #define ISPCCP2_SYSCONFIG_AUTO_IDLE 0x1 #define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12 #define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_FORCE \ @@ -55,44 +55,44 @@ #define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART \ (0x2 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT) #define ISPCCP2_SYSSTATUS (0x008) -#define ISPCCP2_SYSSTATUS_RESET_DONE (1 << 0) +#define ISPCCP2_SYSSTATUS_RESET_DONE BIT(0) #define ISPCCP2_LC01_IRQENABLE (0x00C) #define ISPCCP2_LC01_IRQSTATUS (0x010) -#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ (1 << 11) -#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ (1 << 10) -#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ (1 << 9) -#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ (1 << 8) -#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ (1 << 7) -#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ (1 << 5) -#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ (1 << 4) -#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ (1 << 3) -#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ (1 << 2) -#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ (1 << 1) -#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ (1 << 0) +#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ BIT(11) +#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ BIT(10) +#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ BIT(9) +#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ BIT(8) +#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ BIT(7) +#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ BIT(5) +#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ BIT(4) +#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ BIT(3) +#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ BIT(2) +#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ BIT(1) +#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ BIT(0) #define ISPCCP2_LC23_IRQENABLE (0x014) #define ISPCCP2_LC23_IRQSTATUS (0x018) #define ISPCCP2_LCM_IRQENABLE (0x02C) -#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ (1 << 0) -#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ (1 << 1) +#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ BIT(0) +#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ BIT(1) #define ISPCCP2_LCM_IRQSTATUS (0x030) #define ISPCCP2_CTRL (0x040) -#define ISPCCP2_CTRL_IF_EN (1 << 0) -#define ISPCCP2_CTRL_PHY_SEL (1 << 1) +#define ISPCCP2_CTRL_IF_EN BIT(0) +#define ISPCCP2_CTRL_PHY_SEL BIT(1) #define ISPCCP2_CTRL_PHY_SEL_CLOCK (0 << 1) #define ISPCCP2_CTRL_PHY_SEL_STROBE (1 << 1) #define ISPCCP2_CTRL_PHY_SEL_MASK 0x1 #define ISPCCP2_CTRL_PHY_SEL_SHIFT 1 -#define ISPCCP2_CTRL_IO_OUT_SEL (1 << 2) +#define ISPCCP2_CTRL_IO_OUT_SEL BIT(2) #define ISPCCP2_CTRL_IO_OUT_SEL_MASK 0x1 #define ISPCCP2_CTRL_IO_OUT_SEL_SHIFT 2 -#define ISPCCP2_CTRL_MODE (1 << 4) -#define ISPCCP2_CTRL_VP_CLK_FORCE_ON (1 << 9) -#define ISPCCP2_CTRL_INV (1 << 10) +#define ISPCCP2_CTRL_MODE BIT(4) +#define ISPCCP2_CTRL_VP_CLK_FORCE_ON BIT(9) +#define ISPCCP2_CTRL_INV BIT(10) #define ISPCCP2_CTRL_INV_MASK 0x1 #define ISPCCP2_CTRL_INV_SHIFT 10 -#define ISPCCP2_CTRL_VP_ONLY_EN (1 << 11) -#define ISPCCP2_CTRL_VP_CLK_POL (1 << 12) +#define ISPCCP2_CTRL_VP_ONLY_EN BIT(11) +#define ISPCCP2_CTRL_VP_CLK_POL BIT(12) #define ISPCCP2_CTRL_VP_CLK_POL_MASK 0x1 #define ISPCCP2_CTRL_VP_CLK_POL_SHIFT 12 #define ISPCCP2_CTRL_VPCLK_DIV_SHIFT 15 @@ -102,12 +102,12 @@ #define ISPCCP2_DBG (0x044) #define ISPCCP2_GNQ (0x048) #define ISPCCP2_LCx_CTRL(x) ((0x050)+0x30*(x)) -#define ISPCCP2_LCx_CTRL_CHAN_EN (1 << 0) -#define ISPCCP2_LCx_CTRL_CRC_EN (1 << 19) +#define ISPCCP2_LCx_CTRL_CHAN_EN BIT(0) +#define ISPCCP2_LCx_CTRL_CRC_EN BIT(19) #define ISPCCP2_LCx_CTRL_CRC_MASK 0x1 #define ISPCCP2_LCx_CTRL_CRC_SHIFT 2 #define ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0 19 -#define ISPCCP2_LCx_CTRL_REGION_EN (1 << 1) +#define ISPCCP2_LCx_CTRL_REGION_EN BIT(1) #define ISPCCP2_LCx_CTRL_REGION_MASK 0x1 #define ISPCCP2_LCx_CTRL_REGION_SHIFT 1 #define ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0 0x3f @@ -127,8 +127,8 @@ #define ISPCCP2_LCx_DAT_PONG_ADDR(x) ((0x074)+0x30*(x)) #define ISPCCP2_LCx_DAT_OFST(x) ((0x078)+0x30*(x)) #define ISPCCP2_LCM_CTRL (0x1D0) -#define ISPCCP2_LCM_CTRL_CHAN_EN (1 << 0) -#define ISPCCP2_LCM_CTRL_DST_PORT (1 << 2) +#define ISPCCP2_LCM_CTRL_CHAN_EN BIT(0) +#define ISPCCP2_LCM_CTRL_DST_PORT BIT(2) #define ISPCCP2_LCM_CTRL_DST_PORT_SHIFT 2 #define ISPCCP2_LCM_CTRL_READ_THROTTLE_SHIFT 3 #define ISPCCP2_LCM_CTRL_READ_THROTTLE_MASK 0x11 @@ -138,8 +138,8 @@ #define ISPCCP2_LCM_CTRL_SRC_FORMAT_MASK 0x7 #define ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT 20 #define ISPCCP2_LCM_CTRL_SRC_DECOMPR_MASK 0x3 -#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED (1 << 22) -#define ISPCCP2_LCM_CTRL_SRC_PACK (1 << 23) +#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED BIT(22) +#define ISPCCP2_LCM_CTRL_SRC_PACK BIT(23) #define ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT 24 #define ISPCCP2_LCM_CTRL_DST_FORMAT_MASK 0x7 #define ISPCCP2_LCM_VSIZE (0x1D4) @@ -201,19 +201,19 @@ /* SBL */ #define ISPSBL_PCR 0x4 -#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF (1 << 16) -#define ISPSBL_PCR_H3A_AF_WBL_OVF (1 << 17) -#define ISPSBL_PCR_RSZ4_WBL_OVF (1 << 18) -#define ISPSBL_PCR_RSZ3_WBL_OVF (1 << 19) -#define ISPSBL_PCR_RSZ2_WBL_OVF (1 << 20) -#define ISPSBL_PCR_RSZ1_WBL_OVF (1 << 21) -#define ISPSBL_PCR_PRV_WBL_OVF (1 << 22) -#define ISPSBL_PCR_CCDC_WBL_OVF (1 << 23) -#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF (1 << 24) -#define ISPSBL_PCR_CSIA_WBL_OVF (1 << 25) -#define ISPSBL_PCR_CSIB_WBL_OVF (1 << 26) +#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF BIT(16) +#define ISPSBL_PCR_H3A_AF_WBL_OVF BIT(17) +#define ISPSBL_PCR_RSZ4_WBL_OVF BIT(18) +#define ISPSBL_PCR_RSZ3_WBL_OVF BIT(19) +#define ISPSBL_PCR_RSZ2_WBL_OVF BIT(20) +#define ISPSBL_PCR_RSZ1_WBL_OVF BIT(21) +#define ISPSBL_PCR_PRV_WBL_OVF BIT(22) +#define ISPSBL_PCR_CCDC_WBL_OVF BIT(23) +#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF BIT(24) +#define ISPSBL_PCR_CSIA_WBL_OVF BIT(25) +#define ISPSBL_PCR_CSIB_WBL_OVF BIT(26) #define ISPSBL_CCDC_WR_0 (0x028) -#define ISPSBL_CCDC_WR_0_DATA_READY (1 << 21) +#define ISPSBL_CCDC_WR_0_DATA_READY BIT(21) #define ISPSBL_CCDC_WR_1 (0x02C) #define ISPSBL_CCDC_WR_2 (0x030) #define ISPSBL_CCDC_WR_3 (0x034) @@ -366,16 +366,16 @@ #define ISP_INT_CLR 0xFF113F11 #define ISPPRV_PCR_EN 1 -#define ISPPRV_PCR_BUSY (1 << 1) -#define ISPPRV_PCR_SOURCE (1 << 2) -#define ISPPRV_PCR_ONESHOT (1 << 3) -#define ISPPRV_PCR_WIDTH (1 << 4) -#define ISPPRV_PCR_INVALAW (1 << 5) -#define ISPPRV_PCR_DRKFEN (1 << 6) -#define ISPPRV_PCR_DRKFCAP (1 << 7) -#define ISPPRV_PCR_HMEDEN (1 << 8) -#define ISPPRV_PCR_NFEN (1 << 9) -#define ISPPRV_PCR_CFAEN (1 << 10) +#define ISPPRV_PCR_BUSY BIT(1) +#define ISPPRV_PCR_SOURCE BIT(2) +#define ISPPRV_PCR_ONESHOT BIT(3) +#define ISPPRV_PCR_WIDTH BIT(4) +#define ISPPRV_PCR_INVALAW BIT(5) +#define ISPPRV_PCR_DRKFEN BIT(6) +#define ISPPRV_PCR_DRKFCAP BIT(7) +#define ISPPRV_PCR_HMEDEN BIT(8) +#define ISPPRV_PCR_NFEN BIT(9) +#define ISPPRV_PCR_CFAEN BIT(10) #define ISPPRV_PCR_CFAFMT_SHIFT 11 #define ISPPRV_PCR_CFAFMT_MASK 0x7800 #define ISPPRV_PCR_CFAFMT_BAYER (0 << 11) @@ -384,22 +384,22 @@ #define ISPPRV_PCR_CFAFMT_DNSPL (3 << 11) #define ISPPRV_PCR_CFAFMT_HONEYCOMB (4 << 11) #define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON (5 << 11) -#define ISPPRV_PCR_YNENHEN (1 << 15) -#define ISPPRV_PCR_SUPEN (1 << 16) +#define ISPPRV_PCR_YNENHEN BIT(15) +#define ISPPRV_PCR_SUPEN BIT(16) #define ISPPRV_PCR_YCPOS_SHIFT 17 #define ISPPRV_PCR_YCPOS_YCrYCb (0 << 17) #define ISPPRV_PCR_YCPOS_YCbYCr (1 << 17) #define ISPPRV_PCR_YCPOS_CbYCrY (2 << 17) #define ISPPRV_PCR_YCPOS_CrYCbY (3 << 17) -#define ISPPRV_PCR_RSZPORT (1 << 19) -#define ISPPRV_PCR_SDRPORT (1 << 20) -#define ISPPRV_PCR_SCOMP_EN (1 << 21) +#define ISPPRV_PCR_RSZPORT BIT(19) +#define ISPPRV_PCR_SDRPORT BIT(20) +#define ISPPRV_PCR_SCOMP_EN BIT(21) #define ISPPRV_PCR_SCOMP_SFT_SHIFT (22) #define ISPPRV_PCR_SCOMP_SFT_MASK (7 << 22) -#define ISPPRV_PCR_GAMMA_BYPASS (1 << 26) -#define ISPPRV_PCR_DCOREN (1 << 27) -#define ISPPRV_PCR_DCCOUP (1 << 28) -#define ISPPRV_PCR_DRK_FAIL (1 << 31) +#define ISPPRV_PCR_GAMMA_BYPASS BIT(26) +#define ISPPRV_PCR_DCOREN BIT(27) +#define ISPPRV_PCR_DCCOUP BIT(28) +#define ISPPRV_PCR_DRK_FAIL BIT(31) #define ISPPRV_HORZ_INFO_EPH_SHIFT 0 #define ISPPRV_HORZ_INFO_EPH_MASK 0x3fff @@ -423,8 +423,8 @@ #define ISPPRV_AVE_ODDDIST_4 0x3 #define ISPPRV_HMED_THRESHOLD_SHIFT 0 -#define ISPPRV_HMED_EVENDIST (1 << 8) -#define ISPPRV_HMED_ODDDIST (1 << 9) +#define ISPPRV_HMED_EVENDIST BIT(8) +#define ISPPRV_HMED_ODDDIST BIT(9) #define ISPPRV_WBGAIN_COEF0_SHIFT 0 #define ISPPRV_WBGAIN_COEF1_SHIFT 8 @@ -517,8 +517,8 @@ /* Define bit fields within selected registers */ #define ISP_REVISION_SHIFT 0 -#define ISP_SYSCONFIG_AUTOIDLE (1 << 0) -#define ISP_SYSCONFIG_SOFTRESET (1 << 1) +#define ISP_SYSCONFIG_AUTOIDLE BIT(0) +#define ISP_SYSCONFIG_SOFTRESET BIT(1) #define ISP_SYSCONFIG_MIDLEMODE_SHIFT 12 #define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY 0x0 #define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY 0x1 @@ -526,68 +526,68 @@ #define ISP_SYSSTATUS_RESETDONE 0 -#define IRQ0ENABLE_CSIA_IRQ (1 << 0) -#define IRQ0ENABLE_CSIC_IRQ (1 << 1) -#define IRQ0ENABLE_CCP2_LCM_IRQ (1 << 3) -#define IRQ0ENABLE_CCP2_LC0_IRQ (1 << 4) -#define IRQ0ENABLE_CCP2_LC1_IRQ (1 << 5) -#define IRQ0ENABLE_CCP2_LC2_IRQ (1 << 6) -#define IRQ0ENABLE_CCP2_LC3_IRQ (1 << 7) +#define IRQ0ENABLE_CSIA_IRQ BIT(0) +#define IRQ0ENABLE_CSIC_IRQ BIT(1) +#define IRQ0ENABLE_CCP2_LCM_IRQ BIT(3) +#define IRQ0ENABLE_CCP2_LC0_IRQ BIT(4) +#define IRQ0ENABLE_CCP2_LC1_IRQ BIT(5) +#define IRQ0ENABLE_CCP2_LC2_IRQ BIT(6) +#define IRQ0ENABLE_CCP2_LC3_IRQ BIT(7) #define IRQ0ENABLE_CSIB_IRQ (IRQ0ENABLE_CCP2_LCM_IRQ | \ IRQ0ENABLE_CCP2_LC0_IRQ | \ IRQ0ENABLE_CCP2_LC1_IRQ | \ IRQ0ENABLE_CCP2_LC2_IRQ | \ IRQ0ENABLE_CCP2_LC3_IRQ) -#define IRQ0ENABLE_CCDC_VD0_IRQ (1 << 8) -#define IRQ0ENABLE_CCDC_VD1_IRQ (1 << 9) -#define IRQ0ENABLE_CCDC_VD2_IRQ (1 << 10) -#define IRQ0ENABLE_CCDC_ERR_IRQ (1 << 11) -#define IRQ0ENABLE_H3A_AF_DONE_IRQ (1 << 12) -#define IRQ0ENABLE_H3A_AWB_DONE_IRQ (1 << 13) -#define IRQ0ENABLE_HIST_DONE_IRQ (1 << 16) -#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ (1 << 17) -#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ (1 << 18) -#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ (1 << 19) -#define IRQ0ENABLE_PRV_DONE_IRQ (1 << 20) -#define IRQ0ENABLE_RSZ_DONE_IRQ (1 << 24) -#define IRQ0ENABLE_OVF_IRQ (1 << 25) -#define IRQ0ENABLE_PING_IRQ (1 << 26) -#define IRQ0ENABLE_PONG_IRQ (1 << 27) -#define IRQ0ENABLE_MMU_ERR_IRQ (1 << 28) -#define IRQ0ENABLE_OCP_ERR_IRQ (1 << 29) -#define IRQ0ENABLE_SEC_ERR_IRQ (1 << 30) -#define IRQ0ENABLE_HS_VS_IRQ (1 << 31) - -#define IRQ0STATUS_CSIA_IRQ (1 << 0) -#define IRQ0STATUS_CSI2C_IRQ (1 << 1) -#define IRQ0STATUS_CCP2_LCM_IRQ (1 << 3) -#define IRQ0STATUS_CCP2_LC0_IRQ (1 << 4) +#define IRQ0ENABLE_CCDC_VD0_IRQ BIT(8) +#define IRQ0ENABLE_CCDC_VD1_IRQ BIT(9) +#define IRQ0ENABLE_CCDC_VD2_IRQ BIT(10) +#define IRQ0ENABLE_CCDC_ERR_IRQ BIT(11) +#define IRQ0ENABLE_H3A_AF_DONE_IRQ BIT(12) +#define IRQ0ENABLE_H3A_AWB_DONE_IRQ BIT(13) +#define IRQ0ENABLE_HIST_DONE_IRQ BIT(16) +#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ BIT(17) +#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ BIT(18) +#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ BIT(19) +#define IRQ0ENABLE_PRV_DONE_IRQ BIT(20) +#define IRQ0ENABLE_RSZ_DONE_IRQ BIT(24) +#define IRQ0ENABLE_OVF_IRQ BIT(25) +#define IRQ0ENABLE_PING_IRQ BIT(26) +#define IRQ0ENABLE_PONG_IRQ BIT(27) +#define IRQ0ENABLE_MMU_ERR_IRQ BIT(28) +#define IRQ0ENABLE_OCP_ERR_IRQ BIT(29) +#define IRQ0ENABLE_SEC_ERR_IRQ BIT(30) +#define IRQ0ENABLE_HS_VS_IRQ BIT(31) + +#define IRQ0STATUS_CSIA_IRQ BIT(0) +#define IRQ0STATUS_CSI2C_IRQ BIT(1) +#define IRQ0STATUS_CCP2_LCM_IRQ BIT(3) +#define IRQ0STATUS_CCP2_LC0_IRQ BIT(4) #define IRQ0STATUS_CSIB_IRQ (IRQ0STATUS_CCP2_LCM_IRQ | \ IRQ0STATUS_CCP2_LC0_IRQ) -#define IRQ0STATUS_CSIB_LC1_IRQ (1 << 5) -#define IRQ0STATUS_CSIB_LC2_IRQ (1 << 6) -#define IRQ0STATUS_CSIB_LC3_IRQ (1 << 7) -#define IRQ0STATUS_CCDC_VD0_IRQ (1 << 8) -#define IRQ0STATUS_CCDC_VD1_IRQ (1 << 9) -#define IRQ0STATUS_CCDC_VD2_IRQ (1 << 10) -#define IRQ0STATUS_CCDC_ERR_IRQ (1 << 11) -#define IRQ0STATUS_H3A_AF_DONE_IRQ (1 << 12) -#define IRQ0STATUS_H3A_AWB_DONE_IRQ (1 << 13) -#define IRQ0STATUS_HIST_DONE_IRQ (1 << 16) -#define IRQ0STATUS_CCDC_LSC_DONE_IRQ (1 << 17) -#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ (1 << 18) -#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ (1 << 19) -#define IRQ0STATUS_PRV_DONE_IRQ (1 << 20) -#define IRQ0STATUS_RSZ_DONE_IRQ (1 << 24) -#define IRQ0STATUS_OVF_IRQ (1 << 25) -#define IRQ0STATUS_PING_IRQ (1 << 26) -#define IRQ0STATUS_PONG_IRQ (1 << 27) -#define IRQ0STATUS_MMU_ERR_IRQ (1 << 28) -#define IRQ0STATUS_OCP_ERR_IRQ (1 << 29) -#define IRQ0STATUS_SEC_ERR_IRQ (1 << 30) -#define IRQ0STATUS_HS_VS_IRQ (1 << 31) +#define IRQ0STATUS_CSIB_LC1_IRQ BIT(5) +#define IRQ0STATUS_CSIB_LC2_IRQ BIT(6) +#define IRQ0STATUS_CSIB_LC3_IRQ BIT(7) +#define IRQ0STATUS_CCDC_VD0_IRQ BIT(8) +#define IRQ0STATUS_CCDC_VD1_IRQ BIT(9) +#define IRQ0STATUS_CCDC_VD2_IRQ BIT(10) +#define IRQ0STATUS_CCDC_ERR_IRQ BIT(11) +#define IRQ0STATUS_H3A_AF_DONE_IRQ BIT(12) +#define IRQ0STATUS_H3A_AWB_DONE_IRQ BIT(13) +#define IRQ0STATUS_HIST_DONE_IRQ BIT(16) +#define IRQ0STATUS_CCDC_LSC_DONE_IRQ BIT(17) +#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ BIT(18) +#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ BIT(19) +#define IRQ0STATUS_PRV_DONE_IRQ BIT(20) +#define IRQ0STATUS_RSZ_DONE_IRQ BIT(24) +#define IRQ0STATUS_OVF_IRQ BIT(25) +#define IRQ0STATUS_PING_IRQ BIT(26) +#define IRQ0STATUS_PONG_IRQ BIT(27) +#define IRQ0STATUS_MMU_ERR_IRQ BIT(28) +#define IRQ0STATUS_OCP_ERR_IRQ BIT(29) +#define IRQ0STATUS_SEC_ERR_IRQ BIT(30) +#define IRQ0STATUS_HS_VS_IRQ BIT(31) #define TCTRL_GRESET_LEN 0 @@ -607,20 +607,20 @@ #define ISPCTRL_PAR_BRIDGE_MASK (0x3 << 2) #define ISPCTRL_PAR_CLK_POL_SHIFT 4 -#define ISPCTRL_PAR_CLK_POL_INV (1 << 4) -#define ISPCTRL_PING_PONG_EN (1 << 5) +#define ISPCTRL_PAR_CLK_POL_INV BIT(4) +#define ISPCTRL_PING_PONG_EN BIT(5) #define ISPCTRL_SHIFT_SHIFT 6 #define ISPCTRL_SHIFT_0 (0x0 << 6) #define ISPCTRL_SHIFT_2 (0x1 << 6) #define ISPCTRL_SHIFT_4 (0x2 << 6) #define ISPCTRL_SHIFT_MASK (0x3 << 6) -#define ISPCTRL_CCDC_CLK_EN (1 << 8) -#define ISPCTRL_SCMP_CLK_EN (1 << 9) -#define ISPCTRL_H3A_CLK_EN (1 << 10) -#define ISPCTRL_HIST_CLK_EN (1 << 11) -#define ISPCTRL_PREV_CLK_EN (1 << 12) -#define ISPCTRL_RSZ_CLK_EN (1 << 13) +#define ISPCTRL_CCDC_CLK_EN BIT(8) +#define ISPCTRL_SCMP_CLK_EN BIT(9) +#define ISPCTRL_H3A_CLK_EN BIT(10) +#define ISPCTRL_HIST_CLK_EN BIT(11) +#define ISPCTRL_PREV_CLK_EN BIT(12) +#define ISPCTRL_RSZ_CLK_EN BIT(13) #define ISPCTRL_SYNC_DETECT_SHIFT 14 #define ISPCTRL_SYNC_DETECT_HSFALL (0x0 << ISPCTRL_SYNC_DETECT_SHIFT) #define ISPCTRL_SYNC_DETECT_HSRISE (0x1 << ISPCTRL_SYNC_DETECT_SHIFT) @@ -628,17 +628,17 @@ #define ISPCTRL_SYNC_DETECT_VSRISE (0x3 << ISPCTRL_SYNC_DETECT_SHIFT) #define ISPCTRL_SYNC_DETECT_MASK (0x3 << ISPCTRL_SYNC_DETECT_SHIFT) -#define ISPCTRL_CCDC_RAM_EN (1 << 16) -#define ISPCTRL_PREV_RAM_EN (1 << 17) -#define ISPCTRL_SBL_RD_RAM_EN (1 << 18) -#define ISPCTRL_SBL_WR1_RAM_EN (1 << 19) -#define ISPCTRL_SBL_WR0_RAM_EN (1 << 20) -#define ISPCTRL_SBL_AUTOIDLE (1 << 21) -#define ISPCTRL_SBL_SHARED_WPORTC (1 << 26) -#define ISPCTRL_SBL_SHARED_RPORTA (1 << 27) -#define ISPCTRL_SBL_SHARED_RPORTB (1 << 28) -#define ISPCTRL_JPEG_FLUSH (1 << 30) -#define ISPCTRL_CCDC_FLUSH (1 << 31) +#define ISPCTRL_CCDC_RAM_EN BIT(16) +#define ISPCTRL_PREV_RAM_EN BIT(17) +#define ISPCTRL_SBL_RD_RAM_EN BIT(18) +#define ISPCTRL_SBL_WR1_RAM_EN BIT(19) +#define ISPCTRL_SBL_WR0_RAM_EN BIT(20) +#define ISPCTRL_SBL_AUTOIDLE BIT(21) +#define ISPCTRL_SBL_SHARED_WPORTC BIT(26) +#define ISPCTRL_SBL_SHARED_RPORTA BIT(27) +#define ISPCTRL_SBL_SHARED_RPORTB BIT(28) +#define ISPCTRL_JPEG_FLUSH BIT(30) +#define ISPCTRL_CCDC_FLUSH BIT(31) #define ISPSECURE_SECUREMODE 0 @@ -655,20 +655,20 @@ #define ISPTCTRL_CTRL_DIVC_SHIFT 10 #define ISPTCTRL_CTRL_DIVC_NOCLOCK (0x0 << 10) -#define ISPTCTRL_CTRL_SHUTEN (1 << 21) -#define ISPTCTRL_CTRL_PSTRBEN (1 << 22) -#define ISPTCTRL_CTRL_STRBEN (1 << 23) -#define ISPTCTRL_CTRL_SHUTPOL (1 << 24) -#define ISPTCTRL_CTRL_STRBPSTRBPOL (1 << 26) +#define ISPTCTRL_CTRL_SHUTEN BIT(21) +#define ISPTCTRL_CTRL_PSTRBEN BIT(22) +#define ISPTCTRL_CTRL_STRBEN BIT(23) +#define ISPTCTRL_CTRL_SHUTPOL BIT(24) +#define ISPTCTRL_CTRL_STRBPSTRBPOL BIT(26) #define ISPTCTRL_CTRL_INSEL_SHIFT 27 #define ISPTCTRL_CTRL_INSEL_PARALLEL (0x0 << 27) #define ISPTCTRL_CTRL_INSEL_CSIA (0x1 << 27) #define ISPTCTRL_CTRL_INSEL_CSIB (0x2 << 27) -#define ISPTCTRL_CTRL_GRESETEn (1 << 29) -#define ISPTCTRL_CTRL_GRESETPOL (1 << 30) -#define ISPTCTRL_CTRL_GRESETDIR (1 << 31) +#define ISPTCTRL_CTRL_GRESETEn BIT(29) +#define ISPTCTRL_CTRL_GRESETPOL BIT(30) +#define ISPTCTRL_CTRL_GRESETDIR BIT(31) #define ISPTCTRL_FRAME_SHUT_SHIFT 0 #define ISPTCTRL_FRAME_PSTRB_SHIFT 6 @@ -679,33 +679,33 @@ #define ISPCCDC_PID_TID_SHIFT 16 #define ISPCCDC_PCR_EN 1 -#define ISPCCDC_PCR_BUSY (1 << 1) +#define ISPCCDC_PCR_BUSY BIT(1) #define ISPCCDC_SYN_MODE_VDHDOUT 0x1 -#define ISPCCDC_SYN_MODE_FLDOUT (1 << 1) -#define ISPCCDC_SYN_MODE_VDPOL (1 << 2) -#define ISPCCDC_SYN_MODE_HDPOL (1 << 3) -#define ISPCCDC_SYN_MODE_FLDPOL (1 << 4) -#define ISPCCDC_SYN_MODE_EXWEN (1 << 5) -#define ISPCCDC_SYN_MODE_DATAPOL (1 << 6) -#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7) +#define ISPCCDC_SYN_MODE_FLDOUT BIT(1) +#define ISPCCDC_SYN_MODE_VDPOL BIT(2) +#define ISPCCDC_SYN_MODE_HDPOL BIT(3) +#define ISPCCDC_SYN_MODE_FLDPOL BIT(4) +#define ISPCCDC_SYN_MODE_EXWEN BIT(5) +#define ISPCCDC_SYN_MODE_DATAPOL BIT(6) +#define ISPCCDC_SYN_MODE_FLDMODE BIT(7) #define ISPCCDC_SYN_MODE_DATSIZ_MASK (0x7 << 8) #define ISPCCDC_SYN_MODE_DATSIZ_8_16 (0x0 << 8) #define ISPCCDC_SYN_MODE_DATSIZ_12 (0x4 << 8) #define ISPCCDC_SYN_MODE_DATSIZ_11 (0x5 << 8) #define ISPCCDC_SYN_MODE_DATSIZ_10 (0x6 << 8) #define ISPCCDC_SYN_MODE_DATSIZ_8 (0x7 << 8) -#define ISPCCDC_SYN_MODE_PACK8 (1 << 11) +#define ISPCCDC_SYN_MODE_PACK8 BIT(11) #define ISPCCDC_SYN_MODE_INPMOD_MASK (3 << 12) #define ISPCCDC_SYN_MODE_INPMOD_RAW (0 << 12) #define ISPCCDC_SYN_MODE_INPMOD_YCBCR16 (1 << 12) #define ISPCCDC_SYN_MODE_INPMOD_YCBCR8 (2 << 12) -#define ISPCCDC_SYN_MODE_LPF (1 << 14) -#define ISPCCDC_SYN_MODE_FLDSTAT (1 << 15) -#define ISPCCDC_SYN_MODE_VDHDEN (1 << 16) -#define ISPCCDC_SYN_MODE_WEN (1 << 17) -#define ISPCCDC_SYN_MODE_VP2SDR (1 << 18) -#define ISPCCDC_SYN_MODE_SDR2RSZ (1 << 19) +#define ISPCCDC_SYN_MODE_LPF BIT(14) +#define ISPCCDC_SYN_MODE_FLDSTAT BIT(15) +#define ISPCCDC_SYN_MODE_VDHDEN BIT(16) +#define ISPCCDC_SYN_MODE_WEN BIT(17) +#define ISPCCDC_SYN_MODE_VP2SDR BIT(18) +#define ISPCCDC_SYN_MODE_SDR2RSZ BIT(19) #define ISPCCDC_HD_VD_WID_VDW_SHIFT 0 #define ISPCCDC_HD_VD_WID_HDW_SHIFT 16 @@ -731,7 +731,7 @@ #define ISPCCDC_HSIZE_OFF_SHIFT 0 -#define ISPCCDC_SDOFST_FIINV (1 << 14) +#define ISPCCDC_SDOFST_FIINV BIT(14) #define ISPCCDC_SDOFST_FOFST_SHIFT 12 #define ISPCCDC_SDOFST_FOFST_MASK (3 << 12) #define ISPCCDC_SDOFST_LOFST3_SHIFT 0 @@ -743,7 +743,7 @@ #define ISPCCDC_CLAMP_OBST_SHIFT 10 #define ISPCCDC_CLAMP_OBSLN_SHIFT 25 #define ISPCCDC_CLAMP_OBSLEN_SHIFT 28 -#define ISPCCDC_CLAMP_CLAMPEN (1 << 31) +#define ISPCCDC_CLAMP_CLAMPEN BIT(31) #define ISPCCDC_COLPTN_R_Ye 0x0 #define ISPCCDC_COLPTN_Gr_Cy 0x1 @@ -772,8 +772,8 @@ #define ISPCCDC_BLKCMP_R_YE_SHIFT 24 #define ISPCCDC_FPC_FPNUM_SHIFT 0 -#define ISPCCDC_FPC_FPCEN (1 << 15) -#define ISPCCDC_FPC_FPERR (1 << 16) +#define ISPCCDC_FPC_FPCEN BIT(15) +#define ISPCCDC_FPC_FPERR BIT(16) #define ISPCCDC_VDINT_1_SHIFT 0 #define ISPCCDC_VDINT_1_MASK 0x00007fff @@ -784,23 +784,23 @@ #define ISPCCDC_ALAW_GWDI_11_2 (0x4 << 0) #define ISPCCDC_ALAW_GWDI_10_1 (0x5 << 0) #define ISPCCDC_ALAW_GWDI_9_0 (0x6 << 0) -#define ISPCCDC_ALAW_CCDTBL (1 << 3) +#define ISPCCDC_ALAW_CCDTBL BIT(3) #define ISPCCDC_REC656IF_R656ON 1 -#define ISPCCDC_REC656IF_ECCFVH (1 << 1) +#define ISPCCDC_REC656IF_ECCFVH BIT(1) -#define ISPCCDC_CFG_BW656 (1 << 5) +#define ISPCCDC_CFG_BW656 BIT(5) #define ISPCCDC_CFG_FIDMD_SHIFT 6 -#define ISPCCDC_CFG_WENLOG (1 << 8) +#define ISPCCDC_CFG_WENLOG BIT(8) #define ISPCCDC_CFG_WENLOG_AND (0 << 8) #define ISPCCDC_CFG_WENLOG_OR (1 << 8) -#define ISPCCDC_CFG_Y8POS (1 << 11) -#define ISPCCDC_CFG_BSWD (1 << 12) -#define ISPCCDC_CFG_MSBINVI (1 << 13) -#define ISPCCDC_CFG_VDLC (1 << 15) +#define ISPCCDC_CFG_Y8POS BIT(11) +#define ISPCCDC_CFG_BSWD BIT(12) +#define ISPCCDC_CFG_MSBINVI BIT(13) +#define ISPCCDC_CFG_VDLC BIT(15) #define ISPCCDC_FMTCFG_FMTEN 0x1 -#define ISPCCDC_FMTCFG_LNALT (1 << 1) +#define ISPCCDC_FMTCFG_LNALT BIT(1) #define ISPCCDC_FMTCFG_LNUM_SHIFT 2 #define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT 4 #define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT 8 @@ -809,7 +809,7 @@ #define ISPCCDC_FMTCFG_VPIN_11_2 (0x4 << 12) #define ISPCCDC_FMTCFG_VPIN_10_1 (0x5 << 12) #define ISPCCDC_FMTCFG_VPIN_9_0 (0x6 << 12) -#define ISPCCDC_FMTCFG_VPEN (1 << 15) +#define ISPCCDC_FMTCFG_VPEN BIT(15) #define ISPCCDC_FMTCFG_VPIF_FRQ_MASK 0x003f0000 #define ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT 16 @@ -839,9 +839,9 @@ #define ISPRSZ_PID_CID_SHIFT 8 #define ISPRSZ_PID_TID_SHIFT 16 -#define ISPRSZ_PCR_ENABLE (1 << 0) -#define ISPRSZ_PCR_BUSY (1 << 1) -#define ISPRSZ_PCR_ONESHOT (1 << 2) +#define ISPRSZ_PCR_ENABLE BIT(0) +#define ISPRSZ_PCR_BUSY BIT(1) +#define ISPRSZ_PCR_ONESHOT BIT(2) #define ISPRSZ_CNT_HRSZ_SHIFT 0 #define ISPRSZ_CNT_HRSZ_MASK \ @@ -853,10 +853,10 @@ #define ISPRSZ_CNT_HSTPH_MASK (0x7 << ISPRSZ_CNT_HSTPH_SHIFT) #define ISPRSZ_CNT_VSTPH_SHIFT 23 #define ISPRSZ_CNT_VSTPH_MASK (0x7 << ISPRSZ_CNT_VSTPH_SHIFT) -#define ISPRSZ_CNT_YCPOS (1 << 26) -#define ISPRSZ_CNT_INPTYP (1 << 27) -#define ISPRSZ_CNT_INPSRC (1 << 28) -#define ISPRSZ_CNT_CBILIN (1 << 29) +#define ISPRSZ_CNT_YCPOS BIT(26) +#define ISPRSZ_CNT_INPTYP BIT(27) +#define ISPRSZ_CNT_INPSRC BIT(28) +#define ISPRSZ_CNT_CBILIN BIT(29) #define ISPRSZ_OUT_SIZE_HORZ_SHIFT 0 #define ISPRSZ_OUT_SIZE_HORZ_MASK \ @@ -1081,8 +1081,8 @@ #define ISPH3A_PCR_AF_RGBPOS_SHIFT 11 #define ISPH3A_PCR_AEW_AVE2LMT_SHIFT 22 #define ISPH3A_PCR_AEW_AVE2LMT_MASK 0xFFC00000 -#define ISPH3A_PCR_BUSYAF (1 << 15) -#define ISPH3A_PCR_BUSYAEAWB (1 << 18) +#define ISPH3A_PCR_BUSYAF BIT(15) +#define ISPH3A_PCR_BUSYAEAWB BIT(18) #define ISPH3A_AEWWIN1_WINHC_SHIFT 0 #define ISPH3A_AEWWIN1_WINHC_MASK 0x3F @@ -1166,15 +1166,15 @@ #define ISPHIST_HV_INFO_MASK 0x3FFF3FFF -#define ISPCCDC_LSC_ENABLE 1 -#define ISPCCDC_LSC_BUSY (1 << 7) +#define ISPCCDC_LSC_ENABLE BIT(0) +#define ISPCCDC_LSC_BUSY BIT(7) #define ISPCCDC_LSC_GAIN_MODE_N_MASK 0x700 #define ISPCCDC_LSC_GAIN_MODE_N_SHIFT 8 #define ISPCCDC_LSC_GAIN_MODE_M_MASK 0x3800 #define ISPCCDC_LSC_GAIN_MODE_M_SHIFT 12 #define ISPCCDC_LSC_GAIN_FORMAT_MASK 0xE #define ISPCCDC_LSC_GAIN_FORMAT_SHIFT 1 -#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK (1<<6) +#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK BIT(6) #define ISPCCDC_LSC_INITIAL_X_MASK 0x3F #define ISPCCDC_LSC_INITIAL_X_SHIFT 0 @@ -1196,43 +1196,43 @@ (0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT) #define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART \ (0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT) -#define ISPCSI2_SYSCONFIG_SOFT_RESET (1 << 1) -#define ISPCSI2_SYSCONFIG_AUTO_IDLE (1 << 0) +#define ISPCSI2_SYSCONFIG_SOFT_RESET BIT(1) +#define ISPCSI2_SYSCONFIG_AUTO_IDLE BIT(0) #define ISPCSI2_SYSSTATUS (0x014) -#define ISPCSI2_SYSSTATUS_RESET_DONE (1 << 0) +#define ISPCSI2_SYSSTATUS_RESET_DONE BIT(0) #define ISPCSI2_IRQSTATUS (0x018) -#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ (1 << 14) -#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ (1 << 13) -#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 12) -#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ (1 << 11) -#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ (1 << 10) -#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ (1 << 9) -#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ (1 << 8) -#define ISPCSI2_IRQSTATUS_CONTEXT(n) (1 << (n)) +#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ BIT(14) +#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ BIT(13) +#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ BIT(12) +#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ BIT(11) +#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ BIT(10) +#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ BIT(9) +#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ BIT(8) +#define ISPCSI2_IRQSTATUS_CONTEXT(n) BIT(n) #define ISPCSI2_IRQENABLE (0x01c) #define ISPCSI2_CTRL (0x040) -#define ISPCSI2_CTRL_VP_CLK_EN (1 << 15) -#define ISPCSI2_CTRL_VP_ONLY_EN (1 << 11) +#define ISPCSI2_CTRL_VP_CLK_EN BIT(15) +#define ISPCSI2_CTRL_VP_ONLY_EN BIT(11) #define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT 8 #define ISPCSI2_CTRL_VP_OUT_CTRL_MASK \ (3 << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) -#define ISPCSI2_CTRL_DBG_EN (1 << 7) +#define ISPCSI2_CTRL_DBG_EN BIT(7) #define ISPCSI2_CTRL_BURST_SIZE_SHIFT 5 #define ISPCSI2_CTRL_BURST_SIZE_MASK \ (3 << ISPCSI2_CTRL_BURST_SIZE_SHIFT) -#define ISPCSI2_CTRL_FRAME (1 << 3) -#define ISPCSI2_CTRL_ECC_EN (1 << 2) -#define ISPCSI2_CTRL_SECURE (1 << 1) -#define ISPCSI2_CTRL_IF_EN (1 << 0) +#define ISPCSI2_CTRL_FRAME BIT(3) +#define ISPCSI2_CTRL_ECC_EN BIT(2) +#define ISPCSI2_CTRL_SECURE BIT(1) +#define ISPCSI2_CTRL_IF_EN BIT(0) #define ISPCSI2_DBG_H (0x044) #define ISPCSI2_GNQ (0x048) #define ISPCSI2_PHY_CFG (0x050) -#define ISPCSI2_PHY_CFG_RESET_CTRL (1 << 30) -#define ISPCSI2_PHY_CFG_RESET_DONE (1 << 29) +#define ISPCSI2_PHY_CFG_RESET_CTRL BIT(30) +#define ISPCSI2_PHY_CFG_RESET_DONE BIT(29) #define ISPCSI2_PHY_CFG_PWR_CMD_SHIFT 27 #define ISPCSI2_PHY_CFG_PWR_CMD_MASK \ (0x3 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT) @@ -1251,7 +1251,7 @@ (0x1 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT) #define ISPCSI2_PHY_CFG_PWR_STATUS_ULPW \ (0x2 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT) -#define ISPCSI2_PHY_CFG_PWR_AUTO (1 << 24) +#define ISPCSI2_PHY_CFG_PWR_AUTO BIT(24) #define ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n) (3 + ((n) * 4)) #define ISPCSI2_PHY_CFG_DATA_POL_MASK(n) \ @@ -1300,63 +1300,63 @@ (0x5 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT) #define ISPCSI2_PHY_IRQSTATUS (0x054) -#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT (1 << 26) -#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER (1 << 25) -#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5 (1 << 24) -#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4 (1 << 23) -#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3 (1 << 22) -#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2 (1 << 21) -#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1 (1 << 20) -#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5 (1 << 19) -#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4 (1 << 18) -#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3 (1 << 17) -#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2 (1 << 16) -#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1 (1 << 15) -#define ISPCSI2_PHY_IRQSTATUS_ERRESC5 (1 << 14) -#define ISPCSI2_PHY_IRQSTATUS_ERRESC4 (1 << 13) -#define ISPCSI2_PHY_IRQSTATUS_ERRESC3 (1 << 12) -#define ISPCSI2_PHY_IRQSTATUS_ERRESC2 (1 << 11) -#define ISPCSI2_PHY_IRQSTATUS_ERRESC1 (1 << 10) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5 (1 << 9) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4 (1 << 8) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3 (1 << 7) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2 (1 << 6) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1 (1 << 5) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5 (1 << 4) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4 (1 << 3) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3 (1 << 2) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2 (1 << 1) -#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1 1 +#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT BIT(26) +#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER BIT(25) +#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5 BIT(24) +#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4 BIT(23) +#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3 BIT(22) +#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2 BIT(21) +#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1 BIT(20) +#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5 BIT(19) +#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4 BIT(18) +#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3 BIT(17) +#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2 BIT(16) +#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1 BIT(15) +#define ISPCSI2_PHY_IRQSTATUS_ERRESC5 BIT(14) +#define ISPCSI2_PHY_IRQSTATUS_ERRESC4 BIT(13) +#define ISPCSI2_PHY_IRQSTATUS_ERRESC3 BIT(12) +#define ISPCSI2_PHY_IRQSTATUS_ERRESC2 BIT(11) +#define ISPCSI2_PHY_IRQSTATUS_ERRESC1 BIT(10) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5 BIT(9) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4 BIT(8) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3 BIT(7) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2 BIT(6) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1 BIT(5) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5 BIT(4) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4 BIT(3) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3 BIT(2) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2 BIT(1) +#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1 BIT(0) #define ISPCSI2_SHORT_PACKET (0x05c) #define ISPCSI2_PHY_IRQENABLE (0x060) -#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT (1 << 26) -#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER (1 << 25) -#define ISPCSI2_PHY_IRQENABLE_STATEULPM5 (1 << 24) -#define ISPCSI2_PHY_IRQENABLE_STATEULPM4 (1 << 23) -#define ISPCSI2_PHY_IRQENABLE_STATEULPM3 (1 << 22) -#define ISPCSI2_PHY_IRQENABLE_STATEULPM2 (1 << 21) -#define ISPCSI2_PHY_IRQENABLE_STATEULPM1 (1 << 20) -#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 (1 << 19) -#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 (1 << 18) -#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 (1 << 17) -#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 (1 << 16) -#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 (1 << 15) -#define ISPCSI2_PHY_IRQENABLE_ERRESC5 (1 << 14) -#define ISPCSI2_PHY_IRQENABLE_ERRESC4 (1 << 13) -#define ISPCSI2_PHY_IRQENABLE_ERRESC3 (1 << 12) -#define ISPCSI2_PHY_IRQENABLE_ERRESC2 (1 << 11) -#define ISPCSI2_PHY_IRQENABLE_ERRESC1 (1 << 10) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 (1 << 9) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 (1 << 8) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 (1 << 7) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 (1 << 6) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 (1 << 5) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 (1 << 4) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 (1 << 3) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 (1 << 2) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 (1 << 1) -#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1 (1 << 0) +#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT BIT(26) +#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER BIT(25) +#define ISPCSI2_PHY_IRQENABLE_STATEULPM5 BIT(24) +#define ISPCSI2_PHY_IRQENABLE_STATEULPM4 BIT(23) +#define ISPCSI2_PHY_IRQENABLE_STATEULPM3 BIT(22) +#define ISPCSI2_PHY_IRQENABLE_STATEULPM2 BIT(21) +#define ISPCSI2_PHY_IRQENABLE_STATEULPM1 BIT(20) +#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 BIT(19) +#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 BIT(18) +#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 BIT(17) +#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 BIT(16) +#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 BIT(15) +#define ISPCSI2_PHY_IRQENABLE_ERRESC5 BIT(14) +#define ISPCSI2_PHY_IRQENABLE_ERRESC4 BIT(13) +#define ISPCSI2_PHY_IRQENABLE_ERRESC3 BIT(12) +#define ISPCSI2_PHY_IRQENABLE_ERRESC2 BIT(11) +#define ISPCSI2_PHY_IRQENABLE_ERRESC1 BIT(10) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 BIT(9) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 BIT(8) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 BIT(7) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 BIT(6) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 BIT(5) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 BIT(4) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 BIT(3) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 BIT(2) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 BIT(1) +#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1 BIT(0) #define ISPCSI2_DBG_P (0x068) #define ISPCSI2_TIMING (0x06c) @@ -1371,12 +1371,12 @@ #define ISPCSI2_CTX_CTRL1_COUNT_SHIFT 8 #define ISPCSI2_CTX_CTRL1_COUNT_MASK \ (0xff << ISPCSI2_CTX_CTRL1_COUNT_SHIFT) -#define ISPCSI2_CTX_CTRL1_EOF_EN (1 << 7) -#define ISPCSI2_CTX_CTRL1_EOL_EN (1 << 6) -#define ISPCSI2_CTX_CTRL1_CS_EN (1 << 5) -#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4) -#define ISPCSI2_CTX_CTRL1_PING_PONG (1 << 3) -#define ISPCSI2_CTX_CTRL1_CTX_EN (1 << 0) +#define ISPCSI2_CTX_CTRL1_EOF_EN BIT(7) +#define ISPCSI2_CTX_CTRL1_EOL_EN BIT(6) +#define ISPCSI2_CTX_CTRL1_CS_EN BIT(5) +#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK BIT(4) +#define ISPCSI2_CTX_CTRL1_PING_PONG BIT(3) +#define ISPCSI2_CTX_CTRL1_CTX_EN BIT(0) #define ISPCSI2_CTX_CTRL2(n) ((0x074) + 0x20 * (n)) #define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13 @@ -1385,7 +1385,7 @@ #define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11 #define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK \ (0x3 << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT) -#define ISPCSI2_CTX_CTRL2_DPCM_PRED (1 << 10) +#define ISPCSI2_CTX_CTRL2_DPCM_PRED BIT(10) #define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT 0 #define ISPCSI2_CTX_CTRL2_FORMAT_MASK \ (0x3ff << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT) @@ -1401,24 +1401,24 @@ #define ISPCSI2_CTX_DAT_PING_ADDR(n) ((0x07c) + 0x20 * (n)) #define ISPCSI2_CTX_DAT_PONG_ADDR(n) ((0x080) + 0x20 * (n)) #define ISPCSI2_CTX_IRQENABLE(n) ((0x084) + 0x20 * (n)) -#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ (1 << 8) -#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ (1 << 7) -#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ (1 << 6) -#define ISPCSI2_CTX_IRQENABLE_CS_IRQ (1 << 5) -#define ISPCSI2_CTX_IRQENABLE_LE_IRQ (1 << 3) -#define ISPCSI2_CTX_IRQENABLE_LS_IRQ (1 << 2) -#define ISPCSI2_CTX_IRQENABLE_FE_IRQ (1 << 1) -#define ISPCSI2_CTX_IRQENABLE_FS_IRQ (1 << 0) +#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ BIT(8) +#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ BIT(7) +#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ BIT(6) +#define ISPCSI2_CTX_IRQENABLE_CS_IRQ BIT(5) +#define ISPCSI2_CTX_IRQENABLE_LE_IRQ BIT(3) +#define ISPCSI2_CTX_IRQENABLE_LS_IRQ BIT(2) +#define ISPCSI2_CTX_IRQENABLE_FE_IRQ BIT(1) +#define ISPCSI2_CTX_IRQENABLE_FS_IRQ BIT(0) #define ISPCSI2_CTX_IRQSTATUS(n) ((0x088) + 0x20 * (n)) -#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 8) -#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ (1 << 7) -#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ (1 << 6) -#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ (1 << 5) -#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ (1 << 3) -#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ (1 << 2) -#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ (1 << 1) -#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ (1 << 0) +#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ BIT(8) +#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ BIT(7) +#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ BIT(6) +#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ BIT(5) +#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ BIT(3) +#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ BIT(2) +#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ BIT(1) +#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ BIT(0) #define ISPCSI2_CTX_CTRL3(n) ((0x08c) + 0x20 * (n)) #define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT 5 @@ -1454,9 +1454,9 @@ (0xff << ISPCSIPHY_REG0_THS_SETTLE_SHIFT) #define ISPCSIPHY_REG1 (0x004) -#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK (1 << 29) +#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK BIT(29) /* This field is for OMAP3630 only */ -#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS (1 << 25) +#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS BIT(25) #define ISPCSIPHY_REG1_TCLK_TERM_SHIFT 18 #define ISPCSIPHY_REG1_TCLK_TERM_MASK \ (0x7f << ISPCSIPHY_REG1_TCLK_TERM_SHIFT) @@ -1498,11 +1498,11 @@ */ /* OMAP343X_CONTROL_CSIRXFE */ -#define OMAP343X_CONTROL_CSIRXFE_CSIB_INV (1 << 7) -#define OMAP343X_CONTROL_CSIRXFE_RESENABLE (1 << 8) -#define OMAP343X_CONTROL_CSIRXFE_SELFORM (1 << 10) -#define OMAP343X_CONTROL_CSIRXFE_PWRDNZ (1 << 12) -#define OMAP343X_CONTROL_CSIRXFE_RESET (1 << 13) +#define OMAP343X_CONTROL_CSIRXFE_CSIB_INV BIT(7) +#define OMAP343X_CONTROL_CSIRXFE_RESENABLE BIT(8) +#define OMAP343X_CONTROL_CSIRXFE_SELFORM BIT(10) +#define OMAP343X_CONTROL_CSIRXFE_PWRDNZ BIT(12) +#define OMAP343X_CONTROL_CSIRXFE_RESET BIT(13) /* OMAP3630_CONTROL_CAMERA_PHY_CTRL */ #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_PHY1_SHIFT 2 @@ -1513,6 +1513,6 @@ #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_GPI 0x3 #define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CAMMODE_MASK 0x3 /* CCP2B: set to receive data from PHY2 instead of PHY1 */ -#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2 (1 << 4) +#define OMAP3630_CONTROL_CAMERA_PHY_CTRL_CSI1_RX_SEL_PHY2 BIT(4) #endif /* OMAP3_ISP_REG_H */ diff --git a/drivers/media/platform/omap3isp/ispresizer.c b/drivers/media/platform/omap3isp/ispresizer.c index 21ca6954df72..78d9dd7ea2da 100644 --- a/drivers/media/platform/omap3isp/ispresizer.c +++ b/drivers/media/platform/omap3isp/ispresizer.c @@ -1681,6 +1681,7 @@ int omap3isp_resizer_register_entities(struct isp_res_device *res, int ret; /* Register the subdev and video nodes. */ + res->subdev.dev = vdev->mdev->dev; ret = v4l2_device_register_subdev(vdev, &res->subdev); if (ret < 0) goto error; diff --git a/drivers/media/platform/omap3isp/ispstat.c b/drivers/media/platform/omap3isp/ispstat.c index 62b2eacb96fd..5b9b57f4d9bf 100644 --- a/drivers/media/platform/omap3isp/ispstat.c +++ b/drivers/media/platform/omap3isp/ispstat.c @@ -1026,6 +1026,8 @@ void omap3isp_stat_unregister_entities(struct ispstat *stat) int omap3isp_stat_register_entities(struct ispstat *stat, struct v4l2_device *vdev) { + stat->subdev.dev = vdev->mdev->dev; + return v4l2_device_register_subdev(vdev, &stat->subdev); } diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index 499a7284c5a8..ee183c35ff3b 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -658,10 +658,6 @@ isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; - if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; - else - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; return 0; } @@ -1024,8 +1020,8 @@ static int isp_video_check_external_subdevs(struct isp_video *video, ctrls.count = 1; ctrls.controls = &ctrl; - - ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, NULL, &ctrls); + ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &video->video, + NULL, &ctrls); if (ret < 0) { dev_warn(isp->dev, "no pixel rate control in subdev %s\n", pipe->external->name); @@ -1460,6 +1456,13 @@ int omap3isp_video_init(struct isp_video *video, const char *name) video->video.vfl_type = VFL_TYPE_GRABBER; video->video.release = video_device_release_empty; video->video.ioctl_ops = &isp_video_ioctl_ops; + if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + video->video.device_caps = V4L2_CAP_VIDEO_CAPTURE + | V4L2_CAP_STREAMING; + else + video->video.device_caps = V4L2_CAP_VIDEO_OUTPUT + | V4L2_CAP_STREAMING; + video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED; video_set_drvdata(&video->video, video); diff --git a/drivers/media/platform/pxa_camera.c b/drivers/media/platform/pxa_camera.c index 1c9bfaabc54c..8d47ea0c33f8 100644 --- a/drivers/media/platform/pxa_camera.c +++ b/drivers/media/platform/pxa_camera.c @@ -64,7 +64,7 @@ #define CIBR1 0x0030 #define CIBR2 0x0038 -#define CICR0_DMAEN (1 << 31) /* DMA request enable */ +#define CICR0_DMAEN (1UL << 31) /* DMA request enable */ #define CICR0_PAR_EN (1 << 30) /* Parity enable */ #define CICR0_SL_CAP_EN (1 << 29) /* Capture enable for slave mode */ #define CICR0_ENB (1 << 28) /* Camera interface enable */ @@ -81,7 +81,7 @@ #define CICR0_EOFM (1 << 1) /* End-of-frame mask */ #define CICR0_FOM (1 << 0) /* FIFO-overrun mask */ -#define CICR1_TBIT (1 << 31) /* Transparency bit */ +#define CICR1_TBIT (1UL << 31) /* Transparency bit */ #define CICR1_RGBT_CONV (0x3 << 29) /* RGBT conversion mask */ #define CICR1_PPL (0x7ff << 15) /* Pixels per line mask */ #define CICR1_RGB_CONV (0x7 << 12) /* RGB conversion mask */ @@ -1992,9 +1992,6 @@ static int pxac_vidioc_querycap(struct file *file, void *priv, strscpy(cap->bus_info, "platform:pxa-camera", sizeof(cap->bus_info)); strscpy(cap->driver, PXA_CAM_DRV_NAME, sizeof(cap->driver)); strscpy(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; - return 0; } diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 63da18773d24..3fdc9f964a3c 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -486,9 +486,9 @@ static int camss_of_parse_ports(struct camss *camss) asd = v4l2_async_notifier_add_fwnode_subdev( &camss->notifier, of_fwnode_handle(remote), sizeof(*csd)); + of_node_put(remote); if (IS_ERR(asd)) { ret = PTR_ERR(asd); - of_node_put(remote); goto err_cleanup; } diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index 0acc7576cc58..e6eff512a8a1 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -198,7 +198,7 @@ static int venus_enumerate_codecs(struct venus_core *core, u32 type) goto err; for (i = 0; i < MAX_CODEC_NUM; i++) { - codec = (1 << i) & codecs; + codec = (1UL << i) & codecs; if (!codec) continue; diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h index 9ab95fd57760..922cb7e64bfa 100644 --- a/drivers/media/platform/qcom/venus/core.h +++ b/drivers/media/platform/qcom/venus/core.h @@ -46,6 +46,7 @@ struct venus_format { u32 pixfmt; unsigned int num_planes; u32 type; + u32 flags; }; #define MAX_PLANES 4 @@ -209,6 +210,25 @@ struct venus_buffer { #define to_venus_buffer(ptr) container_of(ptr, struct venus_buffer, vb) +enum venus_dec_state { + VENUS_DEC_STATE_DEINIT = 0, + VENUS_DEC_STATE_INIT = 1, + VENUS_DEC_STATE_CAPTURE_SETUP = 2, + VENUS_DEC_STATE_STOPPED = 3, + VENUS_DEC_STATE_SEEK = 4, + VENUS_DEC_STATE_DRAIN = 5, + VENUS_DEC_STATE_DECODING = 6, + VENUS_DEC_STATE_DRC = 7 +}; + +struct venus_ts_metadata { + bool used; + u64 ts_ns; + u64 ts_us; + u32 flags; + struct v4l2_timecode tc; +}; + /** * struct venus_inst - holds per instance parameters * @@ -232,6 +252,10 @@ struct venus_buffer { * @colorspace: current color space * @quantization: current quantization * @xfer_func: current xfer function + * @codec_state: current codec API state (see DEC/ENC_STATE_) + * @reconf_wait: wait queue for resolution change event + * @subscriptions: used to hold current events subscriptions + * @buf_count: used to count number of buffers (reqbuf(0)) * @fps: holds current FPS * @timeperframe: holds current time per frame structure * @fmt_out: a reference to output format structure @@ -246,8 +270,6 @@ struct venus_buffer { * @opb_buftype: output picture buffer type * @opb_fmt: output picture buffer raw format * @reconfig: a flag raised by decoder when the stream resolution changed - * @reconfig_width: holds the new width - * @reconfig_height: holds the new height * @hfi_codec: current codec for this instance in HFI space * @sequence_cap: a sequence counter for capture queue * @sequence_out: a sequence counter for output queue @@ -287,6 +309,11 @@ struct venus_inst { u8 ycbcr_enc; u8 quantization; u8 xfer_func; + enum venus_dec_state codec_state; + wait_queue_head_t reconf_wait; + unsigned int subscriptions; + int buf_count; + struct venus_ts_metadata tss[VIDEO_MAX_FRAME]; u64 fps; struct v4l2_fract timeperframe; const struct venus_format *fmt_out; @@ -301,8 +328,6 @@ struct venus_inst { u32 opb_buftype; u32 opb_fmt; bool reconfig; - u32 reconfig_width; - u32 reconfig_height; u32 hfi_codec; u32 sequence_cap; u32 sequence_out; diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c index 71b06dfc6dc4..1ad96c25ab09 100644 --- a/drivers/media/platform/qcom/venus/helpers.c +++ b/drivers/media/platform/qcom/venus/helpers.c @@ -79,7 +79,7 @@ bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt) } EXPORT_SYMBOL_GPL(venus_helper_check_codec); -static int venus_helper_queue_dpb_bufs(struct venus_inst *inst) +int venus_helper_queue_dpb_bufs(struct venus_inst *inst) { struct intbuf *buf; int ret = 0; @@ -100,6 +100,7 @@ static int venus_helper_queue_dpb_bufs(struct venus_inst *inst) fail: return ret; } +EXPORT_SYMBOL_GPL(venus_helper_queue_dpb_bufs); int venus_helper_free_dpb_bufs(struct venus_inst *inst) { @@ -278,7 +279,7 @@ static const unsigned int intbuf_types_4xx[] = { HFI_BUFFER_INTERNAL_PERSIST_1, }; -static int intbufs_alloc(struct venus_inst *inst) +int venus_helper_intbufs_alloc(struct venus_inst *inst) { const unsigned int *intbuf; size_t arr_sz, i; @@ -304,11 +305,59 @@ error: intbufs_unset_buffers(inst); return ret; } +EXPORT_SYMBOL_GPL(venus_helper_intbufs_alloc); -static int intbufs_free(struct venus_inst *inst) +int venus_helper_intbufs_free(struct venus_inst *inst) { return intbufs_unset_buffers(inst); } +EXPORT_SYMBOL_GPL(venus_helper_intbufs_free); + +int venus_helper_intbufs_realloc(struct venus_inst *inst) +{ + enum hfi_version ver = inst->core->res->hfi_version; + struct hfi_buffer_desc bd; + struct intbuf *buf, *n; + int ret; + + list_for_each_entry_safe(buf, n, &inst->internalbufs, list) { + if (buf->type == HFI_BUFFER_INTERNAL_PERSIST || + buf->type == HFI_BUFFER_INTERNAL_PERSIST_1) + continue; + + memset(&bd, 0, sizeof(bd)); + bd.buffer_size = buf->size; + bd.buffer_type = buf->type; + bd.num_buffers = 1; + bd.device_addr = buf->da; + bd.response_required = true; + + ret = hfi_session_unset_buffers(inst, &bd); + + dma_free_attrs(inst->core->dev, buf->size, buf->va, buf->da, + buf->attrs); + + list_del_init(&buf->list); + kfree(buf); + } + + ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH(ver)); + if (ret) + goto err; + + ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_1(ver)); + if (ret) + goto err; + + ret = intbufs_set_buffer(inst, HFI_BUFFER_INTERNAL_SCRATCH_2(ver)); + if (ret) + goto err; + + return 0; +err: + return ret; +} +EXPORT_SYMBOL_GPL(venus_helper_intbufs_realloc); static u32 load_per_instance(struct venus_inst *inst) { @@ -339,7 +388,7 @@ static u32 load_per_type(struct venus_core *core, u32 session_type) return mbs_per_sec; } -static int load_scale_clocks(struct venus_core *core) +int venus_helper_load_scale_clocks(struct venus_core *core) { const struct freq_tbl *table = core->res->freq_tbl; unsigned int num_rows = core->res->freq_tbl_size; @@ -388,6 +437,7 @@ err: dev_err(dev, "failed to set clock rate %lu (%d)\n", freq, ret); return ret; } +EXPORT_SYMBOL_GPL(venus_helper_load_scale_clocks); static void fill_buffer_desc(const struct venus_buffer *buf, struct hfi_buffer_desc *bd, bool response) @@ -413,6 +463,57 @@ static void return_buf_error(struct venus_inst *inst, v4l2_m2m_buf_done(vbuf, VB2_BUF_STATE_ERROR); } +static void +put_ts_metadata(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) +{ + struct vb2_buffer *vb = &vbuf->vb2_buf; + unsigned int i; + int slot = -1; + u64 ts_us = vb->timestamp; + + for (i = 0; i < ARRAY_SIZE(inst->tss); i++) { + if (!inst->tss[i].used) { + slot = i; + break; + } + } + + if (slot == -1) { + dev_dbg(inst->core->dev, "%s: no free slot\n", __func__); + return; + } + + do_div(ts_us, NSEC_PER_USEC); + + inst->tss[slot].used = true; + inst->tss[slot].flags = vbuf->flags; + inst->tss[slot].tc = vbuf->timecode; + inst->tss[slot].ts_us = ts_us; + inst->tss[slot].ts_ns = vb->timestamp; +} + +void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us, + struct vb2_v4l2_buffer *vbuf) +{ + struct vb2_buffer *vb = &vbuf->vb2_buf; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(inst->tss); ++i) { + if (!inst->tss[i].used) + continue; + + if (inst->tss[i].ts_us != timestamp_us) + continue; + + inst->tss[i].used = false; + vbuf->flags |= inst->tss[i].flags; + vbuf->timecode = inst->tss[i].tc; + vb->timestamp = inst->tss[i].ts_ns; + break; + } +} +EXPORT_SYMBOL_GPL(venus_helper_get_ts_metadata); + static int session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) { @@ -437,6 +538,9 @@ session_process_buf(struct venus_inst *inst, struct vb2_v4l2_buffer *vbuf) if (vbuf->flags & V4L2_BUF_FLAG_LAST || !fdata.filled_len) fdata.flags |= HFI_BUFFERFLAG_EOS; + + if (inst->session_type == VIDC_SESSION_TYPE_DEC) + put_ts_metadata(inst, vbuf); } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (inst->session_type == VIDC_SESSION_TYPE_ENC) fdata.buffer_type = HFI_BUFFER_OUTPUT; @@ -472,7 +576,7 @@ static bool is_dynamic_bufmode(struct venus_inst *inst) return caps->cap_bufs_mode_dynamic; } -static int session_unregister_bufs(struct venus_inst *inst) +int venus_helper_unregister_bufs(struct venus_inst *inst) { struct venus_buffer *buf, *n; struct hfi_buffer_desc bd; @@ -489,6 +593,7 @@ static int session_unregister_bufs(struct venus_inst *inst) return ret; } +EXPORT_SYMBOL_GPL(venus_helper_unregister_bufs); static int session_register_bufs(struct venus_inst *inst) { @@ -947,6 +1052,17 @@ int venus_helper_vb2_buf_prepare(struct vb2_buffer *vb) { struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); unsigned int out_buf_size = venus_helper_get_opb_size(inst); + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); + + if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) { + if (vbuf->field == V4L2_FIELD_ANY) + vbuf->field = V4L2_FIELD_NONE; + if (vbuf->field != V4L2_FIELD_NONE) { + dev_err(inst->core->dev, "%s field isn't supported\n", + __func__); + return -EINVAL; + } + } if (vb->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE && vb2_plane_size(vb, 0) < out_buf_size) @@ -970,16 +1086,19 @@ void venus_helper_vb2_buf_queue(struct vb2_buffer *vb) v4l2_m2m_buf_queue(m2m_ctx, vbuf); - if (!(inst->streamon_out & inst->streamon_cap)) + if (inst->session_type == VIDC_SESSION_TYPE_ENC && + !(inst->streamon_out && inst->streamon_cap)) goto unlock; - ret = is_buf_refed(inst, vbuf); - if (ret) - goto unlock; + if (vb2_start_streaming_called(vb->vb2_queue)) { + ret = is_buf_refed(inst, vbuf); + if (ret) + goto unlock; - ret = session_process_buf(inst, vbuf); - if (ret) - return_buf_error(inst, vbuf); + ret = session_process_buf(inst, vbuf); + if (ret) + return_buf_error(inst, vbuf); + } unlock: mutex_unlock(&inst->lock); @@ -1009,8 +1128,8 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q) if (inst->streamon_out & inst->streamon_cap) { ret = hfi_session_stop(inst); ret |= hfi_session_unload_res(inst); - ret |= session_unregister_bufs(inst); - ret |= intbufs_free(inst); + ret |= venus_helper_unregister_bufs(inst); + ret |= venus_helper_intbufs_free(inst); ret |= hfi_session_deinit(inst); if (inst->session_error || core->sys_error) @@ -1021,7 +1140,7 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q) venus_helper_free_dpb_bufs(inst); - load_scale_clocks(core); + venus_helper_load_scale_clocks(core); INIT_LIST_HEAD(&inst->registeredbufs); } @@ -1036,12 +1155,48 @@ void venus_helper_vb2_stop_streaming(struct vb2_queue *q) } EXPORT_SYMBOL_GPL(venus_helper_vb2_stop_streaming); +int venus_helper_process_initial_cap_bufs(struct venus_inst *inst) +{ + struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; + struct v4l2_m2m_buffer *buf, *n; + int ret; + + v4l2_m2m_for_each_dst_buf_safe(m2m_ctx, buf, n) { + ret = session_process_buf(inst, &buf->vb); + if (ret) { + return_buf_error(inst, &buf->vb); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(venus_helper_process_initial_cap_bufs); + +int venus_helper_process_initial_out_bufs(struct venus_inst *inst) +{ + struct v4l2_m2m_ctx *m2m_ctx = inst->m2m_ctx; + struct v4l2_m2m_buffer *buf, *n; + int ret; + + v4l2_m2m_for_each_src_buf_safe(m2m_ctx, buf, n) { + ret = session_process_buf(inst, &buf->vb); + if (ret) { + return_buf_error(inst, &buf->vb); + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(venus_helper_process_initial_out_bufs); + int venus_helper_vb2_start_streaming(struct venus_inst *inst) { struct venus_core *core = inst->core; int ret; - ret = intbufs_alloc(inst); + ret = venus_helper_intbufs_alloc(inst); if (ret) return ret; @@ -1049,7 +1204,7 @@ int venus_helper_vb2_start_streaming(struct venus_inst *inst) if (ret) goto err_bufs_free; - load_scale_clocks(core); + venus_helper_load_scale_clocks(core); ret = hfi_session_load_res(inst); if (ret) @@ -1059,20 +1214,14 @@ int venus_helper_vb2_start_streaming(struct venus_inst *inst) if (ret) goto err_unload_res; - ret = venus_helper_queue_dpb_bufs(inst); - if (ret) - goto err_session_stop; - return 0; -err_session_stop: - hfi_session_stop(inst); err_unload_res: hfi_session_unload_res(inst); err_unreg_bufs: - session_unregister_bufs(inst); + venus_helper_unregister_bufs(inst); err_bufs_free: - intbufs_free(inst); + venus_helper_intbufs_free(inst); return ret; } EXPORT_SYMBOL_GPL(venus_helper_vb2_start_streaming); diff --git a/drivers/media/platform/qcom/venus/helpers.h b/drivers/media/platform/qcom/venus/helpers.h index 153783687a0c..01f411b12f81 100644 --- a/drivers/media/platform/qcom/venus/helpers.h +++ b/drivers/media/platform/qcom/venus/helpers.h @@ -9,6 +9,7 @@ #include <media/videobuf2-v4l2.h> struct venus_inst; +struct venus_core; bool venus_helper_check_codec(struct venus_inst *inst, u32 v4l2_pixfmt); struct vb2_v4l2_buffer *venus_helper_find_buf(struct venus_inst *inst, @@ -53,4 +54,14 @@ int venus_helper_alloc_dpb_bufs(struct venus_inst *inst); int venus_helper_free_dpb_bufs(struct venus_inst *inst); int venus_helper_power_enable(struct venus_core *core, u32 session_type, bool enable); +int venus_helper_intbufs_alloc(struct venus_inst *inst); +int venus_helper_intbufs_free(struct venus_inst *inst); +int venus_helper_intbufs_realloc(struct venus_inst *inst); +int venus_helper_queue_dpb_bufs(struct venus_inst *inst); +int venus_helper_unregister_bufs(struct venus_inst *inst); +int venus_helper_load_scale_clocks(struct venus_core *core); +int venus_helper_process_initial_cap_bufs(struct venus_inst *inst); +int venus_helper_process_initial_out_bufs(struct venus_inst *inst); +void venus_helper_get_ts_metadata(struct venus_inst *inst, u64 timestamp_us, + struct vb2_v4l2_buffer *vbuf); #endif diff --git a/drivers/media/platform/qcom/venus/hfi.c b/drivers/media/platform/qcom/venus/hfi.c index 6ad0c1772ea7..3d8b1284d1f3 100644 --- a/drivers/media/platform/qcom/venus/hfi.c +++ b/drivers/media/platform/qcom/venus/hfi.c @@ -198,6 +198,9 @@ int hfi_session_init(struct venus_inst *inst, u32 pixfmt) const struct hfi_ops *ops = core->ops; int ret; + if (inst->state != INST_UNINIT) + return -EINVAL; + inst->hfi_codec = to_codec_type(pixfmt); reinit_completion(&inst->done); @@ -276,6 +279,7 @@ int hfi_session_start(struct venus_inst *inst) return 0; } +EXPORT_SYMBOL_GPL(hfi_session_start); int hfi_session_stop(struct venus_inst *inst) { @@ -299,6 +303,7 @@ int hfi_session_stop(struct venus_inst *inst) return 0; } +EXPORT_SYMBOL_GPL(hfi_session_stop); int hfi_session_continue(struct venus_inst *inst) { @@ -328,6 +333,7 @@ int hfi_session_abort(struct venus_inst *inst) return 0; } +EXPORT_SYMBOL_GPL(hfi_session_abort); int hfi_session_load_res(struct venus_inst *inst) { @@ -374,15 +380,16 @@ int hfi_session_unload_res(struct venus_inst *inst) return 0; } +EXPORT_SYMBOL_GPL(hfi_session_unload_res); -int hfi_session_flush(struct venus_inst *inst) +int hfi_session_flush(struct venus_inst *inst, u32 type) { const struct hfi_ops *ops = inst->core->ops; int ret; reinit_completion(&inst->done); - ret = ops->session_flush(inst, HFI_FLUSH_ALL); + ret = ops->session_flush(inst, type); if (ret) return ret; diff --git a/drivers/media/platform/qcom/venus/hfi.h b/drivers/media/platform/qcom/venus/hfi.h index b121cb1427ac..855822c9f39b 100644 --- a/drivers/media/platform/qcom/venus/hfi.h +++ b/drivers/media/platform/qcom/venus/hfi.h @@ -161,7 +161,7 @@ int hfi_session_continue(struct venus_inst *inst); int hfi_session_abort(struct venus_inst *inst); int hfi_session_load_res(struct venus_inst *inst); int hfi_session_unload_res(struct venus_inst *inst); -int hfi_session_flush(struct venus_inst *inst); +int hfi_session_flush(struct venus_inst *inst, u32 type); int hfi_session_set_buffers(struct venus_inst *inst, struct hfi_buffer_desc *bd); int hfi_session_unset_buffers(struct venus_inst *inst, diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index e1f998656c07..7f4660555ddb 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -37,42 +37,52 @@ static const struct venus_format vdec_formats[] = { .pixfmt = V4L2_PIX_FMT_MPEG4, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_MPEG2, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_H263, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_G, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_VC1_ANNEX_L, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_H264, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_VP8, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_VP9, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_XVID, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, { .pixfmt = V4L2_PIX_FMT_HEVC, .num_planes = 1, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + .flags = V4L2_FMT_FLAG_DYN_RESOLUTION, }, }; @@ -133,6 +143,7 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; const struct venus_format *fmt; + u32 szimage; memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); @@ -161,14 +172,17 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) pixmp->num_planes = fmt->num_planes; pixmp->flags = 0; - pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat, - pixmp->width, - pixmp->height); + szimage = venus_helper_get_framesz(pixmp->pixelformat, pixmp->width, + pixmp->height); - if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + pfmt[0].sizeimage = szimage; pfmt[0].bytesperline = ALIGN(pixmp->width, 128); - else + } else { + pfmt[0].sizeimage = clamp_t(u32, pfmt[0].sizeimage, 0, SZ_8M); + pfmt[0].sizeimage = max(pfmt[0].sizeimage, szimage); pfmt[0].bytesperline = 0; + } return fmt; } @@ -182,33 +196,56 @@ static int vdec_try_fmt(struct file *file, void *fh, struct v4l2_format *f) return 0; } +static int vdec_check_src_change(struct venus_inst *inst) +{ + int ret; + + if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE && + inst->codec_state == VENUS_DEC_STATE_INIT && + !inst->reconfig) + return -EINVAL; + + if (inst->subscriptions & V4L2_EVENT_SOURCE_CHANGE) + return 0; + + /* + * The code snippet below is a workaround for backward compatibility + * with applications which doesn't support V4L2 events. It will be + * dropped in future once those applications are fixed. + */ + + if (inst->codec_state != VENUS_DEC_STATE_INIT) + goto done; + + ret = wait_event_timeout(inst->reconf_wait, inst->reconfig, + msecs_to_jiffies(100)); + if (!ret) + return -EINVAL; + + if (!(inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) || + !inst->reconfig) + dev_dbg(inst->core->dev, "%s: wrong state\n", __func__); + +done: + return 0; +} + static int vdec_g_fmt(struct file *file, void *fh, struct v4l2_format *f) { struct venus_inst *inst = to_inst(file); const struct venus_format *fmt = NULL; struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; + int ret; if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) fmt = inst->fmt_cap; else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) fmt = inst->fmt_out; - if (inst->reconfig) { - struct v4l2_format format = {}; - - inst->out_width = inst->reconfig_width; - inst->out_height = inst->reconfig_height; - inst->reconfig = false; - - format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt; - format.fmt.pix_mp.width = inst->out_width; - format.fmt.pix_mp.height = inst->out_height; - - vdec_try_fmt_common(inst, &format); - - inst->width = format.fmt.pix_mp.width; - inst->height = format.fmt.pix_mp.height; + if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { + ret = vdec_check_src_change(inst); + if (ret) + return ret; } pixmp->pixelformat = fmt->pixfmt; @@ -266,6 +303,7 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) inst->ycbcr_enc = pixmp->ycbcr_enc; inst->quantization = pixmp->quantization; inst->xfer_func = pixmp->xfer_func; + inst->input_buf_size = pixmp->plane_fmt[0].sizeimage; } memset(&format, 0, sizeof(format)); @@ -351,6 +389,7 @@ static int vdec_enum_fmt(struct file *file, void *fh, struct v4l2_fmtdesc *f) return -EINVAL; f->pixelformat = fmt->pixfmt; + f->flags = fmt->flags; return 0; } @@ -422,11 +461,18 @@ static int vdec_enum_framesizes(struct file *file, void *fh, static int vdec_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub) { + struct venus_inst *inst = container_of(fh, struct venus_inst, fh); + int ret; + switch (sub->type) { case V4L2_EVENT_EOS: return v4l2_event_subscribe(fh, sub, 2, NULL); case V4L2_EVENT_SOURCE_CHANGE: - return v4l2_src_change_event_subscribe(fh, sub); + ret = v4l2_src_change_event_subscribe(fh, sub); + if (ret) + return ret; + inst->subscriptions |= V4L2_EVENT_SOURCE_CHANGE; + return 0; case V4L2_EVENT_CTRL: return v4l2_ctrl_subscribe_event(fh, sub); default: @@ -435,45 +481,35 @@ static int vdec_subscribe_event(struct v4l2_fh *fh, } static int -vdec_try_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) -{ - switch (cmd->cmd) { - case V4L2_DEC_CMD_STOP: - if (cmd->flags & V4L2_DEC_CMD_STOP_TO_BLACK) - return -EINVAL; - break; - default: - return -EINVAL; - } - - return 0; -} - -static int vdec_decoder_cmd(struct file *file, void *fh, struct v4l2_decoder_cmd *cmd) { struct venus_inst *inst = to_inst(file); struct hfi_frame_data fdata = {0}; int ret; - ret = vdec_try_decoder_cmd(file, fh, cmd); + ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, cmd); if (ret) return ret; mutex_lock(&inst->lock); - /* - * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on decoder - * input to signal EOS. - */ - if (!(inst->streamon_out & inst->streamon_cap)) - goto unlock; + if (cmd->cmd == V4L2_DEC_CMD_STOP) { + /* + * Implement V4L2_DEC_CMD_STOP by enqueue an empty buffer on + * decoder input to signal EOS. + */ + if (!(inst->streamon_out && inst->streamon_cap)) + goto unlock; - fdata.buffer_type = HFI_BUFFER_INPUT; - fdata.flags |= HFI_BUFFERFLAG_EOS; - fdata.device_addr = 0xdeadbeef; + fdata.buffer_type = HFI_BUFFER_INPUT; + fdata.flags |= HFI_BUFFERFLAG_EOS; + fdata.device_addr = 0xdeadb000; - ret = hfi_session_process_buf(inst, &fdata); + ret = hfi_session_process_buf(inst, &fdata); + + if (!ret && inst->codec_state == VENUS_DEC_STATE_DECODING) + inst->codec_state = VENUS_DEC_STATE_DRAIN; + } unlock: mutex_unlock(&inst->lock); @@ -504,7 +540,7 @@ static const struct v4l2_ioctl_ops vdec_ioctl_ops = { .vidioc_enum_framesizes = vdec_enum_framesizes, .vidioc_subscribe_event = vdec_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, - .vidioc_try_decoder_cmd = vdec_try_decoder_cmd, + .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd, .vidioc_decoder_cmd = vdec_decoder_cmd, }; @@ -634,20 +670,18 @@ static int vdec_output_conf(struct venus_inst *inst) return 0; } -static int vdec_init_session(struct venus_inst *inst) +static int vdec_session_init(struct venus_inst *inst) { int ret; ret = hfi_session_init(inst, inst->fmt_out->pixfmt); - if (ret) + if (ret == -EINVAL) + return 0; + else if (ret) return ret; - ret = venus_helper_set_input_resolution(inst, inst->out_width, - inst->out_height); - if (ret) - goto deinit; - - ret = venus_helper_set_color_format(inst, inst->fmt_cap->pixfmt); + ret = venus_helper_set_input_resolution(inst, frame_width_min(inst), + frame_height_min(inst)); if (ret) goto deinit; @@ -666,26 +700,19 @@ static int vdec_num_buffers(struct venus_inst *inst, unsigned int *in_num, *in_num = *out_num = 0; - ret = vdec_init_session(inst); - if (ret) - return ret; - ret = venus_helper_get_bufreq(inst, HFI_BUFFER_INPUT, &bufreq); if (ret) - goto deinit; + return ret; *in_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); if (ret) - goto deinit; + return ret; *out_num = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); -deinit: - hfi_session_deinit(inst); - - return ret; + return 0; } static int vdec_queue_setup(struct vb2_queue *q, @@ -718,6 +745,10 @@ static int vdec_queue_setup(struct vb2_queue *q, return 0; } + ret = vdec_session_init(inst); + if (ret) + return ret; + ret = vdec_num_buffers(inst, &in_num, &out_num); if (ret) return ret; @@ -728,6 +759,7 @@ static int vdec_queue_setup(struct vb2_queue *q, sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt, inst->out_width, inst->out_height); + sizes[0] = max(sizes[0], inst->input_buf_size); inst->input_buf_size = sizes[0]; *num_buffers = max(*num_buffers, in_num); inst->num_input_bufs = *num_buffers; @@ -741,6 +773,11 @@ static int vdec_queue_setup(struct vb2_queue *q, inst->output_buf_size = sizes[0]; *num_buffers = max(*num_buffers, out_num); inst->num_output_bufs = *num_buffers; + + mutex_lock(&inst->lock); + if (inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) + inst->codec_state = VENUS_DEC_STATE_STOPPED; + mutex_unlock(&inst->lock); break; default: ret = -EINVAL; @@ -777,80 +814,295 @@ static int vdec_verify_conf(struct venus_inst *inst) return 0; } -static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) +static int vdec_start_capture(struct venus_inst *inst) { - struct venus_inst *inst = vb2_get_drv_priv(q); int ret; - mutex_lock(&inst->lock); + if (!inst->streamon_out) + return 0; - if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - inst->streamon_out = 1; - else - inst->streamon_cap = 1; + if (inst->codec_state == VENUS_DEC_STATE_DECODING) { + if (inst->reconfig) + goto reconfigure; - if (!(inst->streamon_out & inst->streamon_cap)) { - mutex_unlock(&inst->lock); + venus_helper_queue_dpb_bufs(inst); + venus_helper_process_initial_cap_bufs(inst); + inst->streamon_cap = 1; return 0; } - venus_helper_init_instance(inst); + if (inst->codec_state != VENUS_DEC_STATE_STOPPED) + return 0; - inst->reconfig = false; - inst->sequence_cap = 0; - inst->sequence_out = 0; +reconfigure: + ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT); + if (ret) + return ret; - ret = vdec_init_session(inst); + ret = vdec_output_conf(inst); if (ret) - goto bufs_done; + return ret; + + ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, + VB2_MAX_FRAME, VB2_MAX_FRAME); + if (ret) + return ret; + + ret = venus_helper_intbufs_realloc(inst); + if (ret) + goto err; + + ret = venus_helper_alloc_dpb_bufs(inst); + if (ret) + goto err; + + ret = venus_helper_queue_dpb_bufs(inst); + if (ret) + goto free_dpb_bufs; + + ret = venus_helper_process_initial_cap_bufs(inst); + if (ret) + goto free_dpb_bufs; + + venus_helper_load_scale_clocks(inst->core); + + ret = hfi_session_continue(inst); + if (ret) + goto free_dpb_bufs; + + inst->codec_state = VENUS_DEC_STATE_DECODING; + + inst->streamon_cap = 1; + inst->sequence_cap = 0; + inst->reconfig = false; + + return 0; + +free_dpb_bufs: + venus_helper_free_dpb_bufs(inst); +err: + return ret; +} + +static int vdec_start_output(struct venus_inst *inst) +{ + int ret; + + if (inst->codec_state == VENUS_DEC_STATE_SEEK) { + ret = venus_helper_process_initial_out_bufs(inst); + inst->codec_state = VENUS_DEC_STATE_DECODING; + goto done; + } + + if (inst->codec_state == VENUS_DEC_STATE_INIT || + inst->codec_state == VENUS_DEC_STATE_CAPTURE_SETUP) { + ret = venus_helper_process_initial_out_bufs(inst); + goto done; + } + + if (inst->codec_state != VENUS_DEC_STATE_DEINIT) + return -EINVAL; + + venus_helper_init_instance(inst); + inst->sequence_out = 0; + inst->reconfig = false; ret = vdec_set_properties(inst); if (ret) - goto deinit_sess; + return ret; ret = vdec_output_conf(inst); if (ret) - goto deinit_sess; + return ret; ret = vdec_verify_conf(inst); if (ret) - goto deinit_sess; + return ret; ret = venus_helper_set_num_bufs(inst, inst->num_input_bufs, VB2_MAX_FRAME, VB2_MAX_FRAME); if (ret) - goto deinit_sess; + return ret; - ret = venus_helper_alloc_dpb_bufs(inst); + ret = venus_helper_vb2_start_streaming(inst); if (ret) - goto deinit_sess; + return ret; - ret = venus_helper_vb2_start_streaming(inst); + ret = venus_helper_process_initial_out_bufs(inst); if (ret) - goto deinit_sess; + return ret; - mutex_unlock(&inst->lock); + inst->codec_state = VENUS_DEC_STATE_INIT; + +done: + inst->streamon_out = 1; + return ret; +} + +static int vdec_start_streaming(struct vb2_queue *q, unsigned int count) +{ + struct venus_inst *inst = vb2_get_drv_priv(q); + int ret; + + mutex_lock(&inst->lock); + + if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + ret = vdec_start_capture(inst); + else + ret = vdec_start_output(inst); + if (ret) + goto error; + + mutex_unlock(&inst->lock); return 0; -deinit_sess: - hfi_session_deinit(inst); -bufs_done: +error: venus_helper_buffers_done(inst, VB2_BUF_STATE_QUEUED); + mutex_unlock(&inst->lock); + return ret; +} + +static void vdec_cancel_dst_buffers(struct venus_inst *inst) +{ + struct vb2_v4l2_buffer *buf; + + while ((buf = v4l2_m2m_dst_buf_remove(inst->m2m_ctx))) + v4l2_m2m_buf_done(buf, VB2_BUF_STATE_ERROR); +} + +static int vdec_stop_capture(struct venus_inst *inst) +{ + int ret = 0; + + switch (inst->codec_state) { + case VENUS_DEC_STATE_DECODING: + ret = hfi_session_flush(inst, HFI_FLUSH_ALL); + /* fallthrough */ + case VENUS_DEC_STATE_DRAIN: + vdec_cancel_dst_buffers(inst); + inst->codec_state = VENUS_DEC_STATE_STOPPED; + break; + case VENUS_DEC_STATE_DRC: + ret = hfi_session_flush(inst, HFI_FLUSH_OUTPUT); + vdec_cancel_dst_buffers(inst); + inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; + INIT_LIST_HEAD(&inst->registeredbufs); + venus_helper_free_dpb_bufs(inst); + break; + default: + return 0; + } + + return ret; +} + +static int vdec_stop_output(struct venus_inst *inst) +{ + int ret = 0; + + switch (inst->codec_state) { + case VENUS_DEC_STATE_DECODING: + case VENUS_DEC_STATE_DRAIN: + case VENUS_DEC_STATE_STOPPED: + ret = hfi_session_flush(inst, HFI_FLUSH_ALL); + inst->codec_state = VENUS_DEC_STATE_SEEK; + break; + case VENUS_DEC_STATE_INIT: + case VENUS_DEC_STATE_CAPTURE_SETUP: + ret = hfi_session_flush(inst, HFI_FLUSH_INPUT); + break; + default: + break; + } + + return ret; +} + +static void vdec_stop_streaming(struct vb2_queue *q) +{ + struct venus_inst *inst = vb2_get_drv_priv(q); + int ret = -EINVAL; + + mutex_lock(&inst->lock); + + if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + ret = vdec_stop_capture(inst); + else + ret = vdec_stop_output(inst); + + venus_helper_buffers_done(inst, VB2_BUF_STATE_ERROR); + + if (ret) + goto unlock; + if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) inst->streamon_out = 0; else inst->streamon_cap = 0; + +unlock: mutex_unlock(&inst->lock); - return ret; +} + +static void vdec_session_release(struct venus_inst *inst) +{ + struct venus_core *core = inst->core; + int ret, abort = 0; + + mutex_lock(&inst->lock); + + inst->codec_state = VENUS_DEC_STATE_DEINIT; + + ret = hfi_session_stop(inst); + abort = (ret && ret != -EINVAL) ? 1 : 0; + ret = hfi_session_unload_res(inst); + abort = (ret && ret != -EINVAL) ? 1 : 0; + ret = venus_helper_unregister_bufs(inst); + abort = (ret && ret != -EINVAL) ? 1 : 0; + ret = venus_helper_intbufs_free(inst); + abort = (ret && ret != -EINVAL) ? 1 : 0; + ret = hfi_session_deinit(inst); + abort = (ret && ret != -EINVAL) ? 1 : 0; + + if (inst->session_error || core->sys_error) + abort = 1; + + if (abort) + hfi_session_abort(inst); + + venus_helper_free_dpb_bufs(inst); + venus_helper_load_scale_clocks(core); + INIT_LIST_HEAD(&inst->registeredbufs); + + mutex_unlock(&inst->lock); +} + +static int vdec_buf_init(struct vb2_buffer *vb) +{ + struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); + + inst->buf_count++; + + return venus_helper_vb2_buf_init(vb); +} + +static void vdec_buf_cleanup(struct vb2_buffer *vb) +{ + struct venus_inst *inst = vb2_get_drv_priv(vb->vb2_queue); + + inst->buf_count--; + if (!inst->buf_count) + vdec_session_release(inst); } static const struct vb2_ops vdec_vb2_ops = { .queue_setup = vdec_queue_setup, - .buf_init = venus_helper_vb2_buf_init, + .buf_init = vdec_buf_init, + .buf_cleanup = vdec_buf_cleanup, .buf_prepare = venus_helper_vb2_buf_prepare, .start_streaming = vdec_start_streaming, - .stop_streaming = venus_helper_vb2_stop_streaming, + .stop_streaming = vdec_stop_streaming, .buf_queue = venus_helper_vb2_buf_queue, }; @@ -874,9 +1126,9 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, vbuf->flags = flags; vbuf->field = V4L2_FIELD_NONE; + vb = &vbuf->vb2_buf; if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - vb = &vbuf->vb2_buf; vb2_set_plane_payload(vb, 0, bytesused); vb->planes[0].data_offset = data_offset; vb->timestamp = timestamp_us * NSEC_PER_USEC; @@ -886,28 +1138,85 @@ static void vdec_buf_done(struct venus_inst *inst, unsigned int buf_type, const struct v4l2_event ev = { .type = V4L2_EVENT_EOS }; v4l2_event_queue_fh(&inst->fh, &ev); + + if (inst->codec_state == VENUS_DEC_STATE_DRAIN) + inst->codec_state = VENUS_DEC_STATE_STOPPED; } } else { vbuf->sequence = inst->sequence_out++; } + venus_helper_get_ts_metadata(inst, timestamp_us, vbuf); + if (hfi_flags & HFI_BUFFERFLAG_READONLY) venus_helper_acquire_buf_ref(vbuf); if (hfi_flags & HFI_BUFFERFLAG_DATACORRUPT) state = VB2_BUF_STATE_ERROR; + if (hfi_flags & HFI_BUFFERFLAG_DROP_FRAME) { + state = VB2_BUF_STATE_ERROR; + vb2_set_plane_payload(vb, 0, 0); + vb->timestamp = 0; + } + v4l2_m2m_buf_done(vbuf, state); } +static void vdec_event_change(struct venus_inst *inst, + struct hfi_event_data *ev_data, bool sufficient) +{ + static const struct v4l2_event ev = { + .type = V4L2_EVENT_SOURCE_CHANGE, + .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION }; + struct device *dev = inst->core->dev_dec; + struct v4l2_format format = {}; + + mutex_lock(&inst->lock); + + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + format.fmt.pix_mp.pixelformat = inst->fmt_cap->pixfmt; + format.fmt.pix_mp.width = ev_data->width; + format.fmt.pix_mp.height = ev_data->height; + + vdec_try_fmt_common(inst, &format); + + inst->width = format.fmt.pix_mp.width; + inst->height = format.fmt.pix_mp.height; + + inst->out_width = ev_data->width; + inst->out_height = ev_data->height; + + dev_dbg(dev, "event %s sufficient resources (%ux%u)\n", + sufficient ? "" : "not", ev_data->width, ev_data->height); + + if (sufficient) { + hfi_session_continue(inst); + } else { + switch (inst->codec_state) { + case VENUS_DEC_STATE_INIT: + inst->codec_state = VENUS_DEC_STATE_CAPTURE_SETUP; + break; + case VENUS_DEC_STATE_DECODING: + inst->codec_state = VENUS_DEC_STATE_DRC; + break; + default: + break; + } + } + + inst->reconfig = true; + v4l2_event_queue_fh(&inst->fh, &ev); + wake_up(&inst->reconf_wait); + + mutex_unlock(&inst->lock); +} + static void vdec_event_notify(struct venus_inst *inst, u32 event, struct hfi_event_data *data) { struct venus_core *core = inst->core; struct device *dev = core->dev_dec; - static const struct v4l2_event ev = { - .type = V4L2_EVENT_SOURCE_CHANGE, - .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION }; switch (event) { case EVT_SESSION_ERROR: @@ -917,18 +1226,10 @@ static void vdec_event_notify(struct venus_inst *inst, u32 event, case EVT_SYS_EVENT_CHANGE: switch (data->event_type) { case HFI_EVENT_DATA_SEQUENCE_CHANGED_SUFFICIENT_BUF_RESOURCES: - hfi_session_continue(inst); - dev_dbg(dev, "event sufficient resources\n"); + vdec_event_change(inst, data, true); break; case HFI_EVENT_DATA_SEQUENCE_CHANGED_INSUFFICIENT_BUF_RESOURCES: - inst->reconfig_height = data->height; - inst->reconfig_width = data->width; - inst->reconfig = true; - - v4l2_event_queue_fh(&inst->fh, &ev); - - dev_dbg(dev, "event not sufficient resources (%ux%u)\n", - data->width, data->height); + vdec_event_change(inst, data, false); break; case HFI_EVENT_RELEASE_BUFFER_REFERENCE: venus_helper_release_buf_ref(inst, data->tag); @@ -949,20 +1250,25 @@ static const struct hfi_inst_ops vdec_hfi_ops = { static void vdec_inst_init(struct venus_inst *inst) { + inst->hfi_codec = HFI_VIDEO_CODEC_H264; inst->fmt_out = &vdec_formats[6]; inst->fmt_cap = &vdec_formats[0]; - inst->width = 1280; - inst->height = ALIGN(720, 32); - inst->out_width = 1280; - inst->out_height = 720; + inst->width = frame_width_min(inst); + inst->height = ALIGN(frame_height_min(inst), 32); + inst->out_width = frame_width_min(inst); + inst->out_height = frame_height_min(inst); inst->fps = 30; inst->timeperframe.numerator = 1; inst->timeperframe.denominator = 30; - inst->hfi_codec = HFI_VIDEO_CODEC_H264; + inst->opb_buftype = HFI_BUFFER_OUTPUT; +} + +static void vdec_m2m_device_run(void *priv) +{ } static const struct v4l2_m2m_ops vdec_m2m_ops = { - .device_run = venus_helper_m2m_device_run, + .device_run = vdec_m2m_device_run, .job_abort = venus_helper_m2m_job_abort, }; @@ -980,7 +1286,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, src_vq->drv_priv = inst; src_vq->buf_struct_size = sizeof(struct venus_buffer); src_vq->allow_zero_bytesused = 1; - src_vq->min_buffers_needed = 1; + src_vq->min_buffers_needed = 0; src_vq->dev = inst->core->dev; ret = vb2_queue_init(src_vq); if (ret) @@ -994,7 +1300,7 @@ static int m2m_queue_init(void *priv, struct vb2_queue *src_vq, dst_vq->drv_priv = inst; dst_vq->buf_struct_size = sizeof(struct venus_buffer); dst_vq->allow_zero_bytesused = 1; - dst_vq->min_buffers_needed = 1; + dst_vq->min_buffers_needed = 0; dst_vq->dev = inst->core->dev; ret = vb2_queue_init(dst_vq); if (ret) { @@ -1024,7 +1330,9 @@ static int vdec_open(struct file *file) inst->core = core; inst->session_type = VIDC_SESSION_TYPE_DEC; inst->num_output_bufs = 1; - + inst->codec_state = VENUS_DEC_STATE_DEINIT; + inst->buf_count = 0; + init_waitqueue_head(&inst->reconf_wait); venus_helper_init_instance(inst); ret = pm_runtime_get_sync(core->dev_dec); diff --git a/drivers/media/platform/qcom/venus/vdec_ctrls.c b/drivers/media/platform/qcom/venus/vdec_ctrls.c index 300350bfe8bd..3a963cbd342a 100644 --- a/drivers/media/platform/qcom/venus/vdec_ctrls.c +++ b/drivers/media/platform/qcom/venus/vdec_ctrls.c @@ -7,6 +7,7 @@ #include <media/v4l2-ctrls.h> #include "core.h" +#include "helpers.h" #include "vdec.h" static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) @@ -38,7 +39,9 @@ static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) { struct venus_inst *inst = ctrl_to_inst(ctrl); struct vdec_controls *ctr = &inst->controls.dec; + struct hfi_buffer_requirements bufreq; union hfi_get_property hprop; + enum hfi_version ver = inst->core->res->hfi_version; u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; int ret; @@ -62,7 +65,9 @@ static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) ctrl->val = ctr->post_loop_deb_mode; break; case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: - ctrl->val = inst->num_output_bufs; + ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); + if (!ret) + ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); break; default: return -EINVAL; diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index a5f3d2c46bea..1b7fb2d5887c 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -294,6 +294,7 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; const struct venus_format *fmt; + u32 sizeimage; memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); @@ -325,9 +326,10 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) pixmp->num_planes = fmt->num_planes; pixmp->flags = 0; - pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat, - pixmp->width, - pixmp->height); + sizeimage = venus_helper_get_framesz(pixmp->pixelformat, + pixmp->width, + pixmp->height); + pfmt[0].sizeimage = max(ALIGN(pfmt[0].sizeimage, SZ_4K), sizeimage); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) pfmt[0].bytesperline = ALIGN(pixmp->width, 128); @@ -399,8 +401,10 @@ static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) inst->fmt_out = fmt; - else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { inst->fmt_cap = fmt; + inst->output_buf_size = pixmp->plane_fmt[0].sizeimage; + } return 0; } @@ -918,6 +922,7 @@ static int venc_queue_setup(struct vb2_queue *q, sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt, inst->width, inst->height); + sizes[0] = max(sizes[0], inst->output_buf_size); inst->output_buf_size = sizes[0]; break; default: diff --git a/drivers/media/platform/rcar-vin/rcar-core.c b/drivers/media/platform/rcar-vin/rcar-core.c index 64f9cf790445..6993484ff0f3 100644 --- a/drivers/media/platform/rcar-vin/rcar-core.c +++ b/drivers/media/platform/rcar-vin/rcar-core.c @@ -390,6 +390,28 @@ out: } /* ----------------------------------------------------------------------------- + * Controls + */ + +static int rvin_s_ctrl(struct v4l2_ctrl *ctrl) +{ + struct rvin_dev *vin = + container_of(ctrl->handler, struct rvin_dev, ctrl_handler); + + switch (ctrl->id) { + case V4L2_CID_ALPHA_COMPONENT: + rvin_set_alpha(vin, ctrl->val); + break; + } + + return 0; +} + +static const struct v4l2_ctrl_ops rvin_ctrl_ops = { + .s_ctrl = rvin_s_ctrl, +}; + +/* ----------------------------------------------------------------------------- * Async notifier */ @@ -478,6 +500,15 @@ static int rvin_parallel_subdevice_attach(struct rvin_dev *vin, if (ret < 0) return ret; + v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, + V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); + + if (vin->ctrl_handler.error) { + ret = vin->ctrl_handler.error; + v4l2_ctrl_handler_free(&vin->ctrl_handler); + return ret; + } + ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler, NULL, true); if (ret < 0) { @@ -633,7 +664,7 @@ static int rvin_parallel_init(struct rvin_dev *vin) ret = v4l2_async_notifier_register(&vin->v4l2_dev, &vin->notifier); if (ret < 0) { vin_err(vin, "Notifier registration failed\n"); - v4l2_async_notifier_cleanup(&vin->group->notifier); + v4l2_async_notifier_cleanup(&vin->notifier); return ret; } @@ -870,6 +901,21 @@ static int rvin_mc_init(struct rvin_dev *vin) if (ret) rvin_group_put(vin); + ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1); + if (ret < 0) + return ret; + + v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, + V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); + + if (vin->ctrl_handler.error) { + ret = vin->ctrl_handler.error; + v4l2_ctrl_handler_free(&vin->ctrl_handler); + return ret; + } + + vin->vdev.ctrl_handler = &vin->ctrl_handler; + return ret; } @@ -1245,6 +1291,7 @@ static int rcar_vin_probe(struct platform_device *pdev) vin->dev = &pdev->dev; vin->info = of_device_get_match_data(&pdev->dev); + vin->alpha = 0xff; /* * Special care is needed on r8a7795 ES1.x since it @@ -1288,6 +1335,8 @@ static int rcar_vin_probe(struct platform_device *pdev) return 0; error_group_unregister: + v4l2_ctrl_handler_free(&vin->ctrl_handler); + if (vin->info->use_mc) { mutex_lock(&vin->group->lock); if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { @@ -1323,10 +1372,10 @@ static int rcar_vin_remove(struct platform_device *pdev) } mutex_unlock(&vin->group->lock); rvin_group_put(vin); - } else { - v4l2_ctrl_handler_free(&vin->ctrl_handler); } + v4l2_ctrl_handler_free(&vin->ctrl_handler); + rvin_dma_unregister(vin); return 0; diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c b/drivers/media/platform/rcar-vin/rcar-dma.c index 91ab064404a1..3cb29b2e0b2b 100644 --- a/drivers/media/platform/rcar-vin/rcar-dma.c +++ b/drivers/media/platform/rcar-vin/rcar-dma.c @@ -111,10 +111,13 @@ #define VNIE_EFE (1 << 1) /* Video n Data Mode Register bits */ +#define VNDMR_A8BIT(n) (((n) & 0xff) << 24) +#define VNDMR_A8BIT_MASK (0xff << 24) #define VNDMR_EXRGB (1 << 8) #define VNDMR_BPSM (1 << 4) +#define VNDMR_ABIT (1 << 2) #define VNDMR_DTMD_YCSEP (1 << 1) -#define VNDMR_DTMD_ARGB1555 (1 << 0) +#define VNDMR_DTMD_ARGB (1 << 0) /* Video n Data Mode Register 2 bits */ #define VNDMR2_VPS (1 << 30) @@ -574,6 +577,9 @@ static void rvin_crop_scale_comp_gen2(struct rvin_dev *vin) void rvin_crop_scale_comp(struct rvin_dev *vin) { + const struct rvin_video_format *fmt; + u32 stride; + /* Set Start/End Pixel/Line Pre-Clip */ rvin_write(vin, vin->crop.left, VNSPPRC_REG); rvin_write(vin, vin->crop.left + vin->crop.width - 1, VNEPPRC_REG); @@ -597,10 +603,9 @@ void rvin_crop_scale_comp(struct rvin_dev *vin) if (vin->info->model != RCAR_GEN3) rvin_crop_scale_comp_gen2(vin); - if (vin->format.pixelformat == V4L2_PIX_FMT_NV16) - rvin_write(vin, ALIGN(vin->format.width, 0x20), VNIS_REG); - else - rvin_write(vin, ALIGN(vin->format.width, 0x10), VNIS_REG); + fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); + stride = vin->format.bytesperline / fmt->bpp; + rvin_write(vin, stride, VNIS_REG); } /* ----------------------------------------------------------------------------- @@ -721,7 +726,7 @@ static int rvin_setup(struct rvin_dev *vin) output_is_yuv = true; break; case V4L2_PIX_FMT_XRGB555: - dmr = VNDMR_DTMD_ARGB1555; + dmr = VNDMR_DTMD_ARGB; break; case V4L2_PIX_FMT_RGB565: dmr = 0; @@ -730,6 +735,12 @@ static int rvin_setup(struct rvin_dev *vin) /* Note: not supported on M1 */ dmr = VNDMR_EXRGB; break; + case V4L2_PIX_FMT_ARGB555: + dmr = (vin->alpha ? VNDMR_ABIT : 0) | VNDMR_DTMD_ARGB; + break; + case V4L2_PIX_FMT_ABGR32: + dmr = VNDMR_A8BIT(vin->alpha) | VNDMR_EXRGB | VNDMR_DTMD_ARGB; + break; default: vin_err(vin, "Invalid pixelformat (0x%x)\n", vin->format.pixelformat); @@ -794,7 +805,7 @@ static void rvin_set_slot_addr(struct rvin_dev *vin, int slot, dma_addr_t addr) int offsetx, offsety; dma_addr_t offset; - fmt = rvin_format_from_pixel(vin->format.pixelformat); + fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); /* * There is no HW support for composition do the beast we can @@ -1343,3 +1354,34 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel) return 0; } + +void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha) +{ + unsigned long flags; + u32 dmr; + + spin_lock_irqsave(&vin->qlock, flags); + + vin->alpha = alpha; + + if (vin->state == STOPPED) + goto out; + + switch (vin->format.pixelformat) { + case V4L2_PIX_FMT_ARGB555: + dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_ABIT; + if (vin->alpha) + dmr |= VNDMR_ABIT; + break; + case V4L2_PIX_FMT_ABGR32: + dmr = rvin_read(vin, VNDMR_REG) & ~VNDMR_A8BIT_MASK; + dmr |= VNDMR_A8BIT(vin->alpha); + break; + default: + goto out; + } + + rvin_write(vin, dmr, VNDMR_REG); +out: + spin_unlock_irqrestore(&vin->qlock, flags); +} diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c index 0936bcd98df1..cbc1c07f0a96 100644 --- a/drivers/media/platform/rcar-vin/rcar-v4l2.c +++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c @@ -54,12 +54,24 @@ static const struct rvin_video_format rvin_formats[] = { .fourcc = V4L2_PIX_FMT_XBGR32, .bpp = 4, }, + { + .fourcc = V4L2_PIX_FMT_ARGB555, + .bpp = 2, + }, + { + .fourcc = V4L2_PIX_FMT_ABGR32, + .bpp = 4, + }, }; -const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat) +const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin, + u32 pixelformat) { int i; + if (vin->info->model == RCAR_M1 && pixelformat == V4L2_PIX_FMT_XBGR32) + return NULL; + for (i = 0; i < ARRAY_SIZE(rvin_formats); i++) if (rvin_formats[i].fourcc == pixelformat) return rvin_formats + i; @@ -67,16 +79,20 @@ const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat) return NULL; } -static u32 rvin_format_bytesperline(struct v4l2_pix_format *pix) +static u32 rvin_format_bytesperline(struct rvin_dev *vin, + struct v4l2_pix_format *pix) { const struct rvin_video_format *fmt; + u32 align; - fmt = rvin_format_from_pixel(pix->pixelformat); + fmt = rvin_format_from_pixel(vin, pix->pixelformat); if (WARN_ON(!fmt)) return -EINVAL; - return pix->width * fmt->bpp; + align = pix->pixelformat == V4L2_PIX_FMT_NV16 ? 0x20 : 0x10; + + return ALIGN(pix->width, align) * fmt->bpp; } static u32 rvin_format_sizeimage(struct v4l2_pix_format *pix) @@ -91,9 +107,7 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) { u32 walign; - if (!rvin_format_from_pixel(pix->pixelformat) || - (vin->info->model == RCAR_M1 && - pix->pixelformat == V4L2_PIX_FMT_XBGR32)) + if (!rvin_format_from_pixel(vin, pix->pixelformat)) pix->pixelformat = RVIN_DEFAULT_FORMAT; switch (pix->field) { @@ -125,7 +139,7 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, &pix->height, 4, vin->info->max_height, 2, 0); - pix->bytesperline = rvin_format_bytesperline(pix); + pix->bytesperline = rvin_format_bytesperline(vin, pix); pix->sizeimage = rvin_format_sizeimage(pix); vin_dbg(vin, "Format %ux%u bpl: %u size: %u\n", @@ -181,9 +195,7 @@ static int rvin_try_format(struct rvin_dev *vin, u32 which, if (pad_cfg == NULL) return -ENOMEM; - if (!rvin_format_from_pixel(pix->pixelformat) || - (vin->info->model == RCAR_M1 && - pix->pixelformat == V4L2_PIX_FMT_XBGR32)) + if (!rvin_format_from_pixel(vin, pix->pixelformat)) pix->pixelformat = RVIN_DEFAULT_FORMAT; v4l2_fill_mbus_format(&format.format, pix, vin->mbus_code); @@ -384,7 +396,7 @@ static int rvin_s_selection(struct file *file, void *fh, while ((r.top * vin->format.bytesperline) & HW_BUFFER_MASK) r.top--; - fmt = rvin_format_from_pixel(vin->format.pixelformat); + fmt = rvin_format_from_pixel(vin, vin->format.pixelformat); while ((r.left * fmt->bpp) & HW_BUFFER_MASK) r.left--; @@ -781,26 +793,26 @@ static int rvin_open(struct file *file) if (ret) goto err_unlock; - if (vin->info->use_mc) { + if (vin->info->use_mc) ret = v4l2_pipeline_pm_use(&vin->vdev.entity, 1); - if (ret < 0) - goto err_open; - } else { - if (v4l2_fh_is_singular_file(file)) { - ret = rvin_power_parallel(vin, true); - if (ret < 0) - goto err_open; - - ret = v4l2_ctrl_handler_setup(&vin->ctrl_handler); - if (ret) - goto err_parallel; - } - } + else if (v4l2_fh_is_singular_file(file)) + ret = rvin_power_parallel(vin, true); + + if (ret < 0) + goto err_open; + + ret = v4l2_ctrl_handler_setup(&vin->ctrl_handler); + if (ret) + goto err_power; + mutex_unlock(&vin->lock); return 0; -err_parallel: - rvin_power_parallel(vin, false); +err_power: + if (vin->info->use_mc) + v4l2_pipeline_pm_use(&vin->vdev.entity, 0); + else if (v4l2_fh_is_singular_file(file)) + rvin_power_parallel(vin, false); err_open: v4l2_fh_release(file); err_unlock: diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h index 0b13b34d03e3..e562c2ff21ec 100644 --- a/drivers/media/platform/rcar-vin/rcar-vin.h +++ b/drivers/media/platform/rcar-vin/rcar-vin.h @@ -178,6 +178,8 @@ struct rvin_info { * @compose: active composing * @source: active size of the video source * @std: active video standard of the video source + * + * @alpha: Alpha component to fill in for supported pixel formats */ struct rvin_dev { struct device *dev; @@ -215,6 +217,8 @@ struct rvin_dev { struct v4l2_rect compose; struct v4l2_rect source; v4l2_std_id std; + + unsigned int alpha; }; #define vin_to_source(vin) ((vin)->parallel->subdev) @@ -260,11 +264,14 @@ void rvin_dma_unregister(struct rvin_dev *vin); int rvin_v4l2_register(struct rvin_dev *vin); void rvin_v4l2_unregister(struct rvin_dev *vin); -const struct rvin_video_format *rvin_format_from_pixel(u32 pixelformat); +const struct rvin_video_format *rvin_format_from_pixel(struct rvin_dev *vin, + u32 pixelformat); + /* Cropping, composing and scaling */ void rvin_crop_scale_comp(struct rvin_dev *vin); int rvin_set_channel_routing(struct rvin_dev *vin, u8 chsel); +void rvin_set_alpha(struct rvin_dev *vin, unsigned int alpha); #endif diff --git a/drivers/media/platform/rcar_fdp1.c b/drivers/media/platform/rcar_fdp1.c index 43aae9b6bb20..cb93a13e1777 100644 --- a/drivers/media/platform/rcar_fdp1.c +++ b/drivers/media/platform/rcar_fdp1.c @@ -2122,6 +2122,7 @@ static int fdp1_open(struct file *file) if (ctx->hdl.error) { ret = ctx->hdl.error; v4l2_ctrl_handler_free(&ctx->hdl); + kfree(ctx); goto done; } @@ -2306,7 +2307,7 @@ static int fdp1_probe(struct platform_device *pdev) fdp1->fcp = rcar_fcp_get(fcp_node); of_node_put(fcp_node); if (IS_ERR(fdp1->fcp)) { - dev_err(&pdev->dev, "FCP not found (%ld)\n", + dev_dbg(&pdev->dev, "FCP not found (%ld)\n", PTR_ERR(fdp1->fcp)); return PTR_ERR(fdp1->fcp); } diff --git a/drivers/media/platform/renesas-ceu.c b/drivers/media/platform/renesas-ceu.c index 57d0c0f9fa4b..197b3991330d 100644 --- a/drivers/media/platform/renesas-ceu.c +++ b/drivers/media/platform/renesas-ceu.c @@ -1659,10 +1659,8 @@ static int ceu_probe(struct platform_device *pdev) } ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(dev, "Failed to get irq: %d\n", ret); + if (ret < 0) goto error_free_ceudev; - } irq = ret; ret = devm_request_irq(dev, irq, ceu_irq, diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c index 5283d4533fa0..e9ff12b6b5bb 100644 --- a/drivers/media/platform/rockchip/rga/rga.c +++ b/drivers/media/platform/rockchip/rga/rga.c @@ -831,7 +831,6 @@ static int rga_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); if (irq < 0) { - dev_err(rga->dev, "failed to get irq\n"); ret = irq; goto err_put_clk; } diff --git a/drivers/media/platform/s3c-camif/camif-capture.c b/drivers/media/platform/s3c-camif/camif-capture.c index a876d0873ebc..2fb45db8e4ba 100644 --- a/drivers/media/platform/s3c-camif/camif-capture.c +++ b/drivers/media/platform/s3c-camif/camif-capture.c @@ -641,10 +641,6 @@ static int s3c_camif_vidioc_querycap(struct file *file, void *priv, strscpy(cap->card, S3C_CAMIF_DRIVER_NAME, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s.%d", dev_name(vp->camif->dev), vp->id); - - cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; } @@ -685,10 +681,7 @@ static int s3c_camif_vidioc_enum_fmt(struct file *file, void *priv, if (!fmt) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; - - pr_debug("fmt(%d): %s\n", f->index, f->description); return 0; } @@ -802,10 +795,10 @@ static int s3c_camif_vidioc_s_fmt(struct file *file, void *priv, if (vp->owner == NULL) vp->owner = priv; - pr_debug("%ux%u. payload: %u. fmt: %s. %d %d. sizeimage: %d. bpl: %d\n", - out_frame->f_width, out_frame->f_height, vp->payload, fmt->name, - pix->width * pix->height * fmt->depth, fmt->depth, - pix->sizeimage, pix->bytesperline); + pr_debug("%ux%u. payload: %u. fmt: 0x%08x. %d %d. sizeimage: %d. bpl: %d\n", + out_frame->f_width, out_frame->f_height, vp->payload, + fmt->fourcc, pix->width * pix->height * fmt->depth, + fmt->depth, pix->sizeimage, pix->bytesperline); return 0; } @@ -1163,6 +1156,7 @@ int s3c_camif_register_video_node(struct camif_dev *camif, int idx) goto err_me_cleanup; vfd->ctrl_handler = &vp->ctrl_handler; + vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) diff --git a/drivers/media/platform/s3c-camif/camif-core.c b/drivers/media/platform/s3c-camif/camif-core.c index b05ce0149ca1..c6fbcd7036d6 100644 --- a/drivers/media/platform/s3c-camif/camif-core.c +++ b/drivers/media/platform/s3c-camif/camif-core.c @@ -42,7 +42,6 @@ static char *camif_clocks[CLK_MAX_NUM] = { static const struct camif_fmt camif_formats[] = { { - .name = "YUV 4:2:2 planar, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV422P, .depth = 16, .ybpp = 1, @@ -51,7 +50,6 @@ static const struct camif_fmt camif_formats[] = { .flags = FMT_FL_S3C24XX_CODEC | FMT_FL_S3C64XX, }, { - .name = "YUV 4:2:0 planar, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420, .depth = 12, .ybpp = 1, @@ -60,7 +58,6 @@ static const struct camif_fmt camif_formats[] = { .flags = FMT_FL_S3C24XX_CODEC | FMT_FL_S3C64XX, }, { - .name = "YVU 4:2:0 planar, Y/Cr/Cb", .fourcc = V4L2_PIX_FMT_YVU420, .depth = 12, .ybpp = 1, @@ -69,7 +66,6 @@ static const struct camif_fmt camif_formats[] = { .flags = FMT_FL_S3C24XX_CODEC | FMT_FL_S3C64XX, }, { - .name = "RGB565, 16 bpp", .fourcc = V4L2_PIX_FMT_RGB565X, .depth = 16, .ybpp = 2, @@ -78,7 +74,6 @@ static const struct camif_fmt camif_formats[] = { .flags = FMT_FL_S3C24XX_PREVIEW | FMT_FL_S3C64XX, }, { - .name = "XRGB8888, 32 bpp", .fourcc = V4L2_PIX_FMT_RGB32, .depth = 32, .ybpp = 4, @@ -87,7 +82,6 @@ static const struct camif_fmt camif_formats[] = { .flags = FMT_FL_S3C24XX_PREVIEW | FMT_FL_S3C64XX, }, { - .name = "BGR666", .fourcc = V4L2_PIX_FMT_BGR666, .depth = 32, .ybpp = 4, @@ -386,10 +380,8 @@ static int camif_request_irqs(struct platform_device *pdev, init_waitqueue_head(&vp->irq_queue); irq = platform_get_irq(pdev, i); - if (irq <= 0) { - dev_err(&pdev->dev, "failed to get IRQ %d\n", i); + if (irq <= 0) return -ENXIO; - } ret = devm_request_irq(&pdev->dev, irq, s3c_camif_irq_handler, 0, dev_name(&pdev->dev), vp); diff --git a/drivers/media/platform/s3c-camif/camif-core.h b/drivers/media/platform/s3c-camif/camif-core.h index efdc00b4ec6f..f937e638490f 100644 --- a/drivers/media/platform/s3c-camif/camif-core.h +++ b/drivers/media/platform/s3c-camif/camif-core.h @@ -89,7 +89,6 @@ enum img_fmt { * @ybpp: number of luminance bytes per pixel */ struct camif_fmt { - char *name; u32 fourcc; u32 color; u16 colplanes; diff --git a/drivers/media/platform/s3c-camif/camif-regs.h b/drivers/media/platform/s3c-camif/camif-regs.h index 29f839cdb486..052948a7b669 100644 --- a/drivers/media/platform/s3c-camif/camif-regs.h +++ b/drivers/media/platform/s3c-camif/camif-regs.h @@ -9,6 +9,8 @@ #ifndef CAMIF_REGS_H_ #define CAMIF_REGS_H_ +#include <linux/bitops.h> + #include "camif-core.h" #include <media/drv-intf/s3c_camif.h> @@ -19,7 +21,7 @@ /* Camera input format */ #define S3C_CAMIF_REG_CISRCFMT 0x00 -#define CISRCFMT_ITU601_8BIT (1 << 31) +#define CISRCFMT_ITU601_8BIT BIT(31) #define CISRCFMT_ITU656_8BIT (0 << 31) #define CISRCFMT_ORDER422_YCBYCR (0 << 14) #define CISRCFMT_ORDER422_YCRYCB (1 << 14) @@ -30,14 +32,14 @@ /* Window offset */ #define S3C_CAMIF_REG_CIWDOFST 0x04 -#define CIWDOFST_WINOFSEN (1 << 31) -#define CIWDOFST_CLROVCOFIY (1 << 30) -#define CIWDOFST_CLROVRLB_PR (1 << 28) -/* #define CIWDOFST_CLROVPRFIY (1 << 27) */ -#define CIWDOFST_CLROVCOFICB (1 << 15) -#define CIWDOFST_CLROVCOFICR (1 << 14) -#define CIWDOFST_CLROVPRFICB (1 << 13) -#define CIWDOFST_CLROVPRFICR (1 << 12) +#define CIWDOFST_WINOFSEN BIT(31) +#define CIWDOFST_CLROVCOFIY BIT(30) +#define CIWDOFST_CLROVRLB_PR BIT(28) +/* #define CIWDOFST_CLROVPRFIY BIT(27) */ +#define CIWDOFST_CLROVCOFICB BIT(15) +#define CIWDOFST_CLROVCOFICR BIT(14) +#define CIWDOFST_CLROVPRFICB BIT(13) +#define CIWDOFST_CLROVPRFICR BIT(12) #define CIWDOFST_OFST_MASK (0x7ff << 16 | 0x7ff) /* Window offset 2 */ @@ -46,24 +48,24 @@ /* Global control */ #define S3C_CAMIF_REG_CIGCTRL 0x08 -#define CIGCTRL_SWRST (1 << 31) -#define CIGCTRL_CAMRST (1 << 30) +#define CIGCTRL_SWRST BIT(31) +#define CIGCTRL_CAMRST BIT(30) #define CIGCTRL_TESTPATTERN_NORMAL (0 << 27) #define CIGCTRL_TESTPATTERN_COLOR_BAR (1 << 27) #define CIGCTRL_TESTPATTERN_HOR_INC (2 << 27) #define CIGCTRL_TESTPATTERN_VER_INC (3 << 27) #define CIGCTRL_TESTPATTERN_MASK (3 << 27) -#define CIGCTRL_INVPOLPCLK (1 << 26) -#define CIGCTRL_INVPOLVSYNC (1 << 25) -#define CIGCTRL_INVPOLHREF (1 << 24) -#define CIGCTRL_IRQ_OVFEN (1 << 22) -#define CIGCTRL_HREF_MASK (1 << 21) -#define CIGCTRL_IRQ_LEVEL (1 << 20) +#define CIGCTRL_INVPOLPCLK BIT(26) +#define CIGCTRL_INVPOLVSYNC BIT(25) +#define CIGCTRL_INVPOLHREF BIT(24) +#define CIGCTRL_IRQ_OVFEN BIT(22) +#define CIGCTRL_HREF_MASK BIT(21) +#define CIGCTRL_IRQ_LEVEL BIT(20) /* IRQ_CLR_C, IRQ_CLR_P */ -#define CIGCTRL_IRQ_CLR(id) (1 << (19 - (id))) -#define CIGCTRL_FIELDMODE (1 << 2) -#define CIGCTRL_INVPOLFIELD (1 << 1) -#define CIGCTRL_CAM_INTERLACE (1 << 0) +#define CIGCTRL_IRQ_CLR(id) BIT(19 - (id)) +#define CIGCTRL_FIELDMODE BIT(2) +#define CIGCTRL_INVPOLFIELD BIT(1) +#define CIGCTRL_CAM_INTERLACE BIT(0) /* Y DMA output frame start address. n = 0..3. */ #define S3C_CAMIF_REG_CIYSA(id, n) (0x18 + (id) * 0x54 + (n) * 4) @@ -74,8 +76,8 @@ /* CICOTRGFMT, CIPRTRGFMT - Target format */ #define S3C_CAMIF_REG_CITRGFMT(id, _offs) (0x48 + (id) * (0x34 + (_offs))) -#define CITRGFMT_IN422 (1 << 31) /* only for s3c24xx */ -#define CITRGFMT_OUT422 (1 << 30) /* only for s3c24xx */ +#define CITRGFMT_IN422 BIT(31) /* only for s3c24xx */ +#define CITRGFMT_OUT422 BIT(30) /* only for s3c24xx */ #define CITRGFMT_OUTFORMAT_YCBCR420 (0 << 29) /* only for s3c6410 */ #define CITRGFMT_OUTFORMAT_YCBCR422 (1 << 29) /* only for s3c6410 */ #define CITRGFMT_OUTFORMAT_YCBCR422I (2 << 29) /* only for s3c6410 */ @@ -88,7 +90,7 @@ #define CITRGFMT_FLIP_180 (3 << 14) #define CITRGFMT_FLIP_MASK (3 << 14) /* Preview path only */ -#define CITRGFMT_ROT90_PR (1 << 13) +#define CITRGFMT_ROT90_PR BIT(13) #define CITRGFMT_TARGETVSIZE(x) ((x) << 0) #define CITRGFMT_TARGETSIZE_MASK ((0x1fff << 16) | 0x1fff) @@ -102,7 +104,7 @@ #define CICTRL_RGBBURST2(x) ((x) << 14) #define CICTRL_CBURST1(x) ((x) << 9) #define CICTRL_CBURST2(x) ((x) << 4) -#define CICTRL_LASTIRQ_ENABLE (1 << 2) +#define CICTRL_LASTIRQ_ENABLE BIT(2) #define CICTRL_ORDER422_MASK (3 << 0) /* CICOSCPRERATIO, CIPRSCPRERATIO. Pre-scaler control 1. */ @@ -113,22 +115,22 @@ /* CICOSCCTRL, CIPRSCCTRL. Main scaler control. */ #define S3C_CAMIF_REG_CISCCTRL(id, _offs) (0x58 + (id) * (0x34 + (_offs))) -#define CISCCTRL_SCALERBYPASS (1 << 31) +#define CISCCTRL_SCALERBYPASS BIT(31) /* s3c244x preview path only, s3c64xx both */ -#define CIPRSCCTRL_SAMPLE (1 << 31) +#define CIPRSCCTRL_SAMPLE BIT(31) /* 0 - 16-bit RGB, 1 - 24-bit RGB */ -#define CIPRSCCTRL_RGB_FORMAT_24BIT (1 << 30) /* only for s3c244x */ -#define CIPRSCCTRL_SCALEUP_H (1 << 29) /* only for s3c244x */ -#define CIPRSCCTRL_SCALEUP_V (1 << 28) /* only for s3c244x */ +#define CIPRSCCTRL_RGB_FORMAT_24BIT BIT(30) /* only for s3c244x */ +#define CIPRSCCTRL_SCALEUP_H BIT(29) /* only for s3c244x */ +#define CIPRSCCTRL_SCALEUP_V BIT(28) /* only for s3c244x */ /* s3c64xx */ -#define CISCCTRL_SCALEUP_H (1 << 30) -#define CISCCTRL_SCALEUP_V (1 << 29) +#define CISCCTRL_SCALEUP_H BIT(30) +#define CISCCTRL_SCALEUP_V BIT(29) #define CISCCTRL_SCALEUP_MASK (0x3 << 29) -#define CISCCTRL_CSCR2Y_WIDE (1 << 28) -#define CISCCTRL_CSCY2R_WIDE (1 << 27) -#define CISCCTRL_LCDPATHEN_FIFO (1 << 26) -#define CISCCTRL_INTERLACE (1 << 25) -#define CISCCTRL_SCALERSTART (1 << 15) +#define CISCCTRL_CSCR2Y_WIDE BIT(28) +#define CISCCTRL_CSCY2R_WIDE BIT(27) +#define CISCCTRL_LCDPATHEN_FIFO BIT(26) +#define CISCCTRL_INTERLACE BIT(25) +#define CISCCTRL_SCALERSTART BIT(15) #define CISCCTRL_INRGB_FMT_RGB565 (0 << 13) #define CISCCTRL_INRGB_FMT_RGB666 (1 << 13) #define CISCCTRL_INRGB_FMT_RGB888 (2 << 13) @@ -137,8 +139,8 @@ #define CISCCTRL_OUTRGB_FMT_RGB666 (1 << 11) #define CISCCTRL_OUTRGB_FMT_RGB888 (2 << 11) #define CISCCTRL_OUTRGB_FMT_MASK (3 << 11) -#define CISCCTRL_EXTRGB_EXTENSION (1 << 10) -#define CISCCTRL_ONE2ONE (1 << 9) +#define CISCCTRL_EXTRGB_EXTENSION BIT(10) +#define CISCCTRL_ONE2ONE BIT(9) #define CISCCTRL_MAIN_RATIO_MASK (0x1ff << 16 | 0x1ff) /* CICOTAREA, CIPRTAREA. Target area for DMA (Hsize x Vsize). */ @@ -147,38 +149,38 @@ /* Codec (id = 0) or preview (id = 1) path status. */ #define S3C_CAMIF_REG_CISTATUS(id, _offs) (0x64 + (id) * (0x34 + (_offs))) -#define CISTATUS_OVFIY_STATUS (1 << 31) -#define CISTATUS_OVFICB_STATUS (1 << 30) -#define CISTATUS_OVFICR_STATUS (1 << 29) +#define CISTATUS_OVFIY_STATUS BIT(31) +#define CISTATUS_OVFICB_STATUS BIT(30) +#define CISTATUS_OVFICR_STATUS BIT(29) #define CISTATUS_OVF_MASK (0x7 << 29) #define CIPRSTATUS_OVF_MASK (0x3 << 30) -#define CISTATUS_VSYNC_STATUS (1 << 28) +#define CISTATUS_VSYNC_STATUS BIT(28) #define CISTATUS_FRAMECNT_MASK (3 << 26) #define CISTATUS_FRAMECNT(__reg) (((__reg) >> 26) & 0x3) -#define CISTATUS_WINOFSTEN_STATUS (1 << 25) -#define CISTATUS_IMGCPTEN_STATUS (1 << 22) -#define CISTATUS_IMGCPTENSC_STATUS (1 << 21) -#define CISTATUS_VSYNC_A_STATUS (1 << 20) -#define CISTATUS_FRAMEEND_STATUS (1 << 19) /* 17 on s3c64xx */ +#define CISTATUS_WINOFSTEN_STATUS BIT(25) +#define CISTATUS_IMGCPTEN_STATUS BIT(22) +#define CISTATUS_IMGCPTENSC_STATUS BIT(21) +#define CISTATUS_VSYNC_A_STATUS BIT(20) +#define CISTATUS_FRAMEEND_STATUS BIT(19) /* 17 on s3c64xx */ /* Image capture enable */ #define S3C_CAMIF_REG_CIIMGCPT(_offs) (0xa0 + (_offs)) -#define CIIMGCPT_IMGCPTEN (1 << 31) -#define CIIMGCPT_IMGCPTEN_SC(id) (1 << (30 - (id))) +#define CIIMGCPT_IMGCPTEN BIT(31) +#define CIIMGCPT_IMGCPTEN_SC(id) BIT(30 - (id)) /* Frame control: 1 - one-shot, 0 - free run */ -#define CIIMGCPT_CPT_FREN_ENABLE(id) (1 << (25 - (id))) +#define CIIMGCPT_CPT_FREN_ENABLE(id) BIT(25 - (id)) #define CIIMGCPT_CPT_FRMOD_ENABLE (0 << 18) -#define CIIMGCPT_CPT_FRMOD_CNT (1 << 18) +#define CIIMGCPT_CPT_FRMOD_CNT BIT(18) /* Capture sequence */ #define S3C_CAMIF_REG_CICPTSEQ 0xc4 /* Image effects */ #define S3C_CAMIF_REG_CIIMGEFF(_offs) (0xb0 + (_offs)) -#define CIIMGEFF_IE_ENABLE(id) (1 << (30 + (id))) +#define CIIMGEFF_IE_ENABLE(id) BIT(30 + (id)) #define CIIMGEFF_IE_ENABLE_MASK (3 << 30) /* Image effect: 1 - after scaler, 0 - before scaler */ -#define CIIMGEFF_IE_AFTER_SC (1 << 29) +#define CIIMGEFF_IE_AFTER_SC BIT(29) #define CIIMGEFF_FIN_MASK (7 << 26) #define CIIMGEFF_FIN_BYPASS (0 << 26) #define CIIMGEFF_FIN_ARBITRARY (1 << 26) @@ -207,8 +209,8 @@ /* Real input DMA data size. n = 0 - codec, 1 - preview. */ #define S3C_CAMIF_REG_MSWIDTH(id) (0xf8 + (id) * 0x2c) -#define AUTOLOAD_ENABLE (1 << 31) -#define ADDR_CH_DIS (1 << 30) +#define AUTOLOAD_ENABLE BIT(31) +#define ADDR_CH_DIS BIT(30) #define MSHEIGHT(x) (((x) & 0x3ff) << 16) #define MSWIDTH(x) ((x) & 0x3ff) @@ -219,12 +221,12 @@ #define MSCTRL_ORDER422_M_CBYCRY (2 << 4) #define MSCTRL_ORDER422_M_CRYCBY (3 << 4) /* 0 - camera, 1 - DMA */ -#define MSCTRL_SEL_DMA_CAM (1 << 3) +#define MSCTRL_SEL_DMA_CAM BIT(3) #define MSCTRL_INFORMAT_M_YCBCR420 (0 << 1) #define MSCTRL_INFORMAT_M_YCBCR422 (1 << 1) #define MSCTRL_INFORMAT_M_YCBCR422I (2 << 1) #define MSCTRL_INFORMAT_M_RGB (3 << 1) -#define MSCTRL_ENVID_M (1 << 0) +#define MSCTRL_ENVID_M BIT(0) /* CICOSCOSY, CIPRSCOSY. Scan line Y/Cb/Cr offset. */ #define S3C_CAMIF_REG_CISSY(id) (0x12c + (id) * 0x0c) diff --git a/drivers/media/platform/s5p-cec/s5p_cec.c b/drivers/media/platform/s5p-cec/s5p_cec.c index ea6231b387ed..6ddcc35b0bbd 100644 --- a/drivers/media/platform/s5p-cec/s5p_cec.c +++ b/drivers/media/platform/s5p-cec/s5p_cec.c @@ -214,21 +214,23 @@ static int s5p_cec_probe(struct platform_device *pdev) if (IS_ERR(cec->reg)) return PTR_ERR(cec->reg); - cec->notifier = cec_notifier_get(hdmi_dev); - if (cec->notifier == NULL) - return -ENOMEM; - cec->adap = cec_allocate_adapter(&s5p_cec_adap_ops, cec, CEC_NAME, - CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0), 1); + CEC_CAP_DEFAULTS | (needs_hpd ? CEC_CAP_NEEDS_HPD : 0) | + CEC_CAP_CONNECTOR_INFO, 1); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) return ret; - ret = cec_register_adapter(cec->adap, &pdev->dev); - if (ret) + cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL, + cec->adap); + if (!cec->notifier) { + ret = -ENOMEM; goto err_delete_adapter; + } - cec_register_cec_notifier(cec->adap, cec->notifier); + ret = cec_register_adapter(cec->adap, &pdev->dev); + if (ret) + goto err_notifier; platform_set_drvdata(pdev, cec); pm_runtime_enable(dev); @@ -236,6 +238,9 @@ static int s5p_cec_probe(struct platform_device *pdev) dev_dbg(dev, "successfully probed\n"); return 0; +err_notifier: + cec_notifier_cec_adap_unregister(cec->notifier); + err_delete_adapter: cec_delete_adapter(cec->adap); return ret; @@ -245,8 +250,8 @@ static int s5p_cec_remove(struct platform_device *pdev) { struct s5p_cec_dev *cec = platform_get_drvdata(pdev); + cec_notifier_cec_adap_unregister(cec->notifier); cec_unregister_adapter(cec->adap); - cec_notifier_put(cec->notifier); pm_runtime_disable(&pdev->dev); return 0; } diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 152d192d5c3f..f5f05ea9f521 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -29,31 +29,26 @@ static struct g2d_fmt formats[] = { { - .name = "XRGB_8888", .fourcc = V4L2_PIX_FMT_RGB32, .depth = 32, .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_8888), }, { - .name = "RGB_565", .fourcc = V4L2_PIX_FMT_RGB565X, .depth = 16, .hw = COLOR_MODE(ORDER_XRGB, MODE_RGB_565), }, { - .name = "XRGB_1555", .fourcc = V4L2_PIX_FMT_RGB555X, .depth = 16, .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_1555), }, { - .name = "XRGB_4444", .fourcc = V4L2_PIX_FMT_RGB444, .depth = 16, .hw = COLOR_MODE(ORDER_XRGB, MODE_XRGB_4444), }, { - .name = "PACKED_RGB_888", .fourcc = V4L2_PIX_FMT_RGB24, .depth = 24, .hw = COLOR_MODE(ORDER_XRGB, MODE_PACKED_RGB_888), @@ -296,19 +291,14 @@ static int vidioc_querycap(struct file *file, void *priv, strscpy(cap->driver, G2D_NAME, sizeof(cap->driver)); strscpy(cap->card, G2D_NAME, sizeof(cap->card)); cap->bus_info[0] = 0; - cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } static int vidioc_enum_fmt(struct file *file, void *prv, struct v4l2_fmtdesc *f) { - struct g2d_fmt *fmt; if (f->index >= NUM_FORMATS) return -EINVAL; - fmt = &formats[f->index]; - f->pixelformat = fmt->fourcc; - strscpy(f->description, fmt->name, sizeof(f->description)); + f->pixelformat = formats[f->index].fourcc; return 0; } @@ -704,6 +694,7 @@ static int g2d_probe(struct platform_device *pdev) set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags); vfd->lock = &dev->mutex; vfd->v4l2_dev = &dev->v4l2_dev; + vfd->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); diff --git a/drivers/media/platform/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h index def0ec0dabeb..c2309c1370da 100644 --- a/drivers/media/platform/s5p-g2d/g2d.h +++ b/drivers/media/platform/s5p-g2d/g2d.h @@ -61,7 +61,6 @@ struct g2d_ctx { }; struct g2d_fmt { - char *name; u32 fourcc; int depth; u32 hw; diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index a3bc884b7df1..8dbbd5f2a40a 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c @@ -35,7 +35,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { { - .name = "JPEG JFIF", .fourcc = V4L2_PIX_FMT_JPEG, .flags = SJPEG_FMT_FLAG_ENC_CAPTURE | SJPEG_FMT_FLAG_DEC_OUTPUT | @@ -44,7 +43,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { SJPEG_FMT_FLAG_EXYNOS4, }, { - .name = "YUV 4:2:2 packed, YCbYCr", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .colplanes = 1, @@ -57,7 +55,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 packed, YCbYCr", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .colplanes = 1, @@ -70,7 +67,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 packed, YCbYCr", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .colplanes = 1, @@ -83,7 +79,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_YVYU, .depth = 16, .colplanes = 1, @@ -96,7 +91,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_YVYU, .depth = 16, .colplanes = 1, @@ -109,7 +103,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16, .colplanes = 1, @@ -122,7 +115,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 packed, YCrYCb", .fourcc = V4L2_PIX_FMT_VYUY, .depth = 16, .colplanes = 1, @@ -135,7 +127,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565, .depth = 16, .colplanes = 1, @@ -148,7 +139,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565, .depth = 16, .colplanes = 1, @@ -161,7 +151,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "RGB565X", .fourcc = V4L2_PIX_FMT_RGB565X, .depth = 16, .colplanes = 1, @@ -174,7 +163,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565, .depth = 16, .colplanes = 1, @@ -186,7 +174,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "ARGB8888, 32 bpp", .fourcc = V4L2_PIX_FMT_RGB32, .depth = 32, .colplanes = 1, @@ -199,7 +186,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "ARGB8888, 32 bpp", .fourcc = V4L2_PIX_FMT_RGB32, .depth = 32, .colplanes = 1, @@ -212,7 +198,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "YUV 4:4:4 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV24, .depth = 24, .colplanes = 2, @@ -225,7 +210,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "YUV 4:4:4 planar, Y/CrCb", .fourcc = V4L2_PIX_FMT_NV42, .depth = 24, .colplanes = 2, @@ -238,7 +222,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, }, { - .name = "YUV 4:2:2 planar, Y/CrCb", .fourcc = V4L2_PIX_FMT_NV61, .depth = 16, .colplanes = 2, @@ -251,7 +234,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:2 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV16, .depth = 16, .colplanes = 2, @@ -264,7 +246,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, }, { - .name = "YUV 4:2:0 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12, .depth = 12, .colplanes = 2, @@ -277,7 +258,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "YUV 4:2:0 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12, .depth = 12, .colplanes = 2, @@ -290,7 +270,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "YUV 4:2:0 planar, Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12, .depth = 12, .colplanes = 2, @@ -303,7 +282,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "YUV 4:2:0 planar, Y/CrCb", .fourcc = V4L2_PIX_FMT_NV21, .depth = 12, .colplanes = 2, @@ -316,7 +294,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "YUV 4:2:0 planar, Y/CrCb", .fourcc = V4L2_PIX_FMT_NV21, .depth = 12, .colplanes = 2, @@ -330,7 +307,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420, .depth = 12, .colplanes = 3, @@ -343,7 +319,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr", .fourcc = V4L2_PIX_FMT_YUV420, .depth = 12, .colplanes = 3, @@ -356,7 +331,6 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, }, { - .name = "Gray", .fourcc = V4L2_PIX_FMT_GREY, .depth = 8, .colplanes = 1, @@ -1285,8 +1259,6 @@ static int s5p_jpeg_querycap(struct file *file, void *priv, } snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", dev_name(ctx->jpeg->dev)); - cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -1314,7 +1286,6 @@ static int enum_fmt(struct s5p_jpeg_ctx *ctx, if (i >= n) return -EINVAL; - strscpy(f->description, sjpeg_formats[i].name, sizeof(f->description)); f->pixelformat = sjpeg_formats[i].fourcc; return 0; @@ -2974,6 +2945,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev) jpeg->vfd_encoder->lock = &jpeg->lock; jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev; jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M; + jpeg->vfd_encoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1); if (ret) { @@ -3003,6 +2975,7 @@ static int s5p_jpeg_probe(struct platform_device *pdev) jpeg->vfd_decoder->lock = &jpeg->lock; jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev; jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M; + jpeg->vfd_decoder->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1); if (ret) { diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index 34f87f6c02f2..3bc52f83f5bc 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h @@ -150,7 +150,6 @@ struct s5p_jpeg_variant { /** * struct jpeg_fmt - driver's internal color format data - * @name: format description * @fourcc: the fourcc code, 0 if not applicable * @depth: number of bits per pixel * @colplanes: number of color planes (1 for packed formats) @@ -159,7 +158,6 @@ struct s5p_jpeg_variant { * @flags: flags describing format applicability */ struct s5p_jpeg_fmt { - char *name; u32 fourcc; int depth; int colplanes; diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h index bab7fa46b89a..86f376b50581 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h @@ -121,14 +121,14 @@ /* JPEG timer setting register */ #define S5P_JPG_TIMER_SE 0x7c -#define S5P_TIMER_INT_EN_MASK (0x1 << 31) -#define S5P_TIMER_INT_EN (0x1 << 31) +#define S5P_TIMER_INT_EN_MASK (0x1UL << 31) +#define S5P_TIMER_INT_EN (0x1UL << 31) #define S5P_TIMER_INIT_MASK 0x7fffffff /* JPEG timer status register */ #define S5P_JPG_TIMER_ST 0x80 #define S5P_TIMER_INT_STAT_SHIFT 31 -#define S5P_TIMER_INT_STAT_MASK (0x1 << S5P_TIMER_INT_STAT_SHIFT) +#define S5P_TIMER_INT_STAT_MASK (0x1UL << S5P_TIMER_INT_STAT_SHIFT) #define S5P_TIMER_CNT_SHIFT 0 #define S5P_TIMER_CNT_MASK 0x7fffffff @@ -562,13 +562,13 @@ /* JPEG timer setting register */ #define EXYNOS3250_TIMER_SE 0x148 #define EXYNOS3250_TIMER_INT_EN_SHIFT 31 -#define EXYNOS3250_TIMER_INT_EN (1 << EXYNOS3250_TIMER_INT_EN_SHIFT) +#define EXYNOS3250_TIMER_INT_EN (1UL << EXYNOS3250_TIMER_INT_EN_SHIFT) #define EXYNOS3250_TIMER_INIT_MASK 0x7fffffff /* JPEG timer status register */ #define EXYNOS3250_TIMER_ST 0x14c #define EXYNOS3250_TIMER_INT_STAT_SHIFT 31 -#define EXYNOS3250_TIMER_INT_STAT (1 << EXYNOS3250_TIMER_INT_STAT_SHIFT) +#define EXYNOS3250_TIMER_INT_STAT (1UL << EXYNOS3250_TIMER_INT_STAT_SHIFT) #define EXYNOS3250_TIMER_CNT_SHIFT 0 #define EXYNOS3250_TIMER_CNT_MASK 0x7fffffff diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h index 5dc086516360..96d1ecd1521b 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_common.h +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_common.h @@ -718,7 +718,6 @@ struct s5p_mfc_ctx { * used by the MFC */ struct s5p_mfc_fmt { - char *name; u32 fourcc; u32 codec_mode; enum s5p_mfc_fmt_type type; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c index 4017c8b471f4..61e144a35201 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_dec.c @@ -29,7 +29,6 @@ static struct s5p_mfc_fmt formats[] = { { - .name = "4:2:0 2 Planes 16x16 Tiles", .fourcc = V4L2_PIX_FMT_NV12MT_16X16, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -37,7 +36,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6_BIT | MFC_V7_BIT, }, { - .name = "4:2:0 2 Planes 64x32 Tiles", .fourcc = V4L2_PIX_FMT_NV12MT, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -45,7 +43,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5_BIT, }, { - .name = "4:2:0 2 Planes Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12M, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -53,7 +50,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6PLUS_BITS, }, { - .name = "4:2:0 2 Planes Y/CrCb", .fourcc = V4L2_PIX_FMT_NV21M, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -61,7 +57,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6PLUS_BITS, }, { - .name = "H264 Encoded Stream", .fourcc = V4L2_PIX_FMT_H264, .codec_mode = S5P_MFC_CODEC_H264_DEC, .type = MFC_FMT_DEC, @@ -69,7 +64,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "H264/MVC Encoded Stream", .fourcc = V4L2_PIX_FMT_H264_MVC, .codec_mode = S5P_MFC_CODEC_H264_MVC_DEC, .type = MFC_FMT_DEC, @@ -77,7 +71,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6PLUS_BITS, }, { - .name = "H263 Encoded Stream", .fourcc = V4L2_PIX_FMT_H263, .codec_mode = S5P_MFC_CODEC_H263_DEC, .type = MFC_FMT_DEC, @@ -85,7 +78,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "MPEG1 Encoded Stream", .fourcc = V4L2_PIX_FMT_MPEG1, .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, .type = MFC_FMT_DEC, @@ -93,7 +85,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "MPEG2 Encoded Stream", .fourcc = V4L2_PIX_FMT_MPEG2, .codec_mode = S5P_MFC_CODEC_MPEG2_DEC, .type = MFC_FMT_DEC, @@ -101,7 +92,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "MPEG4 Encoded Stream", .fourcc = V4L2_PIX_FMT_MPEG4, .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, .type = MFC_FMT_DEC, @@ -109,7 +99,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "XviD Encoded Stream", .fourcc = V4L2_PIX_FMT_XVID, .codec_mode = S5P_MFC_CODEC_MPEG4_DEC, .type = MFC_FMT_DEC, @@ -117,7 +106,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "VC1 Encoded Stream", .fourcc = V4L2_PIX_FMT_VC1_ANNEX_G, .codec_mode = S5P_MFC_CODEC_VC1_DEC, .type = MFC_FMT_DEC, @@ -125,7 +113,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "VC1 RCV Encoded Stream", .fourcc = V4L2_PIX_FMT_VC1_ANNEX_L, .codec_mode = S5P_MFC_CODEC_VC1RCV_DEC, .type = MFC_FMT_DEC, @@ -133,7 +120,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "VP8 Encoded Stream", .fourcc = V4L2_PIX_FMT_VP8, .codec_mode = S5P_MFC_CODEC_VP8_DEC, .type = MFC_FMT_DEC, @@ -279,7 +265,6 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, bool out) { struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_fmt *fmt; int i, j = 0; for (i = 0; i < ARRAY_SIZE(formats); ++i) { @@ -296,9 +281,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, } if (i == ARRAY_SIZE(formats)) return -EINVAL; - fmt = &formats[i]; - strscpy(f->description, fmt->name, sizeof(f->description)); - f->pixelformat = fmt->fourcc; + f->pixelformat = formats[i].fourcc; return 0; } diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c index 97e76480e942..912fe0c5ab18 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_enc.c @@ -32,7 +32,6 @@ static struct s5p_mfc_fmt formats[] = { { - .name = "4:2:0 2 Planes 16x16 Tiles", .fourcc = V4L2_PIX_FMT_NV12MT_16X16, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -40,7 +39,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6_BIT | MFC_V7_BIT, }, { - .name = "4:2:0 2 Planes 64x32 Tiles", .fourcc = V4L2_PIX_FMT_NV12MT, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -48,7 +46,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5_BIT, }, { - .name = "4:2:0 2 Planes Y/CbCr", .fourcc = V4L2_PIX_FMT_NV12M, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -56,7 +53,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "4:2:0 2 Planes Y/CrCb", .fourcc = V4L2_PIX_FMT_NV21M, .codec_mode = S5P_MFC_CODEC_NONE, .type = MFC_FMT_RAW, @@ -64,7 +60,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V6PLUS_BITS, }, { - .name = "H264 Encoded Stream", .fourcc = V4L2_PIX_FMT_H264, .codec_mode = S5P_MFC_CODEC_H264_ENC, .type = MFC_FMT_ENC, @@ -72,7 +67,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "MPEG4 Encoded Stream", .fourcc = V4L2_PIX_FMT_MPEG4, .codec_mode = S5P_MFC_CODEC_MPEG4_ENC, .type = MFC_FMT_ENC, @@ -80,7 +74,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "H263 Encoded Stream", .fourcc = V4L2_PIX_FMT_H263, .codec_mode = S5P_MFC_CODEC_H263_ENC, .type = MFC_FMT_ENC, @@ -88,7 +81,6 @@ static struct s5p_mfc_fmt formats[] = { .versions = MFC_V5PLUS_BITS, }, { - .name = "VP8 Encoded Stream", .fourcc = V4L2_PIX_FMT_VP8, .codec_mode = S5P_MFC_CODEC_VP8_ENC, .type = MFC_FMT_ENC, @@ -1320,7 +1312,6 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, bool out) { struct s5p_mfc_dev *dev = video_drvdata(file); - struct s5p_mfc_fmt *fmt; int i, j = 0; for (i = 0; i < ARRAY_SIZE(formats); ++i) { @@ -1332,10 +1323,7 @@ static int vidioc_enum_fmt(struct file *file, struct v4l2_fmtdesc *f, continue; if (j == f->index) { - fmt = &formats[i]; - strscpy(f->description, fmt->name, - sizeof(f->description)); - f->pixelformat = fmt->fourcc; + f->pixelformat = formats[i].fourcc; return 0; } ++j; diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c index f76a07400966..49503c20d320 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v5.c @@ -711,7 +711,7 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) reg = mfc_read(dev, S5P_FIMV_ENC_PADDING_CTRL); if (p->pad) { /** enable */ - reg |= (1 << 31); + reg |= (1UL << 31); /** cr value */ reg &= ~(0xFF << 16); reg |= (p->pad_cr << 16); @@ -955,7 +955,7 @@ static int s5p_mfc_set_enc_params_mpeg4(struct s5p_mfc_ctx *ctx) S5P_FIMV_ENC_RC_FRAME_RATE); shm = s5p_mfc_read_info_v5(ctx, RC_VOP_TIMING); shm &= ~(0xFFFFFFFF); - shm |= (1 << 31); + shm |= (1UL << 31); shm |= ((p->rc_framerate_num & 0x7FFF) << 16); shm |= (p->rc_framerate_denom & 0xFFFF); s5p_mfc_write_info_v5(ctx, shm, RC_VOP_TIMING); diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index f7621a9051cb..a1453053e31a 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -840,7 +840,7 @@ static int s5p_mfc_set_enc_params(struct s5p_mfc_ctx *ctx) if (p->pad) { reg = 0; /** enable */ - reg |= (1 << 31); + reg |= (1UL << 31); /** cr value */ reg |= ((p->pad_cr & 0xFF) << 16); /** cb value */ diff --git a/drivers/media/platform/seco-cec/seco-cec.c b/drivers/media/platform/seco-cec/seco-cec.c index 1d0133f01e00..9cd60fe1867c 100644 --- a/drivers/media/platform/seco-cec/seco-cec.c +++ b/drivers/media/platform/seco-cec/seco-cec.c @@ -507,10 +507,10 @@ err: } struct cec_dmi_match { - char *sys_vendor; - char *product_name; - char *devname; - char *conn; + const char *sys_vendor; + const char *product_name; + const char *devname; + const char *conn; }; static const struct cec_dmi_match secocec_dmi_match_table[] = { @@ -518,7 +518,8 @@ static const struct cec_dmi_match secocec_dmi_match_table[] = { { "SECO", "UDOO x86", "0000:00:02.0", "Port B" }, }; -static int secocec_cec_get_notifier(struct cec_notifier **notify) +static struct device *secocec_cec_find_hdmi_dev(struct device *dev, + const char **conn) { int i; @@ -533,16 +534,15 @@ static int secocec_cec_get_notifier(struct cec_notifier **notify) d = bus_find_device_by_name(&pci_bus_type, NULL, m->devname); if (!d) - return -EPROBE_DEFER; + return ERR_PTR(-EPROBE_DEFER); - *notify = cec_notifier_get_conn(d, m->conn); put_device(d); - - return 0; + *conn = m->conn; + return d; } } - return -EINVAL; + return ERR_PTR(-EINVAL); } static int secocec_acpi_probe(struct secocec_data *sdev) @@ -573,9 +573,15 @@ static int secocec_probe(struct platform_device *pdev) { struct secocec_data *secocec; struct device *dev = &pdev->dev; + struct device *hdmi_dev; + const char *conn = NULL; int ret; u16 val; + hdmi_dev = secocec_cec_find_hdmi_dev(&pdev->dev, &conn); + if (IS_ERR(hdmi_dev)) + return PTR_ERR(hdmi_dev); + secocec = devm_kzalloc(dev, sizeof(*secocec), GFP_KERNEL); if (!secocec) return -ENOMEM; @@ -617,12 +623,6 @@ static int secocec_probe(struct platform_device *pdev) goto err; } - ret = secocec_cec_get_notifier(&secocec->notifier); - if (ret) { - dev_err(dev, "no CEC notifier available\n"); - goto err; - } - ret = devm_request_threaded_irq(dev, secocec->irq, NULL, @@ -640,7 +640,8 @@ static int secocec_probe(struct platform_device *pdev) secocec->cec_adap = cec_allocate_adapter(&secocec_cec_adap_ops, secocec, dev_name(dev), - CEC_CAP_DEFAULTS, + CEC_CAP_DEFAULTS | + CEC_CAP_CONNECTOR_INFO, SECOCEC_MAX_ADDRS); if (IS_ERR(secocec->cec_adap)) { @@ -648,16 +649,20 @@ static int secocec_probe(struct platform_device *pdev) goto err; } - ret = cec_register_adapter(secocec->cec_adap, dev); - if (ret) + secocec->notifier = cec_notifier_cec_adap_register(hdmi_dev, conn, + secocec->cec_adap); + if (!secocec->notifier) { + ret = -ENOMEM; goto err_delete_adapter; + } - if (secocec->notifier) - cec_register_cec_notifier(secocec->cec_adap, secocec->notifier); + ret = cec_register_adapter(secocec->cec_adap, dev); + if (ret) + goto err_notifier; ret = secocec_ir_probe(secocec); if (ret) - goto err_delete_adapter; + goto err_notifier; platform_set_drvdata(pdev, secocec); @@ -665,6 +670,8 @@ static int secocec_probe(struct platform_device *pdev) return ret; +err_notifier: + cec_notifier_cec_adap_unregister(secocec->notifier); err_delete_adapter: cec_delete_adapter(secocec->cec_adap); err: @@ -685,11 +692,9 @@ static int secocec_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "IR disabled"); } + cec_notifier_cec_adap_unregister(secocec->notifier); cec_unregister_adapter(secocec->cec_adap); - if (secocec->notifier) - cec_notifier_put(secocec->notifier); - release_region(BRA_SMB_BASE_ADDR, 7); dev_dbg(&pdev->dev, "CEC device removed"); diff --git a/drivers/media/platform/sh_veu.c b/drivers/media/platform/sh_veu.c index 5a9ba05c996e..2b4c0d9d6928 100644 --- a/drivers/media/platform/sh_veu.c +++ b/drivers/media/platform/sh_veu.c @@ -81,12 +81,12 @@ struct sh_veu_dev; struct sh_veu_file { + struct v4l2_fh fh; struct sh_veu_dev *veu_dev; bool cfg_needed; }; struct sh_veu_format { - char *name; u32 fourcc; unsigned int depth; unsigned int ydepth; @@ -144,14 +144,14 @@ enum sh_veu_fmt_idx { * aligned for NV24. */ static const struct sh_veu_format sh_veu_fmt[] = { - [SH_VEU_FMT_NV12] = { .ydepth = 8, .depth = 12, .name = "NV12", .fourcc = V4L2_PIX_FMT_NV12 }, - [SH_VEU_FMT_NV16] = { .ydepth = 8, .depth = 16, .name = "NV16", .fourcc = V4L2_PIX_FMT_NV16 }, - [SH_VEU_FMT_NV24] = { .ydepth = 8, .depth = 24, .name = "NV24", .fourcc = V4L2_PIX_FMT_NV24 }, - [SH_VEU_FMT_RGB332] = { .ydepth = 8, .depth = 8, .name = "RGB332", .fourcc = V4L2_PIX_FMT_RGB332 }, - [SH_VEU_FMT_RGB444] = { .ydepth = 16, .depth = 16, .name = "RGB444", .fourcc = V4L2_PIX_FMT_RGB444 }, - [SH_VEU_FMT_RGB565] = { .ydepth = 16, .depth = 16, .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565 }, - [SH_VEU_FMT_RGB666] = { .ydepth = 32, .depth = 32, .name = "BGR666", .fourcc = V4L2_PIX_FMT_BGR666 }, - [SH_VEU_FMT_RGB24] = { .ydepth = 24, .depth = 24, .name = "RGB24", .fourcc = V4L2_PIX_FMT_RGB24 }, + [SH_VEU_FMT_NV12] = { .ydepth = 8, .depth = 12, .fourcc = V4L2_PIX_FMT_NV12 }, + [SH_VEU_FMT_NV16] = { .ydepth = 8, .depth = 16, .fourcc = V4L2_PIX_FMT_NV16 }, + [SH_VEU_FMT_NV24] = { .ydepth = 8, .depth = 24, .fourcc = V4L2_PIX_FMT_NV24 }, + [SH_VEU_FMT_RGB332] = { .ydepth = 8, .depth = 8, .fourcc = V4L2_PIX_FMT_RGB332 }, + [SH_VEU_FMT_RGB444] = { .ydepth = 16, .depth = 16, .fourcc = V4L2_PIX_FMT_RGB444 }, + [SH_VEU_FMT_RGB565] = { .ydepth = 16, .depth = 16, .fourcc = V4L2_PIX_FMT_RGB565 }, + [SH_VEU_FMT_RGB666] = { .ydepth = 32, .depth = 32, .fourcc = V4L2_PIX_FMT_BGR666 }, + [SH_VEU_FMT_RGB24] = { .ydepth = 24, .depth = 24, .fourcc = V4L2_PIX_FMT_RGB24 }, }; #define DEFAULT_IN_VFMT (struct sh_veu_vfmt){ \ @@ -348,9 +348,6 @@ static int sh_veu_querycap(struct file *file, void *priv, strscpy(cap->driver, "sh-veu", sizeof(cap->driver)); strscpy(cap->card, "sh-mobile VEU", sizeof(cap->card)); strscpy(cap->bus_info, "platform:sh-veu", sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; } @@ -359,8 +356,6 @@ static int sh_veu_enum_fmt(struct v4l2_fmtdesc *f, const int *fmt, int fmt_num) if (f->index >= fmt_num) return -EINVAL; - strscpy(f->description, sh_veu_fmt[fmt[f->index]].name, - sizeof(f->description)); f->pixelformat = sh_veu_fmt[fmt[f->index]].fourcc; return 0; } @@ -967,12 +962,14 @@ static int sh_veu_open(struct file *file) if (!veu_file) return -ENOMEM; + v4l2_fh_init(&veu_file->fh, video_devdata(file)); veu_file->veu_dev = veu; veu_file->cfg_needed = true; file->private_data = veu_file; pm_runtime_get_sync(veu->dev); + v4l2_fh_add(&veu_file->fh); dev_dbg(veu->dev, "Created instance %p\n", veu_file); @@ -1002,6 +999,8 @@ static int sh_veu_release(struct file *file) } pm_runtime_put(veu->dev); + v4l2_fh_del(&veu_file->fh); + v4l2_fh_exit(&veu_file->fh); kfree(veu_file); @@ -1039,6 +1038,7 @@ static const struct video_device sh_veu_videodev = { .minor = -1, .release = video_device_release_empty, .vfl_dir = VFL_DIR_M2M, + .device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING, }; static const struct v4l2_m2m_ops sh_veu_m2m_ops = { diff --git a/drivers/media/platform/sh_vou.c b/drivers/media/platform/sh_vou.c index 5799aa4b9323..2236702c21b4 100644 --- a/drivers/media/platform/sh_vou.c +++ b/drivers/media/platform/sh_vou.c @@ -138,7 +138,6 @@ static void sh_vou_reg_ab_set(struct sh_vou_device *vou_dev, unsigned int reg, struct sh_vou_fmt { u32 pfmt; - char *desc; unsigned char bpp; unsigned char bpl; unsigned char rgb; @@ -152,7 +151,6 @@ static struct sh_vou_fmt vou_fmt[] = { .pfmt = V4L2_PIX_FMT_NV12, .bpp = 12, .bpl = 1, - .desc = "YVU420 planar", .yf = 0, .rgb = 0, }, @@ -160,7 +158,6 @@ static struct sh_vou_fmt vou_fmt[] = { .pfmt = V4L2_PIX_FMT_NV16, .bpp = 16, .bpl = 1, - .desc = "YVYU planar", .yf = 1, .rgb = 0, }, @@ -168,7 +165,6 @@ static struct sh_vou_fmt vou_fmt[] = { .pfmt = V4L2_PIX_FMT_RGB24, .bpp = 24, .bpl = 3, - .desc = "RGB24", .pkf = 2, .rgb = 1, }, @@ -176,7 +172,6 @@ static struct sh_vou_fmt vou_fmt[] = { .pfmt = V4L2_PIX_FMT_RGB565, .bpp = 16, .bpl = 2, - .desc = "RGB565", .pkf = 3, .rgb = 1, }, @@ -184,7 +179,6 @@ static struct sh_vou_fmt vou_fmt[] = { .pfmt = V4L2_PIX_FMT_RGB565X, .bpp = 16, .bpl = 2, - .desc = "RGB565 byteswapped", .pkf = 3, .rgb = 1, }, @@ -381,9 +375,6 @@ static int sh_vou_querycap(struct file *file, void *priv, strscpy(cap->card, "SuperH VOU", sizeof(cap->card)); strscpy(cap->driver, "sh-vou", sizeof(cap->driver)); strscpy(cap->bus_info, "platform:sh-vou", sizeof(cap->bus_info)); - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -398,9 +389,6 @@ static int sh_vou_enum_fmt_vid_out(struct file *file, void *priv, dev_dbg(vou_dev->v4l2_dev.dev, "%s()\n", __func__); - fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; - strscpy(fmt->description, vou_fmt[fmt->index].desc, - sizeof(fmt->description)); fmt->pixelformat = vou_fmt[fmt->index].pfmt; return 0; @@ -494,7 +482,8 @@ static void sh_vou_configure_geometry(struct sh_vou_device *vou_dev, if (h_idx) vouvcr |= (1 << 14) | vou_scale_v_fld[h_idx - 1]; - dev_dbg(vou_dev->v4l2_dev.dev, "%s: scaling 0x%x\n", fmt->desc, vouvcr); + dev_dbg(vou_dev->v4l2_dev.dev, "0x%08x: scaling 0x%x\n", + fmt->pfmt, vouvcr); /* To produce a colour bar for testing set bit 23 of VOUVCR */ sh_vou_reg_ab_write(vou_dev, VOUVCR, vouvcr); @@ -1218,6 +1207,8 @@ static const struct video_device sh_vou_video_template = { .ioctl_ops = &sh_vou_ioctl_ops, .tvnorms = V4L2_STD_525_60, /* PAL only supported in 8-bit non-bt656 mode */ .vfl_dir = VFL_DIR_TX, + .device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING, }; static int sh_vou_probe(struct platform_device *pdev) diff --git a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c index 79f7db1a9d18..e90f1ba30574 100644 --- a/drivers/media/platform/sti/bdisp/bdisp-v4l2.c +++ b/drivers/media/platform/sti/bdisp/bdisp-v4l2.c @@ -692,11 +692,6 @@ static int bdisp_querycap(struct file *file, void *fh, strscpy(cap->card, bdisp->pdev->name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", BDISP_NAME, bdisp->id); - - cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; - - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; - return 0; } @@ -1059,6 +1054,7 @@ static int bdisp_register_device(struct bdisp_dev *bdisp) bdisp->vdev.lock = &bdisp->lock; bdisp->vdev.vfl_dir = VFL_DIR_M2M; bdisp->vdev.v4l2_dev = &bdisp->v4l2_dev; + bdisp->vdev.device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M; snprintf(bdisp->vdev.name, sizeof(bdisp->vdev.name), "%s.%d", BDISP_NAME, bdisp->id); diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c index 3c05b3dc49ec..5baada4f65e5 100644 --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -693,16 +693,12 @@ static int c8sectpfe_probe(struct platform_device *pdev) fei->sram_size = resource_size(res); fei->idle_irq = platform_get_irq_byname(pdev, "c8sectpfe-idle-irq"); - if (fei->idle_irq < 0) { - dev_err(dev, "Can't get c8sectpfe-idle-irq\n"); + if (fei->idle_irq < 0) return fei->idle_irq; - } fei->error_irq = platform_get_irq_byname(pdev, "c8sectpfe-error-irq"); - if (fei->error_irq < 0) { - dev_err(dev, "Can't get c8sectpfe-error-irq\n"); + if (fei->error_irq < 0) return fei->error_irq; - } platform_set_drvdata(pdev, fei); diff --git a/drivers/media/platform/sti/cec/stih-cec.c b/drivers/media/platform/sti/cec/stih-cec.c index fc37efe1d554..8118c7365d3f 100644 --- a/drivers/media/platform/sti/cec/stih-cec.c +++ b/drivers/media/platform/sti/cec/stih-cec.c @@ -313,10 +313,6 @@ static int stih_cec_probe(struct platform_device *pdev) if (!cec) return -ENOMEM; - cec->notifier = cec_notifier_get(hdmi_dev); - if (!cec->notifier) - return -ENOMEM; - cec->dev = dev; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -340,30 +336,42 @@ static int stih_cec_probe(struct platform_device *pdev) return PTR_ERR(cec->clk); } - cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, - CEC_NAME, CEC_CAP_DEFAULTS, CEC_MAX_LOG_ADDRS); + cec->adap = cec_allocate_adapter(&sti_cec_adap_ops, cec, CEC_NAME, + CEC_CAP_DEFAULTS | + CEC_CAP_CONNECTOR_INFO, + CEC_MAX_LOG_ADDRS); ret = PTR_ERR_OR_ZERO(cec->adap); if (ret) return ret; - ret = cec_register_adapter(cec->adap, &pdev->dev); - if (ret) { - cec_delete_adapter(cec->adap); - return ret; + cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL, + cec->adap); + if (!cec->notifier) { + ret = -ENOMEM; + goto err_delete_adapter; } - cec_register_cec_notifier(cec->adap, cec->notifier); + ret = cec_register_adapter(cec->adap, &pdev->dev); + if (ret) + goto err_notifier; platform_set_drvdata(pdev, cec); return 0; + +err_notifier: + cec_notifier_cec_adap_unregister(cec->notifier); + +err_delete_adapter: + cec_delete_adapter(cec->adap); + return ret; } static int stih_cec_remove(struct platform_device *pdev) { struct stih_cec *cec = platform_get_drvdata(pdev); + cec_notifier_cec_adap_unregister(cec->notifier); cec_unregister_adapter(cec->adap); - cec_notifier_put(cec->notifier); return 0; } diff --git a/drivers/media/platform/sti/hva/hva-hw.c b/drivers/media/platform/sti/hva/hva-hw.c index 7917fd2c4bd4..401aaafa1710 100644 --- a/drivers/media/platform/sti/hva/hva-hw.c +++ b/drivers/media/platform/sti/hva/hva-hw.c @@ -341,10 +341,8 @@ int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva) /* get status interruption resource */ ret = platform_get_irq(pdev, 0); - if (ret < 0) { - dev_err(dev, "%s failed to get status IRQ\n", HVA_PREFIX); + if (ret < 0) goto err_clk; - } hva->irq_its = ret; ret = devm_request_threaded_irq(dev, hva->irq_its, hva_hw_its_interrupt, @@ -360,10 +358,8 @@ int hva_hw_probe(struct platform_device *pdev, struct hva_dev *hva) /* get error interruption resource */ ret = platform_get_irq(pdev, 1); - if (ret < 0) { - dev_err(dev, "%s failed to get error IRQ\n", HVA_PREFIX); + if (ret < 0) goto err_clk; - } hva->irq_err = ret; ret = devm_request_threaded_irq(dev, hva->irq_err, hva_hw_err_interrupt, diff --git a/drivers/media/platform/stm32/stm32-dcmi.c b/drivers/media/platform/stm32/stm32-dcmi.c index d855e9c09c08..9392e3409fba 100644 --- a/drivers/media/platform/stm32/stm32-dcmi.c +++ b/drivers/media/platform/stm32/stm32-dcmi.c @@ -100,10 +100,10 @@ enum state { #define OVERRUN_ERROR_THRESHOLD 3 struct dcmi_graph_entity { - struct device_node *node; - struct v4l2_async_subdev asd; - struct v4l2_subdev *subdev; + + struct device_node *remote_node; + struct v4l2_subdev *source; }; struct dcmi_format { @@ -169,6 +169,10 @@ struct stm32_dcmi { /* Ensure DMA operations atomicity */ struct mutex dma_lock; + + struct media_device mdev; + struct media_pad vid_cap_pad; + struct media_pipeline pipeline; }; static inline struct stm32_dcmi *notifier_to_dcmi(struct v4l2_async_notifier *n) @@ -580,6 +584,144 @@ static void dcmi_buf_queue(struct vb2_buffer *vb) spin_unlock_irq(&dcmi->irqlock); } +static struct media_entity *dcmi_find_source(struct stm32_dcmi *dcmi) +{ + struct media_entity *entity = &dcmi->vdev->entity; + struct media_pad *pad; + + /* Walk searching for entity having no sink */ + while (1) { + pad = &entity->pads[0]; + if (!(pad->flags & MEDIA_PAD_FL_SINK)) + break; + + pad = media_entity_remote_pad(pad); + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) + break; + + entity = pad->entity; + } + + return entity; +} + +static int dcmi_pipeline_s_fmt(struct stm32_dcmi *dcmi, + struct v4l2_subdev_pad_config *pad_cfg, + struct v4l2_subdev_format *format) +{ + struct media_entity *entity = &dcmi->entity.source->entity; + struct v4l2_subdev *subdev; + struct media_pad *sink_pad = NULL; + struct media_pad *src_pad = NULL; + struct media_pad *pad = NULL; + struct v4l2_subdev_format fmt = *format; + bool found = false; + int ret; + + /* + * Starting from sensor subdevice, walk within + * pipeline and set format on each subdevice + */ + while (1) { + unsigned int i; + + /* Search if current entity has a source pad */ + for (i = 0; i < entity->num_pads; i++) { + pad = &entity->pads[i]; + if (pad->flags & MEDIA_PAD_FL_SOURCE) { + src_pad = pad; + found = true; + break; + } + } + if (!found) + break; + + subdev = media_entity_to_v4l2_subdev(entity); + + /* Propagate format on sink pad if any, otherwise source pad */ + if (sink_pad) + pad = sink_pad; + + dev_dbg(dcmi->dev, "\"%s\":%d pad format set to 0x%x %ux%u\n", + subdev->name, pad->index, format->format.code, + format->format.width, format->format.height); + + fmt.pad = pad->index; + ret = v4l2_subdev_call(subdev, pad, set_fmt, pad_cfg, &fmt); + if (ret < 0) { + dev_err(dcmi->dev, "%s: Failed to set format 0x%x %ux%u on \"%s\":%d pad (%d)\n", + __func__, format->format.code, + format->format.width, format->format.height, + subdev->name, pad->index, ret); + return ret; + } + + if (fmt.format.code != format->format.code || + fmt.format.width != format->format.width || + fmt.format.height != format->format.height) { + dev_dbg(dcmi->dev, "\"%s\":%d pad format has been changed to 0x%x %ux%u\n", + subdev->name, pad->index, fmt.format.code, + fmt.format.width, fmt.format.height); + } + + /* Walk to next entity */ + sink_pad = media_entity_remote_pad(src_pad); + if (!sink_pad || !is_media_entity_v4l2_subdev(sink_pad->entity)) + break; + + entity = sink_pad->entity; + } + *format = fmt; + + return 0; +} + +static int dcmi_pipeline_s_stream(struct stm32_dcmi *dcmi, int state) +{ + struct media_entity *entity = &dcmi->vdev->entity; + struct v4l2_subdev *subdev; + struct media_pad *pad; + int ret; + + /* Start/stop all entities within pipeline */ + while (1) { + pad = &entity->pads[0]; + if (!(pad->flags & MEDIA_PAD_FL_SINK)) + break; + + pad = media_entity_remote_pad(pad); + if (!pad || !is_media_entity_v4l2_subdev(pad->entity)) + break; + + entity = pad->entity; + subdev = media_entity_to_v4l2_subdev(entity); + + ret = v4l2_subdev_call(subdev, video, s_stream, state); + if (ret < 0 && ret != -ENOIOCTLCMD) { + dev_err(dcmi->dev, "%s: \"%s\" failed to %s streaming (%d)\n", + __func__, subdev->name, + state ? "start" : "stop", ret); + return ret; + } + + dev_dbg(dcmi->dev, "\"%s\" is %s\n", + subdev->name, state ? "started" : "stopped"); + } + + return 0; +} + +static int dcmi_pipeline_start(struct stm32_dcmi *dcmi) +{ + return dcmi_pipeline_s_stream(dcmi, 1); +} + +static void dcmi_pipeline_stop(struct stm32_dcmi *dcmi) +{ + dcmi_pipeline_s_stream(dcmi, 0); +} + static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); @@ -594,14 +736,17 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) goto err_release_buffers; } - /* Enable stream on the sub device */ - ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 1); - if (ret && ret != -ENOIOCTLCMD) { - dev_err(dcmi->dev, "%s: Failed to start streaming, subdev streamon error", - __func__); + ret = media_pipeline_start(&dcmi->vdev->entity, &dcmi->pipeline); + if (ret < 0) { + dev_err(dcmi->dev, "%s: Failed to start streaming, media pipeline start error (%d)\n", + __func__, ret); goto err_pm_put; } + ret = dcmi_pipeline_start(dcmi); + if (ret) + goto err_media_pipeline_stop; + spin_lock_irq(&dcmi->irqlock); /* Set bus width */ @@ -673,7 +818,7 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) if (ret) { dev_err(dcmi->dev, "%s: Start streaming failed, cannot start capture\n", __func__); - goto err_subdev_streamoff; + goto err_pipeline_stop; } /* Enable interruptions */ @@ -684,8 +829,11 @@ static int dcmi_start_streaming(struct vb2_queue *vq, unsigned int count) return 0; -err_subdev_streamoff: - v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0); +err_pipeline_stop: + dcmi_pipeline_stop(dcmi); + +err_media_pipeline_stop: + media_pipeline_stop(&dcmi->vdev->entity); err_pm_put: pm_runtime_put(dcmi->dev); @@ -710,13 +858,10 @@ static void dcmi_stop_streaming(struct vb2_queue *vq) { struct stm32_dcmi *dcmi = vb2_get_drv_priv(vq); struct dcmi_buf *buf, *node; - int ret; - /* Disable stream on the sub device */ - ret = v4l2_subdev_call(dcmi->entity.subdev, video, s_stream, 0); - if (ret && ret != -ENOIOCTLCMD) - dev_err(dcmi->dev, "%s: Failed to stop streaming, subdev streamoff error (%d)\n", - __func__, ret); + dcmi_pipeline_stop(dcmi); + + media_pipeline_stop(&dcmi->vdev->entity); spin_lock_irq(&dcmi->irqlock); @@ -857,7 +1002,7 @@ static int dcmi_try_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f, } v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, + ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; @@ -934,8 +1079,7 @@ static int dcmi_set_fmt(struct stm32_dcmi *dcmi, struct v4l2_format *f) mf->width = sd_framesize.width; mf->height = sd_framesize.height; - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, - set_fmt, NULL, &format); + ret = dcmi_pipeline_s_fmt(dcmi, NULL, &format); if (ret < 0) return ret; @@ -991,7 +1135,7 @@ static int dcmi_get_sensor_format(struct stm32_dcmi *dcmi, }; int ret; - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_fmt, NULL, &fmt); + ret = v4l2_subdev_call(dcmi->entity.source, pad, get_fmt, NULL, &fmt); if (ret) return ret; @@ -1020,7 +1164,7 @@ static int dcmi_set_sensor_format(struct stm32_dcmi *dcmi, } v4l2_fill_mbus_format(&format.format, pix, sd_fmt->mbus_code); - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, set_fmt, + ret = v4l2_subdev_call(dcmi->entity.source, pad, set_fmt, &pad_cfg, &format); if (ret < 0) return ret; @@ -1043,7 +1187,7 @@ static int dcmi_get_sensor_bounds(struct stm32_dcmi *dcmi, /* * Get sensor bounds first */ - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, get_selection, + ret = v4l2_subdev_call(dcmi->entity.source, pad, get_selection, NULL, &bounds); if (!ret) *r = bounds.r; @@ -1224,7 +1368,7 @@ static int dcmi_enum_framesizes(struct file *file, void *fh, fse.code = sd_fmt->mbus_code; - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, enum_frame_size, + ret = v4l2_subdev_call(dcmi->entity.source, pad, enum_frame_size, NULL, &fse); if (ret) return ret; @@ -1241,7 +1385,7 @@ static int dcmi_g_parm(struct file *file, void *priv, { struct stm32_dcmi *dcmi = video_drvdata(file); - return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.subdev, p); + return v4l2_g_parm_cap(video_devdata(file), dcmi->entity.source, p); } static int dcmi_s_parm(struct file *file, void *priv, @@ -1249,7 +1393,7 @@ static int dcmi_s_parm(struct file *file, void *priv, { struct stm32_dcmi *dcmi = video_drvdata(file); - return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.subdev, p); + return v4l2_s_parm_cap(video_devdata(file), dcmi->entity.source, p); } static int dcmi_enum_frameintervals(struct file *file, void *fh, @@ -1271,7 +1415,7 @@ static int dcmi_enum_frameintervals(struct file *file, void *fh, fie.code = sd_fmt->mbus_code; - ret = v4l2_subdev_call(dcmi->entity.subdev, pad, + ret = v4l2_subdev_call(dcmi->entity.source, pad, enum_frame_interval, NULL, &fie); if (ret) return ret; @@ -1291,7 +1435,7 @@ MODULE_DEVICE_TABLE(of, stm32_dcmi_of_match); static int dcmi_open(struct file *file) { struct stm32_dcmi *dcmi = video_drvdata(file); - struct v4l2_subdev *sd = dcmi->entity.subdev; + struct v4l2_subdev *sd = dcmi->entity.source; int ret; if (mutex_lock_interruptible(&dcmi->lock)) @@ -1322,7 +1466,7 @@ unlock: static int dcmi_release(struct file *file) { struct stm32_dcmi *dcmi = video_drvdata(file); - struct v4l2_subdev *sd = dcmi->entity.subdev; + struct v4l2_subdev *sd = dcmi->entity.source; bool fh_singular; int ret; @@ -1409,6 +1553,12 @@ static int dcmi_set_default_fmt(struct stm32_dcmi *dcmi) return 0; } +/* + * FIXME: For the time being we only support subdevices + * which expose RGB & YUV "parallel form" mbus code (_2X8). + * Nevertheless, this allows to support serial source subdevices + * and serial to parallel bridges which conform to this. + */ static const struct dcmi_format dcmi_formats[] = { { .fourcc = V4L2_PIX_FMT_RGB565, @@ -1433,7 +1583,7 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi) { const struct dcmi_format *sd_fmts[ARRAY_SIZE(dcmi_formats)]; unsigned int num_fmts = 0, i, j; - struct v4l2_subdev *subdev = dcmi->entity.subdev; + struct v4l2_subdev *subdev = dcmi->entity.source; struct v4l2_subdev_mbus_code_enum mbus_code = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; @@ -1447,12 +1597,20 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi) /* Code supported, have we got this fourcc yet? */ for (j = 0; j < num_fmts; j++) if (sd_fmts[j]->fourcc == - dcmi_formats[i].fourcc) + dcmi_formats[i].fourcc) { /* Already available */ + dev_dbg(dcmi->dev, "Skipping fourcc/code: %4.4s/0x%x\n", + (char *)&sd_fmts[j]->fourcc, + mbus_code.code); break; - if (j == num_fmts) + } + if (j == num_fmts) { /* New */ sd_fmts[num_fmts++] = dcmi_formats + i; + dev_dbg(dcmi->dev, "Supported fourcc/code: %4.4s/0x%x\n", + (char *)&sd_fmts[num_fmts - 1]->fourcc, + sd_fmts[num_fmts - 1]->mbus_code); + } } mbus_code.index++; } @@ -1479,7 +1637,7 @@ static int dcmi_formats_init(struct stm32_dcmi *dcmi) static int dcmi_framesizes_init(struct stm32_dcmi *dcmi) { unsigned int num_fsize = 0; - struct v4l2_subdev *subdev = dcmi->entity.subdev; + struct v4l2_subdev *subdev = dcmi->entity.source; struct v4l2_subdev_frame_size_enum fse = { .which = V4L2_SUBDEV_FORMAT_ACTIVE, .code = dcmi->sd_format->mbus_code, @@ -1526,7 +1684,20 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier); int ret; - dcmi->vdev->ctrl_handler = dcmi->entity.subdev->ctrl_handler; + /* + * Now that the graph is complete, + * we search for the source subdevice + * in order to expose it through V4L2 interface + */ + dcmi->entity.source = + media_entity_to_v4l2_subdev(dcmi_find_source(dcmi)); + if (!dcmi->entity.source) { + dev_err(dcmi->dev, "Source subdevice not found\n"); + return -ENODEV; + } + + dcmi->vdev->ctrl_handler = dcmi->entity.source->ctrl_handler; + ret = dcmi_formats_init(dcmi); if (ret) { dev_err(dcmi->dev, "No supported mediabus format found\n"); @@ -1551,14 +1722,6 @@ static int dcmi_graph_notify_complete(struct v4l2_async_notifier *notifier) return ret; } - ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1); - if (ret) { - dev_err(dcmi->dev, "Failed to register video device\n"); - return ret; - } - - dev_dbg(dcmi->dev, "Device registered as %s\n", - video_device_node_name(dcmi->vdev)); return 0; } @@ -1579,12 +1742,31 @@ static int dcmi_graph_notify_bound(struct v4l2_async_notifier *notifier, struct v4l2_async_subdev *asd) { struct stm32_dcmi *dcmi = notifier_to_dcmi(notifier); + unsigned int ret; + int src_pad; - dev_dbg(dcmi->dev, "Subdev %s bound\n", subdev->name); + dev_dbg(dcmi->dev, "Subdev \"%s\" bound\n", subdev->name); - dcmi->entity.subdev = subdev; + /* + * Link this sub-device to DCMI, it could be + * a parallel camera sensor or a bridge + */ + src_pad = media_entity_get_fwnode_pad(&subdev->entity, + subdev->fwnode, + MEDIA_PAD_FL_SOURCE); + + ret = media_create_pad_link(&subdev->entity, src_pad, + &dcmi->vdev->entity, 0, + MEDIA_LNK_FL_IMMUTABLE | + MEDIA_LNK_FL_ENABLED); + if (ret) + dev_err(dcmi->dev, "Failed to create media pad link with subdev \"%s\"\n", + subdev->name); + else + dev_dbg(dcmi->dev, "DCMI is now linked to \"%s\"\n", + subdev->name); - return 0; + return ret; } static const struct v4l2_async_notifier_operations dcmi_graph_notify_ops = { @@ -1608,7 +1790,7 @@ static int dcmi_graph_parse(struct stm32_dcmi *dcmi, struct device_node *node) return -EINVAL; /* Remote node to connect */ - dcmi->entity.node = remote; + dcmi->entity.remote_node = remote; dcmi->entity.asd.match_type = V4L2_ASYNC_MATCH_FWNODE; dcmi->entity.asd.match.fwnode = of_fwnode_handle(remote); return 0; @@ -1631,7 +1813,7 @@ static int dcmi_graph_init(struct stm32_dcmi *dcmi) &dcmi->entity.asd); if (ret) { dev_err(dcmi->dev, "Failed to add subdev notifier\n"); - of_node_put(dcmi->entity.node); + of_node_put(dcmi->entity.remote_node); return ret; } @@ -1679,7 +1861,6 @@ static int dcmi_probe(struct platform_device *pdev) np = of_graph_get_next_endpoint(np, NULL); if (!np) { dev_err(&pdev->dev, "Could not find the endpoint\n"); - of_node_put(np); return -ENODEV; } @@ -1699,11 +1880,8 @@ static int dcmi_probe(struct platform_device *pdev) dcmi->bus.data_shift = ep.bus.parallel.data_shift; irq = platform_get_irq(pdev, 0); - if (irq <= 0) { - if (irq != -EPROBE_DEFER) - dev_err(&pdev->dev, "Could not get irq\n"); + if (irq <= 0) return irq ? irq : -ENXIO; - } dcmi->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!dcmi->res) { @@ -1751,10 +1929,19 @@ static int dcmi_probe(struct platform_device *pdev) q = &dcmi->queue; + dcmi->v4l2_dev.mdev = &dcmi->mdev; + + /* Initialize media device */ + strscpy(dcmi->mdev.model, DRV_NAME, sizeof(dcmi->mdev.model)); + snprintf(dcmi->mdev.bus_info, sizeof(dcmi->mdev.bus_info), + "platform:%s", DRV_NAME); + dcmi->mdev.dev = &pdev->dev; + media_device_init(&dcmi->mdev); + /* Initialize the top-level structure */ ret = v4l2_device_register(&pdev->dev, &dcmi->v4l2_dev); if (ret) - goto err_dma_release; + goto err_media_device_cleanup; dcmi->vdev = video_device_alloc(); if (!dcmi->vdev) { @@ -1774,6 +1961,25 @@ static int dcmi_probe(struct platform_device *pdev) V4L2_CAP_READWRITE; video_set_drvdata(dcmi->vdev, dcmi); + /* Media entity pads */ + dcmi->vid_cap_pad.flags = MEDIA_PAD_FL_SINK; + ret = media_entity_pads_init(&dcmi->vdev->entity, + 1, &dcmi->vid_cap_pad); + if (ret) { + dev_err(dcmi->dev, "Failed to init media entity pad\n"); + goto err_device_release; + } + dcmi->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT; + + ret = video_register_device(dcmi->vdev, VFL_TYPE_GRABBER, -1); + if (ret) { + dev_err(dcmi->dev, "Failed to register video device\n"); + goto err_media_entity_cleanup; + } + + dev_dbg(dcmi->dev, "Device registered as %s\n", + video_device_node_name(dcmi->vdev)); + /* Buffer queue */ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF; @@ -1789,12 +1995,12 @@ static int dcmi_probe(struct platform_device *pdev) ret = vb2_queue_init(q); if (ret < 0) { dev_err(&pdev->dev, "Failed to initialize vb2 queue\n"); - goto err_device_release; + goto err_media_entity_cleanup; } ret = dcmi_graph_init(dcmi); if (ret < 0) - goto err_device_release; + goto err_media_entity_cleanup; /* Reset device */ ret = reset_control_assert(dcmi->rstc); @@ -1821,11 +2027,14 @@ static int dcmi_probe(struct platform_device *pdev) err_cleanup: v4l2_async_notifier_cleanup(&dcmi->notifier); +err_media_entity_cleanup: + media_entity_cleanup(&dcmi->vdev->entity); err_device_release: video_device_release(dcmi->vdev); err_device_unregister: v4l2_device_unregister(&dcmi->v4l2_dev); -err_dma_release: +err_media_device_cleanup: + media_device_cleanup(&dcmi->mdev); dma_release_channel(dcmi->dma_chan); return ret; @@ -1839,7 +2048,9 @@ static int dcmi_remove(struct platform_device *pdev) v4l2_async_notifier_unregister(&dcmi->notifier); v4l2_async_notifier_cleanup(&dcmi->notifier); + media_entity_cleanup(&dcmi->vdev->entity); v4l2_device_unregister(&dcmi->v4l2_dev); + media_device_cleanup(&dcmi->mdev); dma_release_channel(dcmi->dma_chan); diff --git a/drivers/media/platform/sunxi/Kconfig b/drivers/media/platform/sunxi/Kconfig new file mode 100644 index 000000000000..71808e93ac2e --- /dev/null +++ b/drivers/media/platform/sunxi/Kconfig @@ -0,0 +1,2 @@ +source "drivers/media/platform/sunxi/sun4i-csi/Kconfig" +source "drivers/media/platform/sunxi/sun6i-csi/Kconfig" diff --git a/drivers/media/platform/sunxi/Makefile b/drivers/media/platform/sunxi/Makefile new file mode 100644 index 000000000000..a05127529006 --- /dev/null +++ b/drivers/media/platform/sunxi/Makefile @@ -0,0 +1,2 @@ +obj-y += sun4i-csi/ +obj-y += sun6i-csi/ diff --git a/drivers/media/platform/sunxi/sun4i-csi/Kconfig b/drivers/media/platform/sunxi/sun4i-csi/Kconfig new file mode 100644 index 000000000000..e86e29b6a603 --- /dev/null +++ b/drivers/media/platform/sunxi/sun4i-csi/Kconfig @@ -0,0 +1,11 @@ +config VIDEO_SUN4I_CSI + tristate "Allwinner A10 CMOS Sensor Interface Support" + depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API && HAS_DMA + depends on ARCH_SUNXI || COMPILE_TEST + select VIDEOBUF2_DMA_CONTIG + select V4L2_FWNODE + help + This is a V4L2 driver for the Allwinner A10 CSI + + To compile this driver as a module, choose M here: the module + will be called sun4i_csi. diff --git a/drivers/media/platform/sunxi/sun4i-csi/Makefile b/drivers/media/platform/sunxi/sun4i-csi/Makefile new file mode 100644 index 000000000000..7c790a57f5ee --- /dev/null +++ b/drivers/media/platform/sunxi/sun4i-csi/Makefile @@ -0,0 +1,5 @@ +sun4i-csi-y += sun4i_csi.o +sun4i-csi-y += sun4i_dma.o +sun4i-csi-y += sun4i_v4l2.o + +obj-$(CONFIG_VIDEO_SUN4I_CSI) += sun4i-csi.o diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c new file mode 100644 index 000000000000..f36dc6258900 --- /dev/null +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.c @@ -0,0 +1,314 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 NextThing Co + * Copyright (C) 2016-2019 Bootlin + * + * Author: Maxime Ripard <maxime.ripard@bootlin.com> + */ + +#include <linux/clk.h> +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> +#include <linux/videodev2.h> + +#include <media/v4l2-dev.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/v4l2-ioctl.h> +#include <media/v4l2-mediabus.h> + +#include <media/videobuf2-core.h> +#include <media/videobuf2-dma-contig.h> + +#include "sun4i_csi.h" + +static const struct media_entity_operations sun4i_csi_video_entity_ops = { + .link_validate = v4l2_subdev_link_validate, +}; + +static int sun4i_csi_notify_bound(struct v4l2_async_notifier *notifier, + struct v4l2_subdev *subdev, + struct v4l2_async_subdev *asd) +{ + struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi, + notifier); + + csi->src_subdev = subdev; + csi->src_pad = media_entity_get_fwnode_pad(&subdev->entity, + subdev->fwnode, + MEDIA_PAD_FL_SOURCE); + if (csi->src_pad < 0) { + dev_err(csi->dev, "Couldn't find output pad for subdev %s\n", + subdev->name); + return csi->src_pad; + } + + dev_dbg(csi->dev, "Bound %s pad: %d\n", subdev->name, csi->src_pad); + return 0; +} + +static int sun4i_csi_notify_complete(struct v4l2_async_notifier *notifier) +{ + struct sun4i_csi *csi = container_of(notifier, struct sun4i_csi, + notifier); + struct v4l2_subdev *subdev = &csi->subdev; + struct video_device *vdev = &csi->vdev; + int ret; + + ret = v4l2_device_register_subdev(&csi->v4l, subdev); + if (ret < 0) + return ret; + + ret = sun4i_csi_v4l2_register(csi); + if (ret < 0) + return ret; + + ret = media_device_register(&csi->mdev); + if (ret) + return ret; + + /* Create link from subdev to main device */ + ret = media_create_pad_link(&subdev->entity, CSI_SUBDEV_SOURCE, + &vdev->entity, 0, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + if (ret) + goto err_clean_media; + + ret = media_create_pad_link(&csi->src_subdev->entity, csi->src_pad, + &subdev->entity, CSI_SUBDEV_SINK, + MEDIA_LNK_FL_ENABLED | + MEDIA_LNK_FL_IMMUTABLE); + if (ret) + goto err_clean_media; + + ret = v4l2_device_register_subdev_nodes(&csi->v4l); + if (ret < 0) + goto err_clean_media; + + return 0; + +err_clean_media: + media_device_unregister(&csi->mdev); + + return ret; +} + +static const struct v4l2_async_notifier_operations sun4i_csi_notify_ops = { + .bound = sun4i_csi_notify_bound, + .complete = sun4i_csi_notify_complete, +}; + +static int sun4i_csi_notifier_init(struct sun4i_csi *csi) +{ + struct v4l2_fwnode_endpoint vep = { + .bus_type = V4L2_MBUS_PARALLEL, + }; + struct fwnode_handle *ep; + int ret; + + v4l2_async_notifier_init(&csi->notifier); + + ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0, + FWNODE_GRAPH_ENDPOINT_NEXT); + if (!ep) + return -EINVAL; + + ret = v4l2_fwnode_endpoint_parse(ep, &vep); + if (ret) + goto out; + + csi->bus = vep.bus.parallel; + + ret = v4l2_async_notifier_add_fwnode_remote_subdev(&csi->notifier, + ep, &csi->asd); + if (ret) + goto out; + + csi->notifier.ops = &sun4i_csi_notify_ops; + +out: + fwnode_handle_put(ep); + return ret; +} + +static int sun4i_csi_probe(struct platform_device *pdev) +{ + struct v4l2_subdev *subdev; + struct video_device *vdev; + struct sun4i_csi *csi; + struct resource *res; + int ret; + int irq; + + csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL); + if (!csi) + return -ENOMEM; + platform_set_drvdata(pdev, csi); + csi->dev = &pdev->dev; + subdev = &csi->subdev; + vdev = &csi->vdev; + + csi->mdev.dev = csi->dev; + strscpy(csi->mdev.model, "Allwinner Video Capture Device", + sizeof(csi->mdev.model)); + csi->mdev.hw_revision = 0; + media_device_init(&csi->mdev); + csi->v4l.mdev = &csi->mdev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + csi->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(csi->regs)) + return PTR_ERR(csi->regs); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + csi->bus_clk = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(csi->bus_clk)) { + dev_err(&pdev->dev, "Couldn't get our bus clock\n"); + return PTR_ERR(csi->bus_clk); + } + + csi->isp_clk = devm_clk_get(&pdev->dev, "isp"); + if (IS_ERR(csi->isp_clk)) { + dev_err(&pdev->dev, "Couldn't get our ISP clock\n"); + return PTR_ERR(csi->isp_clk); + } + + csi->ram_clk = devm_clk_get(&pdev->dev, "ram"); + if (IS_ERR(csi->ram_clk)) { + dev_err(&pdev->dev, "Couldn't get our ram clock\n"); + return PTR_ERR(csi->ram_clk); + } + + csi->rst = devm_reset_control_get(&pdev->dev, NULL); + if (IS_ERR(csi->rst)) { + dev_err(&pdev->dev, "Couldn't get our reset line\n"); + return PTR_ERR(csi->rst); + } + + /* Initialize subdev */ + v4l2_subdev_init(subdev, &sun4i_csi_subdev_ops); + subdev->flags = V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; + subdev->entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; + subdev->owner = THIS_MODULE; + snprintf(subdev->name, sizeof(subdev->name), "sun4i-csi-0"); + v4l2_set_subdevdata(subdev, csi); + + csi->subdev_pads[CSI_SUBDEV_SINK].flags = + MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; + csi->subdev_pads[CSI_SUBDEV_SOURCE].flags = MEDIA_PAD_FL_SOURCE; + ret = media_entity_pads_init(&subdev->entity, CSI_SUBDEV_PADS, + csi->subdev_pads); + if (ret < 0) + return ret; + + csi->vdev_pad.flags = MEDIA_PAD_FL_SINK | MEDIA_PAD_FL_MUST_CONNECT; + vdev->entity.ops = &sun4i_csi_video_entity_ops; + ret = media_entity_pads_init(&vdev->entity, 1, &csi->vdev_pad); + if (ret < 0) + return ret; + + ret = sun4i_csi_dma_register(csi, irq); + if (ret) + goto err_clean_pad; + + ret = sun4i_csi_notifier_init(csi); + if (ret) + goto err_unregister_media; + + ret = v4l2_async_notifier_register(&csi->v4l, &csi->notifier); + if (ret) { + dev_err(csi->dev, "Couldn't register our notifier.\n"); + goto err_unregister_media; + } + + pm_runtime_enable(&pdev->dev); + + return 0; + +err_unregister_media: + media_device_unregister(&csi->mdev); + sun4i_csi_dma_unregister(csi); + +err_clean_pad: + media_device_cleanup(&csi->mdev); + + return ret; +} + +static int sun4i_csi_remove(struct platform_device *pdev) +{ + struct sun4i_csi *csi = platform_get_drvdata(pdev); + + v4l2_async_notifier_unregister(&csi->notifier); + v4l2_async_notifier_cleanup(&csi->notifier); + media_device_unregister(&csi->mdev); + sun4i_csi_dma_unregister(csi); + media_device_cleanup(&csi->mdev); + + return 0; +} + +static const struct of_device_id sun4i_csi_of_match[] = { + { .compatible = "allwinner,sun7i-a20-csi0" }, + { /* Sentinel */ } +}; +MODULE_DEVICE_TABLE(of, sun4i_csi_of_match); + +static int __maybe_unused sun4i_csi_runtime_resume(struct device *dev) +{ + struct sun4i_csi *csi = dev_get_drvdata(dev); + + reset_control_deassert(csi->rst); + clk_prepare_enable(csi->bus_clk); + clk_prepare_enable(csi->ram_clk); + clk_set_rate(csi->isp_clk, 80000000); + clk_prepare_enable(csi->isp_clk); + + writel(1, csi->regs + CSI_EN_REG); + + return 0; +} + +static int __maybe_unused sun4i_csi_runtime_suspend(struct device *dev) +{ + struct sun4i_csi *csi = dev_get_drvdata(dev); + + clk_disable_unprepare(csi->isp_clk); + clk_disable_unprepare(csi->ram_clk); + clk_disable_unprepare(csi->bus_clk); + + reset_control_assert(csi->rst); + + return 0; +} + +static const struct dev_pm_ops sun4i_csi_pm_ops = { + SET_RUNTIME_PM_OPS(sun4i_csi_runtime_suspend, + sun4i_csi_runtime_resume, + NULL) +}; + +static struct platform_driver sun4i_csi_driver = { + .probe = sun4i_csi_probe, + .remove = sun4i_csi_remove, + .driver = { + .name = "sun4i-csi", + .of_match_table = sun4i_csi_of_match, + .pm = &sun4i_csi_pm_ops, + }, +}; +module_platform_driver(sun4i_csi_driver); + +MODULE_DESCRIPTION("Allwinner A10 Camera Sensor Interface driver"); +MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h new file mode 100644 index 000000000000..001c8bde006c --- /dev/null +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_csi.h @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2016 NextThing Co + * Copyright (C) 2016-2019 Bootlin + * + * Author: Maxime Ripard <maxime.ripard@bootlin.com> + */ + +#ifndef _SUN4I_CSI_H_ +#define _SUN4I_CSI_H_ + +#include <media/media-device.h> +#include <media/v4l2-async.h> +#include <media/v4l2-dev.h> +#include <media/v4l2-device.h> +#include <media/v4l2-fwnode.h> +#include <media/videobuf2-core.h> + +#define CSI_EN_REG 0x00 + +#define CSI_CFG_REG 0x04 +#define CSI_CFG_INPUT_FMT(fmt) ((fmt) << 20) +#define CSI_CFG_OUTPUT_FMT(fmt) ((fmt) << 16) +#define CSI_CFG_YUV_DATA_SEQ(seq) ((seq) << 8) +#define CSI_CFG_VSYNC_POL(pol) ((pol) << 2) +#define CSI_CFG_HSYNC_POL(pol) ((pol) << 1) +#define CSI_CFG_PCLK_POL(pol) ((pol) << 0) + +#define CSI_CPT_CTRL_REG 0x08 +#define CSI_CPT_CTRL_VIDEO_START BIT(1) +#define CSI_CPT_CTRL_IMAGE_START BIT(0) + +#define CSI_BUF_ADDR_REG(fifo, buf) (0x10 + (0x8 * (fifo)) + (0x4 * (buf))) + +#define CSI_BUF_CTRL_REG 0x28 +#define CSI_BUF_CTRL_DBN BIT(2) +#define CSI_BUF_CTRL_DBS BIT(1) +#define CSI_BUF_CTRL_DBE BIT(0) + +#define CSI_INT_EN_REG 0x30 +#define CSI_INT_FRM_DONE BIT(1) +#define CSI_INT_CPT_DONE BIT(0) + +#define CSI_INT_STA_REG 0x34 + +#define CSI_WIN_CTRL_W_REG 0x40 +#define CSI_WIN_CTRL_W_ACTIVE(w) ((w) << 16) + +#define CSI_WIN_CTRL_H_REG 0x44 +#define CSI_WIN_CTRL_H_ACTIVE(h) ((h) << 16) + +#define CSI_BUF_LEN_REG 0x48 + +#define CSI_MAX_BUFFER 2 +#define CSI_MAX_HEIGHT 8192U +#define CSI_MAX_WIDTH 8192U + +enum csi_input { + CSI_INPUT_RAW = 0, + CSI_INPUT_BT656 = 2, + CSI_INPUT_YUV = 3, +}; + +enum csi_output_raw { + CSI_OUTPUT_RAW_PASSTHROUGH = 0, +}; + +enum csi_output_yuv { + CSI_OUTPUT_YUV_422_PLANAR = 0, + CSI_OUTPUT_YUV_420_PLANAR = 1, + CSI_OUTPUT_YUV_422_UV = 4, + CSI_OUTPUT_YUV_420_UV = 5, + CSI_OUTPUT_YUV_422_MACRO = 8, + CSI_OUTPUT_YUV_420_MACRO = 9, +}; + +enum csi_yuv_data_seq { + CSI_YUV_DATA_SEQ_YUYV = 0, + CSI_YUV_DATA_SEQ_YVYU = 1, + CSI_YUV_DATA_SEQ_UYVY = 2, + CSI_YUV_DATA_SEQ_VYUY = 3, +}; + +enum csi_subdev_pads { + CSI_SUBDEV_SINK, + CSI_SUBDEV_SOURCE, + + CSI_SUBDEV_PADS, +}; + +extern const struct v4l2_subdev_ops sun4i_csi_subdev_ops; + +struct sun4i_csi_format { + u32 mbus; + u32 fourcc; + enum csi_input input; + u32 output; + unsigned int num_planes; + u8 bpp[3]; + unsigned int hsub; + unsigned int vsub; +}; + +const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc, + const u32 *mbus); + +struct sun4i_csi { + /* Device resources */ + struct device *dev; + + void __iomem *regs; + struct clk *bus_clk; + struct clk *isp_clk; + struct clk *ram_clk; + struct reset_control *rst; + + struct vb2_v4l2_buffer *current_buf[CSI_MAX_BUFFER]; + + struct { + size_t size; + void *vaddr; + dma_addr_t paddr; + } scratch; + + struct v4l2_fwnode_bus_parallel bus; + + /* Main Device */ + struct v4l2_device v4l; + struct media_device mdev; + struct video_device vdev; + struct media_pad vdev_pad; + struct v4l2_pix_format_mplane fmt; + + /* Local subdev */ + struct v4l2_subdev subdev; + struct media_pad subdev_pads[CSI_SUBDEV_PADS]; + struct v4l2_mbus_framefmt subdev_fmt; + + /* V4L2 Async variables */ + struct v4l2_async_subdev asd; + struct v4l2_async_notifier notifier; + struct v4l2_subdev *src_subdev; + int src_pad; + + /* V4L2 variables */ + struct mutex lock; + + /* Videobuf2 */ + struct vb2_queue queue; + struct list_head buf_list; + spinlock_t qlock; + unsigned int sequence; +}; + +int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq); +void sun4i_csi_dma_unregister(struct sun4i_csi *csi); + +int sun4i_csi_v4l2_register(struct sun4i_csi *csi); + +#endif /* _SUN4I_CSI_H_ */ diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c new file mode 100644 index 000000000000..d6979e11a67b --- /dev/null +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_dma.c @@ -0,0 +1,454 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 NextThing Co + * Copyright (C) 2016-2019 Bootlin + * + * Author: Maxime Ripard <maxime.ripard@bootlin.com> + */ + +#include <linux/device.h> +#include <linux/interrupt.h> +#include <linux/list.h> +#include <linux/mutex.h> +#include <linux/spinlock.h> +#include <media/videobuf2-dma-contig.h> +#include <media/videobuf2-v4l2.h> + +#include "sun4i_csi.h" + +struct sun4i_csi_buffer { + struct vb2_v4l2_buffer vb; + struct list_head list; +}; + +static inline struct sun4i_csi_buffer * +vb2_v4l2_to_csi_buffer(const struct vb2_v4l2_buffer *p) +{ + return container_of(p, struct sun4i_csi_buffer, vb); +} + +static inline struct sun4i_csi_buffer * +vb2_to_csi_buffer(const struct vb2_buffer *p) +{ + return vb2_v4l2_to_csi_buffer(to_vb2_v4l2_buffer(p)); +} + +static void sun4i_csi_capture_start(struct sun4i_csi *csi) +{ + writel(CSI_CPT_CTRL_VIDEO_START, csi->regs + CSI_CPT_CTRL_REG); +} + +static void sun4i_csi_capture_stop(struct sun4i_csi *csi) +{ + writel(0, csi->regs + CSI_CPT_CTRL_REG); +} + +static int sun4i_csi_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, + unsigned int *nplanes, + unsigned int sizes[], + struct device *alloc_devs[]) +{ + struct sun4i_csi *csi = vb2_get_drv_priv(vq); + unsigned int num_planes = csi->fmt.num_planes; + unsigned int i; + + if (*nplanes) { + if (*nplanes != num_planes) + return -EINVAL; + + for (i = 0; i < num_planes; i++) + if (sizes[i] < csi->fmt.plane_fmt[i].sizeimage) + return -EINVAL; + return 0; + } + + *nplanes = num_planes; + for (i = 0; i < num_planes; i++) + sizes[i] = csi->fmt.plane_fmt[i].sizeimage; + + return 0; +}; + +static int sun4i_csi_buffer_prepare(struct vb2_buffer *vb) +{ + struct sun4i_csi *csi = vb2_get_drv_priv(vb->vb2_queue); + unsigned int i; + + for (i = 0; i < csi->fmt.num_planes; i++) { + unsigned long size = csi->fmt.plane_fmt[i].sizeimage; + + if (vb2_plane_size(vb, i) < size) { + dev_err(csi->dev, "buffer too small (%lu < %lu)\n", + vb2_plane_size(vb, i), size); + return -EINVAL; + } + + vb2_set_plane_payload(vb, i, size); + } + + return 0; +} + +static int sun4i_csi_setup_scratch_buffer(struct sun4i_csi *csi, + unsigned int slot) +{ + dma_addr_t addr = csi->scratch.paddr; + unsigned int plane; + + dev_dbg(csi->dev, + "No more available buffer, using the scratch buffer\n"); + + for (plane = 0; plane < csi->fmt.num_planes; plane++) { + writel(addr, csi->regs + CSI_BUF_ADDR_REG(plane, slot)); + addr += csi->fmt.plane_fmt[plane].sizeimage; + } + + csi->current_buf[slot] = NULL; + return 0; +} + +static int sun4i_csi_buffer_fill_slot(struct sun4i_csi *csi, unsigned int slot) +{ + struct sun4i_csi_buffer *c_buf; + struct vb2_v4l2_buffer *v_buf; + unsigned int plane; + + /* + * We should never end up in a situation where we overwrite an + * already filled slot. + */ + if (WARN_ON(csi->current_buf[slot])) + return -EINVAL; + + if (list_empty(&csi->buf_list)) + return sun4i_csi_setup_scratch_buffer(csi, slot); + + c_buf = list_first_entry(&csi->buf_list, struct sun4i_csi_buffer, list); + list_del_init(&c_buf->list); + + v_buf = &c_buf->vb; + csi->current_buf[slot] = v_buf; + + for (plane = 0; plane < csi->fmt.num_planes; plane++) { + dma_addr_t buf_addr; + + buf_addr = vb2_dma_contig_plane_dma_addr(&v_buf->vb2_buf, + plane); + writel(buf_addr, csi->regs + CSI_BUF_ADDR_REG(plane, slot)); + } + + return 0; +} + +static int sun4i_csi_buffer_fill_all(struct sun4i_csi *csi) +{ + unsigned int slot; + int ret; + + for (slot = 0; slot < CSI_MAX_BUFFER; slot++) { + ret = sun4i_csi_buffer_fill_slot(csi, slot); + if (ret) + return ret; + } + + return 0; +} + +static void sun4i_csi_buffer_mark_done(struct sun4i_csi *csi, + unsigned int slot, + unsigned int sequence) +{ + struct vb2_v4l2_buffer *v_buf; + + if (!csi->current_buf[slot]) { + dev_dbg(csi->dev, "Scratch buffer was used, ignoring..\n"); + return; + } + + v_buf = csi->current_buf[slot]; + v_buf->field = csi->fmt.field; + v_buf->sequence = sequence; + v_buf->vb2_buf.timestamp = ktime_get_ns(); + vb2_buffer_done(&v_buf->vb2_buf, VB2_BUF_STATE_DONE); + + csi->current_buf[slot] = NULL; +} + +static int sun4i_csi_buffer_flip(struct sun4i_csi *csi, unsigned int sequence) +{ + u32 reg = readl(csi->regs + CSI_BUF_CTRL_REG); + unsigned int next; + + /* Our next buffer is not the current buffer */ + next = !(reg & CSI_BUF_CTRL_DBS); + + /* Report the previous buffer as done */ + sun4i_csi_buffer_mark_done(csi, next, sequence); + + /* Put a new buffer in there */ + return sun4i_csi_buffer_fill_slot(csi, next); +} + +static void sun4i_csi_buffer_queue(struct vb2_buffer *vb) +{ + struct sun4i_csi *csi = vb2_get_drv_priv(vb->vb2_queue); + struct sun4i_csi_buffer *buf = vb2_to_csi_buffer(vb); + unsigned long flags; + + spin_lock_irqsave(&csi->qlock, flags); + list_add_tail(&buf->list, &csi->buf_list); + spin_unlock_irqrestore(&csi->qlock, flags); +} + +static void return_all_buffers(struct sun4i_csi *csi, + enum vb2_buffer_state state) +{ + struct sun4i_csi_buffer *buf, *node; + unsigned int slot; + + list_for_each_entry_safe(buf, node, &csi->buf_list, list) { + vb2_buffer_done(&buf->vb.vb2_buf, state); + list_del(&buf->list); + } + + for (slot = 0; slot < CSI_MAX_BUFFER; slot++) { + struct vb2_v4l2_buffer *v_buf = csi->current_buf[slot]; + + if (!v_buf) + continue; + + vb2_buffer_done(&v_buf->vb2_buf, state); + csi->current_buf[slot] = NULL; + } +} + +static int sun4i_csi_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct sun4i_csi *csi = vb2_get_drv_priv(vq); + struct v4l2_fwnode_bus_parallel *bus = &csi->bus; + const struct sun4i_csi_format *csi_fmt; + unsigned long hsync_pol, pclk_pol, vsync_pol; + unsigned long flags; + unsigned int i; + int ret; + + csi_fmt = sun4i_csi_find_format(&csi->fmt.pixelformat, NULL); + if (!csi_fmt) + return -EINVAL; + + dev_dbg(csi->dev, "Starting capture\n"); + + csi->sequence = 0; + + /* + * We need a scratch buffer in case where we'll not have any + * more buffer queued so that we don't error out. One of those + * cases is when you end up at the last frame to capture, you + * don't havea any buffer queued any more, and yet it doesn't + * really matter since you'll never reach the next buffer. + * + * Since we support the multi-planar API, we need to have a + * buffer for each plane. Allocating a single one large enough + * to hold all the buffers is simpler, so let's go for that. + */ + csi->scratch.size = 0; + for (i = 0; i < csi->fmt.num_planes; i++) + csi->scratch.size += csi->fmt.plane_fmt[i].sizeimage; + + csi->scratch.vaddr = dma_alloc_coherent(csi->dev, + csi->scratch.size, + &csi->scratch.paddr, + GFP_KERNEL); + if (!csi->scratch.vaddr) { + dev_err(csi->dev, "Failed to allocate scratch buffer\n"); + ret = -ENOMEM; + goto err_clear_dma_queue; + } + + ret = media_pipeline_start(&csi->vdev.entity, &csi->vdev.pipe); + if (ret < 0) + goto err_free_scratch_buffer; + + spin_lock_irqsave(&csi->qlock, flags); + + /* Setup timings */ + writel(CSI_WIN_CTRL_W_ACTIVE(csi->fmt.width * 2), + csi->regs + CSI_WIN_CTRL_W_REG); + writel(CSI_WIN_CTRL_H_ACTIVE(csi->fmt.height), + csi->regs + CSI_WIN_CTRL_H_REG); + + hsync_pol = !!(bus->flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH); + pclk_pol = !!(bus->flags & V4L2_MBUS_DATA_ACTIVE_HIGH); + vsync_pol = !!(bus->flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH); + writel(CSI_CFG_INPUT_FMT(csi_fmt->input) | + CSI_CFG_OUTPUT_FMT(csi_fmt->output) | + CSI_CFG_VSYNC_POL(vsync_pol) | + CSI_CFG_HSYNC_POL(hsync_pol) | + CSI_CFG_PCLK_POL(pclk_pol), + csi->regs + CSI_CFG_REG); + + /* Setup buffer length */ + writel(csi->fmt.plane_fmt[0].bytesperline, + csi->regs + CSI_BUF_LEN_REG); + + /* Prepare our buffers in hardware */ + ret = sun4i_csi_buffer_fill_all(csi); + if (ret) { + spin_unlock_irqrestore(&csi->qlock, flags); + goto err_disable_pipeline; + } + + /* Enable double buffering */ + writel(CSI_BUF_CTRL_DBE, csi->regs + CSI_BUF_CTRL_REG); + + /* Clear the pending interrupts */ + writel(CSI_INT_FRM_DONE, csi->regs + 0x34); + + /* Enable frame done interrupt */ + writel(CSI_INT_FRM_DONE, csi->regs + CSI_INT_EN_REG); + + sun4i_csi_capture_start(csi); + + spin_unlock_irqrestore(&csi->qlock, flags); + + ret = v4l2_subdev_call(csi->src_subdev, video, s_stream, 1); + if (ret < 0 && ret != -ENOIOCTLCMD) + goto err_disable_device; + + return 0; + +err_disable_device: + sun4i_csi_capture_stop(csi); + +err_disable_pipeline: + media_pipeline_stop(&csi->vdev.entity); + +err_free_scratch_buffer: + dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr, + csi->scratch.paddr); + +err_clear_dma_queue: + spin_lock_irqsave(&csi->qlock, flags); + return_all_buffers(csi, VB2_BUF_STATE_QUEUED); + spin_unlock_irqrestore(&csi->qlock, flags); + + return ret; +} + +static void sun4i_csi_stop_streaming(struct vb2_queue *vq) +{ + struct sun4i_csi *csi = vb2_get_drv_priv(vq); + unsigned long flags; + + dev_dbg(csi->dev, "Stopping capture\n"); + + v4l2_subdev_call(csi->src_subdev, video, s_stream, 0); + sun4i_csi_capture_stop(csi); + + /* Release all active buffers */ + spin_lock_irqsave(&csi->qlock, flags); + return_all_buffers(csi, VB2_BUF_STATE_ERROR); + spin_unlock_irqrestore(&csi->qlock, flags); + + media_pipeline_stop(&csi->vdev.entity); + + dma_free_coherent(csi->dev, csi->scratch.size, csi->scratch.vaddr, + csi->scratch.paddr); +} + +static const struct vb2_ops sun4i_csi_qops = { + .queue_setup = sun4i_csi_queue_setup, + .buf_prepare = sun4i_csi_buffer_prepare, + .buf_queue = sun4i_csi_buffer_queue, + .start_streaming = sun4i_csi_start_streaming, + .stop_streaming = sun4i_csi_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, +}; + +static irqreturn_t sun4i_csi_irq(int irq, void *data) +{ + struct sun4i_csi *csi = data; + u32 reg; + + reg = readl(csi->regs + CSI_INT_STA_REG); + + /* Acknowledge the interrupts */ + writel(reg, csi->regs + CSI_INT_STA_REG); + + if (!(reg & CSI_INT_FRM_DONE)) + return IRQ_HANDLED; + + spin_lock(&csi->qlock); + if (sun4i_csi_buffer_flip(csi, csi->sequence++)) { + dev_warn(csi->dev, "%s: Flip failed\n", __func__); + sun4i_csi_capture_stop(csi); + } + spin_unlock(&csi->qlock); + + return IRQ_HANDLED; +} + +int sun4i_csi_dma_register(struct sun4i_csi *csi, int irq) +{ + struct vb2_queue *q = &csi->queue; + int ret; + int i; + + spin_lock_init(&csi->qlock); + mutex_init(&csi->lock); + + INIT_LIST_HEAD(&csi->buf_list); + for (i = 0; i < CSI_MAX_BUFFER; i++) + csi->current_buf[i] = NULL; + + q->min_buffers_needed = 3; + q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + q->io_modes = VB2_MMAP; + q->lock = &csi->lock; + q->drv_priv = csi; + q->buf_struct_size = sizeof(struct sun4i_csi_buffer); + q->ops = &sun4i_csi_qops; + q->mem_ops = &vb2_dma_contig_memops; + q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + q->dev = csi->dev; + + ret = vb2_queue_init(q); + if (ret < 0) { + dev_err(csi->dev, "failed to initialize VB2 queue\n"); + goto err_free_mutex; + } + + ret = v4l2_device_register(csi->dev, &csi->v4l); + if (ret) { + dev_err(csi->dev, "Couldn't register the v4l2 device\n"); + goto err_free_queue; + } + + ret = devm_request_irq(csi->dev, irq, sun4i_csi_irq, 0, + dev_name(csi->dev), csi); + if (ret) { + dev_err(csi->dev, "Couldn't register our interrupt\n"); + goto err_unregister_device; + } + + return 0; + +err_unregister_device: + v4l2_device_unregister(&csi->v4l); + +err_free_queue: + vb2_queue_release(q); + +err_free_mutex: + mutex_destroy(&csi->lock); + return ret; +} + +void sun4i_csi_dma_unregister(struct sun4i_csi *csi) +{ + v4l2_device_unregister(&csi->v4l); + vb2_queue_release(&csi->queue); + mutex_destroy(&csi->lock); +} diff --git a/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c new file mode 100644 index 000000000000..83a3a0257c7b --- /dev/null +++ b/drivers/media/platform/sunxi/sun4i-csi/sun4i_v4l2.c @@ -0,0 +1,385 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 NextThing Co + * Copyright (C) 2016-2019 Bootlin + * + * Author: Maxime Ripard <maxime.ripard@bootlin.com> + */ + +#include <linux/device.h> +#include <linux/pm_runtime.h> + +#include <media/v4l2-ioctl.h> +#include <media/v4l2-mc.h> +#include <media/videobuf2-v4l2.h> + +#include "sun4i_csi.h" + +#define CSI_DEFAULT_WIDTH 640 +#define CSI_DEFAULT_HEIGHT 480 + +static const struct sun4i_csi_format sun4i_csi_formats[] = { + /* YUV422 inputs */ + { + .mbus = MEDIA_BUS_FMT_YUYV8_2X8, + .fourcc = V4L2_PIX_FMT_YUV420M, + .input = CSI_INPUT_YUV, + .output = CSI_OUTPUT_YUV_420_PLANAR, + .num_planes = 3, + .bpp = { 8, 8, 8 }, + .hsub = 2, + .vsub = 2, + }, +}; + +const struct sun4i_csi_format *sun4i_csi_find_format(const u32 *fourcc, + const u32 *mbus) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(sun4i_csi_formats); i++) { + if (fourcc && *fourcc != sun4i_csi_formats[i].fourcc) + continue; + + if (mbus && *mbus != sun4i_csi_formats[i].mbus) + continue; + + return &sun4i_csi_formats[i]; + } + + return NULL; +} + +static int sun4i_csi_querycap(struct file *file, void *priv, + struct v4l2_capability *cap) +{ + struct sun4i_csi *csi = video_drvdata(file); + + strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver)); + strscpy(cap->card, "sun4i-csi", sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", + dev_name(csi->dev)); + + return 0; +} + +static int sun4i_csi_enum_input(struct file *file, void *priv, + struct v4l2_input *inp) +{ + if (inp->index != 0) + return -EINVAL; + + inp->type = V4L2_INPUT_TYPE_CAMERA; + strscpy(inp->name, "Camera", sizeof(inp->name)); + + return 0; +} + +static int sun4i_csi_g_input(struct file *file, void *fh, + unsigned int *i) +{ + *i = 0; + + return 0; +} + +static int sun4i_csi_s_input(struct file *file, void *fh, + unsigned int i) +{ + if (i != 0) + return -EINVAL; + + return 0; +} + +static void _sun4i_csi_try_fmt(struct sun4i_csi *csi, + struct v4l2_pix_format_mplane *pix) +{ + const struct sun4i_csi_format *_fmt; + unsigned int height, width; + unsigned int i; + + _fmt = sun4i_csi_find_format(&pix->pixelformat, NULL); + if (!_fmt) + _fmt = &sun4i_csi_formats[0]; + + pix->field = V4L2_FIELD_NONE; + pix->colorspace = V4L2_COLORSPACE_SRGB; + pix->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(pix->colorspace); + pix->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(pix->colorspace); + pix->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, pix->colorspace, + pix->ycbcr_enc); + + pix->num_planes = _fmt->num_planes; + pix->pixelformat = _fmt->fourcc; + + memset(pix->reserved, 0, sizeof(pix->reserved)); + + /* Align the width and height on the subsampling */ + width = ALIGN(pix->width, _fmt->hsub); + height = ALIGN(pix->height, _fmt->vsub); + + /* Clamp the width and height to our capabilities */ + pix->width = clamp(width, _fmt->hsub, CSI_MAX_WIDTH); + pix->height = clamp(height, _fmt->vsub, CSI_MAX_HEIGHT); + + for (i = 0; i < _fmt->num_planes; i++) { + unsigned int hsub = i > 0 ? _fmt->hsub : 1; + unsigned int vsub = i > 0 ? _fmt->vsub : 1; + unsigned int bpl; + + bpl = pix->width / hsub * _fmt->bpp[i] / 8; + pix->plane_fmt[i].bytesperline = bpl; + pix->plane_fmt[i].sizeimage = bpl * pix->height / vsub; + memset(pix->plane_fmt[i].reserved, 0, + sizeof(pix->plane_fmt[i].reserved)); + } +} + +static int sun4i_csi_try_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct sun4i_csi *csi = video_drvdata(file); + + _sun4i_csi_try_fmt(csi, &f->fmt.pix_mp); + + return 0; +} + +static int sun4i_csi_s_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct sun4i_csi *csi = video_drvdata(file); + + _sun4i_csi_try_fmt(csi, &f->fmt.pix_mp); + csi->fmt = f->fmt.pix_mp; + + return 0; +} + +static int sun4i_csi_g_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_format *f) +{ + struct sun4i_csi *csi = video_drvdata(file); + + f->fmt.pix_mp = csi->fmt; + + return 0; +} + +static int sun4i_csi_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) +{ + if (f->index >= ARRAY_SIZE(sun4i_csi_formats)) + return -EINVAL; + + f->pixelformat = sun4i_csi_formats[f->index].fourcc; + + return 0; +} + +static const struct v4l2_ioctl_ops sun4i_csi_ioctl_ops = { + .vidioc_querycap = sun4i_csi_querycap, + + .vidioc_enum_fmt_vid_cap = sun4i_csi_enum_fmt_vid_cap, + .vidioc_g_fmt_vid_cap_mplane = sun4i_csi_g_fmt_vid_cap, + .vidioc_s_fmt_vid_cap_mplane = sun4i_csi_s_fmt_vid_cap, + .vidioc_try_fmt_vid_cap_mplane = sun4i_csi_try_fmt_vid_cap, + + .vidioc_enum_input = sun4i_csi_enum_input, + .vidioc_g_input = sun4i_csi_g_input, + .vidioc_s_input = sun4i_csi_s_input, + + .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_prepare_buf = vb2_ioctl_prepare_buf, + .vidioc_streamon = vb2_ioctl_streamon, + .vidioc_streamoff = vb2_ioctl_streamoff, +}; + +static int sun4i_csi_open(struct file *file) +{ + struct sun4i_csi *csi = video_drvdata(file); + int ret; + + ret = mutex_lock_interruptible(&csi->lock); + if (ret) + return ret; + + ret = pm_runtime_get_sync(csi->dev); + if (ret < 0) + goto err_pm_put; + + ret = v4l2_pipeline_pm_use(&csi->vdev.entity, 1); + if (ret) + goto err_pm_put; + + ret = v4l2_fh_open(file); + if (ret) + goto err_pipeline_pm_put; + + mutex_unlock(&csi->lock); + + return 0; + +err_pipeline_pm_put: + v4l2_pipeline_pm_use(&csi->vdev.entity, 0); + +err_pm_put: + pm_runtime_put(csi->dev); + mutex_unlock(&csi->lock); + + return ret; +} + +static int sun4i_csi_release(struct file *file) +{ + struct sun4i_csi *csi = video_drvdata(file); + + mutex_lock(&csi->lock); + + v4l2_fh_release(file); + v4l2_pipeline_pm_use(&csi->vdev.entity, 0); + pm_runtime_put(csi->dev); + + mutex_unlock(&csi->lock); + + return 0; +} + +static const struct v4l2_file_operations sun4i_csi_fops = { + .owner = THIS_MODULE, + .open = sun4i_csi_open, + .release = sun4i_csi_release, + .unlocked_ioctl = video_ioctl2, + .read = vb2_fop_read, + .write = vb2_fop_write, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, +}; + +static const struct v4l2_mbus_framefmt sun4i_csi_pad_fmt_default = { + .width = CSI_DEFAULT_WIDTH, + .height = CSI_DEFAULT_HEIGHT, + .code = MEDIA_BUS_FMT_YUYV8_2X8, + .field = V4L2_FIELD_NONE, + .colorspace = V4L2_COLORSPACE_RAW, + .ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT, + .quantization = V4L2_QUANTIZATION_DEFAULT, + .xfer_func = V4L2_XFER_FUNC_DEFAULT, +}; + +static int sun4i_csi_subdev_init_cfg(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg) +{ + struct v4l2_mbus_framefmt *fmt; + + fmt = v4l2_subdev_get_try_format(subdev, cfg, CSI_SUBDEV_SINK); + *fmt = sun4i_csi_pad_fmt_default; + + return 0; +} + +static int sun4i_csi_subdev_get_fmt(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev); + struct v4l2_mbus_framefmt *subdev_fmt; + + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad); + else + subdev_fmt = &csi->subdev_fmt; + + fmt->format = *subdev_fmt; + + return 0; +} + +static int sun4i_csi_subdev_set_fmt(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_format *fmt) +{ + struct sun4i_csi *csi = container_of(subdev, struct sun4i_csi, subdev); + struct v4l2_mbus_framefmt *subdev_fmt; + + if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) + subdev_fmt = v4l2_subdev_get_try_format(subdev, cfg, fmt->pad); + else + subdev_fmt = &csi->subdev_fmt; + + /* We can only set the format on the sink pad */ + if (fmt->pad == CSI_SUBDEV_SINK) { + /* It's the sink, only allow changing the frame size */ + subdev_fmt->width = fmt->format.width; + subdev_fmt->height = fmt->format.height; + subdev_fmt->code = fmt->format.code; + } + + fmt->format = *subdev_fmt; + + return 0; +} + +static int +sun4i_csi_subdev_enum_mbus_code(struct v4l2_subdev *subdev, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *mbus) +{ + if (mbus->index >= ARRAY_SIZE(sun4i_csi_formats)) + return -EINVAL; + + mbus->code = sun4i_csi_formats[mbus->index].mbus; + + return 0; +} + +static const struct v4l2_subdev_pad_ops sun4i_csi_subdev_pad_ops = { + .link_validate = v4l2_subdev_link_validate_default, + .init_cfg = sun4i_csi_subdev_init_cfg, + .get_fmt = sun4i_csi_subdev_get_fmt, + .set_fmt = sun4i_csi_subdev_set_fmt, + .enum_mbus_code = sun4i_csi_subdev_enum_mbus_code, +}; + +const struct v4l2_subdev_ops sun4i_csi_subdev_ops = { + .pad = &sun4i_csi_subdev_pad_ops, +}; + +int sun4i_csi_v4l2_register(struct sun4i_csi *csi) +{ + struct video_device *vdev = &csi->vdev; + int ret; + + vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING; + vdev->v4l2_dev = &csi->v4l; + vdev->queue = &csi->queue; + strscpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); + vdev->release = video_device_release_empty; + vdev->lock = &csi->lock; + + /* Set a default format */ + csi->fmt.pixelformat = sun4i_csi_formats[0].fourcc, + csi->fmt.width = CSI_DEFAULT_WIDTH; + csi->fmt.height = CSI_DEFAULT_HEIGHT; + _sun4i_csi_try_fmt(csi, &csi->fmt); + csi->subdev_fmt = sun4i_csi_pad_fmt_default; + + vdev->fops = &sun4i_csi_fops; + vdev->ioctl_ops = &sun4i_csi_ioctl_ops; + video_set_drvdata(vdev, csi); + + ret = video_register_device(&csi->vdev, VFL_TYPE_GRABBER, -1); + if (ret) + return ret; + + dev_info(csi->dev, "Device registered as %s\n", + video_device_node_name(vdev)); + + return 0; +} diff --git a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c index 6e0e894154f4..055eb0b8e396 100644 --- a/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c +++ b/drivers/media/platform/sunxi/sun6i-csi/sun6i_csi.c @@ -866,11 +866,8 @@ static int sun6i_csi_resource_request(struct sun6i_csi_dev *sdev, } irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "No csi IRQ specified\n"); - ret = -ENXIO; - return ret; - } + if (irq < 0) + return -ENXIO; ret = devm_request_irq(&pdev->dev, irq, sun6i_csi_isr, 0, MODULE_NAME, sdev); diff --git a/drivers/media/platform/tegra-cec/tegra_cec.c b/drivers/media/platform/tegra-cec/tegra_cec.c index 6498b2d0492e..a632602131f2 100644 --- a/drivers/media/platform/tegra-cec/tegra_cec.c +++ b/drivers/media/platform/tegra-cec/tegra_cec.c @@ -380,38 +380,39 @@ static int tegra_cec_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "Unable to request interrupt for device\n"); - goto clk_error; - } - - cec->notifier = cec_notifier_get(hdmi_dev); - if (!cec->notifier) { - ret = -ENOMEM; - goto clk_error; + goto err_clk; } cec->adap = cec_allocate_adapter(&tegra_cec_ops, cec, TEGRA_CEC_NAME, - CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL, + CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | + CEC_CAP_CONNECTOR_INFO, CEC_MAX_LOG_ADDRS); if (IS_ERR(cec->adap)) { ret = -ENOMEM; dev_err(&pdev->dev, "Couldn't create cec adapter\n"); - goto cec_error; + goto err_clk; + } + + cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL, + cec->adap); + if (!cec->notifier) { + ret = -ENOMEM; + goto err_adapter; } + ret = cec_register_adapter(cec->adap, &pdev->dev); if (ret) { dev_err(&pdev->dev, "Couldn't register device\n"); - goto cec_error; + goto err_notifier; } - cec_register_cec_notifier(cec->adap, cec->notifier); - return 0; -cec_error: - if (cec->notifier) - cec_notifier_put(cec->notifier); +err_notifier: + cec_notifier_cec_adap_unregister(cec->notifier); +err_adapter: cec_delete_adapter(cec->adap); -clk_error: +err_clk: clk_disable_unprepare(cec->clk); return ret; } @@ -422,8 +423,8 @@ static int tegra_cec_remove(struct platform_device *pdev) clk_disable_unprepare(cec->clk); + cec_notifier_cec_adap_unregister(cec->notifier); cec_unregister_adapter(cec->adap); - cec_notifier_put(cec->notifier); return 0; } diff --git a/drivers/media/platform/tegra-cec/tegra_cec.h b/drivers/media/platform/tegra-cec/tegra_cec.h index 32d7d69f9491..8c370be38e1e 100644 --- a/drivers/media/platform/tegra-cec/tegra_cec.h +++ b/drivers/media/platform/tegra-cec/tegra_cec.h @@ -34,24 +34,24 @@ #define TEGRA_CEC_HWCTRL_RX_LADDR_MASK 0x7fff #define TEGRA_CEC_HWCTRL_RX_LADDR(x) \ ((x) & TEGRA_CEC_HWCTRL_RX_LADDR_MASK) -#define TEGRA_CEC_HWCTRL_RX_SNOOP (1 << 15) -#define TEGRA_CEC_HWCTRL_RX_NAK_MODE (1 << 16) -#define TEGRA_CEC_HWCTRL_TX_NAK_MODE (1 << 24) -#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE (1 << 30) -#define TEGRA_CEC_HWCTRL_TX_RX_MODE (1 << 31) +#define TEGRA_CEC_HWCTRL_RX_SNOOP BIT(15) +#define TEGRA_CEC_HWCTRL_RX_NAK_MODE BIT(16) +#define TEGRA_CEC_HWCTRL_TX_NAK_MODE BIT(24) +#define TEGRA_CEC_HWCTRL_FAST_SIM_MODE BIT(30) +#define TEGRA_CEC_HWCTRL_TX_RX_MODE BIT(31) -#define TEGRA_CEC_INPUT_FILTER_MODE (1 << 31) +#define TEGRA_CEC_INPUT_FILTER_MODE BIT(31) #define TEGRA_CEC_INPUT_FILTER_FIFO_LENGTH_SHIFT 0 #define TEGRA_CEC_TX_REG_DATA_SHIFT 0 -#define TEGRA_CEC_TX_REG_EOM (1 << 8) -#define TEGRA_CEC_TX_REG_BCAST (1 << 12) -#define TEGRA_CEC_TX_REG_START_BIT (1 << 16) -#define TEGRA_CEC_TX_REG_RETRY (1 << 17) +#define TEGRA_CEC_TX_REG_EOM BIT(8) +#define TEGRA_CEC_TX_REG_BCAST BIT(12) +#define TEGRA_CEC_TX_REG_START_BIT BIT(16) +#define TEGRA_CEC_TX_REG_RETRY BIT(17) #define TEGRA_CEC_RX_REGISTER_SHIFT 0 -#define TEGRA_CEC_RX_REGISTER_EOM (1 << 8) -#define TEGRA_CEC_RX_REGISTER_ACK (1 << 9) +#define TEGRA_CEC_RX_REGISTER_EOM BIT(8) +#define TEGRA_CEC_RX_REGISTER_ACK BIT(9) #define TEGRA_CEC_RX_TIM0_START_BIT_MAX_LO_TIME_SHIFT 0 #define TEGRA_CEC_RX_TIM0_START_BIT_MIN_LO_TIME_SHIFT 8 @@ -79,38 +79,38 @@ #define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_NEW_FRAME_SHIFT 4 #define TEGRA_CEC_TX_TIM2_BUS_IDLE_TIME_RETRY_FRAME_SHIFT 8 -#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY (1 << 0) -#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN (1 << 1) -#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD (1 << 2) -#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED (1 << 3) -#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED (1 << 4) -#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED (1 << 5) -#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL (1 << 8) -#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN (1 << 9) -#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED (1 << 10) -#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED (1 << 11) -#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED (1 << 12) -#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1 << 13) -#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1 << 14) - -#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY (1 << 0) -#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN (1 << 1) -#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD (1 << 2) -#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED (1 << 3) -#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED (1 << 4) -#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED (1 << 5) -#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL (1 << 8) -#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN (1 << 9) -#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED (1 << 10) -#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED (1 << 11) -#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED (1 << 12) -#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L (1 << 13) -#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H (1 << 14) +#define TEGRA_CEC_INT_STAT_TX_REGISTER_EMPTY BIT(0) +#define TEGRA_CEC_INT_STAT_TX_REGISTER_UNDERRUN BIT(1) +#define TEGRA_CEC_INT_STAT_TX_FRAME_OR_BLOCK_NAKD BIT(2) +#define TEGRA_CEC_INT_STAT_TX_ARBITRATION_FAILED BIT(3) +#define TEGRA_CEC_INT_STAT_TX_BUS_ANOMALY_DETECTED BIT(4) +#define TEGRA_CEC_INT_STAT_TX_FRAME_TRANSMITTED BIT(5) +#define TEGRA_CEC_INT_STAT_RX_REGISTER_FULL BIT(8) +#define TEGRA_CEC_INT_STAT_RX_REGISTER_OVERRUN BIT(9) +#define TEGRA_CEC_INT_STAT_RX_START_BIT_DETECTED BIT(10) +#define TEGRA_CEC_INT_STAT_RX_BUS_ANOMALY_DETECTED BIT(11) +#define TEGRA_CEC_INT_STAT_RX_BUS_ERROR_DETECTED BIT(12) +#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_H2L BIT(13) +#define TEGRA_CEC_INT_STAT_FILTERED_RX_DATA_PIN_TRANSITION_L2H BIT(14) + +#define TEGRA_CEC_INT_MASK_TX_REGISTER_EMPTY BIT(0) +#define TEGRA_CEC_INT_MASK_TX_REGISTER_UNDERRUN BIT(1) +#define TEGRA_CEC_INT_MASK_TX_FRAME_OR_BLOCK_NAKD BIT(2) +#define TEGRA_CEC_INT_MASK_TX_ARBITRATION_FAILED BIT(3) +#define TEGRA_CEC_INT_MASK_TX_BUS_ANOMALY_DETECTED BIT(4) +#define TEGRA_CEC_INT_MASK_TX_FRAME_TRANSMITTED BIT(5) +#define TEGRA_CEC_INT_MASK_RX_REGISTER_FULL BIT(8) +#define TEGRA_CEC_INT_MASK_RX_REGISTER_OVERRUN BIT(9) +#define TEGRA_CEC_INT_MASK_RX_START_BIT_DETECTED BIT(10) +#define TEGRA_CEC_INT_MASK_RX_BUS_ANOMALY_DETECTED BIT(11) +#define TEGRA_CEC_INT_MASK_RX_BUS_ERROR_DETECTED BIT(12) +#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_H2L BIT(13) +#define TEGRA_CEC_INT_MASK_FILTERED_RX_DATA_PIN_TRANSITION_L2H BIT(14) #define TEGRA_CEC_HW_DEBUG_TX_DURATION_COUNT_SHIFT 0 #define TEGRA_CEC_HW_DEBUG_TX_TXBIT_COUNT_SHIFT 17 #define TEGRA_CEC_HW_DEBUG_TX_STATE_SHIFT 21 -#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT (1 << 25) -#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER (1 << 26) +#define TEGRA_CEC_HW_DEBUG_TX_FORCELOOUT BIT(25) +#define TEGRA_CEC_HW_DEBUG_TX_TXDATABIT_SAMPLE_TIMER BIT(26) #endif /* TEGRA_CEC_H */ diff --git a/drivers/media/platform/ti-vpe/cal.c b/drivers/media/platform/ti-vpe/cal.c index 9e86d761546b..223161f9c403 100644 --- a/drivers/media/platform/ti-vpe/cal.c +++ b/drivers/media/platform/ti-vpe/cal.c @@ -913,9 +913,6 @@ static int cal_querycap(struct file *file, void *priv, snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", ctx->v4l2_dev.name); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } @@ -1419,6 +1416,8 @@ static const struct video_device cal_videodev = { .ioctl_ops = &cal_ioctl_ops, .minor = -1, .release = video_device_release_empty, + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE, }; /* ----------------------------------------------------------------- @@ -1613,6 +1612,7 @@ of_get_next_port(const struct device_node *parent, } prev = port; } while (!of_node_name_eq(port, "port")); + of_node_put(ports); } return port; diff --git a/drivers/media/platform/ti-vpe/vpdma.c b/drivers/media/platform/ti-vpe/vpdma.c index fd37d79e1619..53d27cd6e10a 100644 --- a/drivers/media/platform/ti-vpe/vpdma.c +++ b/drivers/media/platform/ti-vpe/vpdma.c @@ -445,23 +445,25 @@ int vpdma_list_cleanup(struct vpdma_data *vpdma, int list_num, ret = vpdma_map_desc_buf(vpdma, &abort_list.buf); if (ret) - return ret; + goto free_desc; ret = vpdma_submit_descs(vpdma, &abort_list, list_num); if (ret) - return ret; + goto unmap_desc; while (vpdma_list_busy(vpdma, list_num) && --timeout) ; if (timeout == 0) { dev_err(&vpdma->pdev->dev, "Timed out cleaning up VPDMA list\n"); - return -EBUSY; + ret = -EBUSY; } +unmap_desc: vpdma_unmap_desc_buf(vpdma, &abort_list.buf); +free_desc: vpdma_free_desc_buf(&abort_list.buf); - return 0; + return ret; } EXPORT_SYMBOL(vpdma_list_cleanup); diff --git a/drivers/media/platform/ti-vpe/vpe.c b/drivers/media/platform/ti-vpe/vpe.c index dda04498ac56..60b575bb44c4 100644 --- a/drivers/media/platform/ti-vpe/vpe.c +++ b/drivers/media/platform/ti-vpe/vpe.c @@ -224,7 +224,6 @@ static const struct vpe_port_data port_data[11] = { /* driver info for each of the supported video formats */ struct vpe_fmt { - char *name; /* human-readable name */ u32 fourcc; /* standard format identifier */ u8 types; /* CAPTURE and/or OUTPUT */ u8 coplanar; /* set for unpacked Luma and Chroma */ @@ -234,7 +233,6 @@ struct vpe_fmt { static struct vpe_fmt vpe_formats[] = { { - .name = "NV16 YUV 422 co-planar", .fourcc = V4L2_PIX_FMT_NV16, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 1, @@ -243,7 +241,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "NV12 YUV 420 co-planar", .fourcc = V4L2_PIX_FMT_NV12, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 1, @@ -252,7 +249,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "YUYV 422 packed", .fourcc = V4L2_PIX_FMT_YUYV, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 0, @@ -260,7 +256,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "UYVY 422 packed", .fourcc = V4L2_PIX_FMT_UYVY, .types = VPE_FMT_TYPE_CAPTURE | VPE_FMT_TYPE_OUTPUT, .coplanar = 0, @@ -268,7 +263,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "RGB888 packed", .fourcc = V4L2_PIX_FMT_RGB24, .types = VPE_FMT_TYPE_CAPTURE, .coplanar = 0, @@ -276,7 +270,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "ARGB32", .fourcc = V4L2_PIX_FMT_RGB32, .types = VPE_FMT_TYPE_CAPTURE, .coplanar = 0, @@ -284,7 +277,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "BGR888 packed", .fourcc = V4L2_PIX_FMT_BGR24, .types = VPE_FMT_TYPE_CAPTURE, .coplanar = 0, @@ -292,7 +284,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "ABGR32", .fourcc = V4L2_PIX_FMT_BGR32, .types = VPE_FMT_TYPE_CAPTURE, .coplanar = 0, @@ -300,7 +291,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "RGB565", .fourcc = V4L2_PIX_FMT_RGB565, .types = VPE_FMT_TYPE_CAPTURE, .coplanar = 0, @@ -308,7 +298,6 @@ static struct vpe_fmt vpe_formats[] = { }, }, { - .name = "RGB5551", .fourcc = V4L2_PIX_FMT_RGB555, .types = VPE_FMT_TYPE_CAPTURE, .coplanar = 0, @@ -1514,7 +1503,6 @@ static int __enum_fmt(struct v4l2_fmtdesc *f, u32 type) if (!fmt) return -EINVAL; - strscpy(f->description, fmt->name, sizeof(f->description)); f->pixelformat = fmt->fourcc; return 0; } diff --git a/drivers/media/platform/ti-vpe/vpe_regs.h b/drivers/media/platform/ti-vpe/vpe_regs.h index 9969bea0dded..1a1ad5ae1228 100644 --- a/drivers/media/platform/ti-vpe/vpe_regs.h +++ b/drivers/media/platform/ti-vpe/vpe_regs.h @@ -48,24 +48,24 @@ #define VPE_INT0_ENABLE0_SET 0x0030 #define VPE_INT0_ENABLE0 VPE_INT0_ENABLE0_SET #define VPE_INT0_ENABLE0_CLR 0x0038 -#define VPE_INT0_LIST0_COMPLETE (1 << 0) -#define VPE_INT0_LIST0_NOTIFY (1 << 1) -#define VPE_INT0_LIST1_COMPLETE (1 << 2) -#define VPE_INT0_LIST1_NOTIFY (1 << 3) -#define VPE_INT0_LIST2_COMPLETE (1 << 4) -#define VPE_INT0_LIST2_NOTIFY (1 << 5) -#define VPE_INT0_LIST3_COMPLETE (1 << 6) -#define VPE_INT0_LIST3_NOTIFY (1 << 7) -#define VPE_INT0_LIST4_COMPLETE (1 << 8) -#define VPE_INT0_LIST4_NOTIFY (1 << 9) -#define VPE_INT0_LIST5_COMPLETE (1 << 10) -#define VPE_INT0_LIST5_NOTIFY (1 << 11) -#define VPE_INT0_LIST6_COMPLETE (1 << 12) -#define VPE_INT0_LIST6_NOTIFY (1 << 13) -#define VPE_INT0_LIST7_COMPLETE (1 << 14) -#define VPE_INT0_LIST7_NOTIFY (1 << 15) -#define VPE_INT0_DESCRIPTOR (1 << 16) -#define VPE_DEI_FMD_INT (1 << 18) +#define VPE_INT0_LIST0_COMPLETE BIT(0) +#define VPE_INT0_LIST0_NOTIFY BIT(1) +#define VPE_INT0_LIST1_COMPLETE BIT(2) +#define VPE_INT0_LIST1_NOTIFY BIT(3) +#define VPE_INT0_LIST2_COMPLETE BIT(4) +#define VPE_INT0_LIST2_NOTIFY BIT(5) +#define VPE_INT0_LIST3_COMPLETE BIT(6) +#define VPE_INT0_LIST3_NOTIFY BIT(7) +#define VPE_INT0_LIST4_COMPLETE BIT(8) +#define VPE_INT0_LIST4_NOTIFY BIT(9) +#define VPE_INT0_LIST5_COMPLETE BIT(10) +#define VPE_INT0_LIST5_NOTIFY BIT(11) +#define VPE_INT0_LIST6_COMPLETE BIT(12) +#define VPE_INT0_LIST6_NOTIFY BIT(13) +#define VPE_INT0_LIST7_COMPLETE BIT(14) +#define VPE_INT0_LIST7_NOTIFY BIT(15) +#define VPE_INT0_DESCRIPTOR BIT(16) +#define VPE_DEI_FMD_INT BIT(18) #define VPE_INT0_STATUS1_RAW_SET 0x0024 #define VPE_INT0_STATUS1_RAW VPE_INT0_STATUS1_RAW_SET @@ -74,21 +74,21 @@ #define VPE_INT0_ENABLE1_SET 0x0034 #define VPE_INT0_ENABLE1 VPE_INT0_ENABLE1_SET #define VPE_INT0_ENABLE1_CLR 0x003c -#define VPE_INT0_CHANNEL_GROUP0 (1 << 0) -#define VPE_INT0_CHANNEL_GROUP1 (1 << 1) -#define VPE_INT0_CHANNEL_GROUP2 (1 << 2) -#define VPE_INT0_CHANNEL_GROUP3 (1 << 3) -#define VPE_INT0_CHANNEL_GROUP4 (1 << 4) -#define VPE_INT0_CHANNEL_GROUP5 (1 << 5) -#define VPE_INT0_CLIENT (1 << 7) -#define VPE_DEI_ERROR_INT (1 << 16) -#define VPE_DS1_UV_ERROR_INT (1 << 22) +#define VPE_INT0_CHANNEL_GROUP0 BIT(0) +#define VPE_INT0_CHANNEL_GROUP1 BIT(1) +#define VPE_INT0_CHANNEL_GROUP2 BIT(2) +#define VPE_INT0_CHANNEL_GROUP3 BIT(3) +#define VPE_INT0_CHANNEL_GROUP4 BIT(4) +#define VPE_INT0_CHANNEL_GROUP5 BIT(5) +#define VPE_INT0_CLIENT BIT(7) +#define VPE_DEI_ERROR_INT BIT(16) +#define VPE_DS1_UV_ERROR_INT BIT(22) #define VPE_INTC_EOI 0x00a0 #define VPE_CLK_ENABLE 0x0100 -#define VPE_VPEDMA_CLK_ENABLE (1 << 0) -#define VPE_DATA_PATH_CLK_ENABLE (1 << 1) +#define VPE_VPEDMA_CLK_ENABLE BIT(0) +#define VPE_DATA_PATH_CLK_ENABLE BIT(1) #define VPE_CLK_RESET 0x0104 #define VPE_VPDMA_CLK_RESET_MASK 0x1 @@ -101,11 +101,11 @@ #define VPE_CLK_FORMAT_SELECT 0x010c #define VPE_CSC_SRC_SELECT_MASK 0x03 #define VPE_CSC_SRC_SELECT_SHIFT 0 -#define VPE_RGB_OUT_SELECT (1 << 8) +#define VPE_RGB_OUT_SELECT BIT(8) #define VPE_DS_SRC_SELECT_MASK 0x07 #define VPE_DS_SRC_SELECT_SHIFT 9 -#define VPE_DS_BYPASS (1 << 16) -#define VPE_COLOR_SEPARATE_422 (1 << 18) +#define VPE_DS_BYPASS BIT(16) +#define VPE_COLOR_SEPARATE_422 BIT(18) #define VPE_DS_SRC_DEI_SCALER (5 << VPE_DS_SRC_SELECT_SHIFT) #define VPE_CSC_SRC_DEI_SCALER (3 << VPE_CSC_SRC_SELECT_SHIFT) @@ -115,8 +115,8 @@ #define VPE_RANGE_RANGE_MAP_Y_SHIFT 0 #define VPE_RANGE_RANGE_MAP_UV_MASK 0x07 #define VPE_RANGE_RANGE_MAP_UV_SHIFT 3 -#define VPE_RANGE_MAP_ON (1 << 6) -#define VPE_RANGE_REDUCTION_ON (1 << 28) +#define VPE_RANGE_MAP_ON BIT(6) +#define VPE_RANGE_REDUCTION_ON BIT(28) /* VPE chrominance upsampler regs */ #define VPE_US1_R0 0x0304 @@ -195,13 +195,13 @@ #define VPE_DEI_WIDTH_SHIFT 0 #define VPE_DEI_HEIGHT_MASK 0x07ff #define VPE_DEI_HEIGHT_SHIFT 16 -#define VPE_DEI_INTERLACE_BYPASS (1 << 29) -#define VPE_DEI_FIELD_FLUSH (1 << 30) -#define VPE_DEI_PROGRESSIVE (1 << 31) +#define VPE_DEI_INTERLACE_BYPASS BIT(29) +#define VPE_DEI_FIELD_FLUSH BIT(30) +#define VPE_DEI_PROGRESSIVE BIT(31) #define VPE_MDT_BYPASS 0x0604 -#define VPE_MDT_TEMPMAX_BYPASS (1 << 0) -#define VPE_MDT_SPATMAX_BYPASS (1 << 1) +#define VPE_MDT_TEMPMAX_BYPASS BIT(0) +#define VPE_MDT_SPATMAX_BYPASS BIT(1) #define VPE_MDT_SF_THRESHOLD 0x0608 #define VPE_MDT_SF_SC_THR1_MASK 0xff @@ -214,8 +214,8 @@ #define VPE_EDI_CONFIG 0x060c #define VPE_EDI_INP_MODE_MASK 0x03 #define VPE_EDI_INP_MODE_SHIFT 0 -#define VPE_EDI_ENABLE_3D (1 << 2) -#define VPE_EDI_ENABLE_CHROMA_3D (1 << 3) +#define VPE_EDI_ENABLE_3D BIT(2) +#define VPE_EDI_ENABLE_CHROMA_3D BIT(3) #define VPE_EDI_CHROMA3D_COR_THR_MASK 0xff #define VPE_EDI_CHROMA3D_COR_THR_SHIFT 8 #define VPE_EDI_DIR_COR_LOWER_THR_MASK 0xff @@ -268,7 +268,7 @@ #define VPE_FMD_WINDOW_MINX_SHIFT 0 #define VPE_FMD_WINDOW_MAXX_MASK 0x07ff #define VPE_FMD_WINDOW_MAXX_SHIFT 16 -#define VPE_FMD_WINDOW_ENABLE (1 << 31) +#define VPE_FMD_WINDOW_ENABLE BIT(31) #define VPE_DEI_FMD_WINDOW_R1 0x0624 #define VPE_FMD_WINDOW_MINY_MASK 0x07ff @@ -277,10 +277,10 @@ #define VPE_FMD_WINDOW_MAXY_SHIFT 16 #define VPE_DEI_FMD_CONTROL_R0 0x0628 -#define VPE_FMD_ENABLE (1 << 0) -#define VPE_FMD_LOCK (1 << 1) -#define VPE_FMD_JAM_DIR (1 << 2) -#define VPE_FMD_BED_ENABLE (1 << 3) +#define VPE_FMD_ENABLE BIT(0) +#define VPE_FMD_LOCK BIT(1) +#define VPE_FMD_JAM_DIR BIT(2) +#define VPE_FMD_BED_ENABLE BIT(3) #define VPE_FMD_CAF_FIELD_THR_MASK 0xff #define VPE_FMD_CAF_FIELD_THR_SHIFT 16 #define VPE_FMD_CAF_LINE_THR_MASK 0xff @@ -293,7 +293,7 @@ #define VPE_DEI_FMD_STATUS_R0 0x0630 #define VPE_FMD_CAF_MASK 0x000fffff #define VPE_FMD_CAF_SHIFT 0 -#define VPE_FMD_RESET (1 << 24) +#define VPE_FMD_RESET BIT(24) #define VPE_DEI_FMD_STATUS_R1 0x0634 #define VPE_FMD_FIELD_DIFF_MASK 0x0fffffff diff --git a/drivers/media/platform/via-camera.c b/drivers/media/platform/via-camera.c index 038de7a2027a..78841b9015ce 100644 --- a/drivers/media/platform/via-camera.c +++ b/drivers/media/platform/via-camera.c @@ -18,9 +18,10 @@ #include <media/v4l2-device.h> #include <media/v4l2-ioctl.h> #include <media/v4l2-ctrls.h> +#include <media/v4l2-event.h> #include <media/v4l2-image-sizes.h> #include <media/i2c/ov7670.h> -#include <media/videobuf-dma-sg.h> +#include <media/videobuf2-dma-sg.h> #include <linux/delay.h> #include <linux/dma-mapping.h> #include <linux/pm_qos.h> @@ -84,16 +85,11 @@ struct via_camera { * live in frame buffer memory, so we don't call them "DMA". */ unsigned int cb_offsets[3]; /* offsets into fb mem */ - u8 __iomem *cb_addrs[3]; /* Kernel-space addresses */ + u8 __iomem *cb_addrs[3]; /* Kernel-space addresses */ int n_cap_bufs; /* How many are we using? */ - int next_buf; - struct videobuf_queue vb_queue; - struct list_head buffer_queue; /* prot. by reg_lock */ - /* - * User tracking. - */ - int users; - struct file *owner; + struct vb2_queue vq; + struct list_head buffer_queue; + u32 sequence; /* * Video format information. sensor_format is kept in a form * that we can use to pass to the sensor. We always run the @@ -106,6 +102,13 @@ struct via_camera { u32 mbus_code; }; +/* buffer for one video frame */ +struct via_buffer { + /* common v4l buffer stuff -- must be first */ + struct vb2_v4l2_buffer vbuf; + struct list_head queue; +}; + /* * Yes, this is a hack, but there's only going to be one of these * on any system we know of. @@ -142,13 +145,11 @@ static struct via_camera *via_cam_info; * now this information must be managed at this level too. */ static struct via_format { - __u8 *desc; __u32 pixelformat; int bpp; /* Bytes per pixel */ u32 mbus_code; } via_formats[] = { { - .desc = "YUYV 4:2:2", .pixelformat = V4L2_PIX_FMT_YUYV, .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, .bpp = 2, @@ -324,28 +325,15 @@ static irqreturn_t viacam_quick_irq(int irq, void *data) } /* - * Find the next videobuf buffer which has somebody waiting on it. + * Find the next buffer which has somebody waiting on it. */ -static struct videobuf_buffer *viacam_next_buffer(struct via_camera *cam) +static struct via_buffer *viacam_next_buffer(struct via_camera *cam) { - unsigned long flags; - struct videobuf_buffer *buf = NULL; - - spin_lock_irqsave(&cam->viadev->reg_lock, flags); if (cam->opstate != S_RUNNING) - goto out; + return NULL; if (list_empty(&cam->buffer_queue)) - goto out; - buf = list_entry(cam->buffer_queue.next, struct videobuf_buffer, queue); - if (!waitqueue_active(&buf->done)) {/* Nobody waiting */ - buf = NULL; - goto out; - } - list_del(&buf->queue); - buf->state = VIDEOBUF_ACTIVE; -out: - spin_unlock_irqrestore(&cam->viadev->reg_lock, flags); - return buf; + return NULL; + return list_entry(cam->buffer_queue.next, struct via_buffer, queue); } /* @@ -353,11 +341,12 @@ out: */ static irqreturn_t viacam_irq(int irq, void *data) { - int bufn; - struct videobuf_buffer *vb; struct via_camera *cam = data; - struct videobuf_dmabuf *vdma; + struct via_buffer *vb; + int bufn; + struct sg_table *sgt; + mutex_lock(&cam->lock); /* * If there is no place to put the data frame, don't bother * with anything else. @@ -375,12 +364,15 @@ static irqreturn_t viacam_irq(int irq, void *data) /* * Copy over the data and let any waiters know. */ - vdma = videobuf_to_dma(vb); - viafb_dma_copy_out_sg(cam->cb_offsets[bufn], vdma->sglist, vdma->sglen); - vb->state = VIDEOBUF_DONE; - vb->size = cam->user_format.sizeimage; - wake_up(&vb->done); + sgt = vb2_dma_sg_plane_desc(&vb->vbuf.vb2_buf, 0); + vb->vbuf.vb2_buf.timestamp = ktime_get_ns(); + viafb_dma_copy_out_sg(cam->cb_offsets[bufn], sgt->sgl, sgt->nents); + vb->vbuf.sequence = cam->sequence++; + vb->vbuf.field = V4L2_FIELD_NONE; + list_del(&vb->queue); + vb2_buffer_done(&vb->vbuf.vb2_buf, VB2_BUF_STATE_DONE); done: + mutex_unlock(&cam->lock); return IRQ_HANDLED; } @@ -556,7 +548,6 @@ static int viacam_config_controller(struct via_camera *cam) static void viacam_start_engine(struct via_camera *cam) { spin_lock_irq(&cam->viadev->reg_lock); - cam->next_buf = 0; viacam_write_reg_mask(cam, VCR_CAPINTC, VCR_CI_ENABLE, VCR_CI_ENABLE); viacam_int_enable(cam); (void) viacam_read_reg(cam, VCR_CAPINTC); /* Force post */ @@ -577,81 +568,117 @@ static void viacam_stop_engine(struct via_camera *cam) /* --------------------------------------------------------------------------*/ -/* Videobuf callback ops */ +/* vb2 callback ops */ -/* - * buffer_setup. The purpose of this one would appear to be to tell - * videobuf how big a single image is. It's also evidently up to us - * to put some sort of limit on the maximum number of buffers allowed. - */ -static int viacam_vb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) +static struct via_buffer *vb2_to_via_buffer(struct vb2_buffer *vb) { - struct via_camera *cam = q->priv_data; + struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); - *size = cam->user_format.sizeimage; - if (*count == 0 || *count > 6) /* Arbitrary number */ - *count = 6; - return 0; + return container_of(vbuf, struct via_buffer, vbuf); } -/* - * Prepare a buffer. - */ -static int viacam_vb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) +static void viacam_vb2_queue(struct vb2_buffer *vb) { - struct via_camera *cam = q->priv_data; - - vb->size = cam->user_format.sizeimage; - vb->width = cam->user_format.width; /* bytesperline???? */ - vb->height = cam->user_format.height; - vb->field = field; - if (vb->state == VIDEOBUF_NEEDS_INIT) { - int ret = videobuf_iolock(q, vb, NULL); - if (ret) - return ret; + struct via_camera *cam = vb2_get_drv_priv(vb->vb2_queue); + struct via_buffer *via = vb2_to_via_buffer(vb); + + list_add_tail(&via->queue, &cam->buffer_queue); +} + +static int viacam_vb2_prepare(struct vb2_buffer *vb) +{ + struct via_camera *cam = vb2_get_drv_priv(vb->vb2_queue); + + if (vb2_plane_size(vb, 0) < cam->user_format.sizeimage) { + cam_dbg(cam, + "Plane size too small (%lu < %u)\n", + vb2_plane_size(vb, 0), + cam->user_format.sizeimage); + return -EINVAL; } - vb->state = VIDEOBUF_PREPARED; + + vb2_set_plane_payload(vb, 0, cam->user_format.sizeimage); + return 0; } -/* - * We've got a buffer to put data into. - * - * FIXME: check for a running engine and valid buffers? - */ -static void viacam_vb_buf_queue(struct videobuf_queue *q, - struct videobuf_buffer *vb) +static int viacam_vb2_queue_setup(struct vb2_queue *vq, + unsigned int *nbufs, + unsigned int *num_planes, unsigned int sizes[], + struct device *alloc_devs[]) { - struct via_camera *cam = q->priv_data; + struct via_camera *cam = vb2_get_drv_priv(vq); + int size = cam->user_format.sizeimage; + if (*num_planes) + return sizes[0] < size ? -EINVAL : 0; + + *num_planes = 1; + sizes[0] = size; + return 0; +} + +static int viacam_vb2_start_streaming(struct vb2_queue *vq, unsigned int count) +{ + struct via_camera *cam = vb2_get_drv_priv(vq); + struct via_buffer *buf, *tmp; + int ret = 0; + + if (cam->opstate != S_IDLE) { + ret = -EBUSY; + goto out; + } + /* + * Configure things if need be. + */ + if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) { + ret = viacam_configure_sensor(cam); + if (ret) + goto out; + ret = viacam_config_controller(cam); + if (ret) + goto out; + } + cam->sequence = 0; /* - * Note that videobuf holds the lock when it calls - * us, so we need not (indeed, cannot) take it here. + * If the CPU goes into C3, the DMA transfer gets corrupted and + * users start filing unsightly bug reports. Put in a "latency" + * requirement which will keep the CPU out of the deeper sleep + * states. */ - vb->state = VIDEOBUF_QUEUED; - list_add_tail(&vb->queue, &cam->buffer_queue); + pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50); + viacam_start_engine(cam); + return 0; +out: + list_for_each_entry_safe(buf, tmp, &cam->buffer_queue, queue) { + list_del(&buf->queue); + vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_QUEUED); + } + return ret; } -/* - * Free a buffer. - */ -static void viacam_vb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) +static void viacam_vb2_stop_streaming(struct vb2_queue *vq) { - struct via_camera *cam = q->priv_data; + struct via_camera *cam = vb2_get_drv_priv(vq); + struct via_buffer *buf, *tmp; - videobuf_dma_unmap(&cam->platdev->dev, videobuf_to_dma(vb)); - videobuf_dma_free(videobuf_to_dma(vb)); - vb->state = VIDEOBUF_NEEDS_INIT; + pm_qos_remove_request(&cam->qos_request); + viacam_stop_engine(cam); + + list_for_each_entry_safe(buf, tmp, &cam->buffer_queue, queue) { + list_del(&buf->queue); + vb2_buffer_done(&buf->vbuf.vb2_buf, VB2_BUF_STATE_ERROR); + } } -static const struct videobuf_queue_ops viacam_vb_ops = { - .buf_setup = viacam_vb_buf_setup, - .buf_prepare = viacam_vb_buf_prepare, - .buf_queue = viacam_vb_buf_queue, - .buf_release = viacam_vb_buf_release, +static const struct vb2_ops viacam_vb2_ops = { + .queue_setup = viacam_vb2_queue_setup, + .buf_queue = viacam_vb2_queue, + .buf_prepare = viacam_vb2_prepare, + .start_streaming = viacam_vb2_start_streaming, + .stop_streaming = viacam_vb2_stop_streaming, + .wait_prepare = vb2_ops_wait_prepare, + .wait_finish = vb2_ops_wait_finish, }; /* --------------------------------------------------------------------------*/ @@ -660,62 +687,43 @@ static const struct videobuf_queue_ops viacam_vb_ops = { static int viacam_open(struct file *filp) { struct via_camera *cam = video_drvdata(filp); + int ret; - filp->private_data = cam; /* * Note the new user. If this is the first one, we'll also * need to power up the sensor. */ mutex_lock(&cam->lock); - if (cam->users == 0) { - int ret = viafb_request_dma(); + ret = v4l2_fh_open(filp); + if (ret) + goto out; + if (v4l2_fh_is_singular_file(filp)) { + ret = viafb_request_dma(); if (ret) { - mutex_unlock(&cam->lock); - return ret; + v4l2_fh_release(filp); + goto out; } via_sensor_power_up(cam); set_bit(CF_CONFIG_NEEDED, &cam->flags); - /* - * Hook into videobuf. Evidently this cannot fail. - */ - videobuf_queue_sg_init(&cam->vb_queue, &viacam_vb_ops, - &cam->platdev->dev, &cam->viadev->reg_lock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, - sizeof(struct videobuf_buffer), cam, NULL); } - (cam->users)++; +out: mutex_unlock(&cam->lock); - return 0; + return ret; } static int viacam_release(struct file *filp) { struct via_camera *cam = video_drvdata(filp); + bool last_open; mutex_lock(&cam->lock); - (cam->users)--; - /* - * If the "owner" is closing, shut down any ongoing - * operations. - */ - if (filp == cam->owner) { - videobuf_stop(&cam->vb_queue); - /* - * We don't hold the spinlock here, but, if release() - * is being called by the owner, nobody else will - * be changing the state. And an extra stop would - * not hurt anyway. - */ - if (cam->opstate != S_IDLE) - viacam_stop_engine(cam); - cam->owner = NULL; - } + last_open = v4l2_fh_is_singular_file(filp); + _vb2_fop_release(filp, NULL); /* * Last one out needs to turn out the lights. */ - if (cam->users == 0) { - videobuf_mmap_free(&cam->vb_queue); + if (last_open) { via_sensor_power_down(cam); viafb_release_dma(); } @@ -723,77 +731,14 @@ static int viacam_release(struct file *filp) return 0; } -/* - * Read a frame from the device. - */ -static ssize_t viacam_read(struct file *filp, char __user *buffer, - size_t len, loff_t *pos) -{ - struct via_camera *cam = video_drvdata(filp); - int ret; - - mutex_lock(&cam->lock); - /* - * Enforce the V4l2 "only one owner gets to read data" rule. - */ - if (cam->owner && cam->owner != filp) { - ret = -EBUSY; - goto out_unlock; - } - cam->owner = filp; - /* - * Do we need to configure the hardware? - */ - if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) { - ret = viacam_configure_sensor(cam); - if (!ret) - ret = viacam_config_controller(cam); - if (ret) - goto out_unlock; - } - /* - * Fire up the capture engine, then have videobuf do - * the heavy lifting. Someday it would be good to avoid - * stopping and restarting the engine each time. - */ - INIT_LIST_HEAD(&cam->buffer_queue); - viacam_start_engine(cam); - ret = videobuf_read_stream(&cam->vb_queue, buffer, len, pos, 0, - filp->f_flags & O_NONBLOCK); - viacam_stop_engine(cam); - /* videobuf_stop() ?? */ - -out_unlock: - mutex_unlock(&cam->lock); - return ret; -} - - -static __poll_t viacam_poll(struct file *filp, struct poll_table_struct *pt) -{ - struct via_camera *cam = video_drvdata(filp); - - return videobuf_poll_stream(filp, &cam->vb_queue, pt); -} - - -static int viacam_mmap(struct file *filp, struct vm_area_struct *vma) -{ - struct via_camera *cam = video_drvdata(filp); - - return videobuf_mmap_mapper(&cam->vb_queue, vma); -} - - - static const struct v4l2_file_operations viacam_fops = { .owner = THIS_MODULE, .open = viacam_open, .release = viacam_release, - .read = viacam_read, - .poll = viacam_poll, - .mmap = viacam_mmap, - .unlocked_ioctl = video_ioctl2, + .read = vb2_fop_read, + .poll = vb2_fop_poll, + .mmap = vb2_fop_mmap, + .unlocked_ioctl = video_ioctl2, }; /*----------------------------------------------------------------------------*/ @@ -811,7 +756,6 @@ static int viacam_enum_input(struct file *filp, void *priv, return -EINVAL; input->type = V4L2_INPUT_TYPE_CAMERA; - input->std = V4L2_STD_ALL; /* Not sure what should go here */ strscpy(input->name, "Camera", sizeof(input->name)); return 0; } @@ -829,17 +773,6 @@ static int viacam_s_input(struct file *filp, void *priv, unsigned int i) return 0; } -static int viacam_s_std(struct file *filp, void *priv, v4l2_std_id std) -{ - return 0; -} - -static int viacam_g_std(struct file *filp, void *priv, v4l2_std_id *std) -{ - *std = V4L2_STD_NTSC_M; - return 0; -} - /* * Video format stuff. Here is our default format until * user space messes with things. @@ -851,6 +784,7 @@ static const struct v4l2_pix_format viacam_def_pix_format = { .field = V4L2_FIELD_NONE, .bytesperline = VGA_WIDTH * 2, .sizeimage = VGA_WIDTH * VGA_HEIGHT * 2, + .colorspace = V4L2_COLORSPACE_SRGB, }; static const u32 via_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8; @@ -860,8 +794,6 @@ static int viacam_enum_fmt_vid_cap(struct file *filp, void *priv, { if (fmt->index >= N_VIA_FMTS) return -EINVAL; - strscpy(fmt->description, via_formats[fmt->index].desc, - sizeof(fmt->description)); fmt->pixelformat = via_formats[fmt->index].pixelformat; return 0; } @@ -897,6 +829,10 @@ static void viacam_fmt_post(struct v4l2_pix_format *userfmt, userfmt->field = sensorfmt->field; userfmt->bytesperline = 2 * userfmt->width; userfmt->sizeimage = userfmt->bytesperline * userfmt->height; + userfmt->colorspace = sensorfmt->colorspace; + userfmt->ycbcr_enc = sensorfmt->ycbcr_enc; + userfmt->quantization = sensorfmt->quantization; + userfmt->xfer_func = sensorfmt->xfer_func; } @@ -927,32 +863,26 @@ static int viacam_do_try_fmt(struct via_camera *cam, static int viacam_try_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { - struct via_camera *cam = priv; + struct via_camera *cam = video_drvdata(filp); struct v4l2_format sfmt; - int ret; - mutex_lock(&cam->lock); - ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); - mutex_unlock(&cam->lock); - return ret; + return viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); } static int viacam_g_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { - struct via_camera *cam = priv; + struct via_camera *cam = video_drvdata(filp); - mutex_lock(&cam->lock); fmt->fmt.pix = cam->user_format; - mutex_unlock(&cam->lock); return 0; } static int viacam_s_fmt_vid_cap(struct file *filp, void *priv, struct v4l2_format *fmt) { - struct via_camera *cam = priv; + struct via_camera *cam = video_drvdata(filp); int ret; struct v4l2_format sfmt; struct via_format *f = via_find_format(fmt->fmt.pix.pixelformat); @@ -961,18 +891,15 @@ static int viacam_s_fmt_vid_cap(struct file *filp, void *priv, * Camera must be idle or we can't mess with the * video setup. */ - mutex_lock(&cam->lock); - if (cam->opstate != S_IDLE) { - ret = -EBUSY; - goto out; - } + if (cam->opstate != S_IDLE) + return -EBUSY; /* * Let the sensor code look over and tweak the * requested formatting. */ ret = viacam_do_try_fmt(cam, &fmt->fmt.pix, &sfmt.fmt.pix); if (ret) - goto out; + return ret; /* * OK, let's commit to the new format. */ @@ -982,8 +909,6 @@ static int viacam_s_fmt_vid_cap(struct file *filp, void *priv, ret = viacam_configure_sensor(cam); if (!ret) ret = viacam_config_controller(cam); -out: - mutex_unlock(&cam->lock); return ret; } @@ -992,155 +917,40 @@ static int viacam_querycap(struct file *filp, void *priv, { strscpy(cap->driver, "via-camera", sizeof(cap->driver)); strscpy(cap->card, "via-camera", sizeof(cap->card)); - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + strscpy(cap->bus_info, "platform:via-camera", sizeof(cap->bus_info)); return 0; } -/* - * Streaming operations - pure videobuf stuff. - */ -static int viacam_reqbufs(struct file *filp, void *priv, - struct v4l2_requestbuffers *rb) -{ - struct via_camera *cam = priv; - - return videobuf_reqbufs(&cam->vb_queue, rb); -} - -static int viacam_querybuf(struct file *filp, void *priv, - struct v4l2_buffer *buf) -{ - struct via_camera *cam = priv; - - return videobuf_querybuf(&cam->vb_queue, buf); -} - -static int viacam_qbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) -{ - struct via_camera *cam = priv; - - return videobuf_qbuf(&cam->vb_queue, buf); -} - -static int viacam_dqbuf(struct file *filp, void *priv, struct v4l2_buffer *buf) -{ - struct via_camera *cam = priv; - - return videobuf_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK); -} - -static int viacam_streamon(struct file *filp, void *priv, enum v4l2_buf_type t) -{ - struct via_camera *cam = priv; - int ret = 0; - - if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - - mutex_lock(&cam->lock); - if (cam->opstate != S_IDLE) { - ret = -EBUSY; - goto out; - } - /* - * Enforce the V4l2 "only one owner gets to read data" rule. - */ - if (cam->owner && cam->owner != filp) { - ret = -EBUSY; - goto out; - } - cam->owner = filp; - /* - * Configure things if need be. - */ - if (test_bit(CF_CONFIG_NEEDED, &cam->flags)) { - ret = viacam_configure_sensor(cam); - if (ret) - goto out; - ret = viacam_config_controller(cam); - if (ret) - goto out; - } - /* - * If the CPU goes into C3, the DMA transfer gets corrupted and - * users start filing unsightly bug reports. Put in a "latency" - * requirement which will keep the CPU out of the deeper sleep - * states. - */ - pm_qos_add_request(&cam->qos_request, PM_QOS_CPU_DMA_LATENCY, 50); - /* - * Fire things up. - */ - INIT_LIST_HEAD(&cam->buffer_queue); - ret = videobuf_streamon(&cam->vb_queue); - if (!ret) - viacam_start_engine(cam); -out: - mutex_unlock(&cam->lock); - return ret; -} - -static int viacam_streamoff(struct file *filp, void *priv, enum v4l2_buf_type t) -{ - struct via_camera *cam = priv; - int ret; - - if (t != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - mutex_lock(&cam->lock); - if (cam->opstate != S_RUNNING) { - ret = -EINVAL; - goto out; - } - pm_qos_remove_request(&cam->qos_request); - viacam_stop_engine(cam); - /* - * Videobuf will recycle all of the outstanding buffers, but - * we should be sure we don't retain any references to - * any of them. - */ - ret = videobuf_streamoff(&cam->vb_queue); - INIT_LIST_HEAD(&cam->buffer_queue); -out: - mutex_unlock(&cam->lock); - return ret; -} - /* G/S_PARM */ static int viacam_g_parm(struct file *filp, void *priv, struct v4l2_streamparm *parm) { - struct via_camera *cam = priv; - int ret; + struct via_camera *cam = video_drvdata(filp); - mutex_lock(&cam->lock); - ret = v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm); - mutex_unlock(&cam->lock); - parm->parm.capture.readbuffers = cam->n_cap_bufs; - return ret; + return v4l2_g_parm_cap(video_devdata(filp), cam->sensor, parm); } static int viacam_s_parm(struct file *filp, void *priv, struct v4l2_streamparm *parm) { - struct via_camera *cam = priv; - int ret; + struct via_camera *cam = video_drvdata(filp); - mutex_lock(&cam->lock); - ret = v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm); - mutex_unlock(&cam->lock); - parm->parm.capture.readbuffers = cam->n_cap_bufs; - return ret; + return v4l2_s_parm_cap(video_devdata(filp), cam->sensor, parm); } static int viacam_enum_framesizes(struct file *filp, void *priv, struct v4l2_frmsizeenum *sizes) { + unsigned int i; + if (sizes->index != 0) return -EINVAL; + for (i = 0; i < N_VIA_FMTS; i++) + if (sizes->pixel_format == via_formats[i].pixelformat) + break; + if (i >= N_VIA_FMTS) + return -EINVAL; sizes->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; sizes->stepwise.min_width = QCIF_WIDTH; sizes->stepwise.min_height = QCIF_HEIGHT; @@ -1153,7 +963,7 @@ static int viacam_enum_framesizes(struct file *filp, void *priv, static int viacam_enum_frameintervals(struct file *filp, void *priv, struct v4l2_frmivalenum *interval) { - struct via_camera *cam = priv; + struct via_camera *cam = video_drvdata(filp); struct v4l2_subdev_frame_interval_enum fie = { .index = interval->index, .code = cam->mbus_code, @@ -1161,11 +971,18 @@ static int viacam_enum_frameintervals(struct file *filp, void *priv, .height = cam->sensor_format.height, .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; + unsigned int i; int ret; - mutex_lock(&cam->lock); + for (i = 0; i < N_VIA_FMTS; i++) + if (interval->pixel_format == via_formats[i].pixelformat) + break; + if (i >= N_VIA_FMTS) + return -EINVAL; + if (interval->width < QCIF_WIDTH || interval->width > VGA_WIDTH || + interval->height < QCIF_HEIGHT || interval->height > VGA_HEIGHT) + return -EINVAL; ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie); - mutex_unlock(&cam->lock); if (ret) return ret; interval->type = V4L2_FRMIVAL_TYPE_DISCRETE; @@ -1173,29 +990,30 @@ static int viacam_enum_frameintervals(struct file *filp, void *priv, return 0; } - - static const struct v4l2_ioctl_ops viacam_ioctl_ops = { .vidioc_enum_input = viacam_enum_input, .vidioc_g_input = viacam_g_input, .vidioc_s_input = viacam_s_input, - .vidioc_s_std = viacam_s_std, - .vidioc_g_std = viacam_g_std, .vidioc_enum_fmt_vid_cap = viacam_enum_fmt_vid_cap, .vidioc_try_fmt_vid_cap = viacam_try_fmt_vid_cap, .vidioc_g_fmt_vid_cap = viacam_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = viacam_s_fmt_vid_cap, .vidioc_querycap = viacam_querycap, - .vidioc_reqbufs = viacam_reqbufs, - .vidioc_querybuf = viacam_querybuf, - .vidioc_qbuf = viacam_qbuf, - .vidioc_dqbuf = viacam_dqbuf, - .vidioc_streamon = viacam_streamon, - .vidioc_streamoff = viacam_streamoff, + .vidioc_reqbufs = vb2_ioctl_reqbufs, + .vidioc_create_bufs = vb2_ioctl_create_bufs, + .vidioc_querybuf = vb2_ioctl_querybuf, + .vidioc_prepare_buf = vb2_ioctl_prepare_buf, + .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, .vidioc_g_parm = viacam_g_parm, .vidioc_s_parm = viacam_s_parm, .vidioc_enum_framesizes = viacam_enum_framesizes, .vidioc_enum_frameintervals = viacam_enum_frameintervals, + .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; /*----------------------------------------------------------------------------*/ @@ -1233,7 +1051,7 @@ static int viacam_resume(void *priv) /* * Make sure the sensor's power state is correct */ - if (cam->users > 0) + if (!list_empty(&cam->vdev.fh_list)) via_sensor_power_up(cam); else via_sensor_power_down(cam); @@ -1267,10 +1085,11 @@ static struct viafb_pm_hooks viacam_pm_hooks = { static const struct video_device viacam_v4l_template = { .name = "via-camera", .minor = -1, - .tvnorms = V4L2_STD_NTSC_M, .fops = &viacam_fops, .ioctl_ops = &viacam_ioctl_ops, .release = video_device_release_empty, /* Check this */ + .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | + V4L2_CAP_STREAMING, }; /* @@ -1317,6 +1136,7 @@ static int viacam_probe(struct platform_device *pdev) int ret; struct i2c_adapter *sensor_adapter; struct viafb_dev *viadev = pdev->dev.platform_data; + struct vb2_queue *vq; struct i2c_board_info ov7670_info = { .type = "ov7670", .addr = 0x42 >> 1, @@ -1360,8 +1180,6 @@ static int viacam_probe(struct platform_device *pdev) via_cam_info = cam; cam->platdev = pdev; cam->viadev = viadev; - cam->users = 0; - cam->owner = NULL; cam->opstate = S_IDLE; cam->user_format = cam->sensor_format = viacam_def_pix_format; mutex_init(&cam->lock); @@ -1422,15 +1240,31 @@ static int viacam_probe(struct platform_device *pdev) viacam_irq, IRQF_SHARED, "via-camera", cam); if (ret) goto out_power_down; + + vq = &cam->vq; + vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; + vq->drv_priv = cam; + vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; + vq->buf_struct_size = sizeof(struct via_buffer); + vq->dev = cam->v4l2_dev.dev; + + vq->ops = &viacam_vb2_ops; + vq->mem_ops = &vb2_dma_sg_memops; + vq->lock = &cam->lock; + + ret = vb2_queue_init(vq); /* * Tell V4l2 that we exist. */ cam->vdev = viacam_v4l_template; cam->vdev.v4l2_dev = &cam->v4l2_dev; + cam->vdev.lock = &cam->lock; + cam->vdev.queue = vq; + video_set_drvdata(&cam->vdev, cam); ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1); if (ret) goto out_irq; - video_set_drvdata(&cam->vdev, cam); #ifdef CONFIG_PM /* @@ -1464,6 +1298,9 @@ static int viacam_remove(struct platform_device *pdev) video_unregister_device(&cam->vdev); v4l2_device_unregister(&cam->v4l2_dev); +#ifdef CONFIG_PM + viafb_pm_unregister(&viacam_pm_hooks); +#endif free_irq(viadev->pdev->irq, cam); via_sensor_power_release(cam); v4l2_ctrl_handler_free(&cam->ctrl_handler); diff --git a/drivers/media/platform/vicodec/codec-v4l2-fwht.c b/drivers/media/platform/vicodec/codec-v4l2-fwht.c index 01e7f09efc4e..3c93d9232c3c 100644 --- a/drivers/media/platform/vicodec/codec-v4l2-fwht.c +++ b/drivers/media/platform/vicodec/codec-v4l2-fwht.c @@ -29,11 +29,15 @@ static const struct v4l2_fwht_pixfmt_info v4l2_fwht_pixfmts[] = { { V4L2_PIX_FMT_HSV24, 3, 3, 1, 3, 3, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, { V4L2_PIX_FMT_BGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_XBGR32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_RGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, { V4L2_PIX_FMT_XRGB32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, { V4L2_PIX_FMT_ARGB32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, - { V4L2_PIX_FMT_ABGR32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_BGRX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_BGRA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_RGBX32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_RGBA32, 4, 4, 1, 4, 4, 1, 1, 4, 1, FWHT_FL_PIXENC_RGB}, + { V4L2_PIX_FMT_HSV32, 4, 4, 1, 4, 4, 1, 1, 3, 1, FWHT_FL_PIXENC_HSV}, { V4L2_PIX_FMT_GREY, 1, 1, 1, 1, 0, 1, 1, 1, 1, FWHT_FL_PIXENC_RGB}, }; @@ -193,6 +197,28 @@ static int prepare_raw_frame(struct fwht_raw_frame *rf, rf->luma++; rf->alpha = rf->cr + 1; break; + case V4L2_PIX_FMT_BGRX32: + rf->cb = rf->luma + 1; + rf->cr = rf->cb + 2; + rf->luma += 2; + break; + case V4L2_PIX_FMT_BGRA32: + rf->alpha = rf->luma; + rf->cb = rf->luma + 1; + rf->cr = rf->cb + 2; + rf->luma += 2; + break; + case V4L2_PIX_FMT_RGBX32: + rf->cr = rf->luma; + rf->cb = rf->cr + 2; + rf->luma++; + break; + case V4L2_PIX_FMT_RGBA32: + rf->alpha = rf->luma + 3; + rf->cr = rf->luma; + rf->cb = rf->cr + 2; + rf->luma++; + break; default: return -EINVAL; } diff --git a/drivers/media/platform/vicodec/vicodec-core.c b/drivers/media/platform/vicodec/vicodec-core.c index 7e7c1e80f29f..0ee143ae0f6b 100644 --- a/drivers/media/platform/vicodec/vicodec-core.c +++ b/drivers/media/platform/vicodec/vicodec-core.c @@ -742,6 +742,9 @@ static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx, return -EINVAL; f->pixelformat = ctx->is_stateless ? V4L2_PIX_FMT_FWHT_STATELESS : V4L2_PIX_FMT_FWHT; + if (!ctx->is_enc && !ctx->is_stateless) + f->flags = V4L2_FMT_FLAG_DYN_RESOLUTION | + V4L2_FMT_FLAG_CONTINUOUS_BYTESTREAM; } return 0; } @@ -1661,19 +1664,22 @@ static int vicodec_start_streaming(struct vb2_queue *q, kvfree(state->compressed_frame); state->compressed_frame = new_comp_frame; - if (info->components_num >= 3) { - state->ref_frame.cb = state->ref_frame.luma + size; - state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; - } else { + if (info->components_num < 3) { state->ref_frame.cb = NULL; state->ref_frame.cr = NULL; + state->ref_frame.alpha = NULL; + return 0; } + state->ref_frame.cb = state->ref_frame.luma + size; + state->ref_frame.cr = state->ref_frame.cb + size / chroma_div; + if (info->components_num == 4) state->ref_frame.alpha = state->ref_frame.cr + size / chroma_div; else state->ref_frame.alpha = NULL; + return 0; } diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c index 664855708fdf..1d56b91830ba 100644 --- a/drivers/media/platform/vimc/vimc-capture.c +++ b/drivers/media/platform/vimc/vimc-capture.c @@ -18,32 +18,6 @@ #define VIMC_CAP_DRV_NAME "vimc-capture" -static const u32 vimc_cap_supported_pixfmt[] = { - V4L2_PIX_FMT_BGR24, - V4L2_PIX_FMT_RGB24, - V4L2_PIX_FMT_ARGB32, - V4L2_PIX_FMT_SBGGR8, - V4L2_PIX_FMT_SGBRG8, - V4L2_PIX_FMT_SGRBG8, - V4L2_PIX_FMT_SRGGB8, - V4L2_PIX_FMT_SBGGR10, - V4L2_PIX_FMT_SGBRG10, - V4L2_PIX_FMT_SGRBG10, - V4L2_PIX_FMT_SRGGB10, - V4L2_PIX_FMT_SBGGR10ALAW8, - V4L2_PIX_FMT_SGBRG10ALAW8, - V4L2_PIX_FMT_SGRBG10ALAW8, - V4L2_PIX_FMT_SRGGB10ALAW8, - V4L2_PIX_FMT_SBGGR10DPCM8, - V4L2_PIX_FMT_SGBRG10DPCM8, - V4L2_PIX_FMT_SGRBG10DPCM8, - V4L2_PIX_FMT_SRGGB10DPCM8, - V4L2_PIX_FMT_SBGGR12, - V4L2_PIX_FMT_SGBRG12, - V4L2_PIX_FMT_SGRBG12, - V4L2_PIX_FMT_SRGGB12, -}; - struct vimc_cap_device { struct vimc_ent_device ved; struct video_device vdev; @@ -117,25 +91,29 @@ static int vimc_cap_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct v4l2_pix_format *format = &f->fmt.pix; + const struct vimc_pix_map *vpix; format->width = clamp_t(u32, format->width, VIMC_FRAME_MIN_WIDTH, VIMC_FRAME_MAX_WIDTH) & ~1; format->height = clamp_t(u32, format->height, VIMC_FRAME_MIN_HEIGHT, VIMC_FRAME_MAX_HEIGHT) & ~1; - vimc_colorimetry_clamp(format); + /* Don't accept a pixelformat that is not on the table */ + vpix = vimc_pix_map_by_pixelformat(format->pixelformat); + if (!vpix) { + format->pixelformat = fmt_default.pixelformat; + vpix = vimc_pix_map_by_pixelformat(format->pixelformat); + } + /* TODO: Add support for custom bytesperline values */ + format->bytesperline = format->width * vpix->bpp; + format->sizeimage = format->bytesperline * format->height; if (format->field == V4L2_FIELD_ANY) format->field = fmt_default.field; - /* TODO: Add support for custom bytesperline values */ - - /* Don't accept a pixelformat that is not on the table */ - if (!v4l2_format_info(format->pixelformat)) - format->pixelformat = fmt_default.pixelformat; + vimc_colorimetry_clamp(format); - return v4l2_fill_pixfmt(format, format->pixelformat, - format->width, format->height); + return 0; } static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, @@ -174,31 +152,27 @@ static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv, static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - if (f->index >= ARRAY_SIZE(vimc_cap_supported_pixfmt)) + const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index); + + if (!vpix) return -EINVAL; - f->pixelformat = vimc_cap_supported_pixfmt[f->index]; + f->pixelformat = vpix->pixelformat; return 0; } -static bool vimc_cap_is_pixfmt_supported(u32 pixelformat) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(vimc_cap_supported_pixfmt); i++) - if (vimc_cap_supported_pixfmt[i] == pixelformat) - return true; - return false; -} - static int vimc_cap_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { + const struct vimc_pix_map *vpix; + if (fsize->index) return -EINVAL; - if (!vimc_cap_is_pixfmt_supported(fsize->pixel_format)) + /* Only accept code in the pix map table */ + vpix = vimc_pix_map_by_code(fsize->pixel_format); + if (!vpix) return -EINVAL; fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; @@ -272,7 +246,6 @@ static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count) return ret; } - vcap->stream.producer_pixfmt = vcap->format.pixelformat; ret = vimc_streamer_s_stream(&vcap->stream, &vcap->ved, 1); if (ret) { media_pipeline_stop(entity); @@ -423,6 +396,7 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, { struct v4l2_device *v4l2_dev = master_data; struct vimc_platform_data *pdata = comp->platform_data; + const struct vimc_pix_map *vpix; struct vimc_cap_device *vcap; struct video_device *vdev; struct vb2_queue *q; @@ -477,8 +451,10 @@ static int vimc_cap_comp_bind(struct device *comp, struct device *master, /* Set default frame format */ vcap->format = fmt_default; - v4l2_fill_pixfmt(&vcap->format, vcap->format.pixelformat, - vcap->format.width, vcap->format.height); + vpix = vimc_pix_map_by_pixelformat(vcap->format.pixelformat); + vcap->format.bytesperline = vcap->format.width * vpix->bpp; + vcap->format.sizeimage = vcap->format.bytesperline * + vcap->format.height; /* Fill the vimc_ent_device struct */ vcap->ved.ent = &vcap->vdev.entity; diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c index 03016f204d05..7e1ae0b12f1e 100644 --- a/drivers/media/platform/vimc/vimc-common.c +++ b/drivers/media/platform/vimc/vimc-common.c @@ -10,139 +10,192 @@ #include "vimc-common.h" -static const __u32 vimc_mbus_list[] = { - MEDIA_BUS_FMT_FIXED, - MEDIA_BUS_FMT_RGB444_1X12, - MEDIA_BUS_FMT_RGB444_2X8_PADHI_BE, - MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE, - MEDIA_BUS_FMT_RGB555_2X8_PADHI_BE, - MEDIA_BUS_FMT_RGB555_2X8_PADHI_LE, - MEDIA_BUS_FMT_RGB565_1X16, - MEDIA_BUS_FMT_BGR565_2X8_BE, - MEDIA_BUS_FMT_BGR565_2X8_LE, - MEDIA_BUS_FMT_RGB565_2X8_BE, - MEDIA_BUS_FMT_RGB565_2X8_LE, - MEDIA_BUS_FMT_RGB666_1X18, - MEDIA_BUS_FMT_RBG888_1X24, - MEDIA_BUS_FMT_RGB666_1X24_CPADHI, - MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, - MEDIA_BUS_FMT_BGR888_1X24, - MEDIA_BUS_FMT_GBR888_1X24, - MEDIA_BUS_FMT_RGB888_1X24, - MEDIA_BUS_FMT_RGB888_2X12_BE, - MEDIA_BUS_FMT_RGB888_2X12_LE, - MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, - MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, - MEDIA_BUS_FMT_ARGB8888_1X32, - MEDIA_BUS_FMT_RGB888_1X32_PADHI, - MEDIA_BUS_FMT_RGB101010_1X30, - MEDIA_BUS_FMT_RGB121212_1X36, - MEDIA_BUS_FMT_RGB161616_1X48, - MEDIA_BUS_FMT_Y8_1X8, - MEDIA_BUS_FMT_UV8_1X8, - MEDIA_BUS_FMT_UYVY8_1_5X8, - MEDIA_BUS_FMT_VYUY8_1_5X8, - MEDIA_BUS_FMT_YUYV8_1_5X8, - MEDIA_BUS_FMT_YVYU8_1_5X8, - MEDIA_BUS_FMT_UYVY8_2X8, - MEDIA_BUS_FMT_VYUY8_2X8, - MEDIA_BUS_FMT_YUYV8_2X8, - MEDIA_BUS_FMT_YVYU8_2X8, - MEDIA_BUS_FMT_Y10_1X10, - MEDIA_BUS_FMT_Y10_2X8_PADHI_LE, - MEDIA_BUS_FMT_UYVY10_2X10, - MEDIA_BUS_FMT_VYUY10_2X10, - MEDIA_BUS_FMT_YUYV10_2X10, - MEDIA_BUS_FMT_YVYU10_2X10, - MEDIA_BUS_FMT_Y12_1X12, - MEDIA_BUS_FMT_UYVY12_2X12, - MEDIA_BUS_FMT_VYUY12_2X12, - MEDIA_BUS_FMT_YUYV12_2X12, - MEDIA_BUS_FMT_YVYU12_2X12, - MEDIA_BUS_FMT_UYVY8_1X16, - MEDIA_BUS_FMT_VYUY8_1X16, - MEDIA_BUS_FMT_YUYV8_1X16, - MEDIA_BUS_FMT_YVYU8_1X16, - MEDIA_BUS_FMT_YDYUYDYV8_1X16, - MEDIA_BUS_FMT_UYVY10_1X20, - MEDIA_BUS_FMT_VYUY10_1X20, - MEDIA_BUS_FMT_YUYV10_1X20, - MEDIA_BUS_FMT_YVYU10_1X20, - MEDIA_BUS_FMT_VUY8_1X24, - MEDIA_BUS_FMT_YUV8_1X24, - MEDIA_BUS_FMT_UYYVYY8_0_5X24, - MEDIA_BUS_FMT_UYVY12_1X24, - MEDIA_BUS_FMT_VYUY12_1X24, - MEDIA_BUS_FMT_YUYV12_1X24, - MEDIA_BUS_FMT_YVYU12_1X24, - MEDIA_BUS_FMT_YUV10_1X30, - MEDIA_BUS_FMT_UYYVYY10_0_5X30, - MEDIA_BUS_FMT_AYUV8_1X32, - MEDIA_BUS_FMT_UYYVYY12_0_5X36, - MEDIA_BUS_FMT_YUV12_1X36, - MEDIA_BUS_FMT_YUV16_1X48, - MEDIA_BUS_FMT_UYYVYY16_0_5X48, - MEDIA_BUS_FMT_SBGGR8_1X8, - MEDIA_BUS_FMT_SGBRG8_1X8, - MEDIA_BUS_FMT_SGRBG8_1X8, - MEDIA_BUS_FMT_SRGGB8_1X8, - MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, - MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, - MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, - MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, - MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, - MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, - MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, - MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_BE, - MEDIA_BUS_FMT_SBGGR10_2X8_PADHI_LE, - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_BE, - MEDIA_BUS_FMT_SBGGR10_2X8_PADLO_LE, - MEDIA_BUS_FMT_SBGGR10_1X10, - MEDIA_BUS_FMT_SGBRG10_1X10, - MEDIA_BUS_FMT_SGRBG10_1X10, - MEDIA_BUS_FMT_SRGGB10_1X10, - MEDIA_BUS_FMT_SBGGR12_1X12, - MEDIA_BUS_FMT_SGBRG12_1X12, - MEDIA_BUS_FMT_SGRBG12_1X12, - MEDIA_BUS_FMT_SRGGB12_1X12, - MEDIA_BUS_FMT_SBGGR14_1X14, - MEDIA_BUS_FMT_SGBRG14_1X14, - MEDIA_BUS_FMT_SGRBG14_1X14, - MEDIA_BUS_FMT_SRGGB14_1X14, - MEDIA_BUS_FMT_SBGGR16_1X16, - MEDIA_BUS_FMT_SGBRG16_1X16, - MEDIA_BUS_FMT_SGRBG16_1X16, - MEDIA_BUS_FMT_SRGGB16_1X16, - MEDIA_BUS_FMT_JPEG_1X8, - MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8, - MEDIA_BUS_FMT_AHSV8888_1X32, +/* + * NOTE: non-bayer formats need to come first (necessary for enum_mbus_code + * in the scaler) + */ +static const struct vimc_pix_map vimc_pix_map_list[] = { + /* TODO: add all missing formats */ + + /* RGB formats */ + { + .code = MEDIA_BUS_FMT_BGR888_1X24, + .pixelformat = V4L2_PIX_FMT_BGR24, + .bpp = 3, + .bayer = false, + }, + { + .code = MEDIA_BUS_FMT_RGB888_1X24, + .pixelformat = V4L2_PIX_FMT_RGB24, + .bpp = 3, + .bayer = false, + }, + { + .code = MEDIA_BUS_FMT_ARGB8888_1X32, + .pixelformat = V4L2_PIX_FMT_ARGB32, + .bpp = 4, + .bayer = false, + }, + + /* Bayer formats */ + { + .code = MEDIA_BUS_FMT_SBGGR8_1X8, + .pixelformat = V4L2_PIX_FMT_SBGGR8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGBRG8_1X8, + .pixelformat = V4L2_PIX_FMT_SGBRG8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGRBG8_1X8, + .pixelformat = V4L2_PIX_FMT_SGRBG8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SRGGB8_1X8, + .pixelformat = V4L2_PIX_FMT_SRGGB8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SBGGR10_1X10, + .pixelformat = V4L2_PIX_FMT_SBGGR10, + .bpp = 2, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGBRG10_1X10, + .pixelformat = V4L2_PIX_FMT_SGBRG10, + .bpp = 2, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .pixelformat = V4L2_PIX_FMT_SGRBG10, + .bpp = 2, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SRGGB10_1X10, + .pixelformat = V4L2_PIX_FMT_SRGGB10, + .bpp = 2, + .bayer = true, + }, + + /* 10bit raw bayer a-law compressed to 8 bits */ + { + .code = MEDIA_BUS_FMT_SBGGR10_ALAW8_1X8, + .pixelformat = V4L2_PIX_FMT_SBGGR10ALAW8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGBRG10_ALAW8_1X8, + .pixelformat = V4L2_PIX_FMT_SGBRG10ALAW8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGRBG10_ALAW8_1X8, + .pixelformat = V4L2_PIX_FMT_SGRBG10ALAW8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SRGGB10_ALAW8_1X8, + .pixelformat = V4L2_PIX_FMT_SRGGB10ALAW8, + .bpp = 1, + .bayer = true, + }, + + /* 10bit raw bayer DPCM compressed to 8 bits */ + { + .code = MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8, + .pixelformat = V4L2_PIX_FMT_SBGGR10DPCM8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8, + .pixelformat = V4L2_PIX_FMT_SGBRG10DPCM8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8, + .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8, + .pixelformat = V4L2_PIX_FMT_SRGGB10DPCM8, + .bpp = 1, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SBGGR12_1X12, + .pixelformat = V4L2_PIX_FMT_SBGGR12, + .bpp = 2, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGBRG12_1X12, + .pixelformat = V4L2_PIX_FMT_SGBRG12, + .bpp = 2, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SGRBG12_1X12, + .pixelformat = V4L2_PIX_FMT_SGRBG12, + .bpp = 2, + .bayer = true, + }, + { + .code = MEDIA_BUS_FMT_SRGGB12_1X12, + .pixelformat = V4L2_PIX_FMT_SRGGB12, + .bpp = 2, + .bayer = true, + }, }; -/* Helper function to check mbus codes */ -bool vimc_mbus_code_supported(__u32 code) +const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i) +{ + if (i >= ARRAY_SIZE(vimc_pix_map_list)) + return NULL; + + return &vimc_pix_map_list[i]; +} +EXPORT_SYMBOL_GPL(vimc_pix_map_by_index); + +const struct vimc_pix_map *vimc_pix_map_by_code(u32 code) { unsigned int i; - for (i = 0; i < ARRAY_SIZE(vimc_mbus_list); i++) - if (code == vimc_mbus_list[i]) - return true; - return false; + for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { + if (vimc_pix_map_list[i].code == code) + return &vimc_pix_map_list[i]; + } + return NULL; } -EXPORT_SYMBOL_GPL(vimc_mbus_code_supported); +EXPORT_SYMBOL_GPL(vimc_pix_map_by_code); -/* Helper function to enumerate mbus codes */ -int vimc_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code) +const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat) { - if (code->index >= ARRAY_SIZE(vimc_mbus_list)) - return -EINVAL; + unsigned int i; - code->code = vimc_mbus_list[code->index]; - return 0; + for (i = 0; i < ARRAY_SIZE(vimc_pix_map_list); i++) { + if (vimc_pix_map_list[i].pixelformat == pixelformat) + return &vimc_pix_map_list[i]; + } + return NULL; } -EXPORT_SYMBOL_GPL(vimc_enum_mbus_code); +EXPORT_SYMBOL_GPL(vimc_pix_map_by_pixelformat); /* Helper function to allocate and initialize pads */ struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag) @@ -214,13 +267,15 @@ static int vimc_get_mbus_format(struct media_pad *pad, struct video_device, entity); struct vimc_ent_device *ved = video_get_drvdata(vdev); + const struct vimc_pix_map *vpix; struct v4l2_pix_format vdev_fmt; if (!ved->vdev_get_format) return -ENOIOCTLCMD; ved->vdev_get_format(ved, &vdev_fmt); - v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, 0); + vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat); + v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code); } else { return -EINVAL; } @@ -260,12 +315,8 @@ int vimc_link_validate(struct media_link *link) /* The width, height and code must match. */ if (source_fmt.format.width != sink_fmt.format.width || source_fmt.format.height != sink_fmt.format.height - || (source_fmt.format.code && sink_fmt.format.code && - source_fmt.format.code != sink_fmt.format.code)) { - pr_err("vimc: format doesn't match in link %s->%s\n", - link->source->entity->name, link->sink->entity->name); + || source_fmt.format.code != sink_fmt.format.code) return -EPIPE; - } /* * The field order must match, or the sink field order must be NONE diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h index 7b4d988b208b..9c2e0e216c6b 100644 --- a/drivers/media/platform/vimc/vimc-common.h +++ b/drivers/media/platform/vimc/vimc-common.h @@ -12,8 +12,6 @@ #include <media/media-device.h> #include <media/v4l2-device.h> -#include "vimc-streamer.h" - #define VIMC_PDEV_NAME "vimc" /* VIMC-specific controls */ @@ -70,6 +68,23 @@ struct vimc_platform_data { }; /** + * struct vimc_pix_map - maps media bus code with v4l2 pixel format + * + * @code: media bus format code defined by MEDIA_BUS_FMT_* macros + * @bbp: number of bytes each pixel occupies + * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros + * + * Struct which matches the MEDIA_BUS_FMT_* codes with the corresponding + * V4L2_PIX_FMT_* fourcc pixelformat and its bytes per pixel (bpp) + */ +struct vimc_pix_map { + unsigned int code; + unsigned int bpp; + u32 pixelformat; + bool bayer; +}; + +/** * struct vimc_ent_device - core struct that represents a node in the topology * * @ent: the pointer to struct media_entity for the node @@ -90,7 +105,6 @@ struct vimc_platform_data { struct vimc_ent_device { struct media_entity *ent; struct media_pad *pads; - struct vimc_stream *stream; void * (*process_frame)(struct vimc_ent_device *ved, const void *frame); void (*vdev_get_format)(struct vimc_ent_device *ved, @@ -98,23 +112,6 @@ struct vimc_ent_device { }; /** - * vimc_mbus_code_supported - helper to check supported mbus codes - * - * Helper function to check if mbus code is enumerated by vimc_enum_mbus_code() - */ -bool vimc_mbus_code_supported(__u32 code); - -/** - * vimc_enum_mbus_code - enumerate mbus codes - * - * Helper function to be pluged in .enum_mbus_code from - * struct v4l2_subdev_pad_ops. - */ -int vimc_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_pad_config *cfg, - struct v4l2_subdev_mbus_code_enum *code); - -/** * vimc_pads_init - initialize pads * * @num_pads: number of pads to initialize @@ -149,6 +146,27 @@ static inline void vimc_pads_cleanup(struct media_pad *pads) int vimc_pipeline_s_stream(struct media_entity *ent, int enable); /** + * vimc_pix_map_by_index - get vimc_pix_map struct by its index + * + * @i: index of the vimc_pix_map struct in vimc_pix_map_list + */ +const struct vimc_pix_map *vimc_pix_map_by_index(unsigned int i); + +/** + * vimc_pix_map_by_code - get vimc_pix_map struct by media bus code + * + * @code: media bus format code defined by MEDIA_BUS_FMT_* macros + */ +const struct vimc_pix_map *vimc_pix_map_by_code(u32 code); + +/** + * vimc_pix_map_by_pixelformat - get vimc_pix_map struct by v4l2 pixel format + * + * @pixelformat: pixel format devined by V4L2_PIX_FMT_* macros + */ +const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat); + +/** * vimc_ent_sd_register - initialize and register a subdev node * * @ved: the vimc_ent_device struct to be initialize diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c index 00598fbf3cba..b72b8385067b 100644 --- a/drivers/media/platform/vimc/vimc-debayer.c +++ b/drivers/media/platform/vimc/vimc-debayer.c @@ -16,11 +16,6 @@ #include "vimc-common.h" #define VIMC_DEB_DRV_NAME "vimc-debayer" -/* This module only supports transforming a bayer format - * to V4L2_PIX_FMT_RGB24 - */ -#define VIMC_DEB_SRC_PIXFMT V4L2_PIX_FMT_RGB24 -#define VIMC_DEB_SRC_MBUS_FMT_DEFAULT MEDIA_BUS_FMT_RGB888_1X24 static unsigned int deb_mean_win_size = 3; module_param(deb_mean_win_size, uint, 0000); @@ -39,7 +34,6 @@ enum vimc_deb_rgb_colors { }; struct vimc_deb_pix_map { - u32 pixelformat; u32 code; enum vimc_deb_rgb_colors order[2][2]; }; @@ -69,73 +63,61 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = { static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = { { - .pixelformat = V4L2_PIX_FMT_SBGGR8, .code = MEDIA_BUS_FMT_SBGGR8_1X8, .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, { VIMC_DEB_GREEN, VIMC_DEB_RED } } }, { - .pixelformat = V4L2_PIX_FMT_SGBRG8, .code = MEDIA_BUS_FMT_SGBRG8_1X8, .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, { VIMC_DEB_RED, VIMC_DEB_GREEN } } }, { - .pixelformat = V4L2_PIX_FMT_SGRBG8, .code = MEDIA_BUS_FMT_SGRBG8_1X8, .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } }, { - .pixelformat = V4L2_PIX_FMT_SRGGB8, .code = MEDIA_BUS_FMT_SRGGB8_1X8, .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } }, { - .pixelformat = V4L2_PIX_FMT_SBGGR10, .code = MEDIA_BUS_FMT_SBGGR10_1X10, .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, { VIMC_DEB_GREEN, VIMC_DEB_RED } } }, { - .pixelformat = V4L2_PIX_FMT_SGBRG10, .code = MEDIA_BUS_FMT_SGBRG10_1X10, .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, { VIMC_DEB_RED, VIMC_DEB_GREEN } } }, { - .pixelformat = V4L2_PIX_FMT_SGRBG10, .code = MEDIA_BUS_FMT_SGRBG10_1X10, .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } }, { - .pixelformat = V4L2_PIX_FMT_SRGGB10, .code = MEDIA_BUS_FMT_SRGGB10_1X10, .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } }, { - .pixelformat = V4L2_PIX_FMT_SBGGR12, .code = MEDIA_BUS_FMT_SBGGR12_1X12, .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN }, { VIMC_DEB_GREEN, VIMC_DEB_RED } } }, { - .pixelformat = V4L2_PIX_FMT_SGBRG12, .code = MEDIA_BUS_FMT_SGBRG12_1X12, .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE }, { VIMC_DEB_RED, VIMC_DEB_GREEN } } }, { - .pixelformat = V4L2_PIX_FMT_SGRBG12, .code = MEDIA_BUS_FMT_SGRBG12_1X12, .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED }, { VIMC_DEB_BLUE, VIMC_DEB_GREEN } } }, { - .pixelformat = V4L2_PIX_FMT_SRGGB12, .code = MEDIA_BUS_FMT_SRGGB12_1X12, .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN }, { VIMC_DEB_GREEN, VIMC_DEB_BLUE } } @@ -176,32 +158,41 @@ static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_mbus_code_enum *code) { - /* For the sink pad we only support codes in the map_list */ - if (IS_SINK(code->pad)) { + /* We only support one format for source pads */ + if (IS_SRC(code->pad)) { + struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); + + if (code->index) + return -EINVAL; + + code->code = vdeb->src_code; + } else { if (code->index >= ARRAY_SIZE(vimc_deb_pix_map_list)) return -EINVAL; code->code = vimc_deb_pix_map_list[code->index].code; - return 0; } - return vimc_enum_mbus_code(sd, cfg, code); + return 0; } static int vimc_deb_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { + struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); + if (fse->index) return -EINVAL; - /* For the sink pad we only support codes in the map_list */ if (IS_SINK(fse->pad)) { const struct vimc_deb_pix_map *vpix = vimc_deb_pix_map_by_code(fse->code); if (!vpix) return -EINVAL; + } else if (fse->code != vdeb->src_code) { + return -EINVAL; } fse->min_width = VIMC_FRAME_MIN_WIDTH; @@ -257,12 +248,9 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd, struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *sink_fmt; - if (!vimc_mbus_code_supported(fmt->format.code)) - fmt->format.code = sink_fmt_default.code; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { /* Do not change the format while stream is on */ - if (vdeb->ved.stream) + if (vdeb->src_frame) return -EBUSY; sink_fmt = &vdeb->sink_fmt; @@ -272,11 +260,11 @@ static int vimc_deb_set_fmt(struct v4l2_subdev *sd, /* * Do not change the format of the source pad, - * it is propagated from the sink (except for the code) + * it is propagated from the sink */ if (IS_SRC(fmt->pad)) { - vdeb->src_code = fmt->format.code; fmt->format = *sink_fmt; + /* TODO: Add support for other formats */ fmt->format.code = vdeb->src_code; } else { /* Set the new format in the sink pad */ @@ -308,7 +296,7 @@ static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = { .set_fmt = vimc_deb_set_fmt, }; -static void vimc_deb_set_rgb_pix_rgb24(struct vimc_deb_device *vdeb, +static void vimc_deb_set_rgb_mbus_fmt_rgb888_1x24(struct vimc_deb_device *vdeb, unsigned int lin, unsigned int col, unsigned int rgb[3]) @@ -325,35 +313,25 @@ static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable) struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd); if (enable) { - u32 src_pixelformat = vdeb->ved.stream->producer_pixfmt; - const struct v4l2_format_info *pix_info; + const struct vimc_pix_map *vpix; unsigned int frame_size; - /* We only support translating bayer to RGB24 */ - if (src_pixelformat != V4L2_PIX_FMT_RGB24) { - dev_err(vdeb->dev, - "translating to pixfmt (0x%08x) is not supported\n", - src_pixelformat); - return -EINVAL; - } + if (vdeb->src_frame) + return 0; + + /* Calculate the frame size of the source pad */ + vpix = vimc_pix_map_by_code(vdeb->src_code); + frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height * + vpix->bpp; + + /* Save the bytes per pixel of the sink */ + vpix = vimc_pix_map_by_code(vdeb->sink_fmt.code); + vdeb->sink_bpp = vpix->bpp; /* Get the corresponding pixel map from the table */ vdeb->sink_pix_map = vimc_deb_pix_map_by_code(vdeb->sink_fmt.code); - /* Request bayer format from the pipeline for the sink pad */ - vdeb->ved.stream->producer_pixfmt = - vdeb->sink_pix_map->pixelformat; - - /* Calculate frame_size of the source */ - pix_info = v4l2_format_info(src_pixelformat); - frame_size = vdeb->sink_fmt.width * vdeb->sink_fmt.height * - pix_info->bpp[0]; - - /* Get bpp from the sink */ - pix_info = v4l2_format_info(vdeb->sink_pix_map->pixelformat); - vdeb->sink_bpp = pix_info->bpp[0]; - /* * Allocate the frame buffer. Use vmalloc to be able to * allocate a large amount of memory @@ -554,14 +532,14 @@ static int vimc_deb_comp_bind(struct device *comp, struct device *master, /* Initialize the frame format */ vdeb->sink_fmt = sink_fmt_default; - vdeb->src_code = VIMC_DEB_SRC_MBUS_FMT_DEFAULT; /* * TODO: Add support for more output formats, we only support - * RGB24 for now. + * RGB888 for now * NOTE: the src format is always the same as the sink, except * for the code */ - vdeb->set_rgb_src = vimc_deb_set_rgb_pix_rgb24; + vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24; + vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24; return 0; } diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c index c7123a45c55b..49ab8d9dd9c9 100644 --- a/drivers/media/platform/vimc/vimc-scaler.c +++ b/drivers/media/platform/vimc/vimc-scaler.c @@ -25,12 +25,6 @@ MODULE_PARM_DESC(sca_mult, " the image size multiplier"); #define IS_SRC(pad) (pad) #define MAX_ZOOM 8 -static const u32 vimc_sca_supported_pixfmt[] = { - V4L2_PIX_FMT_BGR24, - V4L2_PIX_FMT_RGB24, - V4L2_PIX_FMT_ARGB32, -}; - struct vimc_sca_device { struct vimc_ent_device ved; struct v4l2_subdev sd; @@ -53,16 +47,6 @@ static const struct v4l2_mbus_framefmt sink_fmt_default = { .colorspace = V4L2_COLORSPACE_DEFAULT, }; -static bool vimc_sca_is_pixfmt_supported(u32 pixelformat) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(vimc_sca_supported_pixfmt); i++) - if (vimc_sca_supported_pixfmt[i] == pixelformat) - return true; - return false; -} - static int vimc_sca_init_cfg(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg) { @@ -82,13 +66,35 @@ static int vimc_sca_init_cfg(struct v4l2_subdev *sd, return 0; } +static int vimc_sca_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index); + + /* We don't support bayer format */ + if (!vpix || vpix->bayer) + return -EINVAL; + + code->code = vpix->code; + + return 0; +} + static int vimc_sca_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { + const struct vimc_pix_map *vpix; + if (fse->index) return -EINVAL; + /* Only accept code in the pix map table in non bayer format */ + vpix = vimc_pix_map_by_code(fse->code); + if (!vpix || vpix->bayer) + return -EINVAL; + fse->min_width = VIMC_FRAME_MIN_WIDTH; fse->min_height = VIMC_FRAME_MIN_HEIGHT; @@ -125,6 +131,13 @@ static int vimc_sca_get_fmt(struct v4l2_subdev *sd, static void vimc_sca_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt) { + const struct vimc_pix_map *vpix; + + /* Only accept code in the pix map table in non bayer format */ + vpix = vimc_pix_map_by_code(fmt->code); + if (!vpix || vpix->bayer) + fmt->code = sink_fmt_default.code; + fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, VIMC_FRAME_MAX_WIDTH) & ~1; fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, @@ -143,12 +156,9 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *sink_fmt; - if (!vimc_mbus_code_supported(fmt->format.code)) - fmt->format.code = sink_fmt_default.code; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { /* Do not change the format while stream is on */ - if (vsca->ved.stream) + if (vsca->src_frame) return -EBUSY; sink_fmt = &vsca->sink_fmt; @@ -188,7 +198,7 @@ static int vimc_sca_set_fmt(struct v4l2_subdev *sd, static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = { .init_cfg = vimc_sca_init_cfg, - .enum_mbus_code = vimc_enum_mbus_code, + .enum_mbus_code = vimc_sca_enum_mbus_code, .enum_frame_size = vimc_sca_enum_frame_size, .get_fmt = vimc_sca_get_fmt, .set_fmt = vimc_sca_set_fmt, @@ -199,19 +209,15 @@ static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable) struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd); if (enable) { - u32 pixelformat = vsca->ved.stream->producer_pixfmt; - const struct v4l2_format_info *pix_info; + const struct vimc_pix_map *vpix; unsigned int frame_size; - if (!vimc_sca_is_pixfmt_supported(pixelformat)) { - dev_err(vsca->dev, "pixfmt (0x%08x) is not supported\n", - pixelformat); - return -EINVAL; - } + if (vsca->src_frame) + return 0; /* Save the bytes per pixel of the sink */ - pix_info = v4l2_format_info(pixelformat); - vsca->bpp = pix_info->bpp[0]; + vpix = vimc_pix_map_by_code(vsca->sink_fmt.code); + vsca->bpp = vpix->bpp; /* Calculate the width in bytes of the src frame */ vsca->src_line_size = vsca->sink_fmt.width * @@ -324,7 +330,7 @@ static void *vimc_sca_process_frame(struct vimc_ent_device *ved, ved); /* If the stream in this node is not active, just return */ - if (!ved->stream) + if (!vsca->src_frame) return ERR_PTR(-EINVAL); vimc_sca_fill_src_frame(vsca, sink_frame); diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c index 51359472eef2..6c53b9fc1617 100644 --- a/drivers/media/platform/vimc/vimc-sensor.c +++ b/drivers/media/platform/vimc/vimc-sensor.c @@ -55,13 +55,34 @@ static int vimc_sen_init_cfg(struct v4l2_subdev *sd, return 0; } +static int vimc_sen_enum_mbus_code(struct v4l2_subdev *sd, + struct v4l2_subdev_pad_config *cfg, + struct v4l2_subdev_mbus_code_enum *code) +{ + const struct vimc_pix_map *vpix = vimc_pix_map_by_index(code->index); + + if (!vpix) + return -EINVAL; + + code->code = vpix->code; + + return 0; +} + static int vimc_sen_enum_frame_size(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_frame_size_enum *fse) { + const struct vimc_pix_map *vpix; + if (fse->index) return -EINVAL; + /* Only accept code in the pix map table */ + vpix = vimc_pix_map_by_code(fse->code); + if (!vpix) + return -EINVAL; + fse->min_width = VIMC_FRAME_MIN_WIDTH; fse->max_width = VIMC_FRAME_MAX_WIDTH; fse->min_height = VIMC_FRAME_MIN_HEIGHT; @@ -86,17 +107,14 @@ static int vimc_sen_get_fmt(struct v4l2_subdev *sd, static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) { - u32 pixelformat = vsen->ved.stream->producer_pixfmt; - const struct v4l2_format_info *pix_info; - - pix_info = v4l2_format_info(pixelformat); + const struct vimc_pix_map *vpix = + vimc_pix_map_by_code(vsen->mbus_format.code); tpg_reset_source(&vsen->tpg, vsen->mbus_format.width, vsen->mbus_format.height, vsen->mbus_format.field); - tpg_s_bytesperline(&vsen->tpg, 0, - vsen->mbus_format.width * pix_info->bpp[0]); + tpg_s_bytesperline(&vsen->tpg, 0, vsen->mbus_format.width * vpix->bpp); tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height); - tpg_s_fourcc(&vsen->tpg, pixelformat); + tpg_s_fourcc(&vsen->tpg, vpix->pixelformat); /* TODO: add support for V4L2_FIELD_ALTERNATE */ tpg_s_field(&vsen->tpg, vsen->mbus_format.field, false); tpg_s_colorspace(&vsen->tpg, vsen->mbus_format.colorspace); @@ -107,6 +125,13 @@ static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen) static void vimc_sen_adjust_fmt(struct v4l2_mbus_framefmt *fmt) { + const struct vimc_pix_map *vpix; + + /* Only accept code in the pix map table */ + vpix = vimc_pix_map_by_code(fmt->code); + if (!vpix) + fmt->code = fmt_default.code; + fmt->width = clamp_t(u32, fmt->width, VIMC_FRAME_MIN_WIDTH, VIMC_FRAME_MAX_WIDTH) & ~1; fmt->height = clamp_t(u32, fmt->height, VIMC_FRAME_MIN_HEIGHT, @@ -126,12 +151,9 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd, struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd); struct v4l2_mbus_framefmt *mf; - if (!vimc_mbus_code_supported(fmt->format.code)) - fmt->format.code = fmt_default.code; - if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { /* Do not change the format while stream is on */ - if (vsen->ved.stream) + if (vsen->frame) return -EBUSY; mf = &vsen->mbus_format; @@ -161,7 +183,7 @@ static int vimc_sen_set_fmt(struct v4l2_subdev *sd, static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = { .init_cfg = vimc_sen_init_cfg, - .enum_mbus_code = vimc_enum_mbus_code, + .enum_mbus_code = vimc_sen_enum_mbus_code, .enum_frame_size = vimc_sen_enum_frame_size, .get_fmt = vimc_sen_get_fmt, .set_fmt = vimc_sen_set_fmt, @@ -183,13 +205,16 @@ static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable) container_of(sd, struct vimc_sen_device, sd); if (enable) { - u32 pixelformat = vsen->ved.stream->producer_pixfmt; - const struct v4l2_format_info *pix_info; + const struct vimc_pix_map *vpix; unsigned int frame_size; + if (vsen->kthread_sen) + /* tpg is already executing */ + return 0; + /* Calculate the frame size */ - pix_info = v4l2_format_info(pixelformat); - frame_size = vsen->mbus_format.width * pix_info->bpp[0] * + vpix = vimc_pix_map_by_code(vsen->mbus_format.code); + frame_size = vsen->mbus_format.width * vpix->bpp * vsen->mbus_format.height; /* diff --git a/drivers/media/platform/vimc/vimc-streamer.c b/drivers/media/platform/vimc/vimc-streamer.c index 3b3f36357a0e..048d770e498b 100644 --- a/drivers/media/platform/vimc/vimc-streamer.c +++ b/drivers/media/platform/vimc/vimc-streamer.c @@ -20,6 +20,8 @@ * * Helper function that returns the media entity containing the source pad * linked with the first sink pad from the given media entity pad list. + * + * Return: The source pad or NULL, if it wasn't found. */ static struct media_entity *vimc_get_source_entity(struct media_entity *ent) { @@ -35,7 +37,7 @@ static struct media_entity *vimc_get_source_entity(struct media_entity *ent) return NULL; } -/* +/** * vimc_streamer_pipeline_terminate - Disable stream in all ved in stream * * @stream: the pointer to the stream structure with the pipeline to be @@ -52,7 +54,6 @@ static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream) while (stream->pipe_size) { stream->pipe_size--; ved = stream->ved_pipeline[stream->pipe_size]; - ved->stream = NULL; stream->ved_pipeline[stream->pipe_size] = NULL; if (!is_media_entity_v4l2_subdev(ved->ent)) @@ -63,15 +64,18 @@ static void vimc_streamer_pipeline_terminate(struct vimc_stream *stream) } } -/* - * vimc_streamer_pipeline_init - initializes the stream structure +/** + * vimc_streamer_pipeline_init - Initializes the stream structure * * @stream: the pointer to the stream structure to be initialized * @ved: the pointer to the vimc entity initializing the stream * * Initializes the stream structure. Walks through the entity graph to * construct the pipeline used later on the streamer thread. - * Calls s_stream to enable stream in all entities of the pipeline. + * Calls vimc_streamer_s_stream() to enable stream in all entities of + * the pipeline. + * + * Return: 0 if success, error code otherwise. */ static int vimc_streamer_pipeline_init(struct vimc_stream *stream, struct vimc_ent_device *ved) @@ -88,7 +92,6 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream, return -EINVAL; } stream->ved_pipeline[stream->pipe_size++] = ved; - ved->stream = stream; if (is_media_entity_v4l2_subdev(ved->ent)) { sd = media_entity_to_v4l2_subdev(ved->ent); @@ -122,13 +125,17 @@ static int vimc_streamer_pipeline_init(struct vimc_stream *stream, return -EINVAL; } -/* - * vimc_streamer_thread - process frames through the pipeline +/** + * vimc_streamer_thread - Process frames through the pipeline * * @data: vimc_stream struct of the current stream * * From the source to the sink, gets a frame from each subdevice and send to * the next one of the pipeline at a fixed framerate. + * + * Return: + * Always zero (created as ``int`` instead of ``void`` to comply with + * kthread API). */ static int vimc_streamer_thread(void *data) { @@ -157,19 +164,20 @@ static int vimc_streamer_thread(void *data) return 0; } -/* - * vimc_streamer_s_stream - start/stop the streaming on the media pipeline +/** + * vimc_streamer_s_stream - Start/stop the streaming on the media pipeline * * @stream: the pointer to the stream structure of the current stream * @ved: pointer to the vimc entity of the entity of the stream * @enable: flag to determine if stream should start/stop * - * When starting, check if there is no stream->kthread allocated. This should - * indicate that a stream is already running. Then, it initializes - * the pipeline, creates and runs a kthread to consume buffers through the - * pipeline. - * When stopping, analogously check if there is a stream running, stop - * the thread and terminates the pipeline. + * When starting, check if there is no ``stream->kthread`` allocated. This + * should indicate that a stream is already running. Then, it initializes the + * pipeline, creates and runs a kthread to consume buffers through the pipeline. + * When stopping, analogously check if there is a stream running, stop the + * thread and terminates the pipeline. + * + * Return: 0 if success, error code otherwise. */ int vimc_streamer_s_stream(struct vimc_stream *stream, struct vimc_ent_device *ved, diff --git a/drivers/media/platform/vimc/vimc-streamer.h b/drivers/media/platform/vimc/vimc-streamer.h index 2b3667408794..fe3c51f15fad 100644 --- a/drivers/media/platform/vimc/vimc-streamer.h +++ b/drivers/media/platform/vimc/vimc-streamer.h @@ -25,11 +25,6 @@ * processed in the pipeline. * @pipe_size: size of @ved_pipeline * @kthread: thread that generates the frames of the stream. - * @producer_pixfmt: the pixel format requested from the pipeline. This must - * be set just before calling vimc_streamer_s_stream(ent, 1). This value is - * propagated up to the source of the base image (usually a sensor node) and - * can be modified by entities during s_stream callback to request a different - * format from rest of the pipeline. * * When the user call stream_on in a video device, struct vimc_stream is * used to keep track of all entities and subdevices that generates and @@ -40,17 +35,8 @@ struct vimc_stream { struct vimc_ent_device *ved_pipeline[VIMC_STREAMER_PIPELINE_MAX_SIZE]; unsigned int pipe_size; struct task_struct *kthread; - u32 producer_pixfmt; }; -/** - * vimc_streamer_s_streamer - start/stop the stream - * - * @stream: the pointer to the stream to start or stop - * @ved: The last entity of the streamer pipeline - * @enable: any non-zero number start the stream, zero stop - * - */ int vimc_streamer_s_stream(struct vimc_stream *stream, struct vimc_ent_device *ved, int enable); diff --git a/drivers/media/platform/vivid/vivid-core.c b/drivers/media/platform/vivid/vivid-core.c index d535aac68ce1..53315c8dd2bb 100644 --- a/drivers/media/platform/vivid/vivid-core.c +++ b/drivers/media/platform/vivid/vivid-core.c @@ -792,7 +792,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (no_error_inj && ccs_cap == -1) ccs_cap = 7; - /* if ccs_cap == -1, then the use can select it using controls */ + /* if ccs_cap == -1, then the user can select it using controls */ if (ccs_cap != -1) { dev->has_crop_cap = ccs_cap & 1; dev->has_compose_cap = ccs_cap & 2; @@ -807,7 +807,7 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) if (no_error_inj && ccs_out == -1) ccs_out = 7; - /* if ccs_out == -1, then the use can select it using controls */ + /* if ccs_out == -1, then the user can select it using controls */ if (ccs_out != -1) { dev->has_crop_out = ccs_out & 1; dev->has_compose_out = ccs_out & 2; diff --git a/drivers/media/platform/vivid/vivid-ctrls.c b/drivers/media/platform/vivid/vivid-ctrls.c index 3e916c8befb7..cb19a9a73092 100644 --- a/drivers/media/platform/vivid/vivid-ctrls.c +++ b/drivers/media/platform/vivid/vivid-ctrls.c @@ -1473,7 +1473,7 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, v4l2_ctrl_handler_init(hdl_vid_cap, 55); v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_class, NULL); v4l2_ctrl_handler_init(hdl_vid_out, 26); - if (!no_error_inj || dev->has_fb) + if (!no_error_inj || dev->has_fb || dev->num_hdmi_outputs) v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_class, NULL); v4l2_ctrl_handler_init(hdl_vbi_cap, 21); v4l2_ctrl_new_custom(hdl_vbi_cap, &vivid_ctrl_class, NULL); @@ -1613,6 +1613,8 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, } if (dev->num_hdmi_inputs) { + s64 hdmi_input_mask = GENMASK(dev->num_hdmi_inputs - 1, 0); + dev->ctrl_dv_timings_signal_mode = v4l2_ctrl_new_custom(hdl_vid_cap, &vivid_ctrl_dv_timings_signal_mode, NULL); @@ -1633,12 +1635,13 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, V4L2_CID_DV_RX_RGB_RANGE, V4L2_DV_RGB_RANGE_FULL, 0, V4L2_DV_RGB_RANGE_AUTO); dev->ctrl_rx_power_present = v4l2_ctrl_new_std(hdl_vid_cap, - NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, - (2 << (dev->num_hdmi_inputs - 1)) - 1, 0, - (2 << (dev->num_hdmi_inputs - 1)) - 1); + NULL, V4L2_CID_DV_RX_POWER_PRESENT, 0, hdmi_input_mask, + 0, hdmi_input_mask); } if (dev->num_hdmi_outputs) { + s64 hdmi_output_mask = GENMASK(dev->num_hdmi_outputs - 1, 0); + /* * We aren't doing anything with this at the moment, but * HDMI outputs typically have this controls. @@ -1652,17 +1655,14 @@ int vivid_create_controls(struct vivid_dev *dev, bool show_ccs_cap, dev->ctrl_display_present = v4l2_ctrl_new_custom(hdl_vid_out, &vivid_ctrl_display_present, NULL); dev->ctrl_tx_hotplug = v4l2_ctrl_new_std(hdl_vid_out, - NULL, V4L2_CID_DV_TX_HOTPLUG, 0, - (2 << (dev->num_hdmi_outputs - 1)) - 1, 0, - (2 << (dev->num_hdmi_outputs - 1)) - 1); + NULL, V4L2_CID_DV_TX_HOTPLUG, 0, hdmi_output_mask, + 0, hdmi_output_mask); dev->ctrl_tx_rxsense = v4l2_ctrl_new_std(hdl_vid_out, - NULL, V4L2_CID_DV_TX_RXSENSE, 0, - (2 << (dev->num_hdmi_outputs - 1)) - 1, 0, - (2 << (dev->num_hdmi_outputs - 1)) - 1); + NULL, V4L2_CID_DV_TX_RXSENSE, 0, hdmi_output_mask, + 0, hdmi_output_mask); dev->ctrl_tx_edid_present = v4l2_ctrl_new_std(hdl_vid_out, - NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, - (2 << (dev->num_hdmi_outputs - 1)) - 1, 0, - (2 << (dev->num_hdmi_outputs - 1)) - 1); + NULL, V4L2_CID_DV_TX_EDID_PRESENT, 0, hdmi_output_mask, + 0, hdmi_output_mask); } if ((dev->has_vid_cap && dev->has_vid_out) || (dev->has_vbi_cap && dev->has_vbi_out)) diff --git a/drivers/media/platform/vivid/vivid-kthread-cap.c b/drivers/media/platform/vivid/vivid-kthread-cap.c index 6cf495a7d5cc..003319d7816d 100644 --- a/drivers/media/platform/vivid/vivid-kthread-cap.c +++ b/drivers/media/platform/vivid/vivid-kthread-cap.c @@ -232,8 +232,8 @@ static void *plane_vaddr(struct tpg_data *tpg, struct vivid_buffer *buf, return vbuf; } -static int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, u8 *vcapbuf, - struct vivid_buffer *vid_cap_buf) +static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned p, + u8 *vcapbuf, struct vivid_buffer *vid_cap_buf) { bool blank = dev->must_blank[vid_cap_buf->vb.vb2_buf.index]; struct tpg_data *tpg = &dev->tpg; @@ -658,6 +658,8 @@ static void vivid_cap_update_frame_period(struct vivid_dev *dev) u64 f_period; f_period = (u64)dev->timeperframe_vid_cap.numerator * 1000000000; + if (WARN_ON(dev->timeperframe_vid_cap.denominator == 0)) + dev->timeperframe_vid_cap.denominator = 1; do_div(f_period, dev->timeperframe_vid_cap.denominator); if (dev->field_cap == V4L2_FIELD_ALTERNATE) f_period >>= 1; @@ -670,7 +672,8 @@ static void vivid_cap_update_frame_period(struct vivid_dev *dev) dev->cap_frame_period = f_period; } -static void vivid_thread_vid_cap_tick(struct vivid_dev *dev, int dropped_bufs) +static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev, + int dropped_bufs) { struct vivid_buffer *vid_cap_buf = NULL; struct vivid_buffer *vbi_cap_buf = NULL; diff --git a/drivers/media/platform/vivid/vivid-vid-common.c b/drivers/media/platform/vivid/vivid-vid-common.c index 1f33eb1a76b6..8665dfd25eb4 100644 --- a/drivers/media/platform/vivid/vivid-vid-common.c +++ b/drivers/media/platform/vivid/vivid-vid-common.c @@ -262,21 +262,66 @@ struct vivid_fmt vivid_formats[] = { .can_do_overlay = true, }, { - .fourcc = V4L2_PIX_FMT_RGB444, /* xxxxrrrr ggggbbbb */ + .fourcc = V4L2_PIX_FMT_RGB444, /* ggggbbbb xxxxrrrr */ .vdownsampling = { 1 }, .bit_depth = { 16 }, .planes = 1, .buffers = 1, }, { - .fourcc = V4L2_PIX_FMT_XRGB444, /* xxxxrrrr ggggbbbb */ + .fourcc = V4L2_PIX_FMT_XRGB444, /* ggggbbbb xxxxrrrr */ .vdownsampling = { 1 }, .bit_depth = { 16 }, .planes = 1, .buffers = 1, }, { - .fourcc = V4L2_PIX_FMT_ARGB444, /* aaaarrrr ggggbbbb */ + .fourcc = V4L2_PIX_FMT_ARGB444, /* ggggbbbb aaaarrrr */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0x00f0, + }, + { + .fourcc = V4L2_PIX_FMT_RGBX444, /* bbbbxxxx rrrrgggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_RGBA444, /* bbbbaaaa rrrrgggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0x00f0, + }, + { + .fourcc = V4L2_PIX_FMT_XBGR444, /* ggggrrrr xxxxbbbb */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_ABGR444, /* ggggrrrr aaaabbbb */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0x00f0, + }, + { + .fourcc = V4L2_PIX_FMT_BGRX444, /* rrrrxxxx bbbbgggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_BGRA444, /* rrrraaaa bbbbgggg */ .vdownsampling = { 1 }, .bit_depth = { 16 }, .planes = 1, @@ -309,6 +354,57 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0x8000, }, { + .fourcc = V4L2_PIX_FMT_RGBX555, /* ggbbbbbx rrrrrggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .can_do_overlay = true, + }, + { + .fourcc = V4L2_PIX_FMT_RGBA555, /* ggbbbbba rrrrrggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .can_do_overlay = true, + .alpha_mask = 0x8000, + }, + { + .fourcc = V4L2_PIX_FMT_XBGR555, /* gggrrrrr xbbbbbgg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .can_do_overlay = true, + }, + { + .fourcc = V4L2_PIX_FMT_ABGR555, /* gggrrrrr abbbbbgg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .can_do_overlay = true, + .alpha_mask = 0x8000, + }, + { + .fourcc = V4L2_PIX_FMT_BGRX555, /* ggrrrrrx bbbbbggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .can_do_overlay = true, + }, + { + .fourcc = V4L2_PIX_FMT_BGRA555, /* ggrrrrra bbbbbggg */ + .vdownsampling = { 1 }, + .bit_depth = { 16 }, + .planes = 1, + .buffers = 1, + .can_do_overlay = true, + .alpha_mask = 0x8000, + }, + { .fourcc = V4L2_PIX_FMT_RGB555X, /* xrrrrrgg gggbbbbb */ .vdownsampling = { 1 }, .bit_depth = { 16 }, @@ -396,6 +492,36 @@ struct vivid_fmt vivid_formats[] = { .alpha_mask = 0xff000000, }, { + .fourcc = V4L2_PIX_FMT_RGBX32, /* rgbx */ + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_BGRX32, /* xbgr */ + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + }, + { + .fourcc = V4L2_PIX_FMT_RGBA32, /* rgba */ + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0x000000ff, + }, + { + .fourcc = V4L2_PIX_FMT_BGRA32, /* abgr */ + .vdownsampling = { 1 }, + .bit_depth = { 32 }, + .planes = 1, + .buffers = 1, + .alpha_mask = 0xff000000, + }, + { .fourcc = V4L2_PIX_FMT_SBGGR8, /* Bayer BG/GR */ .vdownsampling = { 1 }, .bit_depth = { 8 }, diff --git a/drivers/media/platform/vsp1/vsp1_dl.c b/drivers/media/platform/vsp1/vsp1_dl.c index 104b6f514536..d7b43037e500 100644 --- a/drivers/media/platform/vsp1/vsp1_dl.c +++ b/drivers/media/platform/vsp1/vsp1_dl.c @@ -557,8 +557,10 @@ static struct vsp1_dl_list *vsp1_dl_list_alloc(struct vsp1_dl_manager *dlm) /* Get a default body for our list. */ dl->body0 = vsp1_dl_body_get(dlm->pool); - if (!dl->body0) + if (!dl->body0) { + kfree(dl); return NULL; + } header_offset = dl->body0->max_entries * sizeof(*dl->body0->entries); diff --git a/drivers/media/platform/vsp1/vsp1_histo.c b/drivers/media/platform/vsp1/vsp1_histo.c index 8b01e99acd20..30d751f2cccf 100644 --- a/drivers/media/platform/vsp1/vsp1_histo.c +++ b/drivers/media/platform/vsp1/vsp1_histo.c @@ -426,8 +426,6 @@ static int histo_v4l2_querycap(struct file *file, void *fh, | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_META_CAPTURE; - cap->device_caps = V4L2_CAP_META_CAPTURE - | V4L2_CAP_STREAMING; strscpy(cap->driver, "vsp1", sizeof(cap->driver)); strscpy(cap->card, histo->video.name, sizeof(cap->card)); @@ -556,6 +554,7 @@ int vsp1_histogram_init(struct vsp1_device *vsp1, struct vsp1_histogram *histo, histo->video.vfl_type = VFL_TYPE_GRABBER; histo->video.release = video_device_release_empty; histo->video.ioctl_ops = &histo_v4l2_ioctl_ops; + histo->video.device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; video_set_drvdata(&histo->video, histo); diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h index 1bb1d39c60d9..5c67ff92d97a 100644 --- a/drivers/media/platform/vsp1/vsp1_regs.h +++ b/drivers/media/platform/vsp1/vsp1_regs.h @@ -15,8 +15,8 @@ */ #define VI6_CMD(n) (0x0000 + (n) * 4) -#define VI6_CMD_UPDHDR (1 << 4) -#define VI6_CMD_STRCMD (1 << 0) +#define VI6_CMD_UPDHDR BIT(4) +#define VI6_CMD_STRCMD BIT(0) #define VI6_CLK_DCSWT 0x0018 #define VI6_CLK_DCSWT_CSTPW_MASK (0xff << 8) @@ -25,29 +25,29 @@ #define VI6_CLK_DCSWT_CSTRW_SHIFT 0 #define VI6_SRESET 0x0028 -#define VI6_SRESET_SRTS(n) (1 << (n)) +#define VI6_SRESET_SRTS(n) BIT(n) #define VI6_STATUS 0x0038 -#define VI6_STATUS_FLD_STD(n) (1 << ((n) + 28)) -#define VI6_STATUS_SYS_ACT(n) (1 << ((n) + 8)) +#define VI6_STATUS_FLD_STD(n) BIT((n) + 28) +#define VI6_STATUS_SYS_ACT(n) BIT((n) + 8) #define VI6_WPF_IRQ_ENB(n) (0x0048 + (n) * 12) -#define VI6_WFP_IRQ_ENB_DFEE (1 << 1) -#define VI6_WFP_IRQ_ENB_FREE (1 << 0) +#define VI6_WFP_IRQ_ENB_DFEE BIT(1) +#define VI6_WFP_IRQ_ENB_FREE BIT(0) #define VI6_WPF_IRQ_STA(n) (0x004c + (n) * 12) -#define VI6_WFP_IRQ_STA_DFE (1 << 1) -#define VI6_WFP_IRQ_STA_FRE (1 << 0) +#define VI6_WFP_IRQ_STA_DFE BIT(1) +#define VI6_WFP_IRQ_STA_FRE BIT(0) #define VI6_DISP_IRQ_ENB(n) (0x0078 + (n) * 60) -#define VI6_DISP_IRQ_ENB_DSTE (1 << 8) -#define VI6_DISP_IRQ_ENB_MAEE (1 << 5) -#define VI6_DISP_IRQ_ENB_LNEE(n) (1 << (n)) +#define VI6_DISP_IRQ_ENB_DSTE BIT(8) +#define VI6_DISP_IRQ_ENB_MAEE BIT(5) +#define VI6_DISP_IRQ_ENB_LNEE(n) BIT(n) #define VI6_DISP_IRQ_STA(n) (0x007c + (n) * 60) -#define VI6_DISP_IRQ_STA_DST (1 << 8) -#define VI6_DISP_IRQ_STA_MAE (1 << 5) -#define VI6_DISP_IRQ_STA_LNE(n) (1 << (n)) +#define VI6_DISP_IRQ_STA_DST BIT(8) +#define VI6_DISP_IRQ_STA_MAE BIT(5) +#define VI6_DISP_IRQ_STA_LNE(n) BIT(n) #define VI6_WPF_LINE_COUNT(n) (0x0084 + (n) * 4) #define VI6_WPF_LINE_COUNT_MASK (0x1fffff << 0) @@ -59,32 +59,32 @@ #define VI6_DL_CTRL 0x0100 #define VI6_DL_CTRL_AR_WAIT_MASK (0xffff << 16) #define VI6_DL_CTRL_AR_WAIT_SHIFT 16 -#define VI6_DL_CTRL_DC2 (1 << 12) -#define VI6_DL_CTRL_DC1 (1 << 8) -#define VI6_DL_CTRL_DC0 (1 << 4) -#define VI6_DL_CTRL_CFM0 (1 << 2) -#define VI6_DL_CTRL_NH0 (1 << 1) -#define VI6_DL_CTRL_DLE (1 << 0) +#define VI6_DL_CTRL_DC2 BIT(12) +#define VI6_DL_CTRL_DC1 BIT(8) +#define VI6_DL_CTRL_DC0 BIT(4) +#define VI6_DL_CTRL_CFM0 BIT(2) +#define VI6_DL_CTRL_NH0 BIT(1) +#define VI6_DL_CTRL_DLE BIT(0) #define VI6_DL_HDR_ADDR(n) (0x0104 + (n) * 4) #define VI6_DL_SWAP 0x0114 -#define VI6_DL_SWAP_LWS (1 << 2) -#define VI6_DL_SWAP_WDS (1 << 1) -#define VI6_DL_SWAP_BTS (1 << 0) +#define VI6_DL_SWAP_LWS BIT(2) +#define VI6_DL_SWAP_WDS BIT(1) +#define VI6_DL_SWAP_BTS BIT(0) #define VI6_DL_EXT_CTRL(n) (0x011c + (n) * 36) -#define VI6_DL_EXT_CTRL_NWE (1 << 16) +#define VI6_DL_EXT_CTRL_NWE BIT(16) #define VI6_DL_EXT_CTRL_POLINT_MASK (0x3f << 8) #define VI6_DL_EXT_CTRL_POLINT_SHIFT 8 -#define VI6_DL_EXT_CTRL_DLPRI (1 << 5) -#define VI6_DL_EXT_CTRL_EXPRI (1 << 4) -#define VI6_DL_EXT_CTRL_EXT (1 << 0) +#define VI6_DL_EXT_CTRL_DLPRI BIT(5) +#define VI6_DL_EXT_CTRL_EXPRI BIT(4) +#define VI6_DL_EXT_CTRL_EXT BIT(0) #define VI6_DL_EXT_AUTOFLD_INT BIT(0) #define VI6_DL_BODY_SIZE 0x0120 -#define VI6_DL_BODY_SIZE_UPD (1 << 24) +#define VI6_DL_BODY_SIZE_UPD BIT(24) #define VI6_DL_BODY_SIZE_BS_MASK (0x1ffff << 0) #define VI6_DL_BODY_SIZE_BS_SHIFT 0 @@ -107,10 +107,10 @@ #define VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT 0 #define VI6_RPF_INFMT 0x0308 -#define VI6_RPF_INFMT_VIR (1 << 28) -#define VI6_RPF_INFMT_CIPM (1 << 16) -#define VI6_RPF_INFMT_SPYCS (1 << 15) -#define VI6_RPF_INFMT_SPUVS (1 << 14) +#define VI6_RPF_INFMT_VIR BIT(28) +#define VI6_RPF_INFMT_CIPM BIT(16) +#define VI6_RPF_INFMT_SPYCS BIT(15) +#define VI6_RPF_INFMT_SPUVS BIT(14) #define VI6_RPF_INFMT_CEXT_ZERO (0 << 12) #define VI6_RPF_INFMT_CEXT_EXT (1 << 12) #define VI6_RPF_INFMT_CEXT_ONE (2 << 12) @@ -120,19 +120,19 @@ #define VI6_RPF_INFMT_RDTM_BT709 (2 << 9) #define VI6_RPF_INFMT_RDTM_BT709_EXT (3 << 9) #define VI6_RPF_INFMT_RDTM_MASK (7 << 9) -#define VI6_RPF_INFMT_CSC (1 << 8) +#define VI6_RPF_INFMT_CSC BIT(8) #define VI6_RPF_INFMT_RDFMT_MASK (0x7f << 0) #define VI6_RPF_INFMT_RDFMT_SHIFT 0 #define VI6_RPF_DSWAP 0x030c -#define VI6_RPF_DSWAP_A_LLS (1 << 11) -#define VI6_RPF_DSWAP_A_LWS (1 << 10) -#define VI6_RPF_DSWAP_A_WDS (1 << 9) -#define VI6_RPF_DSWAP_A_BTS (1 << 8) -#define VI6_RPF_DSWAP_P_LLS (1 << 3) -#define VI6_RPF_DSWAP_P_LWS (1 << 2) -#define VI6_RPF_DSWAP_P_WDS (1 << 1) -#define VI6_RPF_DSWAP_P_BTS (1 << 0) +#define VI6_RPF_DSWAP_A_LLS BIT(11) +#define VI6_RPF_DSWAP_A_LWS BIT(10) +#define VI6_RPF_DSWAP_A_WDS BIT(9) +#define VI6_RPF_DSWAP_A_BTS BIT(8) +#define VI6_RPF_DSWAP_P_LLS BIT(3) +#define VI6_RPF_DSWAP_P_LWS BIT(2) +#define VI6_RPF_DSWAP_P_WDS BIT(1) +#define VI6_RPF_DSWAP_P_BTS BIT(0) #define VI6_RPF_LOC 0x0310 #define VI6_RPF_LOC_HCOORD_MASK (0x1fff << 16) @@ -150,7 +150,7 @@ #define VI6_RPF_ALPH_SEL_ASEL_SHIFT 28 #define VI6_RPF_ALPH_SEL_IROP_MASK (0xf << 24) #define VI6_RPF_ALPH_SEL_IROP_SHIFT 24 -#define VI6_RPF_ALPH_SEL_BSEL (1 << 23) +#define VI6_RPF_ALPH_SEL_BSEL BIT(23) #define VI6_RPF_ALPH_SEL_AEXT_ZERO (0 << 18) #define VI6_RPF_ALPH_SEL_AEXT_EXT (1 << 18) #define VI6_RPF_ALPH_SEL_AEXT_ONE (2 << 18) @@ -171,7 +171,7 @@ #define VI6_RPF_VRTCOL_SET_LAYB_SHIFT 0 #define VI6_RPF_MSK_CTRL 0x031c -#define VI6_RPF_MSK_CTRL_MSK_EN (1 << 24) +#define VI6_RPF_MSK_CTRL_MSK_EN BIT(24) #define VI6_RPF_MSK_CTRL_MGR_MASK (0xff << 16) #define VI6_RPF_MSK_CTRL_MGR_SHIFT 16 #define VI6_RPF_MSK_CTRL_MGG_MASK (0xff << 8) @@ -191,9 +191,9 @@ #define VI6_RPF_MSK_SET_MSB_SHIFT 0 #define VI6_RPF_CKEY_CTRL 0x0328 -#define VI6_RPF_CKEY_CTRL_CV (1 << 4) -#define VI6_RPF_CKEY_CTRL_SAPE1 (1 << 1) -#define VI6_RPF_CKEY_CTRL_SAPE0 (1 << 0) +#define VI6_RPF_CKEY_CTRL_CV BIT(4) +#define VI6_RPF_CKEY_CTRL_SAPE1 BIT(1) +#define VI6_RPF_CKEY_CTRL_SAPE0 BIT(0) #define VI6_RPF_CKEY_SET0 0x032c #define VI6_RPF_CKEY_SET1 0x0330 @@ -250,7 +250,7 @@ #define VI6_WPF_HSZCLIP 0x1004 #define VI6_WPF_VSZCLIP 0x1008 -#define VI6_WPF_SZCLIP_EN (1 << 28) +#define VI6_WPF_SZCLIP_EN BIT(28) #define VI6_WPF_SZCLIP_OFST_MASK (0xff << 16) #define VI6_WPF_SZCLIP_OFST_SHIFT 16 #define VI6_WPF_SZCLIP_SIZE_MASK (0xfff << 0) @@ -259,12 +259,12 @@ #define VI6_WPF_OUTFMT 0x100c #define VI6_WPF_OUTFMT_PDV_MASK (0xff << 24) #define VI6_WPF_OUTFMT_PDV_SHIFT 24 -#define VI6_WPF_OUTFMT_PXA (1 << 23) -#define VI6_WPF_OUTFMT_ROT (1 << 18) -#define VI6_WPF_OUTFMT_HFLP (1 << 17) -#define VI6_WPF_OUTFMT_FLP (1 << 16) -#define VI6_WPF_OUTFMT_SPYCS (1 << 15) -#define VI6_WPF_OUTFMT_SPUVS (1 << 14) +#define VI6_WPF_OUTFMT_PXA BIT(23) +#define VI6_WPF_OUTFMT_ROT BIT(18) +#define VI6_WPF_OUTFMT_HFLP BIT(17) +#define VI6_WPF_OUTFMT_FLP BIT(16) +#define VI6_WPF_OUTFMT_SPYCS BIT(15) +#define VI6_WPF_OUTFMT_SPUVS BIT(14) #define VI6_WPF_OUTFMT_DITH_DIS (0 << 12) #define VI6_WPF_OUTFMT_DITH_EN (3 << 12) #define VI6_WPF_OUTFMT_DITH_MASK (3 << 12) @@ -273,18 +273,18 @@ #define VI6_WPF_OUTFMT_WRTM_BT709 (2 << 9) #define VI6_WPF_OUTFMT_WRTM_BT709_EXT (3 << 9) #define VI6_WPF_OUTFMT_WRTM_MASK (7 << 9) -#define VI6_WPF_OUTFMT_CSC (1 << 8) +#define VI6_WPF_OUTFMT_CSC BIT(8) #define VI6_WPF_OUTFMT_WRFMT_MASK (0x7f << 0) #define VI6_WPF_OUTFMT_WRFMT_SHIFT 0 #define VI6_WPF_DSWAP 0x1010 -#define VI6_WPF_DSWAP_P_LLS (1 << 3) -#define VI6_WPF_DSWAP_P_LWS (1 << 2) -#define VI6_WPF_DSWAP_P_WDS (1 << 1) -#define VI6_WPF_DSWAP_P_BTS (1 << 0) +#define VI6_WPF_DSWAP_P_LLS BIT(3) +#define VI6_WPF_DSWAP_P_LWS BIT(2) +#define VI6_WPF_DSWAP_P_WDS BIT(1) +#define VI6_WPF_DSWAP_P_BTS BIT(0) #define VI6_WPF_RNDCTRL 0x1014 -#define VI6_WPF_RNDCTRL_CBRM (1 << 28) +#define VI6_WPF_RNDCTRL_CBRM BIT(28) #define VI6_WPF_RNDCTRL_ABRM_TRUNC (0 << 24) #define VI6_WPF_RNDCTRL_ABRM_ROUND (1 << 24) #define VI6_WPF_RNDCTRL_ABRM_THRESH (2 << 24) @@ -297,7 +297,7 @@ #define VI6_WPF_RNDCTRL_CLMD_MASK (3 << 12) #define VI6_WPF_ROT_CTRL 0x1018 -#define VI6_WPF_ROT_CTRL_LN16 (1 << 17) +#define VI6_WPF_ROT_CTRL_LN16 BIT(17) #define VI6_WPF_ROT_CTRL_LMEM_WD_MASK (0x1fff << 0) #define VI6_WPF_ROT_CTRL_LMEM_WD_SHIFT 0 @@ -308,7 +308,7 @@ #define VI6_WPF_DSTM_ADDR_C1 0x102c #define VI6_WPF_WRBCK_CTRL(n) (0x1034 + (n) * 0x100) -#define VI6_WPF_WRBCK_CTRL_WBMD (1 << 0) +#define VI6_WPF_WRBCK_CTRL_WBMD BIT(0) /* ----------------------------------------------------------------------------- * UIF Control Registers @@ -317,20 +317,20 @@ #define VI6_UIF_OFFSET 0x100 #define VI6_UIF_DISCOM_DOCMCR 0x1c00 -#define VI6_UIF_DISCOM_DOCMCR_CMPRU (1 << 16) -#define VI6_UIF_DISCOM_DOCMCR_CMPR (1 << 0) +#define VI6_UIF_DISCOM_DOCMCR_CMPRU BIT(16) +#define VI6_UIF_DISCOM_DOCMCR_CMPR BIT(0) #define VI6_UIF_DISCOM_DOCMSTR 0x1c04 -#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE (1 << 1) -#define VI6_UIF_DISCOM_DOCMSTR_CMPST (1 << 0) +#define VI6_UIF_DISCOM_DOCMSTR_CMPPRE BIT(1) +#define VI6_UIF_DISCOM_DOCMSTR_CMPST BIT(0) #define VI6_UIF_DISCOM_DOCMCLSTR 0x1c08 -#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE (1 << 1) -#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST (1 << 0) +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLPRE BIT(1) +#define VI6_UIF_DISCOM_DOCMCLSTR_CMPCLST BIT(0) #define VI6_UIF_DISCOM_DOCMIENR 0x1c0c -#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN (1 << 1) -#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN (1 << 0) +#define VI6_UIF_DISCOM_DOCMIENR_CMPPREIEN BIT(1) +#define VI6_UIF_DISCOM_DOCMIENR_CMPIEN BIT(0) #define VI6_UIF_DISCOM_DOCMMDR 0x1c10 #define VI6_UIF_DISCOM_DOCMMDR_INTHRH(n) ((n) << 16) @@ -338,7 +338,7 @@ #define VI6_UIF_DISCOM_DOCMPMR 0x1c14 #define VI6_UIF_DISCOM_DOCMPMR_CMPDFF(n) ((n) << 17) #define VI6_UIF_DISCOM_DOCMPMR_CMPDFA(n) ((n) << 8) -#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF (1 << 7) +#define VI6_UIF_DISCOM_DOCMPMR_CMPDAUF BIT(7) #define VI6_UIF_DISCOM_DOCMPMR_SEL(n) ((n) << 0) #define VI6_UIF_DISCOM_DOCMECRCR 0x1c18 @@ -365,7 +365,7 @@ #define VI6_DPR_HSI_ROUTE 0x2048 #define VI6_DPR_BRU_ROUTE 0x204c #define VI6_DPR_ILV_BRS_ROUTE 0x2050 -#define VI6_DPR_ROUTE_BRSSEL (1 << 28) +#define VI6_DPR_ROUTE_BRSSEL BIT(28) #define VI6_DPR_ROUTE_FXA_MASK (0xff << 16) #define VI6_DPR_ROUTE_FXA_SHIFT 16 #define VI6_DPR_ROUTE_FP_MASK (0x3f << 8) @@ -407,10 +407,10 @@ #define VI6_SRU_CTRL0_PARAM1_MASK (0x1f << 8) #define VI6_SRU_CTRL0_PARAM1_SHIFT 8 #define VI6_SRU_CTRL0_MODE_UPSCALE (4 << 4) -#define VI6_SRU_CTRL0_PARAM2 (1 << 3) -#define VI6_SRU_CTRL0_PARAM3 (1 << 2) -#define VI6_SRU_CTRL0_PARAM4 (1 << 1) -#define VI6_SRU_CTRL0_EN (1 << 0) +#define VI6_SRU_CTRL0_PARAM2 BIT(3) +#define VI6_SRU_CTRL0_PARAM3 BIT(2) +#define VI6_SRU_CTRL0_PARAM4 BIT(1) +#define VI6_SRU_CTRL0_EN BIT(0) #define VI6_SRU_CTRL1 0x2204 #define VI6_SRU_CTRL1_PARAM5 0x7ff @@ -427,18 +427,18 @@ #define VI6_UDS_OFFSET 0x100 #define VI6_UDS_CTRL 0x2300 -#define VI6_UDS_CTRL_AMD (1 << 30) -#define VI6_UDS_CTRL_FMD (1 << 29) -#define VI6_UDS_CTRL_BLADV (1 << 28) -#define VI6_UDS_CTRL_AON (1 << 25) -#define VI6_UDS_CTRL_ATHON (1 << 24) -#define VI6_UDS_CTRL_BC (1 << 20) -#define VI6_UDS_CTRL_NE_A (1 << 19) -#define VI6_UDS_CTRL_NE_RCR (1 << 18) -#define VI6_UDS_CTRL_NE_GY (1 << 17) -#define VI6_UDS_CTRL_NE_BCB (1 << 16) -#define VI6_UDS_CTRL_AMDSLH (1 << 2) -#define VI6_UDS_CTRL_TDIPC (1 << 1) +#define VI6_UDS_CTRL_AMD BIT(30) +#define VI6_UDS_CTRL_FMD BIT(29) +#define VI6_UDS_CTRL_BLADV BIT(28) +#define VI6_UDS_CTRL_AON BIT(25) +#define VI6_UDS_CTRL_ATHON BIT(24) +#define VI6_UDS_CTRL_BC BIT(20) +#define VI6_UDS_CTRL_NE_A BIT(19) +#define VI6_UDS_CTRL_NE_RCR BIT(18) +#define VI6_UDS_CTRL_NE_GY BIT(17) +#define VI6_UDS_CTRL_NE_BCB BIT(16) +#define VI6_UDS_CTRL_AMDSLH BIT(2) +#define VI6_UDS_CTRL_TDIPC BIT(1) #define VI6_UDS_SCALE 0x2304 #define VI6_UDS_SCALE_HMANT_MASK (0xf << 28) @@ -477,12 +477,12 @@ #define VI6_UDS_HPHASE_HEDP_SHIFT 0 #define VI6_UDS_IPC 0x2318 -#define VI6_UDS_IPC_FIELD (1 << 27) +#define VI6_UDS_IPC_FIELD BIT(27) #define VI6_UDS_IPC_VEDP_MASK (0xfff << 0) #define VI6_UDS_IPC_VEDP_SHIFT 0 #define VI6_UDS_HSZCLIP 0x231c -#define VI6_UDS_HSZCLIP_HCEN (1 << 28) +#define VI6_UDS_HSZCLIP_HCEN BIT(28) #define VI6_UDS_HSZCLIP_HCL_OFST_MASK (0xff << 16) #define VI6_UDS_HSZCLIP_HCL_OFST_SHIFT 16 #define VI6_UDS_HSZCLIP_HCL_SIZE_MASK (0x1fff << 0) @@ -507,36 +507,36 @@ */ #define VI6_LUT_CTRL 0x2800 -#define VI6_LUT_CTRL_EN (1 << 0) +#define VI6_LUT_CTRL_EN BIT(0) /* ----------------------------------------------------------------------------- * CLU Control Registers */ #define VI6_CLU_CTRL 0x2900 -#define VI6_CLU_CTRL_AAI (1 << 28) -#define VI6_CLU_CTRL_MVS (1 << 24) +#define VI6_CLU_CTRL_AAI BIT(28) +#define VI6_CLU_CTRL_MVS BIT(24) #define VI6_CLU_CTRL_AX1I_2D (3 << 14) #define VI6_CLU_CTRL_AX2I_2D (1 << 12) #define VI6_CLU_CTRL_OS0_2D (3 << 8) #define VI6_CLU_CTRL_OS1_2D (1 << 6) #define VI6_CLU_CTRL_OS2_2D (3 << 4) -#define VI6_CLU_CTRL_M2D (1 << 1) -#define VI6_CLU_CTRL_EN (1 << 0) +#define VI6_CLU_CTRL_M2D BIT(1) +#define VI6_CLU_CTRL_EN BIT(0) /* ----------------------------------------------------------------------------- * HST Control Registers */ #define VI6_HST_CTRL 0x2a00 -#define VI6_HST_CTRL_EN (1 << 0) +#define VI6_HST_CTRL_EN BIT(0) /* ----------------------------------------------------------------------------- * HSI Control Registers */ #define VI6_HSI_CTRL 0x2b00 -#define VI6_HSI_CTRL_EN (1 << 0) +#define VI6_HSI_CTRL_EN BIT(0) /* ----------------------------------------------------------------------------- * BRS and BRU Control Registers @@ -563,7 +563,7 @@ #define VI6_BRS_BASE 0x3900 #define VI6_BRU_INCTRL 0x0000 -#define VI6_BRU_INCTRL_NRM (1 << 28) +#define VI6_BRU_INCTRL_NRM BIT(28) #define VI6_BRU_INCTRL_DnON (1 << (16 + (n))) #define VI6_BRU_INCTRL_DITHn_OFF (0 << ((n) * 4)) #define VI6_BRU_INCTRL_DITHn_18BPP (1 << ((n) * 4)) @@ -597,7 +597,7 @@ #define VI6_BRU_VIRRPF_COL_BCB_SHIFT 0 #define VI6_BRU_CTRL(n) (0x0010 + (n) * 8 + ((n) <= 3 ? 0 : 4)) -#define VI6_BRU_CTRL_RBC (1 << 31) +#define VI6_BRU_CTRL_RBC BIT(31) #define VI6_BRU_CTRL_DSTSEL_BRUIN(n) (((n) <= 3 ? (n) : (n)+1) << 20) #define VI6_BRU_CTRL_DSTSEL_VRPF (4 << 20) #define VI6_BRU_CTRL_DSTSEL_MASK (7 << 20) @@ -610,7 +610,7 @@ #define VI6_BRU_CTRL_AROP_MASK (0xf << 0) #define VI6_BRU_BLD(n) (0x0014 + (n) * 8 + ((n) <= 3 ? 0 : 4)) -#define VI6_BRU_BLD_CBES (1 << 31) +#define VI6_BRU_BLD_CBES BIT(31) #define VI6_BRU_BLD_CCMDX_DST_A (0 << 28) #define VI6_BRU_BLD_CCMDX_255_DST_A (1 << 28) #define VI6_BRU_BLD_CCMDX_SRC_A (2 << 28) @@ -624,7 +624,7 @@ #define VI6_BRU_BLD_CCMDY_COEFY (4 << 24) #define VI6_BRU_BLD_CCMDY_MASK (7 << 24) #define VI6_BRU_BLD_CCMDY_SHIFT 24 -#define VI6_BRU_BLD_ABES (1 << 23) +#define VI6_BRU_BLD_ABES BIT(23) #define VI6_BRU_BLD_ACMDX_DST_A (0 << 20) #define VI6_BRU_BLD_ACMDX_255_DST_A (1 << 20) #define VI6_BRU_BLD_ACMDX_SRC_A (2 << 20) @@ -662,11 +662,11 @@ #define VI6_HGO_SIZE_HSIZE_SHIFT 16 #define VI6_HGO_SIZE_VSIZE_SHIFT 0 #define VI6_HGO_MODE 0x3008 -#define VI6_HGO_MODE_STEP (1 << 10) -#define VI6_HGO_MODE_MAXRGB (1 << 7) -#define VI6_HGO_MODE_OFSB_R (1 << 6) -#define VI6_HGO_MODE_OFSB_G (1 << 5) -#define VI6_HGO_MODE_OFSB_B (1 << 4) +#define VI6_HGO_MODE_STEP BIT(10) +#define VI6_HGO_MODE_MAXRGB BIT(7) +#define VI6_HGO_MODE_OFSB_R BIT(6) +#define VI6_HGO_MODE_OFSB_G BIT(5) +#define VI6_HGO_MODE_OFSB_B BIT(4) #define VI6_HGO_MODE_HRATIO_SHIFT 2 #define VI6_HGO_MODE_VRATIO_SHIFT 0 #define VI6_HGO_LB_TH 0x300c @@ -687,7 +687,7 @@ #define VI6_HGO_EXT_HIST_ADDR 0x335c #define VI6_HGO_EXT_HIST_DATA 0x3360 #define VI6_HGO_REGRST 0x33fc -#define VI6_HGO_REGRST_RCLEA (1 << 0) +#define VI6_HGO_REGRST_RCLEA BIT(0) /* ----------------------------------------------------------------------------- * HGT Control Registers @@ -713,7 +713,7 @@ #define VI6_HGT_SUM 0x3754 #define VI6_HGT_LB_DET 0x3758 #define VI6_HGT_REGRST 0x37fc -#define VI6_HGT_REGRST_RCLEA (1 << 0) +#define VI6_HGT_REGRST_RCLEA BIT(0) /* ----------------------------------------------------------------------------- * LIF Control Registers @@ -724,9 +724,9 @@ #define VI6_LIF_CTRL 0x3b00 #define VI6_LIF_CTRL_OBTH_MASK (0x7ff << 16) #define VI6_LIF_CTRL_OBTH_SHIFT 16 -#define VI6_LIF_CTRL_CFMT (1 << 4) -#define VI6_LIF_CTRL_REQSEL (1 << 1) -#define VI6_LIF_CTRL_LIF_EN (1 << 0) +#define VI6_LIF_CTRL_CFMT BIT(4) +#define VI6_LIF_CTRL_REQSEL BIT(1) +#define VI6_LIF_CTRL_LIF_EN BIT(0) #define VI6_LIF_CSBTH 0x3b04 #define VI6_LIF_CSBTH_HBTH_MASK (0x7ff << 16) @@ -735,7 +735,7 @@ #define VI6_LIF_CSBTH_LBTH_SHIFT 0 #define VI6_LIF_LBA 0x3b0c -#define VI6_LIF_LBA_LBA0 (1 << 31) +#define VI6_LIF_LBA_LBA0 BIT(31) #define VI6_LIF_LBA_LBA1_MASK (0xfff << 16) #define VI6_LIF_LBA_LBA1_SHIFT 16 diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c index fd98e483b2f4..5e59ed2c3614 100644 --- a/drivers/media/platform/vsp1/vsp1_video.c +++ b/drivers/media/platform/vsp1/vsp1_video.c @@ -956,12 +956,6 @@ vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) | V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE; - if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE - | V4L2_CAP_STREAMING; - else - cap->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE - | V4L2_CAP_STREAMING; strscpy(cap->driver, "vsp1", sizeof(cap->driver)); strscpy(cap->card, video->video.name, sizeof(cap->card)); @@ -1268,11 +1262,15 @@ struct vsp1_video *vsp1_video_create(struct vsp1_device *vsp1, video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; video->pad.flags = MEDIA_PAD_FL_SOURCE; video->video.vfl_dir = VFL_DIR_TX; + video->video.device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE | + V4L2_CAP_STREAMING; } else { direction = "output"; video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; video->pad.flags = MEDIA_PAD_FL_SINK; video->video.vfl_dir = VFL_DIR_RX; + video->video.device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE | + V4L2_CAP_STREAMING; } mutex_init(&video->lock); diff --git a/drivers/media/platform/xilinx/xilinx-dma.c b/drivers/media/platform/xilinx/xilinx-dma.c index c9d5fdb2d407..b211380a11f2 100644 --- a/drivers/media/platform/xilinx/xilinx-dma.c +++ b/drivers/media/platform/xilinx/xilinx-dma.c @@ -491,15 +491,8 @@ xvip_dma_querycap(struct file *file, void *fh, struct v4l2_capability *cap) struct v4l2_fh *vfh = file->private_data; struct xvip_dma *dma = to_xvip_dma(vfh->vdev); - cap->device_caps = V4L2_CAP_STREAMING; - - if (dma->queue.type == V4L2_BUF_TYPE_VIDEO_CAPTURE) - cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE; - else - cap->device_caps |= V4L2_CAP_VIDEO_OUTPUT; - - cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS - | dma->xdev->v4l2_caps; + cap->capabilities = dma->xdev->v4l2_caps | V4L2_CAP_STREAMING | + V4L2_CAP_DEVICE_CAPS; strscpy(cap->driver, "xilinx-vipp", sizeof(cap->driver)); strscpy(cap->card, dma->video.name, sizeof(cap->card)); @@ -524,8 +517,6 @@ xvip_dma_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f) return -EINVAL; f->pixelformat = dma->format.pixelformat; - strscpy(f->description, dma->fmtinfo->description, - sizeof(f->description)); return 0; } @@ -700,6 +691,11 @@ int xvip_dma_init(struct xvip_composite_device *xdev, struct xvip_dma *dma, dma->video.release = video_device_release_empty; dma->video.ioctl_ops = &xvip_dma_ioctl_ops; dma->video.lock = &dma->lock; + dma->video.device_caps = V4L2_CAP_STREAMING; + if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) + dma->video.device_caps |= V4L2_CAP_VIDEO_CAPTURE; + else + dma->video.device_caps |= V4L2_CAP_VIDEO_OUTPUT; video_set_drvdata(&dma->video, dma); diff --git a/drivers/media/platform/xilinx/xilinx-vip.c b/drivers/media/platform/xilinx/xilinx-vip.c index 08a825c3a3f6..6ad61b08a31a 100644 --- a/drivers/media/platform/xilinx/xilinx-vip.c +++ b/drivers/media/platform/xilinx/xilinx-vip.c @@ -25,21 +25,21 @@ static const struct xvip_video_format xvip_video_formats[] = { { XVIP_VF_YUV_422, 8, NULL, MEDIA_BUS_FMT_UYVY8_1X16, - 2, V4L2_PIX_FMT_YUYV, "4:2:2, packed, YUYV" }, + 2, V4L2_PIX_FMT_YUYV }, { XVIP_VF_YUV_444, 8, NULL, MEDIA_BUS_FMT_VUY8_1X24, - 3, V4L2_PIX_FMT_YUV444, "4:4:4, packed, YUYV" }, + 3, V4L2_PIX_FMT_YUV444 }, { XVIP_VF_RBG, 8, NULL, MEDIA_BUS_FMT_RBG888_1X24, - 3, 0, NULL }, + 3, 0 }, { XVIP_VF_MONO_SENSOR, 8, "mono", MEDIA_BUS_FMT_Y8_1X8, - 1, V4L2_PIX_FMT_GREY, "Greyscale 8-bit" }, + 1, V4L2_PIX_FMT_GREY }, { XVIP_VF_MONO_SENSOR, 8, "rggb", MEDIA_BUS_FMT_SRGGB8_1X8, - 1, V4L2_PIX_FMT_SRGGB8, "Bayer 8-bit RGGB" }, + 1, V4L2_PIX_FMT_SRGGB8 }, { XVIP_VF_MONO_SENSOR, 8, "grbg", MEDIA_BUS_FMT_SGRBG8_1X8, - 1, V4L2_PIX_FMT_SGRBG8, "Bayer 8-bit GRBG" }, + 1, V4L2_PIX_FMT_SGRBG8 }, { XVIP_VF_MONO_SENSOR, 8, "gbrg", MEDIA_BUS_FMT_SGBRG8_1X8, - 1, V4L2_PIX_FMT_SGBRG8, "Bayer 8-bit GBRG" }, + 1, V4L2_PIX_FMT_SGBRG8 }, { XVIP_VF_MONO_SENSOR, 8, "bggr", MEDIA_BUS_FMT_SBGGR8_1X8, - 1, V4L2_PIX_FMT_SBGGR8, "Bayer 8-bit BGGR" }, + 1, V4L2_PIX_FMT_SBGGR8 }, }; /** diff --git a/drivers/media/platform/xilinx/xilinx-vip.h b/drivers/media/platform/xilinx/xilinx-vip.h index ba939dd52818..f71e2b650453 100644 --- a/drivers/media/platform/xilinx/xilinx-vip.h +++ b/drivers/media/platform/xilinx/xilinx-vip.h @@ -12,6 +12,7 @@ #ifndef __XILINX_VIP_H__ #define __XILINX_VIP_H__ +#include <linux/bitops.h> #include <linux/io.h> #include <media/v4l2-subdev.h> @@ -35,23 +36,23 @@ struct clk; /* Xilinx Video IP Control Registers */ #define XVIP_CTRL_CONTROL 0x0000 -#define XVIP_CTRL_CONTROL_SW_ENABLE (1 << 0) -#define XVIP_CTRL_CONTROL_REG_UPDATE (1 << 1) -#define XVIP_CTRL_CONTROL_BYPASS (1 << 4) -#define XVIP_CTRL_CONTROL_TEST_PATTERN (1 << 5) -#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET (1 << 30) -#define XVIP_CTRL_CONTROL_SW_RESET (1 << 31) +#define XVIP_CTRL_CONTROL_SW_ENABLE BIT(0) +#define XVIP_CTRL_CONTROL_REG_UPDATE BIT(1) +#define XVIP_CTRL_CONTROL_BYPASS BIT(4) +#define XVIP_CTRL_CONTROL_TEST_PATTERN BIT(5) +#define XVIP_CTRL_CONTROL_FRAME_SYNC_RESET BIT(30) +#define XVIP_CTRL_CONTROL_SW_RESET BIT(31) #define XVIP_CTRL_STATUS 0x0004 -#define XVIP_CTRL_STATUS_PROC_STARTED (1 << 0) -#define XVIP_CTRL_STATUS_EOF (1 << 1) +#define XVIP_CTRL_STATUS_PROC_STARTED BIT(0) +#define XVIP_CTRL_STATUS_EOF BIT(1) #define XVIP_CTRL_ERROR 0x0008 -#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY (1 << 0) -#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE (1 << 1) -#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY (1 << 2) -#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE (1 << 3) +#define XVIP_CTRL_ERROR_SLAVE_EOL_EARLY BIT(0) +#define XVIP_CTRL_ERROR_SLAVE_EOL_LATE BIT(1) +#define XVIP_CTRL_ERROR_SLAVE_SOF_EARLY BIT(2) +#define XVIP_CTRL_ERROR_SLAVE_SOF_LATE BIT(3) #define XVIP_CTRL_IRQ_ENABLE 0x000c -#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED (1 << 0) -#define XVIP_CTRL_IRQ_EOF (1 << 1) +#define XVIP_CTRL_IRQ_ENABLE_PROC_STARTED BIT(0) +#define XVIP_CTRL_IRQ_EOF BIT(1) #define XVIP_CTRL_VERSION 0x0010 #define XVIP_CTRL_VERSION_MAJOR_MASK (0xff << 24) #define XVIP_CTRL_VERSION_MAJOR_SHIFT 24 @@ -108,7 +109,6 @@ struct xvip_device { * @code: media bus format code * @bpp: bytes per pixel (when stored in memory) * @fourcc: V4L2 pixel format FCC identifier - * @description: format description, suitable for userspace */ struct xvip_video_format { unsigned int vf_code; @@ -117,7 +117,6 @@ struct xvip_video_format { unsigned int code; unsigned int bpp; u32 fourcc; - const char *description; }; const struct xvip_video_format *xvip_get_format_by_code(unsigned int code); diff --git a/drivers/media/platform/xilinx/xilinx-vipp.c b/drivers/media/platform/xilinx/xilinx-vipp.c index edce0402155d..cc2856efea59 100644 --- a/drivers/media/platform/xilinx/xilinx-vipp.c +++ b/drivers/media/platform/xilinx/xilinx-vipp.c @@ -385,9 +385,9 @@ static int xvip_graph_parse_one(struct xvip_composite_device *xdev, asd = v4l2_async_notifier_add_fwnode_subdev( &xdev->notifier, remote, sizeof(struct xvip_graph_entity)); + fwnode_handle_put(remote); if (IS_ERR(asd)) { ret = PTR_ERR(asd); - fwnode_handle_put(remote); goto err_notifier_cleanup; } } |