linux/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Broadcom BM2835 V4L2 driver
   4 *
   5 * Copyright © 2013 Raspberry Pi (Trading) Ltd.
   6 *
   7 * Authors: Vincent Sanders @ Collabora
   8 *          Dave Stevenson @ Broadcom
   9 *              (now dave.stevenson@raspberrypi.org)
  10 *          Simon Mellor @ Broadcom
  11 *          Luke Diamand @ Broadcom
  12 */
  13
  14#include <linux/errno.h>
  15#include <linux/kernel.h>
  16#include <linux/module.h>
  17#include <linux/slab.h>
  18#include <media/videobuf2-vmalloc.h>
  19#include <media/videobuf2-dma-contig.h>
  20#include <media/v4l2-device.h>
  21#include <media/v4l2-ioctl.h>
  22#include <media/v4l2-ctrls.h>
  23#include <media/v4l2-fh.h>
  24#include <media/v4l2-event.h>
  25#include <media/v4l2-common.h>
  26#include <linux/delay.h>
  27#include <linux/platform_device.h>
  28
  29#include "mmal-common.h"
  30#include "mmal-encodings.h"
  31#include "mmal-vchiq.h"
  32#include "mmal-msg.h"
  33#include "mmal-parameters.h"
  34#include "bcm2835-camera.h"
  35
  36#define BM2835_MMAL_VERSION "0.0.2"
  37#define BM2835_MMAL_MODULE_NAME "bcm2835-v4l2"
  38#define MIN_WIDTH 32
  39#define MIN_HEIGHT 32
  40#define MIN_BUFFER_SIZE (80 * 1024)
  41
  42#define MAX_VIDEO_MODE_WIDTH 1280
  43#define MAX_VIDEO_MODE_HEIGHT 720
  44
  45#define MAX_BCM2835_CAMERAS 2
  46
  47int bcm2835_v4l2_debug;
  48module_param_named(debug, bcm2835_v4l2_debug, int, 0644);
  49MODULE_PARM_DESC(bcm2835_v4l2_debug, "Debug level 0-2");
  50
  51#define UNSET (-1)
  52static int video_nr[] = {[0 ... (MAX_BCM2835_CAMERAS - 1)] = UNSET };
  53module_param_array(video_nr, int, NULL, 0644);
  54MODULE_PARM_DESC(video_nr, "videoX start numbers, -1 is autodetect");
  55
  56static int max_video_width = MAX_VIDEO_MODE_WIDTH;
  57static int max_video_height = MAX_VIDEO_MODE_HEIGHT;
  58module_param(max_video_width, int, 0644);
  59MODULE_PARM_DESC(max_video_width, "Threshold for video mode");
  60module_param(max_video_height, int, 0644);
  61MODULE_PARM_DESC(max_video_height, "Threshold for video mode");
  62
  63/* global device data array */
  64static struct bm2835_mmal_dev *gdev[MAX_BCM2835_CAMERAS];
  65
  66#define FPS_MIN 1
  67#define FPS_MAX 90
  68
  69/* timeperframe: min/max and default */
  70static const struct v4l2_fract
  71        tpf_min     = {.numerator = 1,          .denominator = FPS_MAX},
  72        tpf_max     = {.numerator = 1,          .denominator = FPS_MIN},
  73        tpf_default = {.numerator = 1000,       .denominator = 30000};
  74
  75/* video formats */
  76static struct mmal_fmt formats[] = {
  77        {
  78                .name = "4:2:0, planar, YUV",
  79                .fourcc = V4L2_PIX_FMT_YUV420,
  80                .flags = 0,
  81                .mmal = MMAL_ENCODING_I420,
  82                .depth = 12,
  83                .mmal_component = COMP_CAMERA,
  84                .ybbp = 1,
  85                .remove_padding = 1,
  86        }, {
  87                .name = "4:2:2, packed, YUYV",
  88                .fourcc = V4L2_PIX_FMT_YUYV,
  89                .flags = 0,
  90                .mmal = MMAL_ENCODING_YUYV,
  91                .depth = 16,
  92                .mmal_component = COMP_CAMERA,
  93                .ybbp = 2,
  94                .remove_padding = 0,
  95        }, {
  96                .name = "RGB24 (LE)",
  97                .fourcc = V4L2_PIX_FMT_RGB24,
  98                .flags = 0,
  99                .mmal = MMAL_ENCODING_RGB24,
 100                .depth = 24,
 101                .mmal_component = COMP_CAMERA,
 102                .ybbp = 3,
 103                .remove_padding = 0,
 104        }, {
 105                .name = "JPEG",
 106                .fourcc = V4L2_PIX_FMT_JPEG,
 107                .flags = V4L2_FMT_FLAG_COMPRESSED,
 108                .mmal = MMAL_ENCODING_JPEG,
 109                .depth = 8,
 110                .mmal_component = COMP_IMAGE_ENCODE,
 111                .ybbp = 0,
 112                .remove_padding = 0,
 113        }, {
 114                .name = "H264",
 115                .fourcc = V4L2_PIX_FMT_H264,
 116                .flags = V4L2_FMT_FLAG_COMPRESSED,
 117                .mmal = MMAL_ENCODING_H264,
 118                .depth = 8,
 119                .mmal_component = COMP_VIDEO_ENCODE,
 120                .ybbp = 0,
 121                .remove_padding = 0,
 122        }, {
 123                .name = "MJPEG",
 124                .fourcc = V4L2_PIX_FMT_MJPEG,
 125                .flags = V4L2_FMT_FLAG_COMPRESSED,
 126                .mmal = MMAL_ENCODING_MJPEG,
 127                .depth = 8,
 128                .mmal_component = COMP_VIDEO_ENCODE,
 129                .ybbp = 0,
 130                .remove_padding = 0,
 131        }, {
 132                .name = "4:2:2, packed, YVYU",
 133                .fourcc = V4L2_PIX_FMT_YVYU,
 134                .flags = 0,
 135                .mmal = MMAL_ENCODING_YVYU,
 136                .depth = 16,
 137                .mmal_component = COMP_CAMERA,
 138                .ybbp = 2,
 139                .remove_padding = 0,
 140        }, {
 141                .name = "4:2:2, packed, VYUY",
 142                .fourcc = V4L2_PIX_FMT_VYUY,
 143                .flags = 0,
 144                .mmal = MMAL_ENCODING_VYUY,
 145                .depth = 16,
 146                .mmal_component = COMP_CAMERA,
 147                .ybbp = 2,
 148                .remove_padding = 0,
 149        }, {
 150                .name = "4:2:2, packed, UYVY",
 151                .fourcc = V4L2_PIX_FMT_UYVY,
 152                .flags = 0,
 153                .mmal = MMAL_ENCODING_UYVY,
 154                .depth = 16,
 155                .mmal_component = COMP_CAMERA,
 156                .ybbp = 2,
 157                .remove_padding = 0,
 158        }, {
 159                .name = "4:2:0, planar, NV12",
 160                .fourcc = V4L2_PIX_FMT_NV12,
 161                .flags = 0,
 162                .mmal = MMAL_ENCODING_NV12,
 163                .depth = 12,
 164                .mmal_component = COMP_CAMERA,
 165                .ybbp = 1,
 166                .remove_padding = 1,
 167        }, {
 168                .name = "RGB24 (BE)",
 169                .fourcc = V4L2_PIX_FMT_BGR24,
 170                .flags = 0,
 171                .mmal = MMAL_ENCODING_BGR24,
 172                .depth = 24,
 173                .mmal_component = COMP_CAMERA,
 174                .ybbp = 3,
 175                .remove_padding = 0,
 176        }, {
 177                .name = "4:2:0, planar, YVU",
 178                .fourcc = V4L2_PIX_FMT_YVU420,
 179                .flags = 0,
 180                .mmal = MMAL_ENCODING_YV12,
 181                .depth = 12,
 182                .mmal_component = COMP_CAMERA,
 183                .ybbp = 1,
 184                .remove_padding = 1,
 185        }, {
 186                .name = "4:2:0, planar, NV21",
 187                .fourcc = V4L2_PIX_FMT_NV21,
 188                .flags = 0,
 189                .mmal = MMAL_ENCODING_NV21,
 190                .depth = 12,
 191                .mmal_component = COMP_CAMERA,
 192                .ybbp = 1,
 193                .remove_padding = 1,
 194        }, {
 195                .name = "RGB32 (BE)",
 196                .fourcc = V4L2_PIX_FMT_BGR32,
 197                .flags = 0,
 198                .mmal = MMAL_ENCODING_BGRA,
 199                .depth = 32,
 200                .mmal_component = COMP_CAMERA,
 201                .ybbp = 4,
 202                .remove_padding = 0,
 203        },
 204};
 205
 206static struct mmal_fmt *get_format(struct v4l2_format *f)
 207{
 208        struct mmal_fmt *fmt;
 209        unsigned int k;
 210
 211        for (k = 0; k < ARRAY_SIZE(formats); k++) {
 212                fmt = &formats[k];
 213                if (fmt->fourcc == f->fmt.pix.pixelformat)
 214                        return fmt;
 215        }
 216
 217        return NULL;
 218}
 219
 220/* ------------------------------------------------------------------
 221 *      Videobuf queue operations
 222 * ------------------------------------------------------------------
 223 */
 224
 225static int queue_setup(struct vb2_queue *vq,
 226                       unsigned int *nbuffers, unsigned int *nplanes,
 227                       unsigned int sizes[], struct device *alloc_ctxs[])
 228{
 229        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
 230        unsigned long size;
 231
 232        /* refuse queue setup if port is not configured */
 233        if (!dev->capture.port) {
 234                v4l2_err(&dev->v4l2_dev,
 235                         "%s: capture port not configured\n", __func__);
 236                return -EINVAL;
 237        }
 238
 239        /* Handle CREATE_BUFS situation - *nplanes != 0 */
 240        if (*nplanes) {
 241                if (*nplanes != 1 ||
 242                    sizes[0] < dev->capture.port->current_buffer.size) {
 243                        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 244                                 "%s: dev:%p Invalid buffer request from CREATE_BUFS, size %u < %u, nplanes %u != 1\n",
 245                                 __func__, dev, sizes[0],
 246                                 dev->capture.port->current_buffer.size,
 247                                 *nplanes);
 248                        return -EINVAL;
 249                } else {
 250                        return 0;
 251                }
 252        }
 253
 254        /* Handle REQBUFS situation */
 255        size = dev->capture.port->current_buffer.size;
 256        if (size == 0) {
 257                v4l2_err(&dev->v4l2_dev,
 258                         "%s: capture port buffer size is zero\n", __func__);
 259                return -EINVAL;
 260        }
 261
 262        if (*nbuffers < dev->capture.port->minimum_buffer.num)
 263                *nbuffers = dev->capture.port->minimum_buffer.num;
 264
 265        dev->capture.port->current_buffer.num = *nbuffers;
 266
 267        *nplanes = 1;
 268
 269        sizes[0] = size;
 270
 271        /*
 272         * videobuf2-vmalloc allocator is context-less so no need to set
 273         * alloc_ctxs array.
 274         */
 275
 276        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
 277                 __func__, dev);
 278
 279        return 0;
 280}
 281
 282static int buffer_init(struct vb2_buffer *vb)
 283{
 284        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 285        struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
 286        struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
 287
 288        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
 289                 __func__, dev, vb);
 290        buf->buffer = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
 291        buf->buffer_size = vb2_plane_size(&buf->vb.vb2_buf, 0);
 292
 293        return mmal_vchi_buffer_init(dev->instance, buf);
 294}
 295
 296static int buffer_prepare(struct vb2_buffer *vb)
 297{
 298        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 299        unsigned long size;
 300
 301        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
 302                 __func__, dev, vb);
 303
 304        if (!dev->capture.port || !dev->capture.fmt)
 305                return -ENODEV;
 306
 307        size = dev->capture.stride * dev->capture.height;
 308        if (vb2_plane_size(vb, 0) < size) {
 309                v4l2_err(&dev->v4l2_dev,
 310                         "%s data will not fit into plane (%lu < %lu)\n",
 311                         __func__, vb2_plane_size(vb, 0), size);
 312                return -EINVAL;
 313        }
 314
 315        return 0;
 316}
 317
 318static void buffer_cleanup(struct vb2_buffer *vb)
 319{
 320        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 321        struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
 322        struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
 323
 324        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p, vb %p\n",
 325                 __func__, dev, vb);
 326        mmal_vchi_buffer_cleanup(buf);
 327}
 328
 329static inline bool is_capturing(struct bm2835_mmal_dev *dev)
 330{
 331        return dev->capture.camera_port ==
 332            &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
 333}
 334
 335static void buffer_cb(struct vchiq_mmal_instance *instance,
 336                      struct vchiq_mmal_port *port,
 337                      int status,
 338                      struct mmal_buffer *buf,
 339                      unsigned long length, u32 mmal_flags, s64 dts, s64 pts)
 340{
 341        struct bm2835_mmal_dev *dev = port->cb_ctx;
 342
 343        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 344                 "%s: status:%d, buf:%p, length:%lu, flags %u, pts %lld\n",
 345                 __func__, status, buf, length, mmal_flags, pts);
 346
 347        if (status) {
 348                /* error in transfer */
 349                if (buf) {
 350                        /* there was a buffer with the error so return it */
 351                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 352                }
 353                return;
 354        }
 355
 356        if (length == 0) {
 357                /* stream ended */
 358                if (dev->capture.frame_count) {
 359                        /* empty buffer whilst capturing - expected to be an
 360                         * EOS, so grab another frame
 361                         */
 362                        if (is_capturing(dev)) {
 363                                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 364                                         "Grab another frame");
 365                                vchiq_mmal_port_parameter_set(
 366                                        instance,
 367                                        dev->capture.camera_port,
 368                                        MMAL_PARAMETER_CAPTURE,
 369                                        &dev->capture.frame_count,
 370                                        sizeof(dev->capture.frame_count));
 371                        }
 372                        if (vchiq_mmal_submit_buffer(instance, port, buf))
 373                                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 374                                         "Failed to return EOS buffer");
 375                } else {
 376                        /* stopping streaming.
 377                         * return buffer, and signal frame completion
 378                         */
 379                        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 380                        complete(&dev->capture.frame_cmplt);
 381                }
 382                return;
 383        }
 384
 385        if (!dev->capture.frame_count) {
 386                /* signal frame completion */
 387                vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
 388                complete(&dev->capture.frame_cmplt);
 389                return;
 390        }
 391
 392        if (dev->capture.vc_start_timestamp != -1 && pts) {
 393                ktime_t timestamp;
 394                s64 runtime_us = pts -
 395                    dev->capture.vc_start_timestamp;
 396                timestamp = ktime_add_us(dev->capture.kernel_start_ts,
 397                                         runtime_us);
 398                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 399                         "Convert start time %llu and %llu with offset %llu to %llu\n",
 400                         ktime_to_ns(dev->capture.kernel_start_ts),
 401                         dev->capture.vc_start_timestamp, pts,
 402                         ktime_to_ns(timestamp));
 403                buf->vb.vb2_buf.timestamp = ktime_to_ns(timestamp);
 404        } else {
 405                buf->vb.vb2_buf.timestamp = ktime_get_ns();
 406        }
 407        buf->vb.sequence = dev->capture.sequence++;
 408        buf->vb.field = V4L2_FIELD_NONE;
 409
 410        vb2_set_plane_payload(&buf->vb.vb2_buf, 0, length);
 411        if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_KEYFRAME)
 412                buf->vb.flags |= V4L2_BUF_FLAG_KEYFRAME;
 413
 414        vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
 415
 416        if (mmal_flags & MMAL_BUFFER_HEADER_FLAG_EOS &&
 417            is_capturing(dev)) {
 418                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 419                         "Grab another frame as buffer has EOS");
 420                vchiq_mmal_port_parameter_set(
 421                        instance,
 422                        dev->capture.camera_port,
 423                        MMAL_PARAMETER_CAPTURE,
 424                        &dev->capture.frame_count,
 425                        sizeof(dev->capture.frame_count));
 426        }
 427}
 428
 429static int enable_camera(struct bm2835_mmal_dev *dev)
 430{
 431        int ret;
 432
 433        if (!dev->camera_use_count) {
 434                ret = vchiq_mmal_port_parameter_set(
 435                        dev->instance,
 436                        &dev->component[COMP_CAMERA]->control,
 437                        MMAL_PARAMETER_CAMERA_NUM, &dev->camera_num,
 438                        sizeof(dev->camera_num));
 439                if (ret < 0) {
 440                        v4l2_err(&dev->v4l2_dev,
 441                                 "Failed setting camera num, ret %d\n", ret);
 442                        return -EINVAL;
 443                }
 444
 445                ret = vchiq_mmal_component_enable(
 446                                dev->instance,
 447                                dev->component[COMP_CAMERA]);
 448                if (ret < 0) {
 449                        v4l2_err(&dev->v4l2_dev,
 450                                 "Failed enabling camera, ret %d\n", ret);
 451                        return -EINVAL;
 452                }
 453        }
 454        dev->camera_use_count++;
 455        v4l2_dbg(1, bcm2835_v4l2_debug,
 456                 &dev->v4l2_dev, "enabled camera (refcount %d)\n",
 457                        dev->camera_use_count);
 458        return 0;
 459}
 460
 461static int disable_camera(struct bm2835_mmal_dev *dev)
 462{
 463        int ret;
 464
 465        if (!dev->camera_use_count) {
 466                v4l2_err(&dev->v4l2_dev,
 467                         "Disabled the camera when already disabled\n");
 468                return -EINVAL;
 469        }
 470        dev->camera_use_count--;
 471        if (!dev->camera_use_count) {
 472                unsigned int i = 0xFFFFFFFF;
 473
 474                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 475                         "Disabling camera\n");
 476                ret =
 477                    vchiq_mmal_component_disable(
 478                                dev->instance,
 479                                dev->component[COMP_CAMERA]);
 480                if (ret < 0) {
 481                        v4l2_err(&dev->v4l2_dev,
 482                                 "Failed disabling camera, ret %d\n", ret);
 483                        return -EINVAL;
 484                }
 485                vchiq_mmal_port_parameter_set(
 486                        dev->instance,
 487                        &dev->component[COMP_CAMERA]->control,
 488                        MMAL_PARAMETER_CAMERA_NUM, &i,
 489                        sizeof(i));
 490        }
 491        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 492                 "Camera refcount now %d\n", dev->camera_use_count);
 493        return 0;
 494}
 495
 496static void buffer_queue(struct vb2_buffer *vb)
 497{
 498        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
 499        struct vb2_v4l2_buffer *vb2 = to_vb2_v4l2_buffer(vb);
 500        struct mmal_buffer *buf = container_of(vb2, struct mmal_buffer, vb);
 501        int ret;
 502
 503        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 504                 "%s: dev:%p buf:%p, idx %u\n",
 505                 __func__, dev, buf, vb2->vb2_buf.index);
 506
 507        ret = vchiq_mmal_submit_buffer(dev->instance, dev->capture.port, buf);
 508        if (ret < 0)
 509                v4l2_err(&dev->v4l2_dev, "%s: error submitting buffer\n",
 510                         __func__);
 511}
 512
 513static int start_streaming(struct vb2_queue *vq, unsigned int count)
 514{
 515        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
 516        int ret;
 517        u32 parameter_size;
 518
 519        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
 520                 __func__, dev);
 521
 522        /* ensure a format has actually been set */
 523        if (!dev->capture.port)
 524                return -EINVAL;
 525
 526        if (enable_camera(dev) < 0) {
 527                v4l2_err(&dev->v4l2_dev, "Failed to enable camera\n");
 528                return -EINVAL;
 529        }
 530
 531        /*init_completion(&dev->capture.frame_cmplt); */
 532
 533        /* enable frame capture */
 534        dev->capture.frame_count = 1;
 535
 536        /* reset sequence number */
 537        dev->capture.sequence = 0;
 538
 539        /* if the preview is not already running, wait for a few frames for AGC
 540         * to settle down.
 541         */
 542        if (!dev->component[COMP_PREVIEW]->enabled)
 543                msleep(300);
 544
 545        /* enable the connection from camera to encoder (if applicable) */
 546        if (dev->capture.camera_port != dev->capture.port &&
 547            dev->capture.camera_port) {
 548                ret = vchiq_mmal_port_enable(dev->instance,
 549                                             dev->capture.camera_port, NULL);
 550                if (ret) {
 551                        v4l2_err(&dev->v4l2_dev,
 552                                 "Failed to enable encode tunnel - error %d\n",
 553                                 ret);
 554                        return -1;
 555                }
 556        }
 557
 558        /* Get VC timestamp at this point in time */
 559        parameter_size = sizeof(dev->capture.vc_start_timestamp);
 560        if (vchiq_mmal_port_parameter_get(dev->instance,
 561                                          dev->capture.camera_port,
 562                                          MMAL_PARAMETER_SYSTEM_TIME,
 563                                          &dev->capture.vc_start_timestamp,
 564                                          &parameter_size)) {
 565                v4l2_err(&dev->v4l2_dev,
 566                         "Failed to get VC start time - update your VC f/w\n");
 567
 568                /* Flag to indicate just to rely on kernel timestamps */
 569                dev->capture.vc_start_timestamp = -1;
 570        } else {
 571                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 572                         "Start time %lld size %d\n",
 573                         dev->capture.vc_start_timestamp, parameter_size);
 574        }
 575
 576        dev->capture.kernel_start_ts = ktime_get();
 577
 578        /* enable the camera port */
 579        dev->capture.port->cb_ctx = dev;
 580        ret =
 581            vchiq_mmal_port_enable(dev->instance, dev->capture.port, buffer_cb);
 582        if (ret) {
 583                v4l2_err(&dev->v4l2_dev,
 584                         "Failed to enable capture port - error %d. Disabling camera port again\n",
 585                         ret);
 586
 587                vchiq_mmal_port_disable(dev->instance,
 588                                        dev->capture.camera_port);
 589                if (disable_camera(dev) < 0) {
 590                        v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
 591                        return -EINVAL;
 592                }
 593                return -1;
 594        }
 595
 596        /* capture the first frame */
 597        vchiq_mmal_port_parameter_set(dev->instance,
 598                                      dev->capture.camera_port,
 599                                      MMAL_PARAMETER_CAPTURE,
 600                                      &dev->capture.frame_count,
 601                                      sizeof(dev->capture.frame_count));
 602        return 0;
 603}
 604
 605/* abort streaming and wait for last buffer */
 606static void stop_streaming(struct vb2_queue *vq)
 607{
 608        int ret;
 609        unsigned long timeout;
 610        struct bm2835_mmal_dev *dev = vb2_get_drv_priv(vq);
 611        struct vchiq_mmal_port *port = dev->capture.port;
 612
 613        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "%s: dev:%p\n",
 614                 __func__, dev);
 615
 616        init_completion(&dev->capture.frame_cmplt);
 617        dev->capture.frame_count = 0;
 618
 619        /* ensure a format has actually been set */
 620        if (!dev->capture.port) {
 621                v4l2_err(&dev->v4l2_dev,
 622                         "no capture port - stream not started?\n");
 623                return;
 624        }
 625
 626        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "stopping capturing\n");
 627
 628        /* stop capturing frames */
 629        vchiq_mmal_port_parameter_set(dev->instance,
 630                                      dev->capture.camera_port,
 631                                      MMAL_PARAMETER_CAPTURE,
 632                                      &dev->capture.frame_count,
 633                                      sizeof(dev->capture.frame_count));
 634
 635        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 636                 "disabling connection\n");
 637
 638        /* disable the connection from camera to encoder */
 639        ret = vchiq_mmal_port_disable(dev->instance, dev->capture.camera_port);
 640        if (!ret && dev->capture.camera_port != dev->capture.port) {
 641                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 642                         "disabling port\n");
 643                ret = vchiq_mmal_port_disable(dev->instance, dev->capture.port);
 644        } else if (dev->capture.camera_port != dev->capture.port) {
 645                v4l2_err(&dev->v4l2_dev, "port_disable failed, error %d\n",
 646                         ret);
 647        }
 648
 649        /* wait for all buffers to be returned */
 650        while (atomic_read(&port->buffers_with_vpu)) {
 651                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 652                         "%s: Waiting for buffers to be returned - %d outstanding\n",
 653                         __func__, atomic_read(&port->buffers_with_vpu));
 654                timeout = wait_for_completion_timeout(&dev->capture.frame_cmplt,
 655                                                      HZ);
 656                if (timeout == 0) {
 657                        v4l2_err(&dev->v4l2_dev, "%s: Timeout waiting for buffers to be returned - %d outstanding\n",
 658                                 __func__,
 659                                 atomic_read(&port->buffers_with_vpu));
 660                        break;
 661                }
 662        }
 663
 664        if (disable_camera(dev) < 0)
 665                v4l2_err(&dev->v4l2_dev, "Failed to disable camera\n");
 666}
 667
 668static const struct vb2_ops bm2835_mmal_video_qops = {
 669        .queue_setup = queue_setup,
 670        .buf_init = buffer_init,
 671        .buf_prepare = buffer_prepare,
 672        .buf_cleanup = buffer_cleanup,
 673        .buf_queue = buffer_queue,
 674        .start_streaming = start_streaming,
 675        .stop_streaming = stop_streaming,
 676        .wait_prepare = vb2_ops_wait_prepare,
 677        .wait_finish = vb2_ops_wait_finish,
 678};
 679
 680/* ------------------------------------------------------------------
 681 *      IOCTL operations
 682 * ------------------------------------------------------------------
 683 */
 684
 685static int set_overlay_params(struct bm2835_mmal_dev *dev,
 686                              struct vchiq_mmal_port *port)
 687{
 688        struct mmal_parameter_displayregion prev_config = {
 689                .set =  MMAL_DISPLAY_SET_LAYER |
 690                        MMAL_DISPLAY_SET_ALPHA |
 691                        MMAL_DISPLAY_SET_DEST_RECT |
 692                        MMAL_DISPLAY_SET_FULLSCREEN,
 693                .layer = PREVIEW_LAYER,
 694                .alpha = dev->overlay.global_alpha,
 695                .fullscreen = 0,
 696                .dest_rect = {
 697                        .x = dev->overlay.w.left,
 698                        .y = dev->overlay.w.top,
 699                        .width = dev->overlay.w.width,
 700                        .height = dev->overlay.w.height,
 701                },
 702        };
 703        return vchiq_mmal_port_parameter_set(dev->instance, port,
 704                                             MMAL_PARAMETER_DISPLAYREGION,
 705                                             &prev_config, sizeof(prev_config));
 706}
 707
 708/* overlay ioctl */
 709static int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv,
 710                                       struct v4l2_fmtdesc *f)
 711{
 712        struct mmal_fmt *fmt;
 713
 714        if (f->index >= ARRAY_SIZE(formats))
 715                return -EINVAL;
 716
 717        fmt = &formats[f->index];
 718
 719        strlcpy((char *)f->description, fmt->name, sizeof(f->description));
 720        f->pixelformat = fmt->fourcc;
 721        f->flags = fmt->flags;
 722
 723        return 0;
 724}
 725
 726static int vidioc_g_fmt_vid_overlay(struct file *file, void *priv,
 727                                    struct v4l2_format *f)
 728{
 729        struct bm2835_mmal_dev *dev = video_drvdata(file);
 730
 731        f->fmt.win = dev->overlay;
 732
 733        return 0;
 734}
 735
 736static int vidioc_try_fmt_vid_overlay(struct file *file, void *priv,
 737                                      struct v4l2_format *f)
 738{
 739        struct bm2835_mmal_dev *dev = video_drvdata(file);
 740
 741        f->fmt.win.field = V4L2_FIELD_NONE;
 742        f->fmt.win.chromakey = 0;
 743        f->fmt.win.clips = NULL;
 744        f->fmt.win.clipcount = 0;
 745        f->fmt.win.bitmap = NULL;
 746
 747        v4l_bound_align_image(&f->fmt.win.w.width, MIN_WIDTH, dev->max_width, 1,
 748                              &f->fmt.win.w.height, MIN_HEIGHT, dev->max_height,
 749                              1, 0);
 750        v4l_bound_align_image(&f->fmt.win.w.left, MIN_WIDTH, dev->max_width, 1,
 751                              &f->fmt.win.w.top, MIN_HEIGHT, dev->max_height,
 752                              1, 0);
 753
 754        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 755                 "Overlay: Now w/h %dx%d l/t %dx%d\n",
 756                f->fmt.win.w.width, f->fmt.win.w.height,
 757                f->fmt.win.w.left, f->fmt.win.w.top);
 758
 759        v4l2_dump_win_format(1,
 760                             bcm2835_v4l2_debug,
 761                             &dev->v4l2_dev,
 762                             &f->fmt.win,
 763                             __func__);
 764        return 0;
 765}
 766
 767static int vidioc_s_fmt_vid_overlay(struct file *file, void *priv,
 768                                    struct v4l2_format *f)
 769{
 770        struct bm2835_mmal_dev *dev = video_drvdata(file);
 771
 772        vidioc_try_fmt_vid_overlay(file, priv, f);
 773
 774        dev->overlay = f->fmt.win;
 775        if (dev->component[COMP_PREVIEW]->enabled) {
 776                set_overlay_params(dev,
 777                                   &dev->component[COMP_PREVIEW]->input[0]);
 778        }
 779
 780        return 0;
 781}
 782
 783static int vidioc_overlay(struct file *file, void *f, unsigned int on)
 784{
 785        int ret;
 786        struct bm2835_mmal_dev *dev = video_drvdata(file);
 787        struct vchiq_mmal_port *src;
 788        struct vchiq_mmal_port *dst;
 789
 790        if ((on && dev->component[COMP_PREVIEW]->enabled) ||
 791            (!on && !dev->component[COMP_PREVIEW]->enabled))
 792                return 0;       /* already in requested state */
 793
 794        src =
 795            &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
 796
 797        if (!on) {
 798                /* disconnect preview ports and disable component */
 799                ret = vchiq_mmal_port_disable(dev->instance, src);
 800                if (!ret)
 801                        ret =
 802                            vchiq_mmal_port_connect_tunnel(dev->instance, src,
 803                                                           NULL);
 804                if (ret >= 0)
 805                        ret = vchiq_mmal_component_disable(
 806                                        dev->instance,
 807                                        dev->component[COMP_PREVIEW]);
 808
 809                disable_camera(dev);
 810                return ret;
 811        }
 812
 813        /* set preview port format and connect it to output */
 814        dst = &dev->component[COMP_PREVIEW]->input[0];
 815
 816        ret = vchiq_mmal_port_set_format(dev->instance, src);
 817        if (ret < 0)
 818                return ret;
 819
 820        ret = set_overlay_params(dev, dst);
 821        if (ret < 0)
 822                return ret;
 823
 824        if (enable_camera(dev) < 0)
 825                return -EINVAL;
 826
 827        ret = vchiq_mmal_component_enable(
 828                        dev->instance,
 829                        dev->component[COMP_PREVIEW]);
 830        if (ret < 0)
 831                return ret;
 832
 833        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev, "connecting %p to %p\n",
 834                 src, dst);
 835        ret = vchiq_mmal_port_connect_tunnel(dev->instance, src, dst);
 836        if (ret)
 837                return ret;
 838
 839        return vchiq_mmal_port_enable(dev->instance, src, NULL);
 840}
 841
 842static int vidioc_g_fbuf(struct file *file, void *fh,
 843                         struct v4l2_framebuffer *a)
 844{
 845        /* The video overlay must stay within the framebuffer and can't be
 846         * positioned independently.
 847         */
 848        struct bm2835_mmal_dev *dev = video_drvdata(file);
 849        struct vchiq_mmal_port *preview_port =
 850                &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
 851
 852        a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY |
 853                        V4L2_FBUF_CAP_GLOBAL_ALPHA;
 854        a->flags = V4L2_FBUF_FLAG_OVERLAY;
 855        a->fmt.width = preview_port->es.video.width;
 856        a->fmt.height = preview_port->es.video.height;
 857        a->fmt.pixelformat = V4L2_PIX_FMT_YUV420;
 858        a->fmt.bytesperline = preview_port->es.video.width;
 859        a->fmt.sizeimage = (preview_port->es.video.width *
 860                               preview_port->es.video.height * 3) >> 1;
 861        a->fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
 862
 863        return 0;
 864}
 865
 866/* input ioctls */
 867static int vidioc_enum_input(struct file *file, void *priv,
 868                             struct v4l2_input *inp)
 869{
 870        /* only a single camera input */
 871        if (inp->index)
 872                return -EINVAL;
 873
 874        inp->type = V4L2_INPUT_TYPE_CAMERA;
 875        sprintf((char *)inp->name, "Camera %u", inp->index);
 876        return 0;
 877}
 878
 879static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
 880{
 881        *i = 0;
 882        return 0;
 883}
 884
 885static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 886{
 887        if (i)
 888                return -EINVAL;
 889
 890        return 0;
 891}
 892
 893/* capture ioctls */
 894static int vidioc_querycap(struct file *file, void *priv,
 895                           struct v4l2_capability *cap)
 896{
 897        struct bm2835_mmal_dev *dev = video_drvdata(file);
 898        u32 major;
 899        u32 minor;
 900
 901        vchiq_mmal_version(dev->instance, &major, &minor);
 902
 903        strcpy((char *)cap->driver, "bm2835 mmal");
 904        snprintf((char *)cap->card, sizeof(cap->card), "mmal service %d.%d",
 905                 major, minor);
 906
 907        snprintf((char *)cap->bus_info, sizeof(cap->bus_info),
 908                 "platform:%s", dev->v4l2_dev.name);
 909        return 0;
 910}
 911
 912static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
 913                                   struct v4l2_fmtdesc *f)
 914{
 915        struct mmal_fmt *fmt;
 916
 917        if (f->index >= ARRAY_SIZE(formats))
 918                return -EINVAL;
 919
 920        fmt = &formats[f->index];
 921
 922        strlcpy((char *)f->description, fmt->name, sizeof(f->description));
 923        f->pixelformat = fmt->fourcc;
 924        f->flags = fmt->flags;
 925
 926        return 0;
 927}
 928
 929static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 930                                struct v4l2_format *f)
 931{
 932        struct bm2835_mmal_dev *dev = video_drvdata(file);
 933
 934        f->fmt.pix.width = dev->capture.width;
 935        f->fmt.pix.height = dev->capture.height;
 936        f->fmt.pix.field = V4L2_FIELD_NONE;
 937        f->fmt.pix.pixelformat = dev->capture.fmt->fourcc;
 938        f->fmt.pix.bytesperline = dev->capture.stride;
 939        f->fmt.pix.sizeimage = dev->capture.buffersize;
 940
 941        if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_RGB24)
 942                f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
 943        else if (dev->capture.fmt->fourcc == V4L2_PIX_FMT_JPEG)
 944                f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
 945        else
 946                f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
 947        f->fmt.pix.priv = 0;
 948
 949        v4l2_dump_pix_format(1, bcm2835_v4l2_debug, &dev->v4l2_dev, &f->fmt.pix,
 950                             __func__);
 951        return 0;
 952}
 953
 954static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 955                                  struct v4l2_format *f)
 956{
 957        struct bm2835_mmal_dev *dev = video_drvdata(file);
 958        struct mmal_fmt *mfmt;
 959
 960        mfmt = get_format(f);
 961        if (!mfmt) {
 962                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 963                         "Fourcc format (0x%08x) unknown.\n",
 964                         f->fmt.pix.pixelformat);
 965                f->fmt.pix.pixelformat = formats[0].fourcc;
 966                mfmt = get_format(f);
 967        }
 968
 969        f->fmt.pix.field = V4L2_FIELD_NONE;
 970
 971        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 972                 "Clipping/aligning %dx%d format %08X\n",
 973                 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
 974
 975        v4l_bound_align_image(&f->fmt.pix.width, MIN_WIDTH, dev->max_width, 1,
 976                              &f->fmt.pix.height, MIN_HEIGHT, dev->max_height,
 977                              1, 0);
 978        f->fmt.pix.bytesperline = f->fmt.pix.width * mfmt->ybbp;
 979        if (!mfmt->remove_padding) {
 980                if (mfmt->depth == 24) {
 981                        /*
 982                         * 24bpp is a pain as we can't use simple masking.
 983                         * Min stride is width aligned to 16, times 24bpp.
 984                         */
 985                        f->fmt.pix.bytesperline =
 986                                ((f->fmt.pix.width + 15) & ~15) * 3;
 987                } else {
 988                        /*
 989                         * GPU isn't removing padding, so stride is aligned to
 990                         * 32
 991                         */
 992                        int align_mask = ((32 * mfmt->depth) >> 3) - 1;
 993
 994                        f->fmt.pix.bytesperline =
 995                                (f->fmt.pix.bytesperline + align_mask) &
 996                                                        ~align_mask;
 997                }
 998                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
 999                         "Not removing padding, so bytes/line = %d\n",
1000                         f->fmt.pix.bytesperline);
1001        }
1002
1003        /* Image buffer has to be padded to allow for alignment, even though
1004         * we sometimes then remove that padding before delivering the buffer.
1005         */
1006        f->fmt.pix.sizeimage = ((f->fmt.pix.height + 15) & ~15) *
1007                        (((f->fmt.pix.width + 31) & ~31) * mfmt->depth) >> 3;
1008
1009        if ((mfmt->flags & V4L2_FMT_FLAG_COMPRESSED) &&
1010            f->fmt.pix.sizeimage < MIN_BUFFER_SIZE)
1011                f->fmt.pix.sizeimage = MIN_BUFFER_SIZE;
1012
1013        if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24)
1014                f->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
1015        else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_JPEG)
1016                f->fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;
1017        else
1018                f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1019        f->fmt.pix.priv = 0;
1020
1021        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1022                 "Now %dx%d format %08X\n",
1023                f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.pixelformat);
1024
1025        v4l2_dump_pix_format(1, bcm2835_v4l2_debug, &dev->v4l2_dev, &f->fmt.pix,
1026                             __func__);
1027        return 0;
1028}
1029
1030static int mmal_setup_components(struct bm2835_mmal_dev *dev,
1031                                 struct v4l2_format *f)
1032{
1033        int ret;
1034        struct vchiq_mmal_port *port = NULL, *camera_port = NULL;
1035        struct vchiq_mmal_component *encode_component = NULL;
1036        struct mmal_fmt *mfmt = get_format(f);
1037        u32 remove_padding;
1038
1039        if (!mfmt)
1040                return -EINVAL;
1041
1042        if (dev->capture.encode_component) {
1043                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1044                         "vid_cap - disconnect previous tunnel\n");
1045
1046                /* Disconnect any previous connection */
1047                vchiq_mmal_port_connect_tunnel(dev->instance,
1048                                               dev->capture.camera_port, NULL);
1049                dev->capture.camera_port = NULL;
1050                ret = vchiq_mmal_component_disable(dev->instance,
1051                                                   dev->capture.encode_component);
1052                if (ret)
1053                        v4l2_err(&dev->v4l2_dev,
1054                                 "Failed to disable encode component %d\n",
1055                                 ret);
1056
1057                dev->capture.encode_component = NULL;
1058        }
1059        /* format dependent port setup */
1060        switch (mfmt->mmal_component) {
1061        case COMP_CAMERA:
1062                /* Make a further decision on port based on resolution */
1063                if (f->fmt.pix.width <= max_video_width &&
1064                    f->fmt.pix.height <= max_video_height)
1065                        camera_port =
1066                            &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO];
1067                else
1068                        camera_port =
1069                            &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
1070                port = camera_port;
1071                break;
1072        case COMP_IMAGE_ENCODE:
1073                encode_component = dev->component[COMP_IMAGE_ENCODE];
1074                port = &dev->component[COMP_IMAGE_ENCODE]->output[0];
1075                camera_port =
1076                    &dev->component[COMP_CAMERA]->output[CAM_PORT_CAPTURE];
1077                break;
1078        case COMP_VIDEO_ENCODE:
1079                encode_component = dev->component[COMP_VIDEO_ENCODE];
1080                port = &dev->component[COMP_VIDEO_ENCODE]->output[0];
1081                camera_port =
1082                    &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO];
1083                break;
1084        default:
1085                break;
1086        }
1087
1088        if (!port)
1089                return -EINVAL;
1090
1091        if (encode_component)
1092                camera_port->format.encoding = MMAL_ENCODING_OPAQUE;
1093        else
1094                camera_port->format.encoding = mfmt->mmal;
1095
1096        if (dev->rgb_bgr_swapped) {
1097                if (camera_port->format.encoding == MMAL_ENCODING_RGB24)
1098                        camera_port->format.encoding = MMAL_ENCODING_BGR24;
1099                else if (camera_port->format.encoding == MMAL_ENCODING_BGR24)
1100                        camera_port->format.encoding = MMAL_ENCODING_RGB24;
1101        }
1102
1103        remove_padding = mfmt->remove_padding;
1104        vchiq_mmal_port_parameter_set(dev->instance,
1105                                      camera_port,
1106                                      MMAL_PARAMETER_NO_IMAGE_PADDING,
1107                                      &remove_padding, sizeof(remove_padding));
1108
1109        camera_port->format.encoding_variant = 0;
1110        camera_port->es.video.width = f->fmt.pix.width;
1111        camera_port->es.video.height = f->fmt.pix.height;
1112        camera_port->es.video.crop.x = 0;
1113        camera_port->es.video.crop.y = 0;
1114        camera_port->es.video.crop.width = f->fmt.pix.width;
1115        camera_port->es.video.crop.height = f->fmt.pix.height;
1116        camera_port->es.video.frame_rate.num = 0;
1117        camera_port->es.video.frame_rate.den = 1;
1118        camera_port->es.video.color_space = MMAL_COLOR_SPACE_JPEG_JFIF;
1119
1120        ret = vchiq_mmal_port_set_format(dev->instance, camera_port);
1121
1122        if (!ret
1123            && camera_port ==
1124            &dev->component[COMP_CAMERA]->output[CAM_PORT_VIDEO]) {
1125                bool overlay_enabled =
1126                    !!dev->component[COMP_PREVIEW]->enabled;
1127                struct vchiq_mmal_port *preview_port =
1128                    &dev->component[COMP_CAMERA]->output[CAM_PORT_PREVIEW];
1129                /* Preview and encode ports need to match on resolution */
1130                if (overlay_enabled) {
1131                        /* Need to disable the overlay before we can update
1132                         * the resolution
1133                         */
1134                        ret =
1135                            vchiq_mmal_port_disable(dev->instance,
1136                                                    preview_port);
1137                        if (!ret)
1138                                ret =
1139                                    vchiq_mmal_port_connect_tunnel(
1140                                                dev->instance,
1141                                                preview_port,
1142                                                NULL);
1143                }
1144                preview_port->es.video.width = f->fmt.pix.width;
1145                preview_port->es.video.height = f->fmt.pix.height;
1146                preview_port->es.video.crop.x = 0;
1147                preview_port->es.video.crop.y = 0;
1148                preview_port->es.video.crop.width = f->fmt.pix.width;
1149                preview_port->es.video.crop.height = f->fmt.pix.height;
1150                preview_port->es.video.frame_rate.num =
1151                                          dev->capture.timeperframe.denominator;
1152                preview_port->es.video.frame_rate.den =
1153                                          dev->capture.timeperframe.numerator;
1154                ret = vchiq_mmal_port_set_format(dev->instance, preview_port);
1155                if (overlay_enabled) {
1156                        ret = vchiq_mmal_port_connect_tunnel(
1157                                dev->instance,
1158                                preview_port,
1159                                &dev->component[COMP_PREVIEW]->input[0]);
1160                        if (!ret)
1161                                ret = vchiq_mmal_port_enable(dev->instance,
1162                                                             preview_port,
1163                                                             NULL);
1164                }
1165        }
1166
1167        if (ret) {
1168                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1169                         "%s failed to set format %dx%d %08X\n", __func__,
1170                         f->fmt.pix.width, f->fmt.pix.height,
1171                         f->fmt.pix.pixelformat);
1172                /* ensure capture is not going to be tried */
1173                dev->capture.port = NULL;
1174        } else {
1175                if (encode_component) {
1176                        v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1177                                 "vid_cap - set up encode comp\n");
1178
1179                        /* configure buffering */
1180                        camera_port->current_buffer.size =
1181                            camera_port->recommended_buffer.size;
1182                        camera_port->current_buffer.num =
1183                            camera_port->recommended_buffer.num;
1184
1185                        ret =
1186                            vchiq_mmal_port_connect_tunnel(
1187                                        dev->instance,
1188                                        camera_port,
1189                                        &encode_component->input[0]);
1190                        if (ret) {
1191                                v4l2_dbg(1, bcm2835_v4l2_debug,
1192                                         &dev->v4l2_dev,
1193                                         "%s failed to create connection\n",
1194                                         __func__);
1195                                /* ensure capture is not going to be tried */
1196                                dev->capture.port = NULL;
1197                        } else {
1198                                port->es.video.width = f->fmt.pix.width;
1199                                port->es.video.height = f->fmt.pix.height;
1200                                port->es.video.crop.x = 0;
1201                                port->es.video.crop.y = 0;
1202                                port->es.video.crop.width = f->fmt.pix.width;
1203                                port->es.video.crop.height = f->fmt.pix.height;
1204                                port->es.video.frame_rate.num =
1205                                          dev->capture.timeperframe.denominator;
1206                                port->es.video.frame_rate.den =
1207                                          dev->capture.timeperframe.numerator;
1208
1209                                port->format.encoding = mfmt->mmal;
1210                                port->format.encoding_variant = 0;
1211                                /* Set any encoding specific parameters */
1212                                switch (mfmt->mmal_component) {
1213                                case COMP_VIDEO_ENCODE:
1214                                        port->format.bitrate =
1215                                            dev->capture.encode_bitrate;
1216                                        break;
1217                                case COMP_IMAGE_ENCODE:
1218                                        /* Could set EXIF parameters here */
1219                                        break;
1220                                default:
1221                                        break;
1222                                }
1223                                ret = vchiq_mmal_port_set_format(dev->instance,
1224                                                                 port);
1225                                if (ret)
1226                                        v4l2_dbg(1, bcm2835_v4l2_debug,
1227                                                 &dev->v4l2_dev,
1228                                                 "%s failed to set format %dx%d fmt %08X\n",
1229                                                 __func__,
1230                                                 f->fmt.pix.width,
1231                                                 f->fmt.pix.height,
1232                                                 f->fmt.pix.pixelformat
1233                                                 );
1234                        }
1235
1236                        if (!ret) {
1237                                ret = vchiq_mmal_component_enable(
1238                                                dev->instance,
1239                                                encode_component);
1240                                if (ret) {
1241                                        v4l2_dbg(1, bcm2835_v4l2_debug,
1242                                                 &dev->v4l2_dev,
1243                                                 "%s Failed to enable encode components\n",
1244                                                 __func__);
1245                                }
1246                        }
1247                        if (!ret) {
1248                                /* configure buffering */
1249                                port->current_buffer.num = 1;
1250                                port->current_buffer.size =
1251                                    f->fmt.pix.sizeimage;
1252                                if (port->format.encoding ==
1253                                    MMAL_ENCODING_JPEG) {
1254                                        v4l2_dbg(1, bcm2835_v4l2_debug,
1255                                                 &dev->v4l2_dev,
1256                                                 "JPG - buf size now %d was %d\n",
1257                                                 f->fmt.pix.sizeimage,
1258                                                 port->current_buffer.size);
1259                                        port->current_buffer.size =
1260                                            (f->fmt.pix.sizeimage <
1261                                             (100 << 10)) ?
1262                                            (100 << 10) : f->fmt.pix.sizeimage;
1263                                }
1264                                v4l2_dbg(1, bcm2835_v4l2_debug,
1265                                         &dev->v4l2_dev,
1266                                         "vid_cap - cur_buf.size set to %d\n",
1267                                         f->fmt.pix.sizeimage);
1268                                port->current_buffer.alignment = 0;
1269                        }
1270                } else {
1271                        /* configure buffering */
1272                        camera_port->current_buffer.num = 1;
1273                        camera_port->current_buffer.size = f->fmt.pix.sizeimage;
1274                        camera_port->current_buffer.alignment = 0;
1275                }
1276
1277                if (!ret) {
1278                        dev->capture.fmt = mfmt;
1279                        dev->capture.stride = f->fmt.pix.bytesperline;
1280                        dev->capture.width = camera_port->es.video.crop.width;
1281                        dev->capture.height = camera_port->es.video.crop.height;
1282                        dev->capture.buffersize = port->current_buffer.size;
1283
1284                        /* select port for capture */
1285                        dev->capture.port = port;
1286                        dev->capture.camera_port = camera_port;
1287                        dev->capture.encode_component = encode_component;
1288                        v4l2_dbg(1, bcm2835_v4l2_debug,
1289                                 &dev->v4l2_dev,
1290                                "Set dev->capture.fmt %08X, %dx%d, stride %d, size %d",
1291                                port->format.encoding,
1292                                dev->capture.width, dev->capture.height,
1293                                dev->capture.stride, dev->capture.buffersize);
1294                }
1295        }
1296
1297        /* todo: Need to convert the vchiq/mmal error into a v4l2 error. */
1298        return ret;
1299}
1300
1301static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1302                                struct v4l2_format *f)
1303{
1304        int ret;
1305        struct bm2835_mmal_dev *dev = video_drvdata(file);
1306        struct mmal_fmt *mfmt;
1307
1308        /* try the format to set valid parameters */
1309        ret = vidioc_try_fmt_vid_cap(file, priv, f);
1310        if (ret) {
1311                v4l2_err(&dev->v4l2_dev,
1312                         "vid_cap - vidioc_try_fmt_vid_cap failed\n");
1313                return ret;
1314        }
1315
1316        /* if a capture is running refuse to set format */
1317        if (vb2_is_busy(&dev->capture.vb_vidq)) {
1318                v4l2_info(&dev->v4l2_dev, "%s device busy\n", __func__);
1319                return -EBUSY;
1320        }
1321
1322        /* If the format is unsupported v4l2 says we should switch to
1323         * a supported one and not return an error.
1324         */
1325        mfmt = get_format(f);
1326        if (!mfmt) {
1327                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1328                         "Fourcc format (0x%08x) unknown.\n",
1329                         f->fmt.pix.pixelformat);
1330                f->fmt.pix.pixelformat = formats[0].fourcc;
1331                mfmt = get_format(f);
1332        }
1333
1334        ret = mmal_setup_components(dev, f);
1335        if (ret) {
1336                v4l2_err(&dev->v4l2_dev,
1337                         "%s: failed to setup mmal components: %d\n",
1338                         __func__, ret);
1339                ret = -EINVAL;
1340        }
1341
1342        return ret;
1343}
1344
1345static int vidioc_enum_framesizes(struct file *file, void *fh,
1346                                  struct v4l2_frmsizeenum *fsize)
1347{
1348        struct bm2835_mmal_dev *dev = video_drvdata(file);
1349        static const struct v4l2_frmsize_stepwise sizes = {
1350                MIN_WIDTH, 0, 2,
1351                MIN_HEIGHT, 0, 2
1352        };
1353        int i;
1354
1355        if (fsize->index)
1356                return -EINVAL;
1357        for (i = 0; i < ARRAY_SIZE(formats); i++)
1358                if (formats[i].fourcc == fsize->pixel_format)
1359                        break;
1360        if (i == ARRAY_SIZE(formats))
1361                return -EINVAL;
1362        fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1363        fsize->stepwise = sizes;
1364        fsize->stepwise.max_width = dev->max_width;
1365        fsize->stepwise.max_height = dev->max_height;
1366        return 0;
1367}
1368
1369/* timeperframe is arbitrary and continuous */
1370static int vidioc_enum_frameintervals(struct file *file, void *priv,
1371                                      struct v4l2_frmivalenum *fival)
1372{
1373        struct bm2835_mmal_dev *dev = video_drvdata(file);
1374        int i;
1375
1376        if (fival->index)
1377                return -EINVAL;
1378
1379        for (i = 0; i < ARRAY_SIZE(formats); i++)
1380                if (formats[i].fourcc == fival->pixel_format)
1381                        break;
1382        if (i == ARRAY_SIZE(formats))
1383                return -EINVAL;
1384
1385        /* regarding width & height - we support any within range */
1386        if (fival->width < MIN_WIDTH || fival->width > dev->max_width ||
1387            fival->height < MIN_HEIGHT || fival->height > dev->max_height)
1388                return -EINVAL;
1389
1390        fival->type = V4L2_FRMIVAL_TYPE_CONTINUOUS;
1391
1392        /* fill in stepwise (step=1.0 is required by V4L2 spec) */
1393        fival->stepwise.min  = tpf_min;
1394        fival->stepwise.max  = tpf_max;
1395        fival->stepwise.step = (struct v4l2_fract) {1, 1};
1396
1397        return 0;
1398}
1399
1400static int vidioc_g_parm(struct file *file, void *priv,
1401                         struct v4l2_streamparm *parm)
1402{
1403        struct bm2835_mmal_dev *dev = video_drvdata(file);
1404
1405        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1406                return -EINVAL;
1407
1408        parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
1409        parm->parm.capture.timeperframe = dev->capture.timeperframe;
1410        parm->parm.capture.readbuffers  = 1;
1411        return 0;
1412}
1413
1414static int vidioc_s_parm(struct file *file, void *priv,
1415                         struct v4l2_streamparm *parm)
1416{
1417        struct bm2835_mmal_dev *dev = video_drvdata(file);
1418        struct v4l2_fract tpf;
1419
1420        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1421                return -EINVAL;
1422
1423        tpf = parm->parm.capture.timeperframe;
1424
1425        /* tpf: {*, 0} resets timing; clip to [min, max]*/
1426        tpf = tpf.denominator ? tpf : tpf_default;
1427        tpf = V4L2_FRACT_COMPARE(tpf, <, tpf_min) ? tpf_min : tpf;
1428        tpf = V4L2_FRACT_COMPARE(tpf, >, tpf_max) ? tpf_max : tpf;
1429
1430        dev->capture.timeperframe = tpf;
1431        parm->parm.capture.timeperframe = tpf;
1432        parm->parm.capture.readbuffers  = 1;
1433        parm->parm.capture.capability   = V4L2_CAP_TIMEPERFRAME;
1434
1435        set_framerate_params(dev);
1436
1437        return 0;
1438}
1439
1440static const struct v4l2_ioctl_ops camera0_ioctl_ops = {
1441        /* overlay */
1442        .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
1443        .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
1444        .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
1445        .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
1446        .vidioc_overlay = vidioc_overlay,
1447        .vidioc_g_fbuf = vidioc_g_fbuf,
1448
1449        /* inputs */
1450        .vidioc_enum_input = vidioc_enum_input,
1451        .vidioc_g_input = vidioc_g_input,
1452        .vidioc_s_input = vidioc_s_input,
1453
1454        /* capture */
1455        .vidioc_querycap = vidioc_querycap,
1456        .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1457        .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1458        .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1459        .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1460
1461        /* buffer management */
1462        .vidioc_reqbufs = vb2_ioctl_reqbufs,
1463        .vidioc_create_bufs = vb2_ioctl_create_bufs,
1464        .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1465        .vidioc_querybuf = vb2_ioctl_querybuf,
1466        .vidioc_qbuf = vb2_ioctl_qbuf,
1467        .vidioc_dqbuf = vb2_ioctl_dqbuf,
1468        .vidioc_enum_framesizes = vidioc_enum_framesizes,
1469        .vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1470        .vidioc_g_parm        = vidioc_g_parm,
1471        .vidioc_s_parm        = vidioc_s_parm,
1472        .vidioc_streamon = vb2_ioctl_streamon,
1473        .vidioc_streamoff = vb2_ioctl_streamoff,
1474
1475        .vidioc_log_status = v4l2_ctrl_log_status,
1476        .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1477        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1478};
1479
1480/* ------------------------------------------------------------------
1481 *      Driver init/finalise
1482 * ------------------------------------------------------------------
1483 */
1484
1485static const struct v4l2_file_operations camera0_fops = {
1486        .owner = THIS_MODULE,
1487        .open = v4l2_fh_open,
1488        .release = vb2_fop_release,
1489        .read = vb2_fop_read,
1490        .poll = vb2_fop_poll,
1491        .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
1492        .mmap = vb2_fop_mmap,
1493};
1494
1495static const struct video_device vdev_template = {
1496        .name = "camera0",
1497        .fops = &camera0_fops,
1498        .ioctl_ops = &camera0_ioctl_ops,
1499        .release = video_device_release_empty,
1500        .device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY |
1501                       V4L2_CAP_STREAMING | V4L2_CAP_READWRITE,
1502};
1503
1504/* Returns the number of cameras, and also the max resolution supported
1505 * by those cameras.
1506 */
1507static int get_num_cameras(struct vchiq_mmal_instance *instance,
1508                           unsigned int resolutions[][2], int num_resolutions)
1509{
1510        int ret;
1511        struct vchiq_mmal_component  *cam_info_component;
1512        struct mmal_parameter_camera_info_t cam_info = {0};
1513        u32 param_size = sizeof(cam_info);
1514        int i;
1515
1516        /* create a camera_info component */
1517        ret = vchiq_mmal_component_init(instance, "camera_info",
1518                                        &cam_info_component);
1519        if (ret < 0)
1520                /* Unusual failure - let's guess one camera. */
1521                return 1;
1522
1523        if (vchiq_mmal_port_parameter_get(instance,
1524                                          &cam_info_component->control,
1525                                          MMAL_PARAMETER_CAMERA_INFO,
1526                                          &cam_info,
1527                                          &param_size)) {
1528                pr_info("Failed to get camera info\n");
1529        }
1530        for (i = 0;
1531             i < min_t(unsigned int, cam_info.num_cameras, num_resolutions);
1532             i++) {
1533                resolutions[i][0] = cam_info.cameras[i].max_width;
1534                resolutions[i][1] = cam_info.cameras[i].max_height;
1535        }
1536
1537        vchiq_mmal_component_finalise(instance,
1538                                      cam_info_component);
1539
1540        return cam_info.num_cameras;
1541}
1542
1543static int set_camera_parameters(struct vchiq_mmal_instance *instance,
1544                                 struct vchiq_mmal_component *camera,
1545                                 struct bm2835_mmal_dev *dev)
1546{
1547        struct mmal_parameter_camera_config cam_config = {
1548                .max_stills_w = dev->max_width,
1549                .max_stills_h = dev->max_height,
1550                .stills_yuv422 = 1,
1551                .one_shot_stills = 1,
1552                .max_preview_video_w = (max_video_width > 1920) ?
1553                                                max_video_width : 1920,
1554                .max_preview_video_h = (max_video_height > 1088) ?
1555                                                max_video_height : 1088,
1556                .num_preview_video_frames = 3,
1557                .stills_capture_circular_buffer_height = 0,
1558                .fast_preview_resume = 0,
1559                .use_stc_timestamp = MMAL_PARAM_TIMESTAMP_MODE_RAW_STC
1560        };
1561
1562        return vchiq_mmal_port_parameter_set(instance, &camera->control,
1563                                            MMAL_PARAMETER_CAMERA_CONFIG,
1564                                            &cam_config, sizeof(cam_config));
1565}
1566
1567#define MAX_SUPPORTED_ENCODINGS 20
1568
1569/* MMAL instance and component init */
1570static int mmal_init(struct bm2835_mmal_dev *dev)
1571{
1572        int ret;
1573        struct mmal_es_format_local *format;
1574        u32 supported_encodings[MAX_SUPPORTED_ENCODINGS];
1575        u32 param_size;
1576        struct vchiq_mmal_component  *camera;
1577
1578        ret = vchiq_mmal_init(&dev->instance);
1579        if (ret < 0) {
1580                v4l2_err(&dev->v4l2_dev, "%s: vchiq mmal init failed %d\n",
1581                         __func__, ret);
1582                return ret;
1583        }
1584
1585        /* get the camera component ready */
1586        ret = vchiq_mmal_component_init(dev->instance, "ril.camera",
1587                                        &dev->component[COMP_CAMERA]);
1588        if (ret < 0)
1589                goto unreg_mmal;
1590
1591        camera = dev->component[COMP_CAMERA];
1592        if (camera->outputs < CAM_PORT_COUNT) {
1593                v4l2_err(&dev->v4l2_dev, "%s: too few camera outputs %d needed %d\n",
1594                         __func__, camera->outputs, CAM_PORT_COUNT);
1595                ret = -EINVAL;
1596                goto unreg_camera;
1597        }
1598
1599        ret = set_camera_parameters(dev->instance,
1600                                    camera,
1601                                    dev);
1602        if (ret < 0) {
1603                v4l2_err(&dev->v4l2_dev, "%s: unable to set camera parameters: %d\n",
1604                         __func__, ret);
1605                goto unreg_camera;
1606        }
1607
1608        /* There was an error in the firmware that meant the camera component
1609         * produced BGR instead of RGB.
1610         * This is now fixed, but in order to support the old firmwares, we
1611         * have to check.
1612         */
1613        dev->rgb_bgr_swapped = true;
1614        param_size = sizeof(supported_encodings);
1615        ret = vchiq_mmal_port_parameter_get(dev->instance,
1616                                            &camera->output[CAM_PORT_CAPTURE],
1617                                            MMAL_PARAMETER_SUPPORTED_ENCODINGS,
1618                                            &supported_encodings,
1619                                            &param_size);
1620        if (ret == 0) {
1621                int i;
1622
1623                for (i = 0; i < param_size / sizeof(u32); i++) {
1624                        if (supported_encodings[i] == MMAL_ENCODING_BGR24) {
1625                                /* Found BGR24 first - old firmware. */
1626                                break;
1627                        }
1628                        if (supported_encodings[i] == MMAL_ENCODING_RGB24) {
1629                                /* Found RGB24 first
1630                                 * new firmware, so use RGB24.
1631                                 */
1632                                dev->rgb_bgr_swapped = false;
1633                        break;
1634                        }
1635                }
1636        }
1637        format = &camera->output[CAM_PORT_PREVIEW].format;
1638
1639        format->encoding = MMAL_ENCODING_OPAQUE;
1640        format->encoding_variant = MMAL_ENCODING_I420;
1641
1642        format->es->video.width = 1024;
1643        format->es->video.height = 768;
1644        format->es->video.crop.x = 0;
1645        format->es->video.crop.y = 0;
1646        format->es->video.crop.width = 1024;
1647        format->es->video.crop.height = 768;
1648        format->es->video.frame_rate.num = 0; /* Rely on fps_range */
1649        format->es->video.frame_rate.den = 1;
1650
1651        format = &camera->output[CAM_PORT_VIDEO].format;
1652
1653        format->encoding = MMAL_ENCODING_OPAQUE;
1654        format->encoding_variant = MMAL_ENCODING_I420;
1655
1656        format->es->video.width = 1024;
1657        format->es->video.height = 768;
1658        format->es->video.crop.x = 0;
1659        format->es->video.crop.y = 0;
1660        format->es->video.crop.width = 1024;
1661        format->es->video.crop.height = 768;
1662        format->es->video.frame_rate.num = 0; /* Rely on fps_range */
1663        format->es->video.frame_rate.den = 1;
1664
1665        format = &camera->output[CAM_PORT_CAPTURE].format;
1666
1667        format->encoding = MMAL_ENCODING_OPAQUE;
1668
1669        format->es->video.width = 2592;
1670        format->es->video.height = 1944;
1671        format->es->video.crop.x = 0;
1672        format->es->video.crop.y = 0;
1673        format->es->video.crop.width = 2592;
1674        format->es->video.crop.height = 1944;
1675        format->es->video.frame_rate.num = 0; /* Rely on fps_range */
1676        format->es->video.frame_rate.den = 1;
1677
1678        dev->capture.width = format->es->video.width;
1679        dev->capture.height = format->es->video.height;
1680        dev->capture.fmt = &formats[0];
1681        dev->capture.encode_component = NULL;
1682        dev->capture.timeperframe = tpf_default;
1683        dev->capture.enc_profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
1684        dev->capture.enc_level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
1685
1686        /* get the preview component ready */
1687        ret = vchiq_mmal_component_init(
1688                        dev->instance, "ril.video_render",
1689                        &dev->component[COMP_PREVIEW]);
1690        if (ret < 0)
1691                goto unreg_camera;
1692
1693        if (dev->component[COMP_PREVIEW]->inputs < 1) {
1694                ret = -EINVAL;
1695                v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n",
1696                         __func__, dev->component[COMP_PREVIEW]->inputs, 1);
1697                goto unreg_preview;
1698        }
1699
1700        /* get the image encoder component ready */
1701        ret = vchiq_mmal_component_init(
1702                dev->instance, "ril.image_encode",
1703                &dev->component[COMP_IMAGE_ENCODE]);
1704        if (ret < 0)
1705                goto unreg_preview;
1706
1707        if (dev->component[COMP_IMAGE_ENCODE]->inputs < 1) {
1708                ret = -EINVAL;
1709                v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n",
1710                         __func__, dev->component[COMP_IMAGE_ENCODE]->inputs,
1711                         1);
1712                goto unreg_image_encoder;
1713        }
1714
1715        /* get the video encoder component ready */
1716        ret = vchiq_mmal_component_init(dev->instance, "ril.video_encode",
1717                                        &dev->component[COMP_VIDEO_ENCODE]);
1718        if (ret < 0)
1719                goto unreg_image_encoder;
1720
1721        if (dev->component[COMP_VIDEO_ENCODE]->inputs < 1) {
1722                ret = -EINVAL;
1723                v4l2_err(&dev->v4l2_dev, "%s: too few input ports %d needed %d\n",
1724                         __func__, dev->component[COMP_VIDEO_ENCODE]->inputs,
1725                         1);
1726                goto unreg_vid_encoder;
1727        }
1728
1729        {
1730                struct vchiq_mmal_port *encoder_port =
1731                        &dev->component[COMP_VIDEO_ENCODE]->output[0];
1732                encoder_port->format.encoding = MMAL_ENCODING_H264;
1733                ret = vchiq_mmal_port_set_format(dev->instance,
1734                                                 encoder_port);
1735        }
1736
1737        {
1738                unsigned int enable = 1;
1739
1740                vchiq_mmal_port_parameter_set(
1741                        dev->instance,
1742                        &dev->component[COMP_VIDEO_ENCODE]->control,
1743                        MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT,
1744                        &enable, sizeof(enable));
1745
1746                vchiq_mmal_port_parameter_set(dev->instance,
1747                                              &dev->component[COMP_VIDEO_ENCODE]->control,
1748                                              MMAL_PARAMETER_MINIMISE_FRAGMENTATION,
1749                                              &enable,
1750                                              sizeof(enable));
1751        }
1752        ret = bm2835_mmal_set_all_camera_controls(dev);
1753        if (ret < 0) {
1754                v4l2_err(&dev->v4l2_dev, "%s: failed to set all camera controls: %d\n",
1755                         __func__, ret);
1756                goto unreg_vid_encoder;
1757        }
1758
1759        return 0;
1760
1761unreg_vid_encoder:
1762        pr_err("Cleanup: Destroy video encoder\n");
1763        vchiq_mmal_component_finalise(
1764                dev->instance,
1765                dev->component[COMP_VIDEO_ENCODE]);
1766
1767unreg_image_encoder:
1768        pr_err("Cleanup: Destroy image encoder\n");
1769        vchiq_mmal_component_finalise(
1770                dev->instance,
1771                dev->component[COMP_IMAGE_ENCODE]);
1772
1773unreg_preview:
1774        pr_err("Cleanup: Destroy video render\n");
1775        vchiq_mmal_component_finalise(dev->instance,
1776                                      dev->component[COMP_PREVIEW]);
1777
1778unreg_camera:
1779        pr_err("Cleanup: Destroy camera\n");
1780        vchiq_mmal_component_finalise(dev->instance,
1781                                      dev->component[COMP_CAMERA]);
1782
1783unreg_mmal:
1784        vchiq_mmal_finalise(dev->instance);
1785        return ret;
1786}
1787
1788static int bm2835_mmal_init_device(struct bm2835_mmal_dev *dev,
1789                                   struct video_device *vfd)
1790{
1791        int ret;
1792
1793        *vfd = vdev_template;
1794
1795        vfd->v4l2_dev = &dev->v4l2_dev;
1796
1797        vfd->lock = &dev->mutex;
1798
1799        vfd->queue = &dev->capture.vb_vidq;
1800
1801        /* video device needs to be able to access instance data */
1802        video_set_drvdata(vfd, dev);
1803
1804        ret = video_register_device(vfd,
1805                                    VFL_TYPE_GRABBER,
1806                                    video_nr[dev->camera_num]);
1807        if (ret < 0)
1808                return ret;
1809
1810        v4l2_info(vfd->v4l2_dev,
1811                  "V4L2 device registered as %s - stills mode > %dx%d\n",
1812                  video_device_node_name(vfd),
1813                  max_video_width, max_video_height);
1814
1815        return 0;
1816}
1817
1818static void bcm2835_cleanup_instance(struct bm2835_mmal_dev *dev)
1819{
1820        if (!dev)
1821                return;
1822
1823        v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
1824                  video_device_node_name(&dev->vdev));
1825
1826        video_unregister_device(&dev->vdev);
1827
1828        if (dev->capture.encode_component) {
1829                v4l2_dbg(1, bcm2835_v4l2_debug, &dev->v4l2_dev,
1830                         "mmal_exit - disconnect tunnel\n");
1831                vchiq_mmal_port_connect_tunnel(dev->instance,
1832                                               dev->capture.camera_port, NULL);
1833                vchiq_mmal_component_disable(dev->instance,
1834                                             dev->capture.encode_component);
1835        }
1836        vchiq_mmal_component_disable(dev->instance,
1837                                     dev->component[COMP_CAMERA]);
1838
1839        vchiq_mmal_component_finalise(dev->instance,
1840                                      dev->component[COMP_VIDEO_ENCODE]);
1841
1842        vchiq_mmal_component_finalise(dev->instance,
1843                                      dev->component[COMP_IMAGE_ENCODE]);
1844
1845        vchiq_mmal_component_finalise(dev->instance,
1846                                      dev->component[COMP_PREVIEW]);
1847
1848        vchiq_mmal_component_finalise(dev->instance,
1849                                      dev->component[COMP_CAMERA]);
1850
1851        v4l2_ctrl_handler_free(&dev->ctrl_handler);
1852
1853        v4l2_device_unregister(&dev->v4l2_dev);
1854
1855        kfree(dev);
1856}
1857
1858static struct v4l2_format default_v4l2_format = {
1859        .fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG,
1860        .fmt.pix.width = 1024,
1861        .fmt.pix.bytesperline = 0,
1862        .fmt.pix.height = 768,
1863        .fmt.pix.sizeimage = 1024 * 768,
1864};
1865
1866static int bcm2835_mmal_probe(struct platform_device *pdev)
1867{
1868        int ret;
1869        struct bm2835_mmal_dev *dev;
1870        struct vb2_queue *q;
1871        int camera;
1872        unsigned int num_cameras;
1873        struct vchiq_mmal_instance *instance;
1874        unsigned int resolutions[MAX_BCM2835_CAMERAS][2];
1875        int i;
1876
1877        ret = vchiq_mmal_init(&instance);
1878        if (ret < 0)
1879                return ret;
1880
1881        num_cameras = get_num_cameras(instance,
1882                                      resolutions,
1883                                      MAX_BCM2835_CAMERAS);
1884
1885        if (num_cameras < 1) {
1886                ret = -ENODEV;
1887                goto cleanup_mmal;
1888        }
1889
1890        if (num_cameras > MAX_BCM2835_CAMERAS)
1891                num_cameras = MAX_BCM2835_CAMERAS;
1892
1893        for (camera = 0; camera < num_cameras; camera++) {
1894                dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1895                if (!dev) {
1896                        ret = -ENOMEM;
1897                        goto cleanup_gdev;
1898                }
1899
1900                /* v4l2 core mutex used to protect all fops and v4l2 ioctls. */
1901                mutex_init(&dev->mutex);
1902                dev->camera_num = camera;
1903                dev->max_width = resolutions[camera][0];
1904                dev->max_height = resolutions[camera][1];
1905
1906                /* setup device defaults */
1907                dev->overlay.w.left = 150;
1908                dev->overlay.w.top = 50;
1909                dev->overlay.w.width = 1024;
1910                dev->overlay.w.height = 768;
1911                dev->overlay.clipcount = 0;
1912                dev->overlay.field = V4L2_FIELD_NONE;
1913                dev->overlay.global_alpha = 255;
1914
1915                dev->capture.fmt = &formats[3]; /* JPEG */
1916
1917                /* v4l device registration */
1918                snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
1919                         "%s", BM2835_MMAL_MODULE_NAME);
1920                ret = v4l2_device_register(NULL, &dev->v4l2_dev);
1921                if (ret) {
1922                        dev_err(&pdev->dev, "%s: could not register V4L2 device: %d\n",
1923                                __func__, ret);
1924                        goto free_dev;
1925                }
1926
1927                /* setup v4l controls */
1928                ret = bm2835_mmal_init_controls(dev, &dev->ctrl_handler);
1929                if (ret < 0) {
1930                        v4l2_err(&dev->v4l2_dev, "%s: could not init controls: %d\n",
1931                                 __func__, ret);
1932                        goto unreg_dev;
1933                }
1934                dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
1935
1936                /* mmal init */
1937                dev->instance = instance;
1938                ret = mmal_init(dev);
1939                if (ret < 0) {
1940                        v4l2_err(&dev->v4l2_dev, "%s: mmal init failed: %d\n",
1941                                 __func__, ret);
1942                        goto unreg_dev;
1943                }
1944                /* initialize queue */
1945                q = &dev->capture.vb_vidq;
1946                memset(q, 0, sizeof(*q));
1947                q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1948                q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1949                q->drv_priv = dev;
1950                q->buf_struct_size = sizeof(struct mmal_buffer);
1951                q->ops = &bm2835_mmal_video_qops;
1952                q->mem_ops = &vb2_vmalloc_memops;
1953                q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1954                q->lock = &dev->mutex;
1955                ret = vb2_queue_init(q);
1956                if (ret < 0)
1957                        goto unreg_dev;
1958
1959                /* initialise video devices */
1960                ret = bm2835_mmal_init_device(dev, &dev->vdev);
1961                if (ret < 0) {
1962                        v4l2_err(&dev->v4l2_dev, "%s: could not init device: %d\n",
1963                                 __func__, ret);
1964                        goto unreg_dev;
1965                }
1966
1967                /* Really want to call vidioc_s_fmt_vid_cap with the default
1968                 * format, but currently the APIs don't join up.
1969                 */
1970                ret = mmal_setup_components(dev, &default_v4l2_format);
1971                if (ret < 0) {
1972                        v4l2_err(&dev->v4l2_dev, "%s: could not setup components: %d\n",
1973                                 __func__, ret);
1974                        goto unreg_dev;
1975                }
1976
1977                v4l2_info(&dev->v4l2_dev,
1978                          "Broadcom 2835 MMAL video capture ver %s loaded.\n",
1979                          BM2835_MMAL_VERSION);
1980
1981                gdev[camera] = dev;
1982        }
1983        return 0;
1984
1985unreg_dev:
1986        v4l2_ctrl_handler_free(&dev->ctrl_handler);
1987        v4l2_device_unregister(&dev->v4l2_dev);
1988
1989free_dev:
1990        kfree(dev);
1991
1992cleanup_gdev:
1993        for (i = 0; i < camera; i++) {
1994                bcm2835_cleanup_instance(gdev[i]);
1995                gdev[i] = NULL;
1996        }
1997
1998cleanup_mmal:
1999        vchiq_mmal_finalise(instance);
2000
2001        return ret;
2002}
2003
2004static int bcm2835_mmal_remove(struct platform_device *pdev)
2005{
2006        int camera;
2007        struct vchiq_mmal_instance *instance = gdev[0]->instance;
2008
2009        for (camera = 0; camera < MAX_BCM2835_CAMERAS; camera++) {
2010                bcm2835_cleanup_instance(gdev[camera]);
2011                gdev[camera] = NULL;
2012        }
2013        vchiq_mmal_finalise(instance);
2014
2015        return 0;
2016}
2017
2018static struct platform_driver bcm2835_camera_driver = {
2019        .probe          = bcm2835_mmal_probe,
2020        .remove         = bcm2835_mmal_remove,
2021        .driver         = {
2022                .name   = "bcm2835-camera",
2023        },
2024};
2025
2026module_platform_driver(bcm2835_camera_driver)
2027
2028MODULE_DESCRIPTION("Broadcom 2835 MMAL video capture");
2029MODULE_AUTHOR("Vincent Sanders");
2030MODULE_LICENSE("GPL");
2031MODULE_VERSION(BM2835_MMAL_VERSION);
2032MODULE_ALIAS("platform:bcm2835-camera");
2033