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