The R-Car VIN module supports V4L2_PIX_FMT_ARGB555 and
V4L2_PIX_FMT_ABGR32 pixel formats. Add the hardware register setup and
allow the alpha component to be changed while streaming using the
V4L2_CID_ALPHA_COMPONENT control.

Signed-off-by: Niklas Söderlund <niklas.soderlund+rene...@ragnatech.se>
Reviewed-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham+rene...@ideasonboard.com>
---
 drivers/media/platform/rcar-vin/rcar-dma.c  | 35 +++++++++++++++++++++
 drivers/media/platform/rcar-vin/rcar-v4l2.c |  8 +++++
 2 files changed, 43 insertions(+)

diff --git a/drivers/media/platform/rcar-vin/rcar-dma.c 
b/drivers/media/platform/rcar-vin/rcar-dma.c
index 4e991cce5fb56a90..620976d173585694 100644
--- a/drivers/media/platform/rcar-vin/rcar-dma.c
+++ b/drivers/media/platform/rcar-vin/rcar-dma.c
@@ -111,8 +111,11 @@
 #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_ARGB                (1 << 0)
 
@@ -730,6 +733,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);
@@ -1346,5 +1355,31 @@ int rvin_set_channel_routing(struct rvin_dev *vin, u8 
chsel)
 
 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 0936bcd98df1f75d..f8b6ec4408b2f5fa 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -54,6 +54,14 @@ 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)
-- 
2.21.0

Reply via email to