summaryrefslogtreecommitdiff
path: root/drivers/media/platform/vimc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/vimc')
-rw-r--r--drivers/media/platform/vimc/Kconfig15
-rw-r--r--drivers/media/platform/vimc/Makefile10
-rw-r--r--drivers/media/platform/vimc/vimc-capture.c543
-rw-r--r--drivers/media/platform/vimc/vimc-common.c477
-rw-r--r--drivers/media/platform/vimc/vimc-common.h234
-rw-r--r--drivers/media/platform/vimc/vimc-core.c403
-rw-r--r--drivers/media/platform/vimc/vimc-debayer.c603
-rw-r--r--drivers/media/platform/vimc/vimc-scaler.c457
-rw-r--r--drivers/media/platform/vimc/vimc-sensor.c480
9 files changed, 0 insertions, 3222 deletions
diff --git a/drivers/media/platform/vimc/Kconfig b/drivers/media/platform/vimc/Kconfig
deleted file mode 100644
index 71c9fe7d3370..000000000000
--- a/drivers/media/platform/vimc/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-config VIDEO_VIMC
- tristate "Virtual Media Controller Driver (VIMC)"
- depends on VIDEO_DEV && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
- select VIDEOBUF2_VMALLOC
- select VIDEO_V4L2_TPG
- default n
- ---help---
- Skeleton driver for Virtual Media Controller
-
- This driver can be compared to the vivid driver for emulating
- a media node that exposes a complex media topology. The topology
- is hard coded for now but is meant to be highly configurable in
- the future.
-
- When in doubt, say N.
diff --git a/drivers/media/platform/vimc/Makefile b/drivers/media/platform/vimc/Makefile
deleted file mode 100644
index 4b2e3de7856e..000000000000
--- a/drivers/media/platform/vimc/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-vimc-objs := vimc-core.o
-vimc_capture-objs := vimc-capture.o
-vimc_common-objs := vimc-common.o
-vimc_debayer-objs := vimc-debayer.o
-vimc_scaler-objs := vimc-scaler.o
-vimc_sensor-objs := vimc-sensor.o
-
-obj-$(CONFIG_VIDEO_VIMC) += vimc.o vimc_capture.o vimc_common.o vimc-debayer.o \
- vimc_scaler.o vimc_sensor.o
diff --git a/drivers/media/platform/vimc/vimc-capture.c b/drivers/media/platform/vimc/vimc-capture.c
deleted file mode 100644
index 3f7e9ed56633..000000000000
--- a/drivers/media/platform/vimc/vimc-capture.c
+++ /dev/null
@@ -1,543 +0,0 @@
-/*
- * vimc-capture.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/component.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <media/v4l2-ioctl.h>
-#include <media/videobuf2-core.h>
-#include <media/videobuf2-vmalloc.h>
-
-#include "vimc-common.h"
-
-#define VIMC_CAP_DRV_NAME "vimc-capture"
-
-struct vimc_cap_device {
- struct vimc_ent_device ved;
- struct video_device vdev;
- struct device *dev;
- struct v4l2_pix_format format;
- struct vb2_queue queue;
- struct list_head buf_list;
- /*
- * NOTE: in a real driver, a spin lock must be used to access the
- * queue because the frames are generated from a hardware interruption
- * and the isr is not allowed to sleep.
- * Even if it is not necessary a spinlock in the vimc driver, we
- * use it here as a code reference
- */
- spinlock_t qlock;
- struct mutex lock;
- u32 sequence;
- struct media_pipeline pipe;
-};
-
-static const struct v4l2_pix_format fmt_default = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_RGB24,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-struct vimc_cap_buffer {
- /*
- * struct vb2_v4l2_buffer must be the first element
- * the videobuf2 framework will allocate this struct based on
- * buf_struct_size and use the first sizeof(struct vb2_buffer) bytes of
- * memory as a vb2_buffer
- */
- struct vb2_v4l2_buffer vb2;
- struct list_head list;
-};
-
-static int vimc_cap_querycap(struct file *file, void *priv,
- struct v4l2_capability *cap)
-{
- struct vimc_cap_device *vcap = video_drvdata(file);
-
- strscpy(cap->driver, KBUILD_MODNAME, sizeof(cap->driver));
- strscpy(cap->card, KBUILD_MODNAME, sizeof(cap->card));
- snprintf(cap->bus_info, sizeof(cap->bus_info),
- "platform:%s", vcap->vdev.v4l2_dev->name);
-
- return 0;
-}
-
-static void vimc_cap_get_format(struct vimc_ent_device *ved,
- struct v4l2_pix_format *fmt)
-{
- struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
- ved);
-
- *fmt = vcap->format;
-}
-
-static int vimc_cap_g_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct vimc_cap_device *vcap = video_drvdata(file);
-
- f->fmt.pix = vcap->format;
-
- return 0;
-}
-
-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;
-
- /* 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;
-
- vimc_colorimetry_clamp(format);
-
- return 0;
-}
-
-static int vimc_cap_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct vimc_cap_device *vcap = video_drvdata(file);
-
- /* Do not change the format while stream is on */
- if (vb2_is_busy(&vcap->queue))
- return -EBUSY;
-
- vimc_cap_try_fmt_vid_cap(file, priv, f);
-
- dev_dbg(vcap->dev, "%s: format update: "
- "old:%dx%d (0x%x, %d, %d, %d, %d) "
- "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vcap->vdev.name,
- /* old */
- vcap->format.width, vcap->format.height,
- vcap->format.pixelformat, vcap->format.colorspace,
- vcap->format.quantization, vcap->format.xfer_func,
- vcap->format.ycbcr_enc,
- /* new */
- f->fmt.pix.width, f->fmt.pix.height,
- f->fmt.pix.pixelformat, f->fmt.pix.colorspace,
- f->fmt.pix.quantization, f->fmt.pix.xfer_func,
- f->fmt.pix.ycbcr_enc);
-
- vcap->format = f->fmt.pix;
-
- return 0;
-}
-
-static int vimc_cap_enum_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_fmtdesc *f)
-{
- const struct vimc_pix_map *vpix = vimc_pix_map_by_index(f->index);
-
- if (!vpix)
- return -EINVAL;
-
- f->pixelformat = vpix->pixelformat;
-
- return 0;
-}
-
-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;
-
- /* 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;
- fsize->stepwise.min_width = VIMC_FRAME_MIN_WIDTH;
- fsize->stepwise.max_width = VIMC_FRAME_MAX_WIDTH;
- fsize->stepwise.min_height = VIMC_FRAME_MIN_HEIGHT;
- fsize->stepwise.max_height = VIMC_FRAME_MAX_HEIGHT;
- fsize->stepwise.step_width = 2;
- fsize->stepwise.step_height = 2;
-
- return 0;
-}
-
-static const struct v4l2_file_operations vimc_cap_fops = {
- .owner = THIS_MODULE,
- .open = v4l2_fh_open,
- .release = vb2_fop_release,
- .read = vb2_fop_read,
- .poll = vb2_fop_poll,
- .unlocked_ioctl = video_ioctl2,
- .mmap = vb2_fop_mmap,
-};
-
-static const struct v4l2_ioctl_ops vimc_cap_ioctl_ops = {
- .vidioc_querycap = vimc_cap_querycap,
-
- .vidioc_g_fmt_vid_cap = vimc_cap_g_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vimc_cap_s_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = vimc_cap_try_fmt_vid_cap,
- .vidioc_enum_fmt_vid_cap = vimc_cap_enum_fmt_vid_cap,
- .vidioc_enum_framesizes = vimc_cap_enum_framesizes,
-
- .vidioc_reqbufs = vb2_ioctl_reqbufs,
- .vidioc_create_bufs = vb2_ioctl_create_bufs,
- .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
- .vidioc_querybuf = vb2_ioctl_querybuf,
- .vidioc_qbuf = vb2_ioctl_qbuf,
- .vidioc_dqbuf = vb2_ioctl_dqbuf,
- .vidioc_expbuf = vb2_ioctl_expbuf,
- .vidioc_streamon = vb2_ioctl_streamon,
- .vidioc_streamoff = vb2_ioctl_streamoff,
-};
-
-static void vimc_cap_return_all_buffers(struct vimc_cap_device *vcap,
- enum vb2_buffer_state state)
-{
- struct vimc_cap_buffer *vbuf, *node;
-
- spin_lock(&vcap->qlock);
-
- list_for_each_entry_safe(vbuf, node, &vcap->buf_list, list) {
- list_del(&vbuf->list);
- vb2_buffer_done(&vbuf->vb2.vb2_buf, state);
- }
-
- spin_unlock(&vcap->qlock);
-}
-
-static int vimc_cap_start_streaming(struct vb2_queue *vq, unsigned int count)
-{
- struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
- struct media_entity *entity = &vcap->vdev.entity;
- int ret;
-
- vcap->sequence = 0;
-
- /* Start the media pipeline */
- ret = media_pipeline_start(entity, &vcap->pipe);
- if (ret) {
- vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
- return ret;
- }
-
- /* Enable streaming from the pipe */
- ret = vimc_pipeline_s_stream(&vcap->vdev.entity, 1);
- if (ret) {
- media_pipeline_stop(entity);
- vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_QUEUED);
- return ret;
- }
-
- return 0;
-}
-
-/*
- * Stop the stream engine. Any remaining buffers in the stream queue are
- * dequeued and passed on to the vb2 framework marked as STATE_ERROR.
- */
-static void vimc_cap_stop_streaming(struct vb2_queue *vq)
-{
- struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
-
- /* Disable streaming from the pipe */
- vimc_pipeline_s_stream(&vcap->vdev.entity, 0);
-
- /* Stop the media pipeline */
- media_pipeline_stop(&vcap->vdev.entity);
-
- /* Release all active buffers */
- vimc_cap_return_all_buffers(vcap, VB2_BUF_STATE_ERROR);
-}
-
-static void vimc_cap_buf_queue(struct vb2_buffer *vb2_buf)
-{
- struct vimc_cap_device *vcap = vb2_get_drv_priv(vb2_buf->vb2_queue);
- struct vimc_cap_buffer *buf = container_of(vb2_buf,
- struct vimc_cap_buffer,
- vb2.vb2_buf);
-
- spin_lock(&vcap->qlock);
- list_add_tail(&buf->list, &vcap->buf_list);
- spin_unlock(&vcap->qlock);
-}
-
-static int vimc_cap_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
- unsigned int *nplanes, unsigned int sizes[],
- struct device *alloc_devs[])
-{
- struct vimc_cap_device *vcap = vb2_get_drv_priv(vq);
-
- if (*nplanes)
- return sizes[0] < vcap->format.sizeimage ? -EINVAL : 0;
- /* We don't support multiplanes for now */
- *nplanes = 1;
- sizes[0] = vcap->format.sizeimage;
-
- return 0;
-}
-
-static int vimc_cap_buffer_prepare(struct vb2_buffer *vb)
-{
- struct vimc_cap_device *vcap = vb2_get_drv_priv(vb->vb2_queue);
- unsigned long size = vcap->format.sizeimage;
-
- if (vb2_plane_size(vb, 0) < size) {
- dev_err(vcap->dev, "%s: buffer too small (%lu < %lu)\n",
- vcap->vdev.name, vb2_plane_size(vb, 0), size);
- return -EINVAL;
- }
- return 0;
-}
-
-static const struct vb2_ops vimc_cap_qops = {
- .start_streaming = vimc_cap_start_streaming,
- .stop_streaming = vimc_cap_stop_streaming,
- .buf_queue = vimc_cap_buf_queue,
- .queue_setup = vimc_cap_queue_setup,
- .buf_prepare = vimc_cap_buffer_prepare,
- /*
- * Since q->lock is set we can use the standard
- * vb2_ops_wait_prepare/finish helper functions.
- */
- .wait_prepare = vb2_ops_wait_prepare,
- .wait_finish = vb2_ops_wait_finish,
-};
-
-static const struct media_entity_operations vimc_cap_mops = {
- .link_validate = vimc_link_validate,
-};
-
-static void vimc_cap_comp_unbind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
- struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
- ved);
-
- vb2_queue_release(&vcap->queue);
- media_entity_cleanup(ved->ent);
- video_unregister_device(&vcap->vdev);
- vimc_pads_cleanup(vcap->ved.pads);
- kfree(vcap);
-}
-
-static void vimc_cap_process_frame(struct vimc_ent_device *ved,
- struct media_pad *sink, const void *frame)
-{
- struct vimc_cap_device *vcap = container_of(ved, struct vimc_cap_device,
- ved);
- struct vimc_cap_buffer *vimc_buf;
- void *vbuf;
-
- spin_lock(&vcap->qlock);
-
- /* Get the first entry of the list */
- vimc_buf = list_first_entry_or_null(&vcap->buf_list,
- typeof(*vimc_buf), list);
- if (!vimc_buf) {
- spin_unlock(&vcap->qlock);
- return;
- }
-
- /* Remove this entry from the list */
- list_del(&vimc_buf->list);
-
- spin_unlock(&vcap->qlock);
-
- /* Fill the buffer */
- vimc_buf->vb2.vb2_buf.timestamp = ktime_get_ns();
- vimc_buf->vb2.sequence = vcap->sequence++;
- vimc_buf->vb2.field = vcap->format.field;
-
- vbuf = vb2_plane_vaddr(&vimc_buf->vb2.vb2_buf, 0);
-
- memcpy(vbuf, frame, vcap->format.sizeimage);
-
- /* Set it as ready */
- vb2_set_plane_payload(&vimc_buf->vb2.vb2_buf, 0,
- vcap->format.sizeimage);
- vb2_buffer_done(&vimc_buf->vb2.vb2_buf, VB2_BUF_STATE_DONE);
-}
-
-static int vimc_cap_comp_bind(struct device *comp, struct device *master,
- void *master_data)
-{
- 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;
- int ret;
-
- /* Allocate the vimc_cap_device struct */
- vcap = kzalloc(sizeof(*vcap), GFP_KERNEL);
- if (!vcap)
- return -ENOMEM;
-
- /* Allocate the pads */
- vcap->ved.pads =
- vimc_pads_init(1, (const unsigned long[1]) {MEDIA_PAD_FL_SINK});
- if (IS_ERR(vcap->ved.pads)) {
- ret = PTR_ERR(vcap->ved.pads);
- goto err_free_vcap;
- }
-
- /* Initialize the media entity */
- vcap->vdev.entity.name = pdata->entity_name;
- vcap->vdev.entity.function = MEDIA_ENT_F_IO_V4L;
- ret = media_entity_pads_init(&vcap->vdev.entity,
- 1, vcap->ved.pads);
- if (ret)
- goto err_clean_pads;
-
- /* Initialize the lock */
- mutex_init(&vcap->lock);
-
- /* Initialize the vb2 queue */
- q = &vcap->queue;
- q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- q->io_modes = VB2_MMAP | VB2_DMABUF;
- q->drv_priv = vcap;
- q->buf_struct_size = sizeof(struct vimc_cap_buffer);
- q->ops = &vimc_cap_qops;
- q->mem_ops = &vb2_vmalloc_memops;
- q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
- q->min_buffers_needed = 2;
- q->lock = &vcap->lock;
-
- ret = vb2_queue_init(q);
- if (ret) {
- dev_err(comp, "%s: vb2 queue init failed (err=%d)\n",
- pdata->entity_name, ret);
- goto err_clean_m_ent;
- }
-
- /* Initialize buffer list and its lock */
- INIT_LIST_HEAD(&vcap->buf_list);
- spin_lock_init(&vcap->qlock);
-
- /* Set default frame format */
- vcap->format = fmt_default;
- 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;
- vcap->ved.process_frame = vimc_cap_process_frame;
- vcap->ved.vdev_get_format = vimc_cap_get_format;
- dev_set_drvdata(comp, &vcap->ved);
- vcap->dev = comp;
-
- /* Initialize the video_device struct */
- vdev = &vcap->vdev;
- vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
- vdev->entity.ops = &vimc_cap_mops;
- vdev->release = video_device_release_empty;
- vdev->fops = &vimc_cap_fops;
- vdev->ioctl_ops = &vimc_cap_ioctl_ops;
- vdev->lock = &vcap->lock;
- vdev->queue = q;
- vdev->v4l2_dev = v4l2_dev;
- vdev->vfl_dir = VFL_DIR_RX;
- strscpy(vdev->name, pdata->entity_name, sizeof(vdev->name));
- video_set_drvdata(vdev, &vcap->ved);
-
- /* Register the video_device with the v4l2 and the media framework */
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
- if (ret) {
- dev_err(comp, "%s: video register failed (err=%d)\n",
- vcap->vdev.name, ret);
- goto err_release_queue;
- }
-
- return 0;
-
-err_release_queue:
- vb2_queue_release(q);
-err_clean_m_ent:
- media_entity_cleanup(&vcap->vdev.entity);
-err_clean_pads:
- vimc_pads_cleanup(vcap->ved.pads);
-err_free_vcap:
- kfree(vcap);
-
- return ret;
-}
-
-static const struct component_ops vimc_cap_comp_ops = {
- .bind = vimc_cap_comp_bind,
- .unbind = vimc_cap_comp_unbind,
-};
-
-static int vimc_cap_probe(struct platform_device *pdev)
-{
- return component_add(&pdev->dev, &vimc_cap_comp_ops);
-}
-
-static int vimc_cap_remove(struct platform_device *pdev)
-{
- component_del(&pdev->dev, &vimc_cap_comp_ops);
-
- return 0;
-}
-
-static const struct platform_device_id vimc_cap_driver_ids[] = {
- {
- .name = VIMC_CAP_DRV_NAME,
- },
- { }
-};
-
-static struct platform_driver vimc_cap_pdrv = {
- .probe = vimc_cap_probe,
- .remove = vimc_cap_remove,
- .id_table = vimc_cap_driver_ids,
- .driver = {
- .name = VIMC_CAP_DRV_NAME,
- },
-};
-
-module_platform_driver(vimc_cap_pdrv);
-
-MODULE_DEVICE_TABLE(platform, vimc_cap_driver_ids);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Capture");
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-common.c b/drivers/media/platform/vimc/vimc-common.c
deleted file mode 100644
index 867e24dbd6b5..000000000000
--- a/drivers/media/platform/vimc/vimc-common.c
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- * vimc-common.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-
-#include "vimc-common.h"
-
-/*
- * 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,
- },
-};
-
-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_pix_map_list); i++) {
- if (vimc_pix_map_list[i].code == code)
- return &vimc_pix_map_list[i];
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(vimc_pix_map_by_code);
-
-const struct vimc_pix_map *vimc_pix_map_by_pixelformat(u32 pixelformat)
-{
- unsigned int i;
-
- 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_pix_map_by_pixelformat);
-
-int vimc_propagate_frame(struct media_pad *src, const void *frame)
-{
- struct media_link *link;
-
- if (!(src->flags & MEDIA_PAD_FL_SOURCE))
- return -EINVAL;
-
- /* Send this frame to all sink pads that are direct linked */
- list_for_each_entry(link, &src->entity->links, list) {
- if (link->source == src &&
- (link->flags & MEDIA_LNK_FL_ENABLED)) {
- struct vimc_ent_device *ved = NULL;
- struct media_entity *entity = link->sink->entity;
-
- if (is_media_entity_v4l2_subdev(entity)) {
- struct v4l2_subdev *sd =
- container_of(entity, struct v4l2_subdev,
- entity);
- ved = v4l2_get_subdevdata(sd);
- } else if (is_media_entity_v4l2_video_device(entity)) {
- struct video_device *vdev =
- container_of(entity,
- struct video_device,
- entity);
- ved = video_get_drvdata(vdev);
- }
- if (ved && ved->process_frame)
- ved->process_frame(ved, link->sink, frame);
- }
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vimc_propagate_frame);
-
-/* Helper function to allocate and initialize pads */
-struct media_pad *vimc_pads_init(u16 num_pads, const unsigned long *pads_flag)
-{
- struct media_pad *pads;
- unsigned int i;
-
- /* Allocate memory for the pads */
- pads = kcalloc(num_pads, sizeof(*pads), GFP_KERNEL);
- if (!pads)
- return ERR_PTR(-ENOMEM);
-
- /* Initialize the pads */
- for (i = 0; i < num_pads; i++) {
- pads[i].index = i;
- pads[i].flags = pads_flag[i];
- }
-
- return pads;
-}
-EXPORT_SYMBOL_GPL(vimc_pads_init);
-
-int vimc_pipeline_s_stream(struct media_entity *ent, int enable)
-{
- struct v4l2_subdev *sd;
- struct media_pad *pad;
- unsigned int i;
- int ret;
-
- for (i = 0; i < ent->num_pads; i++) {
- if (ent->pads[i].flags & MEDIA_PAD_FL_SOURCE)
- continue;
-
- /* Start the stream in the subdevice direct connected */
- pad = media_entity_remote_pad(&ent->pads[i]);
- if (!pad)
- continue;
-
- if (!is_media_entity_v4l2_subdev(pad->entity))
- return -EINVAL;
-
- sd = media_entity_to_v4l2_subdev(pad->entity);
- ret = v4l2_subdev_call(sd, video, s_stream, enable);
- if (ret && ret != -ENOIOCTLCMD)
- return ret;
- }
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vimc_pipeline_s_stream);
-
-static int vimc_get_mbus_format(struct media_pad *pad,
- struct v4l2_subdev_format *fmt)
-{
- if (is_media_entity_v4l2_subdev(pad->entity)) {
- struct v4l2_subdev *sd =
- media_entity_to_v4l2_subdev(pad->entity);
- int ret;
-
- fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
- fmt->pad = pad->index;
-
- ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, fmt);
- if (ret)
- return ret;
-
- } else if (is_media_entity_v4l2_video_device(pad->entity)) {
- struct video_device *vdev = container_of(pad->entity,
- 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);
- vpix = vimc_pix_map_by_pixelformat(vdev_fmt.pixelformat);
- v4l2_fill_mbus_format(&fmt->format, &vdev_fmt, vpix->code);
- } else {
- return -EINVAL;
- }
-
- return 0;
-}
-
-int vimc_link_validate(struct media_link *link)
-{
- struct v4l2_subdev_format source_fmt, sink_fmt;
- int ret;
-
- ret = vimc_get_mbus_format(link->source, &source_fmt);
- if (ret)
- return ret;
-
- ret = vimc_get_mbus_format(link->sink, &sink_fmt);
- if (ret)
- return ret;
-
- pr_info("vimc link validate: "
- "%s:src:%dx%d (0x%x, %d, %d, %d, %d) "
- "%s:snk:%dx%d (0x%x, %d, %d, %d, %d)\n",
- /* src */
- link->source->entity->name,
- source_fmt.format.width, source_fmt.format.height,
- source_fmt.format.code, source_fmt.format.colorspace,
- source_fmt.format.quantization, source_fmt.format.xfer_func,
- source_fmt.format.ycbcr_enc,
- /* sink */
- link->sink->entity->name,
- sink_fmt.format.width, sink_fmt.format.height,
- sink_fmt.format.code, sink_fmt.format.colorspace,
- sink_fmt.format.quantization, sink_fmt.format.xfer_func,
- sink_fmt.format.ycbcr_enc);
-
- /* 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)
- return -EPIPE;
-
- /*
- * The field order must match, or the sink field order must be NONE
- * to support interlaced hardware connected to bridges that support
- * progressive formats only.
- */
- if (source_fmt.format.field != sink_fmt.format.field &&
- sink_fmt.format.field != V4L2_FIELD_NONE)
- return -EPIPE;
-
- /*
- * If colorspace is DEFAULT, then assume all the colorimetry is also
- * DEFAULT, return 0 to skip comparing the other colorimetry parameters
- */
- if (source_fmt.format.colorspace == V4L2_COLORSPACE_DEFAULT
- || sink_fmt.format.colorspace == V4L2_COLORSPACE_DEFAULT)
- return 0;
-
- /* Colorspace must match. */
- if (source_fmt.format.colorspace != sink_fmt.format.colorspace)
- return -EPIPE;
-
- /* Colorimetry must match if they are not set to DEFAULT */
- if (source_fmt.format.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT
- && sink_fmt.format.ycbcr_enc != V4L2_YCBCR_ENC_DEFAULT
- && source_fmt.format.ycbcr_enc != sink_fmt.format.ycbcr_enc)
- return -EPIPE;
-
- if (source_fmt.format.quantization != V4L2_QUANTIZATION_DEFAULT
- && sink_fmt.format.quantization != V4L2_QUANTIZATION_DEFAULT
- && source_fmt.format.quantization != sink_fmt.format.quantization)
- return -EPIPE;
-
- if (source_fmt.format.xfer_func != V4L2_XFER_FUNC_DEFAULT
- && sink_fmt.format.xfer_func != V4L2_XFER_FUNC_DEFAULT
- && source_fmt.format.xfer_func != sink_fmt.format.xfer_func)
- return -EPIPE;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(vimc_link_validate);
-
-static const struct media_entity_operations vimc_ent_sd_mops = {
- .link_validate = vimc_link_validate,
-};
-
-int vimc_ent_sd_register(struct vimc_ent_device *ved,
- struct v4l2_subdev *sd,
- struct v4l2_device *v4l2_dev,
- const char *const name,
- u32 function,
- u16 num_pads,
- const unsigned long *pads_flag,
- const struct v4l2_subdev_ops *sd_ops)
-{
- int ret;
-
- /* Allocate the pads */
- ved->pads = vimc_pads_init(num_pads, pads_flag);
- if (IS_ERR(ved->pads))
- return PTR_ERR(ved->pads);
-
- /* Fill the vimc_ent_device struct */
- ved->ent = &sd->entity;
-
- /* Initialize the subdev */
- v4l2_subdev_init(sd, sd_ops);
- sd->entity.function = function;
- sd->entity.ops = &vimc_ent_sd_mops;
- sd->owner = THIS_MODULE;
- strscpy(sd->name, name, sizeof(sd->name));
- v4l2_set_subdevdata(sd, ved);
-
- /* Expose this subdev to user space */
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
- if (sd->ctrl_handler)
- sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS;
-
- /* Initialize the media entity */
- ret = media_entity_pads_init(&sd->entity, num_pads, ved->pads);
- if (ret)
- goto err_clean_pads;
-
- /* Register the subdev with the v4l2 and the media framework */
- ret = v4l2_device_register_subdev(v4l2_dev, sd);
- if (ret) {
- dev_err(v4l2_dev->dev,
- "%s: subdev register failed (err=%d)\n",
- name, ret);
- goto err_clean_m_ent;
- }
-
- return 0;
-
-err_clean_m_ent:
- media_entity_cleanup(&sd->entity);
-err_clean_pads:
- vimc_pads_cleanup(ved->pads);
- return ret;
-}
-EXPORT_SYMBOL_GPL(vimc_ent_sd_register);
-
-void vimc_ent_sd_unregister(struct vimc_ent_device *ved, struct v4l2_subdev *sd)
-{
- v4l2_device_unregister_subdev(sd);
- media_entity_cleanup(ved->ent);
- vimc_pads_cleanup(ved->pads);
-}
-EXPORT_SYMBOL_GPL(vimc_ent_sd_unregister);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Common");
-MODULE_AUTHOR("Helen Koike <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-common.h b/drivers/media/platform/vimc/vimc-common.h
deleted file mode 100644
index 2e9981b18166..000000000000
--- a/drivers/media/platform/vimc/vimc-common.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * vimc-common.h Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#ifndef _VIMC_COMMON_H_
-#define _VIMC_COMMON_H_
-
-#include <linux/slab.h>
-#include <media/media-device.h>
-#include <media/v4l2-device.h>
-
-/* VIMC-specific controls */
-#define VIMC_CID_VIMC_BASE (0x00f00000 | 0xf000)
-#define VIMC_CID_VIMC_CLASS (0x00f00000 | 1)
-#define VIMC_CID_TEST_PATTERN (VIMC_CID_VIMC_BASE + 0)
-
-#define VIMC_FRAME_MAX_WIDTH 4096
-#define VIMC_FRAME_MAX_HEIGHT 2160
-#define VIMC_FRAME_MIN_WIDTH 16
-#define VIMC_FRAME_MIN_HEIGHT 16
-
-#define VIMC_FRAME_INDEX(lin, col, width, bpp) ((lin * width + col) * bpp)
-
-/**
- * struct vimc_colorimetry_clamp - Adjust colorimetry parameters
- *
- * @fmt: the pointer to struct v4l2_pix_format or
- * struct v4l2_mbus_framefmt
- *
- * Entities must check if colorimetry given by the userspace is valid, if not
- * then set them as DEFAULT
- */
-#define vimc_colorimetry_clamp(fmt) \
-do { \
- if ((fmt)->colorspace == V4L2_COLORSPACE_DEFAULT \
- || (fmt)->colorspace > V4L2_COLORSPACE_DCI_P3) { \
- (fmt)->colorspace = V4L2_COLORSPACE_DEFAULT; \
- (fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; \
- (fmt)->quantization = V4L2_QUANTIZATION_DEFAULT; \
- (fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT; \
- } \
- if ((fmt)->ycbcr_enc > V4L2_YCBCR_ENC_SMPTE240M) \
- (fmt)->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; \
- if ((fmt)->quantization > V4L2_QUANTIZATION_LIM_RANGE) \
- (fmt)->quantization = V4L2_QUANTIZATION_DEFAULT; \
- if ((fmt)->xfer_func > V4L2_XFER_FUNC_SMPTE2084) \
- (fmt)->xfer_func = V4L2_XFER_FUNC_DEFAULT; \
-} while (0)
-
-/**
- * struct vimc_platform_data - platform data to components
- *
- * @entity_name: The name of the entity to be created
- *
- * Board setup code will often provide additional information using the device's
- * platform_data field to hold additional information.
- * When injecting a new platform_device in the component system the core needs
- * to provide to the corresponding submodules the name of the entity that should
- * be used when registering the subdevice in the Media Controller system.
- */
-struct vimc_platform_data {
- char entity_name[32];
-};
-
-/**
- * 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
- * @pads: the list of pads of the node
- * @process_frame: callback send a frame to that node
- * @vdev_get_format: callback that returns the current format a pad, used
- * only when is_media_entity_v4l2_video_device(ent) returns
- * true
- *
- * Each node of the topology must create a vimc_ent_device struct. Depending on
- * the node it will be of an instance of v4l2_subdev or video_device struct
- * where both contains a struct media_entity.
- * Those structures should embedded the vimc_ent_device struct through
- * v4l2_set_subdevdata() and video_set_drvdata() respectivaly, allowing the
- * vimc_ent_device struct to be retrieved from the corresponding struct
- * media_entity
- */
-struct vimc_ent_device {
- struct media_entity *ent;
- struct media_pad *pads;
- void (*process_frame)(struct vimc_ent_device *ved,
- struct media_pad *sink, const void *frame);
- void (*vdev_get_format)(struct vimc_ent_device *ved,
- struct v4l2_pix_format *fmt);
-};
-
-/**
- * vimc_propagate_frame - propagate a frame through the topology
- *
- * @src: the source pad where the frame is being originated
- * @frame: the frame to be propagated
- *
- * This function will call the process_frame callback from the vimc_ent_device
- * struct of the nodes directly connected to the @src pad
- */
-int vimc_propagate_frame(struct media_pad *src, const void *frame);
-
-/**
- * vimc_pads_init - initialize pads
- *
- * @num_pads: number of pads to initialize
- * @pads_flags: flags to use in each pad
- *
- * Helper functions to allocate/initialize pads
- */
-struct media_pad *vimc_pads_init(u16 num_pads,
- const unsigned long *pads_flag);
-
-/**
- * vimc_pads_cleanup - free pads
- *
- * @pads: pointer to the pads
- *
- * Helper function to free the pads initialized with vimc_pads_init
- */
-static inline void vimc_pads_cleanup(struct media_pad *pads)
-{
- kfree(pads);
-}
-
-/**
- * vimc_pipeline_s_stream - start stream through the pipeline
- *
- * @ent: the pointer to struct media_entity for the node
- * @enable: 1 to start the stream and 0 to stop
- *
- * Helper function to call the s_stream of the subdevices connected
- * in all the sink pads of the entity
- */
-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
- * @sd: the v4l2_subdev struct to be initialize and registered
- * @v4l2_dev: the v4l2 device to register the v4l2_subdev
- * @name: name of the sub-device. Please notice that the name must be
- * unique.
- * @function: media entity function defined by MEDIA_ENT_F_* macros
- * @num_pads: number of pads to initialize
- * @pads_flag: flags to use in each pad
- * @sd_ops: pointer to &struct v4l2_subdev_ops.
- *
- * Helper function initialize and register the struct vimc_ent_device and struct
- * v4l2_subdev which represents a subdev node in the topology
- */
-int vimc_ent_sd_register(struct vimc_ent_device *ved,
- struct v4l2_subdev *sd,
- struct v4l2_device *v4l2_dev,
- const char *const name,
- u32 function,
- u16 num_pads,
- const unsigned long *pads_flag,
- const struct v4l2_subdev_ops *sd_ops);
-
-/**
- * vimc_ent_sd_unregister - cleanup and unregister a subdev node
- *
- * @ved: the vimc_ent_device struct to be cleaned up
- * @sd: the v4l2_subdev struct to be unregistered
- *
- * Helper function cleanup and unregister the struct vimc_ent_device and struct
- * v4l2_subdev which represents a subdev node in the topology
- */
-void vimc_ent_sd_unregister(struct vimc_ent_device *ved,
- struct v4l2_subdev *sd);
-
-/**
- * vimc_link_validate - validates a media link
- *
- * @link: pointer to &struct media_link
- *
- * This function calls validates if a media link is valid for streaming.
- */
-int vimc_link_validate(struct media_link *link);
-
-#endif
diff --git a/drivers/media/platform/vimc/vimc-core.c b/drivers/media/platform/vimc/vimc-core.c
deleted file mode 100644
index ce809d2e3d53..000000000000
--- a/drivers/media/platform/vimc/vimc-core.c
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * vimc-core.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/component.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <media/media-device.h>
-#include <media/v4l2-device.h>
-
-#include "vimc-common.h"
-
-#define VIMC_PDEV_NAME "vimc"
-#define VIMC_MDEV_MODEL_NAME "VIMC MDEV"
-
-#define VIMC_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) { \
- .src_ent = src, \
- .src_pad = srcpad, \
- .sink_ent = sink, \
- .sink_pad = sinkpad, \
- .flags = link_flags, \
-}
-
-struct vimc_device {
- /* The platform device */
- struct platform_device pdev;
-
- /* The pipeline configuration */
- const struct vimc_pipeline_config *pipe_cfg;
-
- /* The Associated media_device parent */
- struct media_device mdev;
-
- /* Internal v4l2 parent device*/
- struct v4l2_device v4l2_dev;
-
- /* Subdevices */
- struct platform_device **subdevs;
-};
-
-/* Structure which describes individual configuration for each entity */
-struct vimc_ent_config {
- const char *name;
- const char *drv;
-};
-
-/* Structure which describes links between entities */
-struct vimc_ent_link {
- unsigned int src_ent;
- u16 src_pad;
- unsigned int sink_ent;
- u16 sink_pad;
- u32 flags;
-};
-
-/* Structure which describes the whole topology */
-struct vimc_pipeline_config {
- const struct vimc_ent_config *ents;
- size_t num_ents;
- const struct vimc_ent_link *links;
- size_t num_links;
-};
-
-/* --------------------------------------------------------------------------
- * Topology Configuration
- */
-
-static const struct vimc_ent_config ent_config[] = {
- {
- .name = "Sensor A",
- .drv = "vimc-sensor",
- },
- {
- .name = "Sensor B",
- .drv = "vimc-sensor",
- },
- {
- .name = "Debayer A",
- .drv = "vimc-debayer",
- },
- {
- .name = "Debayer B",
- .drv = "vimc-debayer",
- },
- {
- .name = "Raw Capture 0",
- .drv = "vimc-capture",
- },
- {
- .name = "Raw Capture 1",
- .drv = "vimc-capture",
- },
- {
- .name = "RGB/YUV Input",
- /* TODO: change this to vimc-input when it is implemented */
- .drv = "vimc-sensor",
- },
- {
- .name = "Scaler",
- .drv = "vimc-scaler",
- },
- {
- .name = "RGB/YUV Capture",
- .drv = "vimc-capture",
- },
-};
-
-static const struct vimc_ent_link ent_links[] = {
- /* Link: Sensor A (Pad 0)->(Pad 0) Debayer A */
- VIMC_ENT_LINK(0, 0, 2, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
- /* Link: Sensor A (Pad 0)->(Pad 0) Raw Capture 0 */
- VIMC_ENT_LINK(0, 0, 4, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
- /* Link: Sensor B (Pad 0)->(Pad 0) Debayer B */
- VIMC_ENT_LINK(1, 0, 3, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
- /* Link: Sensor B (Pad 0)->(Pad 0) Raw Capture 1 */
- VIMC_ENT_LINK(1, 0, 5, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
- /* Link: Debayer A (Pad 1)->(Pad 0) Scaler */
- VIMC_ENT_LINK(2, 1, 7, 0, MEDIA_LNK_FL_ENABLED),
- /* Link: Debayer B (Pad 1)->(Pad 0) Scaler */
- VIMC_ENT_LINK(3, 1, 7, 0, 0),
- /* Link: RGB/YUV Input (Pad 0)->(Pad 0) Scaler */
- VIMC_ENT_LINK(6, 0, 7, 0, 0),
- /* Link: Scaler (Pad 1)->(Pad 0) RGB/YUV Capture */
- VIMC_ENT_LINK(7, 1, 8, 0, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
-};
-
-static const struct vimc_pipeline_config pipe_cfg = {
- .ents = ent_config,
- .num_ents = ARRAY_SIZE(ent_config),
- .links = ent_links,
- .num_links = ARRAY_SIZE(ent_links)
-};
-
-/* -------------------------------------------------------------------------- */
-
-static int vimc_create_links(struct vimc_device *vimc)
-{
- unsigned int i;
- int ret;
-
- /* Initialize the links between entities */
- for (i = 0; i < vimc->pipe_cfg->num_links; i++) {
- const struct vimc_ent_link *link = &vimc->pipe_cfg->links[i];
- /*
- * TODO: Check another way of retrieving ved struct without
- * relying on platform_get_drvdata
- */
- struct vimc_ent_device *ved_src =
- platform_get_drvdata(vimc->subdevs[link->src_ent]);
- struct vimc_ent_device *ved_sink =
- platform_get_drvdata(vimc->subdevs[link->sink_ent]);
-
- ret = media_create_pad_link(ved_src->ent, link->src_pad,
- ved_sink->ent, link->sink_pad,
- link->flags);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
-static int vimc_comp_bind(struct device *master)
-{
- struct vimc_device *vimc = container_of(to_platform_device(master),
- struct vimc_device, pdev);
- int ret;
-
- dev_dbg(master, "bind");
-
- /* Register the v4l2 struct */
- ret = v4l2_device_register(vimc->mdev.dev, &vimc->v4l2_dev);
- if (ret) {
- dev_err(vimc->mdev.dev,
- "v4l2 device register failed (err=%d)\n", ret);
- return ret;
- }
-
- /* Bind subdevices */
- ret = component_bind_all(master, &vimc->v4l2_dev);
- if (ret)
- goto err_v4l2_unregister;
-
- /* Initialize links */
- ret = vimc_create_links(vimc);
- if (ret)
- goto err_comp_unbind_all;
-
- /* Register the media device */
- ret = media_device_register(&vimc->mdev);
- if (ret) {
- dev_err(vimc->mdev.dev,
- "media device register failed (err=%d)\n", ret);
- goto err_comp_unbind_all;
- }
-
- /* Expose all subdev's nodes*/
- ret = v4l2_device_register_subdev_nodes(&vimc->v4l2_dev);
- if (ret) {
- dev_err(vimc->mdev.dev,
- "vimc subdev nodes registration failed (err=%d)\n",
- ret);
- goto err_mdev_unregister;
- }
-
- return 0;
-
-err_mdev_unregister:
- media_device_unregister(&vimc->mdev);
-err_comp_unbind_all:
- component_unbind_all(master, NULL);
-err_v4l2_unregister:
- v4l2_device_unregister(&vimc->v4l2_dev);
-
- return ret;
-}
-
-static void vimc_comp_unbind(struct device *master)
-{
- struct vimc_device *vimc = container_of(to_platform_device(master),
- struct vimc_device, pdev);
-
- dev_dbg(master, "unbind");
-
- media_device_unregister(&vimc->mdev);
- component_unbind_all(master, NULL);
- v4l2_device_unregister(&vimc->v4l2_dev);
-}
-
-static int vimc_comp_compare(struct device *comp, void *data)
-{
- const struct platform_device *pdev = to_platform_device(comp);
- const char *name = data;
-
- return !strcmp(pdev->dev.platform_data, name);
-}
-
-static struct component_match *vimc_add_subdevs(struct vimc_device *vimc)
-{
- struct component_match *match = NULL;
- struct vimc_platform_data pdata;
- int i;
-
- for (i = 0; i < vimc->pipe_cfg->num_ents; i++) {
- dev_dbg(&vimc->pdev.dev, "new pdev for %s\n",
- vimc->pipe_cfg->ents[i].drv);
-
- strscpy(pdata.entity_name, vimc->pipe_cfg->ents[i].name,
- sizeof(pdata.entity_name));
-
- vimc->subdevs[i] = platform_device_register_data(&vimc->pdev.dev,
- vimc->pipe_cfg->ents[i].drv,
- PLATFORM_DEVID_AUTO,
- &pdata,
- sizeof(pdata));
- if (IS_ERR(vimc->subdevs[i])) {
- match = ERR_CAST(vimc->subdevs[i]);
- while (--i >= 0)
- platform_device_unregister(vimc->subdevs[i]);
-
- return match;
- }
-
- component_match_add(&vimc->pdev.dev, &match, vimc_comp_compare,
- (void *)vimc->pipe_cfg->ents[i].name);
- }
-
- return match;
-}
-
-static void vimc_rm_subdevs(struct vimc_device *vimc)
-{
- unsigned int i;
-
- for (i = 0; i < vimc->pipe_cfg->num_ents; i++)
- platform_device_unregister(vimc->subdevs[i]);
-}
-
-static const struct component_master_ops vimc_comp_ops = {
- .bind = vimc_comp_bind,
- .unbind = vimc_comp_unbind,
-};
-
-static int vimc_probe(struct platform_device *pdev)
-{
- struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev);
- struct component_match *match = NULL;
- int ret;
-
- dev_dbg(&pdev->dev, "probe");
-
- /* Create platform_device for each entity in the topology*/
- vimc->subdevs = devm_kcalloc(&vimc->pdev.dev, vimc->pipe_cfg->num_ents,
- sizeof(*vimc->subdevs), GFP_KERNEL);
- if (!vimc->subdevs)
- return -ENOMEM;
-
- match = vimc_add_subdevs(vimc);
- if (IS_ERR(match))
- return PTR_ERR(match);
-
- /* Link the media device within the v4l2_device */
- vimc->v4l2_dev.mdev = &vimc->mdev;
-
- /* Initialize media device */
- strscpy(vimc->mdev.model, VIMC_MDEV_MODEL_NAME,
- sizeof(vimc->mdev.model));
- vimc->mdev.dev = &pdev->dev;
- media_device_init(&vimc->mdev);
-
- /* Add self to the component system */
- ret = component_master_add_with_match(&pdev->dev, &vimc_comp_ops,
- match);
- if (ret) {
- media_device_cleanup(&vimc->mdev);
- vimc_rm_subdevs(vimc);
- return ret;
- }
-
- return 0;
-}
-
-static int vimc_remove(struct platform_device *pdev)
-{
- struct vimc_device *vimc = container_of(pdev, struct vimc_device, pdev);
-
- dev_dbg(&pdev->dev, "remove");
-
- component_master_del(&pdev->dev, &vimc_comp_ops);
- vimc_rm_subdevs(vimc);
-
- return 0;
-}
-
-static void vimc_dev_release(struct device *dev)
-{
-}
-
-static struct vimc_device vimc_dev = {
- .pipe_cfg = &pipe_cfg,
- .pdev = {
- .name = VIMC_PDEV_NAME,
- .dev.release = vimc_dev_release,
- }
-};
-
-static struct platform_driver vimc_pdrv = {
- .probe = vimc_probe,
- .remove = vimc_remove,
- .driver = {
- .name = VIMC_PDEV_NAME,
- },
-};
-
-static int __init vimc_init(void)
-{
- int ret;
-
- ret = platform_device_register(&vimc_dev.pdev);
- if (ret) {
- dev_err(&vimc_dev.pdev.dev,
- "platform device registration failed (err=%d)\n", ret);
- return ret;
- }
-
- ret = platform_driver_register(&vimc_pdrv);
- if (ret) {
- dev_err(&vimc_dev.pdev.dev,
- "platform driver registration failed (err=%d)\n", ret);
- platform_driver_unregister(&vimc_pdrv);
- return ret;
- }
-
- return 0;
-}
-
-static void __exit vimc_exit(void)
-{
- platform_driver_unregister(&vimc_pdrv);
-
- platform_device_unregister(&vimc_dev.pdev);
-}
-
-module_init(vimc_init);
-module_exit(vimc_exit);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC)");
-MODULE_AUTHOR("Helen Fornazier <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-debayer.c b/drivers/media/platform/vimc/vimc-debayer.c
deleted file mode 100644
index 77887f66f323..000000000000
--- a/drivers/media/platform/vimc/vimc-debayer.c
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- * vimc-debayer.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/component.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/vmalloc.h>
-#include <linux/v4l2-mediabus.h>
-#include <media/v4l2-subdev.h>
-
-#include "vimc-common.h"
-
-#define VIMC_DEB_DRV_NAME "vimc-debayer"
-
-static unsigned int deb_mean_win_size = 3;
-module_param(deb_mean_win_size, uint, 0000);
-MODULE_PARM_DESC(deb_mean_win_size, " the window size to calculate the mean.\n"
- "NOTE: the window size need to be an odd number, as the main pixel "
- "stays in the center of the window, otherwise the next odd number "
- "is considered");
-
-#define IS_SINK(pad) (!pad)
-#define IS_SRC(pad) (pad)
-
-enum vimc_deb_rgb_colors {
- VIMC_DEB_RED = 0,
- VIMC_DEB_GREEN = 1,
- VIMC_DEB_BLUE = 2,
-};
-
-struct vimc_deb_pix_map {
- u32 code;
- enum vimc_deb_rgb_colors order[2][2];
-};
-
-struct vimc_deb_device {
- struct vimc_ent_device ved;
- struct v4l2_subdev sd;
- struct device *dev;
- /* The active format */
- struct v4l2_mbus_framefmt sink_fmt;
- u32 src_code;
- void (*set_rgb_src)(struct vimc_deb_device *vdeb, unsigned int lin,
- unsigned int col, unsigned int rgb[3]);
- /* Values calculated when the stream starts */
- u8 *src_frame;
- const struct vimc_deb_pix_map *sink_pix_map;
- unsigned int sink_bpp;
-};
-
-static const struct v4l2_mbus_framefmt sink_fmt_default = {
- .width = 640,
- .height = 480,
- .code = MEDIA_BUS_FMT_RGB888_1X24,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-static const struct vimc_deb_pix_map vimc_deb_pix_map_list[] = {
- {
- .code = MEDIA_BUS_FMT_SBGGR8_1X8,
- .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
- { VIMC_DEB_GREEN, VIMC_DEB_RED } }
- },
- {
- .code = MEDIA_BUS_FMT_SGBRG8_1X8,
- .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
- { VIMC_DEB_RED, VIMC_DEB_GREEN } }
- },
- {
- .code = MEDIA_BUS_FMT_SGRBG8_1X8,
- .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
- { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
- },
- {
- .code = MEDIA_BUS_FMT_SRGGB8_1X8,
- .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
- { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
- },
- {
- .code = MEDIA_BUS_FMT_SBGGR10_1X10,
- .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
- { VIMC_DEB_GREEN, VIMC_DEB_RED } }
- },
- {
- .code = MEDIA_BUS_FMT_SGBRG10_1X10,
- .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
- { VIMC_DEB_RED, VIMC_DEB_GREEN } }
- },
- {
- .code = MEDIA_BUS_FMT_SGRBG10_1X10,
- .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
- { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
- },
- {
- .code = MEDIA_BUS_FMT_SRGGB10_1X10,
- .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
- { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
- },
- {
- .code = MEDIA_BUS_FMT_SBGGR12_1X12,
- .order = { { VIMC_DEB_BLUE, VIMC_DEB_GREEN },
- { VIMC_DEB_GREEN, VIMC_DEB_RED } }
- },
- {
- .code = MEDIA_BUS_FMT_SGBRG12_1X12,
- .order = { { VIMC_DEB_GREEN, VIMC_DEB_BLUE },
- { VIMC_DEB_RED, VIMC_DEB_GREEN } }
- },
- {
- .code = MEDIA_BUS_FMT_SGRBG12_1X12,
- .order = { { VIMC_DEB_GREEN, VIMC_DEB_RED },
- { VIMC_DEB_BLUE, VIMC_DEB_GREEN } }
- },
- {
- .code = MEDIA_BUS_FMT_SRGGB12_1X12,
- .order = { { VIMC_DEB_RED, VIMC_DEB_GREEN },
- { VIMC_DEB_GREEN, VIMC_DEB_BLUE } }
- },
-};
-
-static const struct vimc_deb_pix_map *vimc_deb_pix_map_by_code(u32 code)
-{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(vimc_deb_pix_map_list); i++)
- if (vimc_deb_pix_map_list[i].code == code)
- return &vimc_deb_pix_map_list[i];
-
- return NULL;
-}
-
-static int vimc_deb_init_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg)
-{
- struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf;
- unsigned int i;
-
- mf = v4l2_subdev_get_try_format(sd, cfg, 0);
- *mf = sink_fmt_default;
-
- for (i = 1; i < sd->entity.num_pads; i++) {
- mf = v4l2_subdev_get_try_format(sd, cfg, i);
- *mf = sink_fmt_default;
- mf->code = vdeb->src_code;
- }
-
- return 0;
-}
-
-static int vimc_deb_enum_mbus_code(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_mbus_code_enum *code)
-{
- /* 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;
-}
-
-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;
-
- 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;
- fse->max_width = VIMC_FRAME_MAX_WIDTH;
- fse->min_height = VIMC_FRAME_MIN_HEIGHT;
- fse->max_height = VIMC_FRAME_MAX_HEIGHT;
-
- return 0;
-}
-
-static int vimc_deb_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
-
- /* Get the current sink format */
- fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
- *v4l2_subdev_get_try_format(sd, cfg, 0) :
- vdeb->sink_fmt;
-
- /* Set the right code for the source pad */
- if (IS_SRC(fmt->pad))
- fmt->format.code = vdeb->src_code;
-
- return 0;
-}
-
-static void vimc_deb_adjust_sink_fmt(struct v4l2_mbus_framefmt *fmt)
-{
- const struct vimc_deb_pix_map *vpix;
-
- /* Don't accept a code that is not on the debayer table */
- vpix = vimc_deb_pix_map_by_code(fmt->code);
- if (!vpix)
- 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,
- VIMC_FRAME_MAX_HEIGHT) & ~1;
-
- if (fmt->field == V4L2_FIELD_ANY)
- fmt->field = sink_fmt_default.field;
-
- vimc_colorimetry_clamp(fmt);
-}
-
-static int vimc_deb_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *sink_fmt;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- /* Do not change the format while stream is on */
- if (vdeb->src_frame)
- return -EBUSY;
-
- sink_fmt = &vdeb->sink_fmt;
- } else {
- sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
- }
-
- /*
- * Do not change the format of the source pad,
- * it is propagated from the sink
- */
- if (IS_SRC(fmt->pad)) {
- 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 */
- vimc_deb_adjust_sink_fmt(&fmt->format);
-
- dev_dbg(vdeb->dev, "%s: sink format update: "
- "old:%dx%d (0x%x, %d, %d, %d, %d) "
- "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vdeb->sd.name,
- /* old */
- sink_fmt->width, sink_fmt->height, sink_fmt->code,
- sink_fmt->colorspace, sink_fmt->quantization,
- sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
- /* new */
- fmt->format.width, fmt->format.height, fmt->format.code,
- fmt->format.colorspace, fmt->format.quantization,
- fmt->format.xfer_func, fmt->format.ycbcr_enc);
-
- *sink_fmt = fmt->format;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_pad_ops vimc_deb_pad_ops = {
- .init_cfg = vimc_deb_init_cfg,
- .enum_mbus_code = vimc_deb_enum_mbus_code,
- .enum_frame_size = vimc_deb_enum_frame_size,
- .get_fmt = vimc_deb_get_fmt,
- .set_fmt = vimc_deb_set_fmt,
-};
-
-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])
-{
- unsigned int i, index;
-
- index = VIMC_FRAME_INDEX(lin, col, vdeb->sink_fmt.width, 3);
- for (i = 0; i < 3; i++)
- vdeb->src_frame[index + i] = rgb[i];
-}
-
-static int vimc_deb_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct vimc_deb_device *vdeb = v4l2_get_subdevdata(sd);
- int ret;
-
- if (enable) {
- const struct vimc_pix_map *vpix;
- unsigned int frame_size;
-
- 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);
-
- /*
- * Allocate the frame buffer. Use vmalloc to be able to
- * allocate a large amount of memory
- */
- vdeb->src_frame = vmalloc(frame_size);
- if (!vdeb->src_frame)
- return -ENOMEM;
-
- /* Turn the stream on in the subdevices directly connected */
- ret = vimc_pipeline_s_stream(&vdeb->sd.entity, 1);
- if (ret) {
- vfree(vdeb->src_frame);
- vdeb->src_frame = NULL;
- return ret;
- }
- } else {
- if (!vdeb->src_frame)
- return 0;
-
- /* Disable streaming from the pipe */
- ret = vimc_pipeline_s_stream(&vdeb->sd.entity, 0);
- if (ret)
- return ret;
-
- vfree(vdeb->src_frame);
- vdeb->src_frame = NULL;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_video_ops vimc_deb_video_ops = {
- .s_stream = vimc_deb_s_stream,
-};
-
-static const struct v4l2_subdev_ops vimc_deb_ops = {
- .pad = &vimc_deb_pad_ops,
- .video = &vimc_deb_video_ops,
-};
-
-static unsigned int vimc_deb_get_val(const u8 *bytes,
- const unsigned int n_bytes)
-{
- unsigned int i;
- unsigned int acc = 0;
-
- for (i = 0; i < n_bytes; i++)
- acc = acc + (bytes[i] << (8 * i));
-
- return acc;
-}
-
-static void vimc_deb_calc_rgb_sink(struct vimc_deb_device *vdeb,
- const u8 *frame,
- const unsigned int lin,
- const unsigned int col,
- unsigned int rgb[3])
-{
- unsigned int i, seek, wlin, wcol;
- unsigned int n_rgb[3] = {0, 0, 0};
-
- for (i = 0; i < 3; i++)
- rgb[i] = 0;
-
- /*
- * Calculate how many we need to subtract to get to the pixel in
- * the top left corner of the mean window (considering the current
- * pixel as the center)
- */
- seek = deb_mean_win_size / 2;
-
- /* Sum the values of the colors in the mean window */
-
- dev_dbg(vdeb->dev,
- "deb: %s: --- Calc pixel %dx%d, window mean %d, seek %d ---\n",
- vdeb->sd.name, lin, col, vdeb->sink_fmt.height, seek);
-
- /*
- * Iterate through all the lines in the mean window, start
- * with zero if the pixel is outside the frame and don't pass
- * the height when the pixel is in the bottom border of the
- * frame
- */
- for (wlin = seek > lin ? 0 : lin - seek;
- wlin < lin + seek + 1 && wlin < vdeb->sink_fmt.height;
- wlin++) {
-
- /*
- * Iterate through all the columns in the mean window, start
- * with zero if the pixel is outside the frame and don't pass
- * the width when the pixel is in the right border of the
- * frame
- */
- for (wcol = seek > col ? 0 : col - seek;
- wcol < col + seek + 1 && wcol < vdeb->sink_fmt.width;
- wcol++) {
- enum vimc_deb_rgb_colors color;
- unsigned int index;
-
- /* Check which color this pixel is */
- color = vdeb->sink_pix_map->order[wlin % 2][wcol % 2];
-
- index = VIMC_FRAME_INDEX(wlin, wcol,
- vdeb->sink_fmt.width,
- vdeb->sink_bpp);
-
- dev_dbg(vdeb->dev,
- "deb: %s: RGB CALC: frame index %d, win pos %dx%d, color %d\n",
- vdeb->sd.name, index, wlin, wcol, color);
-
- /* Get its value */
- rgb[color] = rgb[color] +
- vimc_deb_get_val(&frame[index], vdeb->sink_bpp);
-
- /* Save how many values we already added */
- n_rgb[color]++;
-
- dev_dbg(vdeb->dev, "deb: %s: RGB CALC: val %d, n %d\n",
- vdeb->sd.name, rgb[color], n_rgb[color]);
- }
- }
-
- /* Calculate the mean */
- for (i = 0; i < 3; i++) {
- dev_dbg(vdeb->dev,
- "deb: %s: PRE CALC: %dx%d Color %d, val %d, n %d\n",
- vdeb->sd.name, lin, col, i, rgb[i], n_rgb[i]);
-
- if (n_rgb[i])
- rgb[i] = rgb[i] / n_rgb[i];
-
- dev_dbg(vdeb->dev,
- "deb: %s: FINAL CALC: %dx%d Color %d, val %d\n",
- vdeb->sd.name, lin, col, i, rgb[i]);
- }
-}
-
-static void vimc_deb_process_frame(struct vimc_ent_device *ved,
- struct media_pad *sink,
- const void *sink_frame)
-{
- struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device,
- ved);
- unsigned int rgb[3];
- unsigned int i, j;
-
- /* If the stream in this node is not active, just return */
- if (!vdeb->src_frame)
- return;
-
- for (i = 0; i < vdeb->sink_fmt.height; i++)
- for (j = 0; j < vdeb->sink_fmt.width; j++) {
- vimc_deb_calc_rgb_sink(vdeb, sink_frame, i, j, rgb);
- vdeb->set_rgb_src(vdeb, i, j, rgb);
- }
-
- /* Propagate the frame through all source pads */
- for (i = 1; i < vdeb->sd.entity.num_pads; i++) {
- struct media_pad *pad = &vdeb->sd.entity.pads[i];
-
- vimc_propagate_frame(pad, vdeb->src_frame);
- }
-}
-
-static void vimc_deb_comp_unbind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
- struct vimc_deb_device *vdeb = container_of(ved, struct vimc_deb_device,
- ved);
-
- vimc_ent_sd_unregister(ved, &vdeb->sd);
- kfree(vdeb);
-}
-
-static int vimc_deb_comp_bind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct v4l2_device *v4l2_dev = master_data;
- struct vimc_platform_data *pdata = comp->platform_data;
- struct vimc_deb_device *vdeb;
- int ret;
-
- /* Allocate the vdeb struct */
- vdeb = kzalloc(sizeof(*vdeb), GFP_KERNEL);
- if (!vdeb)
- return -ENOMEM;
-
- /* Initialize ved and sd */
- ret = vimc_ent_sd_register(&vdeb->ved, &vdeb->sd, v4l2_dev,
- pdata->entity_name,
- MEDIA_ENT_F_PROC_VIDEO_PIXEL_ENC_CONV, 2,
- (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
- MEDIA_PAD_FL_SOURCE},
- &vimc_deb_ops);
- if (ret) {
- kfree(vdeb);
- return ret;
- }
-
- vdeb->ved.process_frame = vimc_deb_process_frame;
- dev_set_drvdata(comp, &vdeb->ved);
- vdeb->dev = comp;
-
- /* Initialize the frame format */
- vdeb->sink_fmt = sink_fmt_default;
- /*
- * TODO: Add support for more output formats, we only support
- * RGB888 for now
- * NOTE: the src format is always the same as the sink, except
- * for the code
- */
- vdeb->src_code = MEDIA_BUS_FMT_RGB888_1X24;
- vdeb->set_rgb_src = vimc_deb_set_rgb_mbus_fmt_rgb888_1x24;
-
- return 0;
-}
-
-static const struct component_ops vimc_deb_comp_ops = {
- .bind = vimc_deb_comp_bind,
- .unbind = vimc_deb_comp_unbind,
-};
-
-static int vimc_deb_probe(struct platform_device *pdev)
-{
- return component_add(&pdev->dev, &vimc_deb_comp_ops);
-}
-
-static int vimc_deb_remove(struct platform_device *pdev)
-{
- component_del(&pdev->dev, &vimc_deb_comp_ops);
-
- return 0;
-}
-
-static const struct platform_device_id vimc_deb_driver_ids[] = {
- {
- .name = VIMC_DEB_DRV_NAME,
- },
- { }
-};
-
-static struct platform_driver vimc_deb_pdrv = {
- .probe = vimc_deb_probe,
- .remove = vimc_deb_remove,
- .id_table = vimc_deb_driver_ids,
- .driver = {
- .name = VIMC_DEB_DRV_NAME,
- },
-};
-
-module_platform_driver(vimc_deb_pdrv);
-
-MODULE_DEVICE_TABLE(platform, vimc_deb_driver_ids);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Debayer");
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-scaler.c b/drivers/media/platform/vimc/vimc-scaler.c
deleted file mode 100644
index b0952ee86296..000000000000
--- a/drivers/media/platform/vimc/vimc-scaler.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * vimc-scaler.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/component.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/vmalloc.h>
-#include <linux/v4l2-mediabus.h>
-#include <media/v4l2-subdev.h>
-
-#include "vimc-common.h"
-
-#define VIMC_SCA_DRV_NAME "vimc-scaler"
-
-static unsigned int sca_mult = 3;
-module_param(sca_mult, uint, 0000);
-MODULE_PARM_DESC(sca_mult, " the image size multiplier");
-
-#define IS_SINK(pad) (!pad)
-#define IS_SRC(pad) (pad)
-#define MAX_ZOOM 8
-
-struct vimc_sca_device {
- struct vimc_ent_device ved;
- struct v4l2_subdev sd;
- struct device *dev;
- /* NOTE: the source fmt is the same as the sink
- * with the width and hight multiplied by mult
- */
- struct v4l2_mbus_framefmt sink_fmt;
- /* Values calculated when the stream starts */
- u8 *src_frame;
- unsigned int src_line_size;
- unsigned int bpp;
-};
-
-static const struct v4l2_mbus_framefmt sink_fmt_default = {
- .width = 640,
- .height = 480,
- .code = MEDIA_BUS_FMT_RGB888_1X24,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-static int vimc_sca_init_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg)
-{
- struct v4l2_mbus_framefmt *mf;
- unsigned int i;
-
- mf = v4l2_subdev_get_try_format(sd, cfg, 0);
- *mf = sink_fmt_default;
-
- for (i = 1; i < sd->entity.num_pads; i++) {
- mf = v4l2_subdev_get_try_format(sd, cfg, i);
- *mf = sink_fmt_default;
- mf->width = mf->width * sca_mult;
- mf->height = mf->height * sca_mult;
- }
-
- 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;
-
- if (IS_SINK(fse->pad)) {
- fse->max_width = VIMC_FRAME_MAX_WIDTH;
- fse->max_height = VIMC_FRAME_MAX_HEIGHT;
- } else {
- fse->max_width = VIMC_FRAME_MAX_WIDTH * MAX_ZOOM;
- fse->max_height = VIMC_FRAME_MAX_HEIGHT * MAX_ZOOM;
- }
-
- return 0;
-}
-
-static int vimc_sca_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *format)
-{
- struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
-
- /* Get the current sink format */
- format->format = (format->which == V4L2_SUBDEV_FORMAT_TRY) ?
- *v4l2_subdev_get_try_format(sd, cfg, 0) :
- vsca->sink_fmt;
-
- /* Scale the frame size for the source pad */
- if (IS_SRC(format->pad)) {
- format->format.width = vsca->sink_fmt.width * sca_mult;
- format->format.height = vsca->sink_fmt.height * sca_mult;
- }
-
- return 0;
-}
-
-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,
- VIMC_FRAME_MAX_HEIGHT) & ~1;
-
- if (fmt->field == V4L2_FIELD_ANY)
- fmt->field = sink_fmt_default.field;
-
- vimc_colorimetry_clamp(fmt);
-}
-
-static int vimc_sca_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *sink_fmt;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- /* Do not change the format while stream is on */
- if (vsca->src_frame)
- return -EBUSY;
-
- sink_fmt = &vsca->sink_fmt;
- } else {
- sink_fmt = v4l2_subdev_get_try_format(sd, cfg, 0);
- }
-
- /*
- * Do not change the format of the source pad,
- * it is propagated from the sink
- */
- if (IS_SRC(fmt->pad)) {
- fmt->format = *sink_fmt;
- fmt->format.width = sink_fmt->width * sca_mult;
- fmt->format.height = sink_fmt->height * sca_mult;
- } else {
- /* Set the new format in the sink pad */
- vimc_sca_adjust_sink_fmt(&fmt->format);
-
- dev_dbg(vsca->dev, "%s: sink format update: "
- "old:%dx%d (0x%x, %d, %d, %d, %d) "
- "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsca->sd.name,
- /* old */
- sink_fmt->width, sink_fmt->height, sink_fmt->code,
- sink_fmt->colorspace, sink_fmt->quantization,
- sink_fmt->xfer_func, sink_fmt->ycbcr_enc,
- /* new */
- fmt->format.width, fmt->format.height, fmt->format.code,
- fmt->format.colorspace, fmt->format.quantization,
- fmt->format.xfer_func, fmt->format.ycbcr_enc);
-
- *sink_fmt = fmt->format;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_pad_ops vimc_sca_pad_ops = {
- .init_cfg = vimc_sca_init_cfg,
- .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,
-};
-
-static int vimc_sca_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct vimc_sca_device *vsca = v4l2_get_subdevdata(sd);
- int ret;
-
- if (enable) {
- const struct vimc_pix_map *vpix;
- unsigned int frame_size;
-
- if (vsca->src_frame)
- return 0;
-
- /* Save the bytes per pixel of the sink */
- 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 *
- sca_mult * vsca->bpp;
-
- /* Calculate the frame size of the source pad */
- frame_size = vsca->src_line_size * vsca->sink_fmt.height *
- sca_mult;
-
- /* Allocate the frame buffer. Use vmalloc to be able to
- * allocate a large amount of memory
- */
- vsca->src_frame = vmalloc(frame_size);
- if (!vsca->src_frame)
- return -ENOMEM;
-
- /* Turn the stream on in the subdevices directly connected */
- ret = vimc_pipeline_s_stream(&vsca->sd.entity, 1);
- if (ret) {
- vfree(vsca->src_frame);
- vsca->src_frame = NULL;
- return ret;
- }
- } else {
- if (!vsca->src_frame)
- return 0;
-
- /* Disable streaming from the pipe */
- ret = vimc_pipeline_s_stream(&vsca->sd.entity, 0);
- if (ret)
- return ret;
-
- vfree(vsca->src_frame);
- vsca->src_frame = NULL;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_video_ops vimc_sca_video_ops = {
- .s_stream = vimc_sca_s_stream,
-};
-
-static const struct v4l2_subdev_ops vimc_sca_ops = {
- .pad = &vimc_sca_pad_ops,
- .video = &vimc_sca_video_ops,
-};
-
-static void vimc_sca_fill_pix(u8 *const ptr,
- const u8 *const pixel,
- const unsigned int bpp)
-{
- unsigned int i;
-
- /* copy the pixel to the pointer */
- for (i = 0; i < bpp; i++)
- ptr[i] = pixel[i];
-}
-
-static void vimc_sca_scale_pix(const struct vimc_sca_device *const vsca,
- const unsigned int lin, const unsigned int col,
- const u8 *const sink_frame)
-{
- unsigned int i, j, index;
- const u8 *pixel;
-
- /* Point to the pixel value in position (lin, col) in the sink frame */
- index = VIMC_FRAME_INDEX(lin, col,
- vsca->sink_fmt.width,
- vsca->bpp);
- pixel = &sink_frame[index];
-
- dev_dbg(vsca->dev,
- "sca: %s: --- scale_pix sink pos %dx%d, index %d ---\n",
- vsca->sd.name, lin, col, index);
-
- /* point to the place we are going to put the first pixel
- * in the scaled src frame
- */
- index = VIMC_FRAME_INDEX(lin * sca_mult, col * sca_mult,
- vsca->sink_fmt.width * sca_mult, vsca->bpp);
-
- dev_dbg(vsca->dev, "sca: %s: scale_pix src pos %dx%d, index %d\n",
- vsca->sd.name, lin * sca_mult, col * sca_mult, index);
-
- /* Repeat this pixel mult times */
- for (i = 0; i < sca_mult; i++) {
- /* Iterate through each beginning of a
- * pixel repetition in a line
- */
- for (j = 0; j < sca_mult * vsca->bpp; j += vsca->bpp) {
- dev_dbg(vsca->dev,
- "sca: %s: sca: scale_pix src pos %d\n",
- vsca->sd.name, index + j);
-
- /* copy the pixel to the position index + j */
- vimc_sca_fill_pix(&vsca->src_frame[index + j],
- pixel, vsca->bpp);
- }
-
- /* move the index to the next line */
- index += vsca->src_line_size;
- }
-}
-
-static void vimc_sca_fill_src_frame(const struct vimc_sca_device *const vsca,
- const u8 *const sink_frame)
-{
- unsigned int i, j;
-
- /* Scale each pixel from the original sink frame */
- /* TODO: implement scale down, only scale up is supported for now */
- for (i = 0; i < vsca->sink_fmt.height; i++)
- for (j = 0; j < vsca->sink_fmt.width; j++)
- vimc_sca_scale_pix(vsca, i, j, sink_frame);
-}
-
-static void vimc_sca_process_frame(struct vimc_ent_device *ved,
- struct media_pad *sink,
- const void *sink_frame)
-{
- struct vimc_sca_device *vsca = container_of(ved, struct vimc_sca_device,
- ved);
- unsigned int i;
-
- /* If the stream in this node is not active, just return */
- if (!vsca->src_frame)
- return;
-
- vimc_sca_fill_src_frame(vsca, sink_frame);
-
- /* Propagate the frame through all source pads */
- for (i = 1; i < vsca->sd.entity.num_pads; i++) {
- struct media_pad *pad = &vsca->sd.entity.pads[i];
-
- vimc_propagate_frame(pad, vsca->src_frame);
- }
-};
-
-static void vimc_sca_comp_unbind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
- struct vimc_sca_device *vsca = container_of(ved, struct vimc_sca_device,
- ved);
-
- vimc_ent_sd_unregister(ved, &vsca->sd);
- kfree(vsca);
-}
-
-
-static int vimc_sca_comp_bind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct v4l2_device *v4l2_dev = master_data;
- struct vimc_platform_data *pdata = comp->platform_data;
- struct vimc_sca_device *vsca;
- int ret;
-
- /* Allocate the vsca struct */
- vsca = kzalloc(sizeof(*vsca), GFP_KERNEL);
- if (!vsca)
- return -ENOMEM;
-
- /* Initialize ved and sd */
- ret = vimc_ent_sd_register(&vsca->ved, &vsca->sd, v4l2_dev,
- pdata->entity_name,
- MEDIA_ENT_F_PROC_VIDEO_SCALER, 2,
- (const unsigned long[2]) {MEDIA_PAD_FL_SINK,
- MEDIA_PAD_FL_SOURCE},
- &vimc_sca_ops);
- if (ret) {
- kfree(vsca);
- return ret;
- }
-
- vsca->ved.process_frame = vimc_sca_process_frame;
- dev_set_drvdata(comp, &vsca->ved);
- vsca->dev = comp;
-
- /* Initialize the frame format */
- vsca->sink_fmt = sink_fmt_default;
-
- return 0;
-}
-
-static const struct component_ops vimc_sca_comp_ops = {
- .bind = vimc_sca_comp_bind,
- .unbind = vimc_sca_comp_unbind,
-};
-
-static int vimc_sca_probe(struct platform_device *pdev)
-{
- return component_add(&pdev->dev, &vimc_sca_comp_ops);
-}
-
-static int vimc_sca_remove(struct platform_device *pdev)
-{
- component_del(&pdev->dev, &vimc_sca_comp_ops);
-
- return 0;
-}
-
-static const struct platform_device_id vimc_sca_driver_ids[] = {
- {
- .name = VIMC_SCA_DRV_NAME,
- },
- { }
-};
-
-static struct platform_driver vimc_sca_pdrv = {
- .probe = vimc_sca_probe,
- .remove = vimc_sca_remove,
- .id_table = vimc_sca_driver_ids,
- .driver = {
- .name = VIMC_SCA_DRV_NAME,
- },
-};
-
-module_platform_driver(vimc_sca_pdrv);
-
-MODULE_DEVICE_TABLE(platform, vimc_sca_driver_ids);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Scaler");
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/platform/vimc/vimc-sensor.c b/drivers/media/platform/vimc/vimc-sensor.c
deleted file mode 100644
index 32ca9c6172b1..000000000000
--- a/drivers/media/platform/vimc/vimc-sensor.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * vimc-sensor.c Virtual Media Controller Driver
- *
- * Copyright (C) 2015-2017 Helen Koike <helen.fornazier@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/component.h>
-#include <linux/freezer.h>
-#include <linux/kthread.h>
-#include <linux/module.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/v4l2-mediabus.h>
-#include <linux/vmalloc.h>
-#include <media/v4l2-ctrls.h>
-#include <media/v4l2-event.h>
-#include <media/v4l2-subdev.h>
-#include <media/tpg/v4l2-tpg.h>
-
-#include "vimc-common.h"
-
-#define VIMC_SEN_DRV_NAME "vimc-sensor"
-
-struct vimc_sen_device {
- struct vimc_ent_device ved;
- struct v4l2_subdev sd;
- struct device *dev;
- struct tpg_data tpg;
- struct task_struct *kthread_sen;
- u8 *frame;
- /* The active format */
- struct v4l2_mbus_framefmt mbus_format;
- struct v4l2_ctrl_handler hdl;
-};
-
-static const struct v4l2_mbus_framefmt fmt_default = {
- .width = 640,
- .height = 480,
- .code = MEDIA_BUS_FMT_RGB888_1X24,
- .field = V4L2_FIELD_NONE,
- .colorspace = V4L2_COLORSPACE_DEFAULT,
-};
-
-static int vimc_sen_init_cfg(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg)
-{
- unsigned int i;
-
- for (i = 0; i < sd->entity.num_pads; i++) {
- struct v4l2_mbus_framefmt *mf;
-
- mf = v4l2_subdev_get_try_format(sd, cfg, i);
- *mf = fmt_default;
- }
-
- 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;
- fse->max_height = VIMC_FRAME_MAX_HEIGHT;
-
- return 0;
-}
-
-static int vimc_sen_get_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct vimc_sen_device *vsen =
- container_of(sd, struct vimc_sen_device, sd);
-
- fmt->format = fmt->which == V4L2_SUBDEV_FORMAT_TRY ?
- *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) :
- vsen->mbus_format;
-
- return 0;
-}
-
-static void vimc_sen_tpg_s_format(struct vimc_sen_device *vsen)
-{
- 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 * vpix->bpp);
- tpg_s_buf_height(&vsen->tpg, vsen->mbus_format.height);
- 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);
- tpg_s_ycbcr_enc(&vsen->tpg, vsen->mbus_format.ycbcr_enc);
- tpg_s_quantization(&vsen->tpg, vsen->mbus_format.quantization);
- tpg_s_xfer_func(&vsen->tpg, vsen->mbus_format.xfer_func);
-}
-
-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,
- VIMC_FRAME_MAX_HEIGHT) & ~1;
-
- /* TODO: add support for V4L2_FIELD_ALTERNATE */
- if (fmt->field == V4L2_FIELD_ANY || fmt->field == V4L2_FIELD_ALTERNATE)
- fmt->field = fmt_default.field;
-
- vimc_colorimetry_clamp(fmt);
-}
-
-static int vimc_sen_set_fmt(struct v4l2_subdev *sd,
- struct v4l2_subdev_pad_config *cfg,
- struct v4l2_subdev_format *fmt)
-{
- struct vimc_sen_device *vsen = v4l2_get_subdevdata(sd);
- struct v4l2_mbus_framefmt *mf;
-
- if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
- /* Do not change the format while stream is on */
- if (vsen->frame)
- return -EBUSY;
-
- mf = &vsen->mbus_format;
- } else {
- mf = v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
- }
-
- /* Set the new format */
- vimc_sen_adjust_fmt(&fmt->format);
-
- dev_dbg(vsen->dev, "%s: format update: "
- "old:%dx%d (0x%x, %d, %d, %d, %d) "
- "new:%dx%d (0x%x, %d, %d, %d, %d)\n", vsen->sd.name,
- /* old */
- mf->width, mf->height, mf->code,
- mf->colorspace, mf->quantization,
- mf->xfer_func, mf->ycbcr_enc,
- /* new */
- fmt->format.width, fmt->format.height, fmt->format.code,
- fmt->format.colorspace, fmt->format.quantization,
- fmt->format.xfer_func, fmt->format.ycbcr_enc);
-
- *mf = fmt->format;
-
- return 0;
-}
-
-static const struct v4l2_subdev_pad_ops vimc_sen_pad_ops = {
- .init_cfg = vimc_sen_init_cfg,
- .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,
-};
-
-static int vimc_sen_tpg_thread(void *data)
-{
- struct vimc_sen_device *vsen = data;
- unsigned int i;
-
- set_freezable();
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- for (;;) {
- try_to_freeze();
- if (kthread_should_stop())
- break;
-
- tpg_fill_plane_buffer(&vsen->tpg, 0, 0, vsen->frame);
-
- /* Send the frame to all source pads */
- for (i = 0; i < vsen->sd.entity.num_pads; i++)
- vimc_propagate_frame(&vsen->sd.entity.pads[i],
- vsen->frame);
-
- /* 60 frames per second */
- schedule_timeout(HZ/60);
- }
-
- return 0;
-}
-
-static int vimc_sen_s_stream(struct v4l2_subdev *sd, int enable)
-{
- struct vimc_sen_device *vsen =
- container_of(sd, struct vimc_sen_device, sd);
- int ret;
-
- if (enable) {
- const struct vimc_pix_map *vpix;
- unsigned int frame_size;
-
- if (vsen->kthread_sen)
- /* tpg is already executing */
- return 0;
-
- /* Calculate the frame size */
- vpix = vimc_pix_map_by_code(vsen->mbus_format.code);
- frame_size = vsen->mbus_format.width * vpix->bpp *
- vsen->mbus_format.height;
-
- /*
- * Allocate the frame buffer. Use vmalloc to be able to
- * allocate a large amount of memory
- */
- vsen->frame = vmalloc(frame_size);
- if (!vsen->frame)
- return -ENOMEM;
-
- /* configure the test pattern generator */
- vimc_sen_tpg_s_format(vsen);
-
- /* Initialize the image generator thread */
- vsen->kthread_sen = kthread_run(vimc_sen_tpg_thread, vsen,
- "%s-sen", vsen->sd.v4l2_dev->name);
- if (IS_ERR(vsen->kthread_sen)) {
- dev_err(vsen->dev, "%s: kernel_thread() failed\n",
- vsen->sd.name);
- vfree(vsen->frame);
- vsen->frame = NULL;
- return PTR_ERR(vsen->kthread_sen);
- }
- } else {
- if (!vsen->kthread_sen)
- return 0;
-
- /* Stop image generator */
- ret = kthread_stop(vsen->kthread_sen);
- if (ret)
- return ret;
-
- vsen->kthread_sen = NULL;
- vfree(vsen->frame);
- vsen->frame = NULL;
- return 0;
- }
-
- return 0;
-}
-
-static const struct v4l2_subdev_core_ops vimc_sen_core_ops = {
- .log_status = v4l2_ctrl_subdev_log_status,
- .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
- .unsubscribe_event = v4l2_event_subdev_unsubscribe,
-};
-
-static const struct v4l2_subdev_video_ops vimc_sen_video_ops = {
- .s_stream = vimc_sen_s_stream,
-};
-
-static const struct v4l2_subdev_ops vimc_sen_ops = {
- .core = &vimc_sen_core_ops,
- .pad = &vimc_sen_pad_ops,
- .video = &vimc_sen_video_ops,
-};
-
-static int vimc_sen_s_ctrl(struct v4l2_ctrl *ctrl)
-{
- struct vimc_sen_device *vsen =
- container_of(ctrl->handler, struct vimc_sen_device, hdl);
-
- switch (ctrl->id) {
- case VIMC_CID_TEST_PATTERN:
- tpg_s_pattern(&vsen->tpg, ctrl->val);
- break;
- case V4L2_CID_HFLIP:
- tpg_s_hflip(&vsen->tpg, ctrl->val);
- break;
- case V4L2_CID_VFLIP:
- tpg_s_vflip(&vsen->tpg, ctrl->val);
- break;
- case V4L2_CID_BRIGHTNESS:
- tpg_s_brightness(&vsen->tpg, ctrl->val);
- break;
- case V4L2_CID_CONTRAST:
- tpg_s_contrast(&vsen->tpg, ctrl->val);
- break;
- case V4L2_CID_HUE:
- tpg_s_hue(&vsen->tpg, ctrl->val);
- break;
- case V4L2_CID_SATURATION:
- tpg_s_saturation(&vsen->tpg, ctrl->val);
- break;
- default:
- return -EINVAL;
- }
- return 0;
-}
-
-static const struct v4l2_ctrl_ops vimc_sen_ctrl_ops = {
- .s_ctrl = vimc_sen_s_ctrl,
-};
-
-static void vimc_sen_comp_unbind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct vimc_ent_device *ved = dev_get_drvdata(comp);
- struct vimc_sen_device *vsen =
- container_of(ved, struct vimc_sen_device, ved);
-
- vimc_ent_sd_unregister(ved, &vsen->sd);
- v4l2_ctrl_handler_free(&vsen->hdl);
- tpg_free(&vsen->tpg);
- kfree(vsen);
-}
-
-/* Image Processing Controls */
-static const struct v4l2_ctrl_config vimc_sen_ctrl_class = {
- .flags = V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY,
- .id = VIMC_CID_VIMC_CLASS,
- .name = "VIMC Controls",
- .type = V4L2_CTRL_TYPE_CTRL_CLASS,
-};
-
-static const struct v4l2_ctrl_config vimc_sen_ctrl_test_pattern = {
- .ops = &vimc_sen_ctrl_ops,
- .id = VIMC_CID_TEST_PATTERN,
- .name = "Test Pattern",
- .type = V4L2_CTRL_TYPE_MENU,
- .max = TPG_PAT_NOISE,
- .qmenu = tpg_pattern_strings,
-};
-
-static int vimc_sen_comp_bind(struct device *comp, struct device *master,
- void *master_data)
-{
- struct v4l2_device *v4l2_dev = master_data;
- struct vimc_platform_data *pdata = comp->platform_data;
- struct vimc_sen_device *vsen;
- int ret;
-
- /* Allocate the vsen struct */
- vsen = kzalloc(sizeof(*vsen), GFP_KERNEL);
- if (!vsen)
- return -ENOMEM;
-
- v4l2_ctrl_handler_init(&vsen->hdl, 4);
-
- v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_class, NULL);
- v4l2_ctrl_new_custom(&vsen->hdl, &vimc_sen_ctrl_test_pattern, NULL);
- v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
- V4L2_CID_VFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
- V4L2_CID_HFLIP, 0, 1, 1, 0);
- v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
- V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
- V4L2_CID_CONTRAST, 0, 255, 1, 128);
- v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
- V4L2_CID_HUE, -128, 127, 1, 0);
- v4l2_ctrl_new_std(&vsen->hdl, &vimc_sen_ctrl_ops,
- V4L2_CID_SATURATION, 0, 255, 1, 128);
- vsen->sd.ctrl_handler = &vsen->hdl;
- if (vsen->hdl.error) {
- ret = vsen->hdl.error;
- goto err_free_vsen;
- }
-
- /* Initialize ved and sd */
- ret = vimc_ent_sd_register(&vsen->ved, &vsen->sd, v4l2_dev,
- pdata->entity_name,
- MEDIA_ENT_F_CAM_SENSOR, 1,
- (const unsigned long[1]) {MEDIA_PAD_FL_SOURCE},
- &vimc_sen_ops);
- if (ret)
- goto err_free_hdl;
-
- dev_set_drvdata(comp, &vsen->ved);
- vsen->dev = comp;
-
- /* Initialize the frame format */
- vsen->mbus_format = fmt_default;
-
- /* Initialize the test pattern generator */
- tpg_init(&vsen->tpg, vsen->mbus_format.width,
- vsen->mbus_format.height);
- ret = tpg_alloc(&vsen->tpg, VIMC_FRAME_MAX_WIDTH);
- if (ret)
- goto err_unregister_ent_sd;
-
- return 0;
-
-err_unregister_ent_sd:
- vimc_ent_sd_unregister(&vsen->ved, &vsen->sd);
-err_free_hdl:
- v4l2_ctrl_handler_free(&vsen->hdl);
-err_free_vsen:
- kfree(vsen);
-
- return ret;
-}
-
-static const struct component_ops vimc_sen_comp_ops = {
- .bind = vimc_sen_comp_bind,
- .unbind = vimc_sen_comp_unbind,
-};
-
-static int vimc_sen_probe(struct platform_device *pdev)
-{
- return component_add(&pdev->dev, &vimc_sen_comp_ops);
-}
-
-static int vimc_sen_remove(struct platform_device *pdev)
-{
- component_del(&pdev->dev, &vimc_sen_comp_ops);
-
- return 0;
-}
-
-static const struct platform_device_id vimc_sen_driver_ids[] = {
- {
- .name = VIMC_SEN_DRV_NAME,
- },
- { }
-};
-
-static struct platform_driver vimc_sen_pdrv = {
- .probe = vimc_sen_probe,
- .remove = vimc_sen_remove,
- .id_table = vimc_sen_driver_ids,
- .driver = {
- .name = VIMC_SEN_DRV_NAME,
- },
-};
-
-module_platform_driver(vimc_sen_pdrv);
-
-MODULE_DEVICE_TABLE(platform, vimc_sen_driver_ids);
-
-MODULE_DESCRIPTION("Virtual Media Controller Driver (VIMC) Sensor");
-MODULE_AUTHOR("Helen Mae Koike Fornazier <helen.fornazier@gmail.com>");
-MODULE_LICENSE("GPL");