linux/drivers/staging/media/imx/imx7-media-csi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * V4L2 Capture CSI Subdev for Freescale i.MX6UL/L / i.MX7 SOC
   4 *
   5 * Copyright (c) 2019 Linaro Ltd
   6 *
   7 */
   8
   9#include <linux/clk.h>
  10#include <linux/delay.h>
  11#include <linux/gcd.h>
  12#include <linux/interrupt.h>
  13#include <linux/mfd/syscon.h>
  14#include <linux/module.h>
  15#include <linux/of_graph.h>
  16#include <linux/pinctrl/consumer.h>
  17#include <linux/platform_device.h>
  18#include <linux/regmap.h>
  19#include <linux/types.h>
  20
  21#include <media/v4l2-device.h>
  22#include <media/v4l2-event.h>
  23#include <media/v4l2-fwnode.h>
  24#include <media/v4l2-mc.h>
  25#include <media/v4l2-subdev.h>
  26#include <media/videobuf2-dma-contig.h>
  27
  28#include <media/imx.h>
  29#include "imx-media.h"
  30
  31#define IMX7_CSI_PAD_SINK               0
  32#define IMX7_CSI_PAD_SRC                1
  33#define IMX7_CSI_PADS_NUM               2
  34
  35/* csi control reg 1 */
  36#define BIT_SWAP16_EN                   BIT(31)
  37#define BIT_EXT_VSYNC                   BIT(30)
  38#define BIT_EOF_INT_EN                  BIT(29)
  39#define BIT_PRP_IF_EN                   BIT(28)
  40#define BIT_CCIR_MODE                   BIT(27)
  41#define BIT_COF_INT_EN                  BIT(26)
  42#define BIT_SF_OR_INTEN                 BIT(25)
  43#define BIT_RF_OR_INTEN                 BIT(24)
  44#define BIT_SFF_DMA_DONE_INTEN          BIT(22)
  45#define BIT_STATFF_INTEN                BIT(21)
  46#define BIT_FB2_DMA_DONE_INTEN          BIT(20)
  47#define BIT_FB1_DMA_DONE_INTEN          BIT(19)
  48#define BIT_RXFF_INTEN                  BIT(18)
  49#define BIT_SOF_POL                     BIT(17)
  50#define BIT_SOF_INTEN                   BIT(16)
  51#define BIT_MCLKDIV(n)                  ((n) << 12)
  52#define BIT_MCLKDIV_MASK                (0xf << 12)
  53#define BIT_HSYNC_POL                   BIT(11)
  54#define BIT_CCIR_EN                     BIT(10)
  55#define BIT_MCLKEN                      BIT(9)
  56#define BIT_FCC                         BIT(8)
  57#define BIT_PACK_DIR                    BIT(7)
  58#define BIT_CLR_STATFIFO                BIT(6)
  59#define BIT_CLR_RXFIFO                  BIT(5)
  60#define BIT_GCLK_MODE                   BIT(4)
  61#define BIT_INV_DATA                    BIT(3)
  62#define BIT_INV_PCLK                    BIT(2)
  63#define BIT_REDGE                       BIT(1)
  64#define BIT_PIXEL_BIT                   BIT(0)
  65
  66/* control reg 2 */
  67#define BIT_DMA_BURST_TYPE_RFF_INCR4    (1 << 30)
  68#define BIT_DMA_BURST_TYPE_RFF_INCR8    (2 << 30)
  69#define BIT_DMA_BURST_TYPE_RFF_INCR16   (3 << 30)
  70#define BIT_DMA_BURST_TYPE_RFF_MASK     (3 << 30)
  71
  72/* control reg 3 */
  73#define BIT_FRMCNT(n)                   ((n) << 16)
  74#define BIT_FRMCNT_MASK                 (0xffff << 16)
  75#define BIT_FRMCNT_RST                  BIT(15)
  76#define BIT_DMA_REFLASH_RFF             BIT(14)
  77#define BIT_DMA_REFLASH_SFF             BIT(13)
  78#define BIT_DMA_REQ_EN_RFF              BIT(12)
  79#define BIT_DMA_REQ_EN_SFF              BIT(11)
  80#define BIT_STATFF_LEVEL(n)             ((n) << 8)
  81#define BIT_STATFF_LEVEL_MASK           (0x7 << 8)
  82#define BIT_HRESP_ERR_EN                BIT(7)
  83#define BIT_RXFF_LEVEL(n)               ((n) << 4)
  84#define BIT_RXFF_LEVEL_MASK             (0x7 << 4)
  85#define BIT_TWO_8BIT_SENSOR             BIT(3)
  86#define BIT_ZERO_PACK_EN                BIT(2)
  87#define BIT_ECC_INT_EN                  BIT(1)
  88#define BIT_ECC_AUTO_EN                 BIT(0)
  89
  90/* csi status reg */
  91#define BIT_ADDR_CH_ERR_INT             BIT(28)
  92#define BIT_FIELD0_INT                  BIT(27)
  93#define BIT_FIELD1_INT                  BIT(26)
  94#define BIT_SFF_OR_INT                  BIT(25)
  95#define BIT_RFF_OR_INT                  BIT(24)
  96#define BIT_DMA_TSF_DONE_SFF            BIT(22)
  97#define BIT_STATFF_INT                  BIT(21)
  98#define BIT_DMA_TSF_DONE_FB2            BIT(20)
  99#define BIT_DMA_TSF_DONE_FB1            BIT(19)
 100#define BIT_RXFF_INT                    BIT(18)
 101#define BIT_EOF_INT                     BIT(17)
 102#define BIT_SOF_INT                     BIT(16)
 103#define BIT_F2_INT                      BIT(15)
 104#define BIT_F1_INT                      BIT(14)
 105#define BIT_COF_INT                     BIT(13)
 106#define BIT_HRESP_ERR_INT               BIT(7)
 107#define BIT_ECC_INT                     BIT(1)
 108#define BIT_DRDY                        BIT(0)
 109
 110/* csi image parameter reg */
 111#define BIT_IMAGE_WIDTH(n)              ((n) << 16)
 112#define BIT_IMAGE_HEIGHT(n)             (n)
 113
 114/* csi control reg 18 */
 115#define BIT_CSI_HW_ENABLE               BIT(31)
 116#define BIT_MIPI_DATA_FORMAT_RAW8       (0x2a << 25)
 117#define BIT_MIPI_DATA_FORMAT_RAW10      (0x2b << 25)
 118#define BIT_MIPI_DATA_FORMAT_RAW12      (0x2c << 25)
 119#define BIT_MIPI_DATA_FORMAT_RAW14      (0x2d << 25)
 120#define BIT_MIPI_DATA_FORMAT_YUV422_8B  (0x1e << 25)
 121#define BIT_MIPI_DATA_FORMAT_MASK       (0x3f << 25)
 122#define BIT_DATA_FROM_MIPI              BIT(22)
 123#define BIT_MIPI_YU_SWAP                BIT(21)
 124#define BIT_MIPI_DOUBLE_CMPNT           BIT(20)
 125#define BIT_BASEADDR_CHG_ERR_EN         BIT(9)
 126#define BIT_BASEADDR_SWITCH_SEL         BIT(5)
 127#define BIT_BASEADDR_SWITCH_EN          BIT(4)
 128#define BIT_PARALLEL24_EN               BIT(3)
 129#define BIT_DEINTERLACE_EN              BIT(2)
 130#define BIT_TVDECODER_IN_EN             BIT(1)
 131#define BIT_NTSC_EN                     BIT(0)
 132
 133#define CSI_MCLK_VF                     1
 134#define CSI_MCLK_ENC                    2
 135#define CSI_MCLK_RAW                    4
 136#define CSI_MCLK_I2C                    8
 137
 138#define CSI_CSICR1                      0x00
 139#define CSI_CSICR2                      0x04
 140#define CSI_CSICR3                      0x08
 141#define CSI_STATFIFO                    0x0c
 142#define CSI_CSIRXFIFO                   0x10
 143#define CSI_CSIRXCNT                    0x14
 144#define CSI_CSISR                       0x18
 145
 146#define CSI_CSIDBG                      0x1c
 147#define CSI_CSIDMASA_STATFIFO           0x20
 148#define CSI_CSIDMATS_STATFIFO           0x24
 149#define CSI_CSIDMASA_FB1                0x28
 150#define CSI_CSIDMASA_FB2                0x2c
 151#define CSI_CSIFBUF_PARA                0x30
 152#define CSI_CSIIMAG_PARA                0x34
 153
 154#define CSI_CSICR18                     0x48
 155#define CSI_CSICR19                     0x4c
 156
 157struct imx7_csi {
 158        struct device *dev;
 159        struct v4l2_subdev sd;
 160        struct v4l2_async_notifier notifier;
 161        struct imx_media_video_dev *vdev;
 162        struct imx_media_dev *imxmd;
 163        struct media_pad pad[IMX7_CSI_PADS_NUM];
 164
 165        /* lock to protect members below */
 166        struct mutex lock;
 167        /* lock to protect irq handler when stop streaming */
 168        spinlock_t irqlock;
 169
 170        struct v4l2_subdev *src_sd;
 171
 172        struct v4l2_mbus_framefmt format_mbus[IMX7_CSI_PADS_NUM];
 173        const struct imx_media_pixfmt *cc[IMX7_CSI_PADS_NUM];
 174        struct v4l2_fract frame_interval[IMX7_CSI_PADS_NUM];
 175
 176        void __iomem *regbase;
 177        int irq;
 178        struct clk *mclk;
 179
 180        /* active vb2 buffers to send to video dev sink */
 181        struct imx_media_buffer *active_vb2_buf[2];
 182        struct imx_media_dma_buf underrun_buf;
 183
 184        int buf_num;
 185        u32 frame_sequence;
 186
 187        bool last_eof;
 188        bool is_streaming;
 189        bool is_csi2;
 190
 191        struct completion last_eof_completion;
 192};
 193
 194static struct imx7_csi *
 195imx7_csi_notifier_to_dev(struct v4l2_async_notifier *n)
 196{
 197        return container_of(n, struct imx7_csi, notifier);
 198}
 199
 200/* -----------------------------------------------------------------------------
 201 * Hardware Configuration
 202 */
 203
 204static u32 imx7_csi_reg_read(struct imx7_csi *csi, unsigned int offset)
 205{
 206        return readl(csi->regbase + offset);
 207}
 208
 209static void imx7_csi_reg_write(struct imx7_csi *csi, unsigned int value,
 210                               unsigned int offset)
 211{
 212        writel(value, csi->regbase + offset);
 213}
 214
 215static u32 imx7_csi_irq_clear(struct imx7_csi *csi)
 216{
 217        u32 isr;
 218
 219        isr = imx7_csi_reg_read(csi, CSI_CSISR);
 220        imx7_csi_reg_write(csi, isr, CSI_CSISR);
 221
 222        return isr;
 223}
 224
 225static void imx7_csi_init_default(struct imx7_csi *csi)
 226{
 227        imx7_csi_reg_write(csi, BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE |
 228                           BIT_HSYNC_POL | BIT_FCC | BIT_MCLKDIV(1) |
 229                           BIT_MCLKEN, CSI_CSICR1);
 230        imx7_csi_reg_write(csi, 0, CSI_CSICR2);
 231        imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3);
 232
 233        imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(800) | BIT_IMAGE_HEIGHT(600),
 234                           CSI_CSIIMAG_PARA);
 235
 236        imx7_csi_reg_write(csi, BIT_DMA_REFLASH_RFF, CSI_CSICR3);
 237}
 238
 239static void imx7_csi_hw_enable_irq(struct imx7_csi *csi)
 240{
 241        u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
 242
 243        cr1 |= BIT_RFF_OR_INT;
 244        cr1 |= BIT_FB1_DMA_DONE_INTEN;
 245        cr1 |= BIT_FB2_DMA_DONE_INTEN;
 246
 247        imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
 248}
 249
 250static void imx7_csi_hw_disable_irq(struct imx7_csi *csi)
 251{
 252        u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1);
 253
 254        cr1 &= ~BIT_RFF_OR_INT;
 255        cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
 256        cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
 257
 258        imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
 259}
 260
 261static void imx7_csi_hw_enable(struct imx7_csi *csi)
 262{
 263        u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
 264
 265        cr |= BIT_CSI_HW_ENABLE;
 266
 267        imx7_csi_reg_write(csi, cr, CSI_CSICR18);
 268}
 269
 270static void imx7_csi_hw_disable(struct imx7_csi *csi)
 271{
 272        u32 cr = imx7_csi_reg_read(csi, CSI_CSICR18);
 273
 274        cr &= ~BIT_CSI_HW_ENABLE;
 275
 276        imx7_csi_reg_write(csi, cr, CSI_CSICR18);
 277}
 278
 279static void imx7_csi_dma_reflash(struct imx7_csi *csi)
 280{
 281        u32 cr3;
 282
 283        cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
 284        cr3 |= BIT_DMA_REFLASH_RFF;
 285        imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
 286}
 287
 288static void imx7_csi_rx_fifo_clear(struct imx7_csi *csi)
 289{
 290        u32 cr1 = imx7_csi_reg_read(csi, CSI_CSICR1) & ~BIT_FCC;
 291
 292        imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
 293        imx7_csi_reg_write(csi, cr1 | BIT_CLR_RXFIFO, CSI_CSICR1);
 294        imx7_csi_reg_write(csi, cr1 | BIT_FCC, CSI_CSICR1);
 295}
 296
 297static void imx7_csi_dmareq_rff_enable(struct imx7_csi *csi)
 298{
 299        u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
 300
 301        cr3 |= BIT_DMA_REQ_EN_RFF;
 302        cr3 |= BIT_HRESP_ERR_EN;
 303        cr3 &= ~BIT_RXFF_LEVEL_MASK;
 304        cr3 |= BIT_RXFF_LEVEL(2);
 305
 306        imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
 307}
 308
 309static void imx7_csi_dmareq_rff_disable(struct imx7_csi *csi)
 310{
 311        u32 cr3 = imx7_csi_reg_read(csi, CSI_CSICR3);
 312
 313        cr3 &= ~BIT_DMA_REQ_EN_RFF;
 314        cr3 &= ~BIT_HRESP_ERR_EN;
 315        imx7_csi_reg_write(csi, cr3, CSI_CSICR3);
 316}
 317
 318static void imx7_csi_update_buf(struct imx7_csi *csi, dma_addr_t phys,
 319                                int buf_num)
 320{
 321        if (buf_num == 1)
 322                imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB2);
 323        else
 324                imx7_csi_reg_write(csi, phys, CSI_CSIDMASA_FB1);
 325}
 326
 327static void imx7_csi_setup_vb2_buf(struct imx7_csi *csi)
 328{
 329        struct imx_media_video_dev *vdev = csi->vdev;
 330        struct imx_media_buffer *buf;
 331        struct vb2_buffer *vb2_buf;
 332        dma_addr_t phys[2];
 333        int i;
 334
 335        for (i = 0; i < 2; i++) {
 336                buf = imx_media_capture_device_next_buf(vdev);
 337                if (buf) {
 338                        csi->active_vb2_buf[i] = buf;
 339                        vb2_buf = &buf->vbuf.vb2_buf;
 340                        phys[i] = vb2_dma_contig_plane_dma_addr(vb2_buf, 0);
 341                } else {
 342                        csi->active_vb2_buf[i] = NULL;
 343                        phys[i] = csi->underrun_buf.phys;
 344                }
 345
 346                imx7_csi_update_buf(csi, phys[i], i);
 347        }
 348}
 349
 350static void imx7_csi_dma_unsetup_vb2_buf(struct imx7_csi *csi,
 351                                         enum vb2_buffer_state return_status)
 352{
 353        struct imx_media_buffer *buf;
 354        int i;
 355
 356        /* return any remaining active frames with return_status */
 357        for (i = 0; i < 2; i++) {
 358                buf = csi->active_vb2_buf[i];
 359                if (buf) {
 360                        struct vb2_buffer *vb = &buf->vbuf.vb2_buf;
 361
 362                        vb->timestamp = ktime_get_ns();
 363                        vb2_buffer_done(vb, return_status);
 364                }
 365        }
 366}
 367
 368static int imx7_csi_dma_setup(struct imx7_csi *csi)
 369{
 370        struct imx_media_video_dev *vdev = csi->vdev;
 371        int ret;
 372
 373        ret = imx_media_alloc_dma_buf(csi->dev, &csi->underrun_buf,
 374                                      vdev->fmt.sizeimage);
 375        if (ret < 0) {
 376                v4l2_warn(&csi->sd, "consider increasing the CMA area\n");
 377                return ret;
 378        }
 379
 380        csi->frame_sequence = 0;
 381        csi->last_eof = false;
 382        init_completion(&csi->last_eof_completion);
 383
 384        imx7_csi_setup_vb2_buf(csi);
 385
 386        return 0;
 387}
 388
 389static void imx7_csi_dma_cleanup(struct imx7_csi *csi)
 390{
 391        imx7_csi_dma_unsetup_vb2_buf(csi, VB2_BUF_STATE_ERROR);
 392        imx_media_free_dma_buf(csi->dev, &csi->underrun_buf);
 393}
 394
 395static void imx7_csi_dma_stop(struct imx7_csi *csi)
 396{
 397        unsigned long timeout_jiffies;
 398        unsigned long flags;
 399        int ret;
 400
 401        /* mark next EOF interrupt as the last before stream off */
 402        spin_lock_irqsave(&csi->irqlock, flags);
 403        csi->last_eof = true;
 404        spin_unlock_irqrestore(&csi->irqlock, flags);
 405
 406        /*
 407         * and then wait for interrupt handler to mark completion.
 408         */
 409        timeout_jiffies = msecs_to_jiffies(IMX_MEDIA_EOF_TIMEOUT);
 410        ret = wait_for_completion_timeout(&csi->last_eof_completion,
 411                                          timeout_jiffies);
 412        if (ret == 0)
 413                v4l2_warn(&csi->sd, "wait last EOF timeout\n");
 414
 415        imx7_csi_hw_disable_irq(csi);
 416}
 417
 418static void imx7_csi_configure(struct imx7_csi *csi)
 419{
 420        struct imx_media_video_dev *vdev = csi->vdev;
 421        struct v4l2_pix_format *out_pix = &vdev->fmt;
 422        int width = out_pix->width;
 423        u32 stride = 0;
 424        u32 cr1, cr18;
 425
 426        cr18 = imx7_csi_reg_read(csi, CSI_CSICR18);
 427
 428        cr18 &= ~(BIT_CSI_HW_ENABLE | BIT_MIPI_DATA_FORMAT_MASK |
 429                  BIT_DATA_FROM_MIPI | BIT_BASEADDR_CHG_ERR_EN |
 430                  BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
 431                  BIT_DEINTERLACE_EN);
 432
 433        if (out_pix->field == V4L2_FIELD_INTERLACED) {
 434                cr18 |= BIT_DEINTERLACE_EN;
 435                stride = out_pix->width;
 436        }
 437
 438        if (!csi->is_csi2) {
 439                cr1 = BIT_SOF_POL | BIT_REDGE | BIT_GCLK_MODE | BIT_HSYNC_POL
 440                    | BIT_FCC | BIT_MCLKDIV(1) | BIT_MCLKEN;
 441
 442                cr18 |= BIT_BASEADDR_SWITCH_EN | BIT_BASEADDR_SWITCH_SEL |
 443                        BIT_BASEADDR_CHG_ERR_EN;
 444
 445                if (out_pix->pixelformat == V4L2_PIX_FMT_UYVY ||
 446                    out_pix->pixelformat == V4L2_PIX_FMT_YUYV)
 447                        width *= 2;
 448        } else {
 449                cr1 = BIT_SOF_POL | BIT_REDGE | BIT_HSYNC_POL | BIT_FCC
 450                    | BIT_MCLKDIV(1) | BIT_MCLKEN;
 451
 452                cr18 |= BIT_DATA_FROM_MIPI;
 453
 454                switch (csi->format_mbus[IMX7_CSI_PAD_SINK].code) {
 455                case MEDIA_BUS_FMT_Y8_1X8:
 456                case MEDIA_BUS_FMT_SBGGR8_1X8:
 457                case MEDIA_BUS_FMT_SGBRG8_1X8:
 458                case MEDIA_BUS_FMT_SGRBG8_1X8:
 459                case MEDIA_BUS_FMT_SRGGB8_1X8:
 460                        cr18 |= BIT_MIPI_DATA_FORMAT_RAW8;
 461                        break;
 462                case MEDIA_BUS_FMT_Y10_1X10:
 463                case MEDIA_BUS_FMT_SBGGR10_1X10:
 464                case MEDIA_BUS_FMT_SGBRG10_1X10:
 465                case MEDIA_BUS_FMT_SGRBG10_1X10:
 466                case MEDIA_BUS_FMT_SRGGB10_1X10:
 467                        cr18 |= BIT_MIPI_DATA_FORMAT_RAW10;
 468                        break;
 469                case MEDIA_BUS_FMT_Y12_1X12:
 470                case MEDIA_BUS_FMT_SBGGR12_1X12:
 471                case MEDIA_BUS_FMT_SGBRG12_1X12:
 472                case MEDIA_BUS_FMT_SGRBG12_1X12:
 473                case MEDIA_BUS_FMT_SRGGB12_1X12:
 474                        cr18 |= BIT_MIPI_DATA_FORMAT_RAW12;
 475                        break;
 476                case MEDIA_BUS_FMT_Y14_1X14:
 477                case MEDIA_BUS_FMT_SBGGR14_1X14:
 478                case MEDIA_BUS_FMT_SGBRG14_1X14:
 479                case MEDIA_BUS_FMT_SGRBG14_1X14:
 480                case MEDIA_BUS_FMT_SRGGB14_1X14:
 481                        cr18 |= BIT_MIPI_DATA_FORMAT_RAW14;
 482                        break;
 483                /*
 484                 * CSI-2 sources are supposed to use the 1X16 formats, but not
 485                 * all of them comply. Support both variants.
 486                 */
 487                case MEDIA_BUS_FMT_UYVY8_2X8:
 488                case MEDIA_BUS_FMT_UYVY8_1X16:
 489                case MEDIA_BUS_FMT_YUYV8_2X8:
 490                case MEDIA_BUS_FMT_YUYV8_1X16:
 491                        cr18 |= BIT_MIPI_DATA_FORMAT_YUV422_8B;
 492                        break;
 493                }
 494
 495                switch (out_pix->pixelformat) {
 496                case V4L2_PIX_FMT_Y10:
 497                case V4L2_PIX_FMT_Y12:
 498                case V4L2_PIX_FMT_SBGGR8:
 499                case V4L2_PIX_FMT_SGBRG8:
 500                case V4L2_PIX_FMT_SGRBG8:
 501                case V4L2_PIX_FMT_SRGGB8:
 502                case V4L2_PIX_FMT_SBGGR16:
 503                case V4L2_PIX_FMT_SGBRG16:
 504                case V4L2_PIX_FMT_SGRBG16:
 505                case V4L2_PIX_FMT_SRGGB16:
 506                        cr1 |= BIT_PIXEL_BIT;
 507                        break;
 508                }
 509        }
 510
 511        imx7_csi_reg_write(csi, cr1, CSI_CSICR1);
 512        imx7_csi_reg_write(csi, BIT_DMA_BURST_TYPE_RFF_INCR16, CSI_CSICR2);
 513        imx7_csi_reg_write(csi, BIT_FRMCNT_RST, CSI_CSICR3);
 514        imx7_csi_reg_write(csi, cr18, CSI_CSICR18);
 515
 516        imx7_csi_reg_write(csi, (width * out_pix->height) >> 2, CSI_CSIRXCNT);
 517        imx7_csi_reg_write(csi, BIT_IMAGE_WIDTH(width) |
 518                           BIT_IMAGE_HEIGHT(out_pix->height),
 519                           CSI_CSIIMAG_PARA);
 520        imx7_csi_reg_write(csi, stride, CSI_CSIFBUF_PARA);
 521}
 522
 523static int imx7_csi_init(struct imx7_csi *csi)
 524{
 525        int ret;
 526
 527        ret = clk_prepare_enable(csi->mclk);
 528        if (ret < 0)
 529                return ret;
 530
 531        imx7_csi_configure(csi);
 532
 533        ret = imx7_csi_dma_setup(csi);
 534        if (ret < 0)
 535                return ret;
 536
 537        return 0;
 538}
 539
 540static void imx7_csi_deinit(struct imx7_csi *csi)
 541{
 542        imx7_csi_dma_cleanup(csi);
 543        imx7_csi_init_default(csi);
 544        imx7_csi_dmareq_rff_disable(csi);
 545        clk_disable_unprepare(csi->mclk);
 546}
 547
 548static void imx7_csi_enable(struct imx7_csi *csi)
 549{
 550        /* Clear the Rx FIFO and reflash the DMA controller. */
 551        imx7_csi_rx_fifo_clear(csi);
 552        imx7_csi_dma_reflash(csi);
 553
 554        usleep_range(2000, 3000);
 555
 556        /* Clear and enable the interrupts. */
 557        imx7_csi_irq_clear(csi);
 558        imx7_csi_hw_enable_irq(csi);
 559
 560        /* Enable the RxFIFO DMA and the CSI. */
 561        imx7_csi_dmareq_rff_enable(csi);
 562        imx7_csi_hw_enable(csi);
 563}
 564
 565static void imx7_csi_disable(struct imx7_csi *csi)
 566{
 567        imx7_csi_dma_stop(csi);
 568
 569        imx7_csi_dmareq_rff_disable(csi);
 570
 571        imx7_csi_hw_disable_irq(csi);
 572
 573        imx7_csi_hw_disable(csi);
 574}
 575
 576/* -----------------------------------------------------------------------------
 577 * Interrupt Handling
 578 */
 579
 580static void imx7_csi_error_recovery(struct imx7_csi *csi)
 581{
 582        imx7_csi_hw_disable(csi);
 583
 584        imx7_csi_rx_fifo_clear(csi);
 585
 586        imx7_csi_dma_reflash(csi);
 587
 588        imx7_csi_hw_enable(csi);
 589}
 590
 591static void imx7_csi_vb2_buf_done(struct imx7_csi *csi)
 592{
 593        struct imx_media_video_dev *vdev = csi->vdev;
 594        struct imx_media_buffer *done, *next;
 595        struct vb2_buffer *vb;
 596        dma_addr_t phys;
 597
 598        done = csi->active_vb2_buf[csi->buf_num];
 599        if (done) {
 600                done->vbuf.field = vdev->fmt.field;
 601                done->vbuf.sequence = csi->frame_sequence;
 602                vb = &done->vbuf.vb2_buf;
 603                vb->timestamp = ktime_get_ns();
 604                vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
 605        }
 606        csi->frame_sequence++;
 607
 608        /* get next queued buffer */
 609        next = imx_media_capture_device_next_buf(vdev);
 610        if (next) {
 611                phys = vb2_dma_contig_plane_dma_addr(&next->vbuf.vb2_buf, 0);
 612                csi->active_vb2_buf[csi->buf_num] = next;
 613        } else {
 614                phys = csi->underrun_buf.phys;
 615                csi->active_vb2_buf[csi->buf_num] = NULL;
 616        }
 617
 618        imx7_csi_update_buf(csi, phys, csi->buf_num);
 619}
 620
 621static irqreturn_t imx7_csi_irq_handler(int irq, void *data)
 622{
 623        struct imx7_csi *csi =  data;
 624        u32 status;
 625
 626        spin_lock(&csi->irqlock);
 627
 628        status = imx7_csi_irq_clear(csi);
 629
 630        if (status & BIT_RFF_OR_INT) {
 631                dev_warn(csi->dev, "Rx fifo overflow\n");
 632                imx7_csi_error_recovery(csi);
 633        }
 634
 635        if (status & BIT_HRESP_ERR_INT) {
 636                dev_warn(csi->dev, "Hresponse error detected\n");
 637                imx7_csi_error_recovery(csi);
 638        }
 639
 640        if (status & BIT_ADDR_CH_ERR_INT) {
 641                imx7_csi_hw_disable(csi);
 642
 643                imx7_csi_dma_reflash(csi);
 644
 645                imx7_csi_hw_enable(csi);
 646        }
 647
 648        if ((status & BIT_DMA_TSF_DONE_FB1) &&
 649            (status & BIT_DMA_TSF_DONE_FB2)) {
 650                /*
 651                 * For both FB1 and FB2 interrupter bits set case,
 652                 * CSI DMA is work in one of FB1 and FB2 buffer,
 653                 * but software can not know the state.
 654                 * Skip it to avoid base address updated
 655                 * when csi work in field0 and field1 will write to
 656                 * new base address.
 657                 */
 658        } else if (status & BIT_DMA_TSF_DONE_FB1) {
 659                csi->buf_num = 0;
 660        } else if (status & BIT_DMA_TSF_DONE_FB2) {
 661                csi->buf_num = 1;
 662        }
 663
 664        if ((status & BIT_DMA_TSF_DONE_FB1) ||
 665            (status & BIT_DMA_TSF_DONE_FB2)) {
 666                imx7_csi_vb2_buf_done(csi);
 667
 668                if (csi->last_eof) {
 669                        complete(&csi->last_eof_completion);
 670                        csi->last_eof = false;
 671                }
 672        }
 673
 674        spin_unlock(&csi->irqlock);
 675
 676        return IRQ_HANDLED;
 677}
 678
 679/* -----------------------------------------------------------------------------
 680 * V4L2 Subdev Operations
 681 */
 682
 683static int imx7_csi_s_stream(struct v4l2_subdev *sd, int enable)
 684{
 685        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
 686        int ret = 0;
 687
 688        mutex_lock(&csi->lock);
 689
 690        if (!csi->src_sd) {
 691                ret = -EPIPE;
 692                goto out_unlock;
 693        }
 694
 695        if (csi->is_streaming == !!enable)
 696                goto out_unlock;
 697
 698        if (enable) {
 699                ret = imx7_csi_init(csi);
 700                if (ret < 0)
 701                        goto out_unlock;
 702
 703                ret = v4l2_subdev_call(csi->src_sd, video, s_stream, 1);
 704                if (ret < 0) {
 705                        imx7_csi_deinit(csi);
 706                        goto out_unlock;
 707                }
 708
 709                imx7_csi_enable(csi);
 710        } else {
 711                imx7_csi_disable(csi);
 712
 713                v4l2_subdev_call(csi->src_sd, video, s_stream, 0);
 714
 715                imx7_csi_deinit(csi);
 716        }
 717
 718        csi->is_streaming = !!enable;
 719
 720out_unlock:
 721        mutex_unlock(&csi->lock);
 722
 723        return ret;
 724}
 725
 726static int imx7_csi_init_cfg(struct v4l2_subdev *sd,
 727                             struct v4l2_subdev_state *sd_state)
 728{
 729        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
 730        struct v4l2_mbus_framefmt *mf;
 731        int ret;
 732        int i;
 733
 734        for (i = 0; i < IMX7_CSI_PADS_NUM; i++) {
 735                mf = v4l2_subdev_get_try_format(sd, sd_state, i);
 736
 737                ret = imx_media_init_mbus_fmt(mf, 800, 600, 0, V4L2_FIELD_NONE,
 738                                              &csi->cc[i]);
 739                if (ret < 0)
 740                        return ret;
 741        }
 742
 743        return 0;
 744}
 745
 746static struct v4l2_mbus_framefmt *
 747imx7_csi_get_format(struct imx7_csi *csi,
 748                    struct v4l2_subdev_state *sd_state,
 749                    unsigned int pad,
 750                    enum v4l2_subdev_format_whence which)
 751{
 752        if (which == V4L2_SUBDEV_FORMAT_TRY)
 753                return v4l2_subdev_get_try_format(&csi->sd, sd_state, pad);
 754
 755        return &csi->format_mbus[pad];
 756}
 757
 758static int imx7_csi_enum_mbus_code(struct v4l2_subdev *sd,
 759                                   struct v4l2_subdev_state *sd_state,
 760                                   struct v4l2_subdev_mbus_code_enum *code)
 761{
 762        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
 763        struct v4l2_mbus_framefmt *in_fmt;
 764        int ret = 0;
 765
 766        mutex_lock(&csi->lock);
 767
 768        in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK,
 769                                     code->which);
 770
 771        switch (code->pad) {
 772        case IMX7_CSI_PAD_SINK:
 773                ret = imx_media_enum_mbus_formats(&code->code, code->index,
 774                                                  PIXFMT_SEL_ANY);
 775                break;
 776        case IMX7_CSI_PAD_SRC:
 777                if (code->index != 0) {
 778                        ret = -EINVAL;
 779                        goto out_unlock;
 780                }
 781
 782                code->code = in_fmt->code;
 783                break;
 784        default:
 785                ret = -EINVAL;
 786        }
 787
 788out_unlock:
 789        mutex_unlock(&csi->lock);
 790
 791        return ret;
 792}
 793
 794static int imx7_csi_get_fmt(struct v4l2_subdev *sd,
 795                            struct v4l2_subdev_state *sd_state,
 796                            struct v4l2_subdev_format *sdformat)
 797{
 798        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
 799        struct v4l2_mbus_framefmt *fmt;
 800        int ret = 0;
 801
 802        mutex_lock(&csi->lock);
 803
 804        fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad,
 805                                  sdformat->which);
 806        if (!fmt) {
 807                ret = -EINVAL;
 808                goto out_unlock;
 809        }
 810
 811        sdformat->format = *fmt;
 812
 813out_unlock:
 814        mutex_unlock(&csi->lock);
 815
 816        return ret;
 817}
 818
 819static int imx7_csi_try_fmt(struct imx7_csi *csi,
 820                            struct v4l2_subdev_state *sd_state,
 821                            struct v4l2_subdev_format *sdformat,
 822                            const struct imx_media_pixfmt **cc)
 823{
 824        const struct imx_media_pixfmt *in_cc;
 825        struct v4l2_mbus_framefmt *in_fmt;
 826        u32 code;
 827
 828        in_fmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SINK,
 829                                     sdformat->which);
 830        if (!in_fmt)
 831                return -EINVAL;
 832
 833        switch (sdformat->pad) {
 834        case IMX7_CSI_PAD_SRC:
 835                in_cc = imx_media_find_mbus_format(in_fmt->code,
 836                                                   PIXFMT_SEL_ANY);
 837
 838                sdformat->format.width = in_fmt->width;
 839                sdformat->format.height = in_fmt->height;
 840                sdformat->format.code = in_fmt->code;
 841                sdformat->format.field = in_fmt->field;
 842                *cc = in_cc;
 843
 844                sdformat->format.colorspace = in_fmt->colorspace;
 845                sdformat->format.xfer_func = in_fmt->xfer_func;
 846                sdformat->format.quantization = in_fmt->quantization;
 847                sdformat->format.ycbcr_enc = in_fmt->ycbcr_enc;
 848                break;
 849        case IMX7_CSI_PAD_SINK:
 850                *cc = imx_media_find_mbus_format(sdformat->format.code,
 851                                                 PIXFMT_SEL_ANY);
 852                if (!*cc) {
 853                        imx_media_enum_mbus_formats(&code, 0,
 854                                                    PIXFMT_SEL_YUV_RGB);
 855                        *cc = imx_media_find_mbus_format(code,
 856                                                         PIXFMT_SEL_YUV_RGB);
 857                        sdformat->format.code = (*cc)->codes[0];
 858                }
 859
 860                if (sdformat->format.field != V4L2_FIELD_INTERLACED)
 861                        sdformat->format.field = V4L2_FIELD_NONE;
 862                break;
 863        default:
 864                return -EINVAL;
 865        }
 866
 867        imx_media_try_colorimetry(&sdformat->format, false);
 868
 869        return 0;
 870}
 871
 872static int imx7_csi_set_fmt(struct v4l2_subdev *sd,
 873                            struct v4l2_subdev_state *sd_state,
 874                            struct v4l2_subdev_format *sdformat)
 875{
 876        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
 877        const struct imx_media_pixfmt *outcc;
 878        struct v4l2_mbus_framefmt *outfmt;
 879        const struct imx_media_pixfmt *cc;
 880        struct v4l2_mbus_framefmt *fmt;
 881        struct v4l2_subdev_format format;
 882        int ret = 0;
 883
 884        if (sdformat->pad >= IMX7_CSI_PADS_NUM)
 885                return -EINVAL;
 886
 887        mutex_lock(&csi->lock);
 888
 889        if (csi->is_streaming) {
 890                ret = -EBUSY;
 891                goto out_unlock;
 892        }
 893
 894        ret = imx7_csi_try_fmt(csi, sd_state, sdformat, &cc);
 895        if (ret < 0)
 896                goto out_unlock;
 897
 898        fmt = imx7_csi_get_format(csi, sd_state, sdformat->pad,
 899                                  sdformat->which);
 900        if (!fmt) {
 901                ret = -EINVAL;
 902                goto out_unlock;
 903        }
 904
 905        *fmt = sdformat->format;
 906
 907        if (sdformat->pad == IMX7_CSI_PAD_SINK) {
 908                /* propagate format to source pads */
 909                format.pad = IMX7_CSI_PAD_SRC;
 910                format.which = sdformat->which;
 911                format.format = sdformat->format;
 912                if (imx7_csi_try_fmt(csi, sd_state, &format, &outcc)) {
 913                        ret = -EINVAL;
 914                        goto out_unlock;
 915                }
 916                outfmt = imx7_csi_get_format(csi, sd_state, IMX7_CSI_PAD_SRC,
 917                                             sdformat->which);
 918                *outfmt = format.format;
 919
 920                if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
 921                        csi->cc[IMX7_CSI_PAD_SRC] = outcc;
 922        }
 923
 924        if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
 925                csi->cc[sdformat->pad] = cc;
 926
 927out_unlock:
 928        mutex_unlock(&csi->lock);
 929
 930        return ret;
 931}
 932
 933static int imx7_csi_pad_link_validate(struct v4l2_subdev *sd,
 934                                      struct media_link *link,
 935                                      struct v4l2_subdev_format *source_fmt,
 936                                      struct v4l2_subdev_format *sink_fmt)
 937{
 938        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
 939        struct imx_media_video_dev *vdev = csi->vdev;
 940        const struct v4l2_pix_format *out_pix = &vdev->fmt;
 941        struct media_pad *pad;
 942        int ret;
 943
 944        if (!csi->src_sd)
 945                return -EPIPE;
 946
 947        /*
 948         * Validate the source link, and record whether the source uses the
 949         * parallel input or the CSI-2 receiver.
 950         */
 951        ret = v4l2_subdev_link_validate_default(sd, link, source_fmt, sink_fmt);
 952        if (ret)
 953                return ret;
 954
 955        switch (csi->src_sd->entity.function) {
 956        case MEDIA_ENT_F_VID_IF_BRIDGE:
 957                /* The input is the CSI-2 receiver. */
 958                csi->is_csi2 = true;
 959                break;
 960
 961        case MEDIA_ENT_F_VID_MUX:
 962                /* The input is the mux, check its input. */
 963                pad = imx_media_pipeline_pad(&csi->src_sd->entity, 0, 0, true);
 964                if (!pad)
 965                        return -ENODEV;
 966
 967                csi->is_csi2 = pad->entity->function == MEDIA_ENT_F_VID_IF_BRIDGE;
 968                break;
 969
 970        default:
 971                /*
 972                 * The input is an external entity, it must use the parallel
 973                 * bus.
 974                 */
 975                csi->is_csi2 = false;
 976                break;
 977        }
 978
 979        /* Validate the sink link, ensure the pixel format is supported. */
 980        switch (out_pix->pixelformat) {
 981        case V4L2_PIX_FMT_UYVY:
 982        case V4L2_PIX_FMT_YUYV:
 983        case V4L2_PIX_FMT_GREY:
 984        case V4L2_PIX_FMT_Y10:
 985        case V4L2_PIX_FMT_Y12:
 986        case V4L2_PIX_FMT_SBGGR8:
 987        case V4L2_PIX_FMT_SGBRG8:
 988        case V4L2_PIX_FMT_SGRBG8:
 989        case V4L2_PIX_FMT_SRGGB8:
 990        case V4L2_PIX_FMT_SBGGR16:
 991        case V4L2_PIX_FMT_SGBRG16:
 992        case V4L2_PIX_FMT_SGRBG16:
 993        case V4L2_PIX_FMT_SRGGB16:
 994                break;
 995
 996        default:
 997                dev_dbg(csi->dev, "Invalid capture pixel format 0x%08x\n",
 998                        out_pix->pixelformat);
 999                return -EINVAL;
1000        }
1001
1002        return 0;
1003}
1004
1005static int imx7_csi_registered(struct v4l2_subdev *sd)
1006{
1007        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1008        int ret;
1009        int i;
1010
1011        for (i = 0; i < IMX7_CSI_PADS_NUM; i++) {
1012                /* set a default mbus format  */
1013                ret = imx_media_init_mbus_fmt(&csi->format_mbus[i],
1014                                              800, 600, 0, V4L2_FIELD_NONE,
1015                                              &csi->cc[i]);
1016                if (ret < 0)
1017                        return ret;
1018
1019                /* init default frame interval */
1020                csi->frame_interval[i].numerator = 1;
1021                csi->frame_interval[i].denominator = 30;
1022        }
1023
1024        csi->vdev = imx_media_capture_device_init(csi->sd.dev, &csi->sd,
1025                                                  IMX7_CSI_PAD_SRC, false);
1026        if (IS_ERR(csi->vdev))
1027                return PTR_ERR(csi->vdev);
1028
1029        ret = imx_media_capture_device_register(csi->vdev,
1030                                                MEDIA_LNK_FL_IMMUTABLE);
1031        if (ret)
1032                imx_media_capture_device_remove(csi->vdev);
1033
1034        return ret;
1035}
1036
1037static void imx7_csi_unregistered(struct v4l2_subdev *sd)
1038{
1039        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1040
1041        imx_media_capture_device_unregister(csi->vdev);
1042        imx_media_capture_device_remove(csi->vdev);
1043}
1044
1045static const struct v4l2_subdev_video_ops imx7_csi_video_ops = {
1046        .s_stream       = imx7_csi_s_stream,
1047};
1048
1049static const struct v4l2_subdev_pad_ops imx7_csi_pad_ops = {
1050        .init_cfg       = imx7_csi_init_cfg,
1051        .enum_mbus_code = imx7_csi_enum_mbus_code,
1052        .get_fmt        = imx7_csi_get_fmt,
1053        .set_fmt        = imx7_csi_set_fmt,
1054        .link_validate  = imx7_csi_pad_link_validate,
1055};
1056
1057static const struct v4l2_subdev_ops imx7_csi_subdev_ops = {
1058        .video          = &imx7_csi_video_ops,
1059        .pad            = &imx7_csi_pad_ops,
1060};
1061
1062static const struct v4l2_subdev_internal_ops imx7_csi_internal_ops = {
1063        .registered     = imx7_csi_registered,
1064        .unregistered   = imx7_csi_unregistered,
1065};
1066
1067/* -----------------------------------------------------------------------------
1068 * Media Entity Operations
1069 */
1070
1071static const struct media_entity_operations imx7_csi_entity_ops = {
1072        .link_validate  = v4l2_subdev_link_validate,
1073        .get_fwnode_pad = v4l2_subdev_get_fwnode_pad_1_to_1,
1074};
1075
1076/* -----------------------------------------------------------------------------
1077 * Probe & Remove
1078 */
1079
1080static int imx7_csi_notify_bound(struct v4l2_async_notifier *notifier,
1081                                 struct v4l2_subdev *sd,
1082                                 struct v4l2_async_subdev *asd)
1083{
1084        struct imx7_csi *csi = imx7_csi_notifier_to_dev(notifier);
1085        struct media_pad *sink = &csi->sd.entity.pads[IMX7_CSI_PAD_SINK];
1086
1087        /*
1088         * If the subdev is a video mux, it must be one of the CSI
1089         * muxes. Mark it as such via its group id.
1090         */
1091        if (sd->entity.function == MEDIA_ENT_F_VID_MUX)
1092                sd->grp_id = IMX_MEDIA_GRP_ID_CSI_MUX;
1093
1094        csi->src_sd = sd;
1095
1096        return v4l2_create_fwnode_links_to_pad(sd, sink, MEDIA_LNK_FL_ENABLED |
1097                                               MEDIA_LNK_FL_IMMUTABLE);
1098}
1099
1100static const struct v4l2_async_notifier_operations imx7_csi_notify_ops = {
1101        .bound = imx7_csi_notify_bound,
1102};
1103
1104static int imx7_csi_async_register(struct imx7_csi *csi)
1105{
1106        struct v4l2_async_subdev *asd;
1107        struct fwnode_handle *ep;
1108        int ret;
1109
1110        v4l2_async_notifier_init(&csi->notifier);
1111
1112        ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(csi->dev), 0, 0,
1113                                             FWNODE_GRAPH_ENDPOINT_NEXT);
1114        if (ep) {
1115                asd = v4l2_async_notifier_add_fwnode_remote_subdev(
1116                        &csi->notifier, ep, struct v4l2_async_subdev);
1117
1118                fwnode_handle_put(ep);
1119
1120                if (IS_ERR(asd)) {
1121                        ret = PTR_ERR(asd);
1122                        /* OK if asd already exists */
1123                        if (ret != -EEXIST)
1124                                return ret;
1125                }
1126        }
1127
1128        csi->notifier.ops = &imx7_csi_notify_ops;
1129
1130        ret = v4l2_async_subdev_notifier_register(&csi->sd, &csi->notifier);
1131        if (ret)
1132                return ret;
1133
1134        return v4l2_async_register_subdev(&csi->sd);
1135}
1136
1137static int imx7_csi_probe(struct platform_device *pdev)
1138{
1139        struct device *dev = &pdev->dev;
1140        struct device_node *node = dev->of_node;
1141        struct imx_media_dev *imxmd;
1142        struct imx7_csi *csi;
1143        int i, ret;
1144
1145        csi = devm_kzalloc(&pdev->dev, sizeof(*csi), GFP_KERNEL);
1146        if (!csi)
1147                return -ENOMEM;
1148
1149        csi->dev = dev;
1150
1151        csi->mclk = devm_clk_get(&pdev->dev, "mclk");
1152        if (IS_ERR(csi->mclk)) {
1153                ret = PTR_ERR(csi->mclk);
1154                dev_err(dev, "Failed to get mclk: %d", ret);
1155                return ret;
1156        }
1157
1158        csi->irq = platform_get_irq(pdev, 0);
1159        if (csi->irq < 0)
1160                return csi->irq;
1161
1162        csi->regbase = devm_platform_ioremap_resource(pdev, 0);
1163        if (IS_ERR(csi->regbase))
1164                return PTR_ERR(csi->regbase);
1165
1166        spin_lock_init(&csi->irqlock);
1167        mutex_init(&csi->lock);
1168
1169        /* install interrupt handler */
1170        ret = devm_request_irq(dev, csi->irq, imx7_csi_irq_handler, 0, "csi",
1171                               (void *)csi);
1172        if (ret < 0) {
1173                dev_err(dev, "Request CSI IRQ failed.\n");
1174                goto destroy_mutex;
1175        }
1176
1177        /* add media device */
1178        imxmd = imx_media_dev_init(dev, NULL);
1179        if (IS_ERR(imxmd)) {
1180                ret = PTR_ERR(imxmd);
1181                goto destroy_mutex;
1182        }
1183        platform_set_drvdata(pdev, &csi->sd);
1184
1185        ret = imx_media_of_add_csi(imxmd, node);
1186        if (ret < 0 && ret != -ENODEV && ret != -EEXIST)
1187                goto cleanup;
1188
1189        ret = imx_media_dev_notifier_register(imxmd, NULL);
1190        if (ret < 0)
1191                goto cleanup;
1192
1193        csi->imxmd = imxmd;
1194        v4l2_subdev_init(&csi->sd, &imx7_csi_subdev_ops);
1195        v4l2_set_subdevdata(&csi->sd, csi);
1196        csi->sd.internal_ops = &imx7_csi_internal_ops;
1197        csi->sd.entity.ops = &imx7_csi_entity_ops;
1198        csi->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
1199        csi->sd.dev = &pdev->dev;
1200        csi->sd.owner = THIS_MODULE;
1201        csi->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1202        csi->sd.grp_id = IMX_MEDIA_GRP_ID_CSI;
1203        snprintf(csi->sd.name, sizeof(csi->sd.name), "csi");
1204
1205        for (i = 0; i < IMX7_CSI_PADS_NUM; i++)
1206                csi->pad[i].flags = (i == IMX7_CSI_PAD_SINK) ?
1207                        MEDIA_PAD_FL_SINK : MEDIA_PAD_FL_SOURCE;
1208
1209        ret = media_entity_pads_init(&csi->sd.entity, IMX7_CSI_PADS_NUM,
1210                                     csi->pad);
1211        if (ret < 0)
1212                goto cleanup;
1213
1214        ret = imx7_csi_async_register(csi);
1215        if (ret)
1216                goto subdev_notifier_cleanup;
1217
1218        return 0;
1219
1220subdev_notifier_cleanup:
1221        v4l2_async_notifier_unregister(&csi->notifier);
1222        v4l2_async_notifier_cleanup(&csi->notifier);
1223
1224cleanup:
1225        v4l2_async_notifier_unregister(&imxmd->notifier);
1226        v4l2_async_notifier_cleanup(&imxmd->notifier);
1227        v4l2_device_unregister(&imxmd->v4l2_dev);
1228        media_device_unregister(&imxmd->md);
1229        media_device_cleanup(&imxmd->md);
1230
1231destroy_mutex:
1232        mutex_destroy(&csi->lock);
1233
1234        return ret;
1235}
1236
1237static int imx7_csi_remove(struct platform_device *pdev)
1238{
1239        struct v4l2_subdev *sd = platform_get_drvdata(pdev);
1240        struct imx7_csi *csi = v4l2_get_subdevdata(sd);
1241        struct imx_media_dev *imxmd = csi->imxmd;
1242
1243        v4l2_async_notifier_unregister(&imxmd->notifier);
1244        v4l2_async_notifier_cleanup(&imxmd->notifier);
1245
1246        media_device_unregister(&imxmd->md);
1247        v4l2_device_unregister(&imxmd->v4l2_dev);
1248        media_device_cleanup(&imxmd->md);
1249
1250        v4l2_async_notifier_unregister(&csi->notifier);
1251        v4l2_async_notifier_cleanup(&csi->notifier);
1252        v4l2_async_unregister_subdev(sd);
1253
1254        mutex_destroy(&csi->lock);
1255
1256        return 0;
1257}
1258
1259static const struct of_device_id imx7_csi_of_match[] = {
1260        { .compatible = "fsl,imx7-csi" },
1261        { .compatible = "fsl,imx6ul-csi" },
1262        { },
1263};
1264MODULE_DEVICE_TABLE(of, imx7_csi_of_match);
1265
1266static struct platform_driver imx7_csi_driver = {
1267        .probe = imx7_csi_probe,
1268        .remove = imx7_csi_remove,
1269        .driver = {
1270                .of_match_table = imx7_csi_of_match,
1271                .name = "imx7-csi",
1272        },
1273};
1274module_platform_driver(imx7_csi_driver);
1275
1276MODULE_DESCRIPTION("i.MX7 CSI subdev driver");
1277MODULE_AUTHOR("Rui Miguel Silva <rui.silva@linaro.org>");
1278MODULE_LICENSE("GPL v2");
1279MODULE_ALIAS("platform:imx7-csi");
1280
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.