linux/drivers/media/platform/rcar-vin/rcar-csi2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Driver for Renesas R-Car MIPI CSI-2 Receiver
   4 *
   5 * Copyright (C) 2018 Renesas Electronics Corp.
   6 */
   7
   8#include <linux/delay.h>
   9#include <linux/interrupt.h>
  10#include <linux/io.h>
  11#include <linux/module.h>
  12#include <linux/of.h>
  13#include <linux/of_device.h>
  14#include <linux/of_graph.h>
  15#include <linux/platform_device.h>
  16#include <linux/pm_runtime.h>
  17#include <linux/reset.h>
  18#include <linux/sys_soc.h>
  19
  20#include <media/v4l2-ctrls.h>
  21#include <media/v4l2-device.h>
  22#include <media/v4l2-fwnode.h>
  23#include <media/v4l2-mc.h>
  24#include <media/v4l2-subdev.h>
  25
  26struct rcar_csi2;
  27
  28/* Register offsets and bits */
  29
  30/* Control Timing Select */
  31#define TREF_REG                        0x00
  32#define TREF_TREF                       BIT(0)
  33
  34/* Software Reset */
  35#define SRST_REG                        0x04
  36#define SRST_SRST                       BIT(0)
  37
  38/* PHY Operation Control */
  39#define PHYCNT_REG                      0x08
  40#define PHYCNT_SHUTDOWNZ                BIT(17)
  41#define PHYCNT_RSTZ                     BIT(16)
  42#define PHYCNT_ENABLECLK                BIT(4)
  43#define PHYCNT_ENABLE_3                 BIT(3)
  44#define PHYCNT_ENABLE_2                 BIT(2)
  45#define PHYCNT_ENABLE_1                 BIT(1)
  46#define PHYCNT_ENABLE_0                 BIT(0)
  47
  48/* Checksum Control */
  49#define CHKSUM_REG                      0x0c
  50#define CHKSUM_ECC_EN                   BIT(1)
  51#define CHKSUM_CRC_EN                   BIT(0)
  52
  53/*
  54 * Channel Data Type Select
  55 * VCDT[0-15]:  Channel 1 VCDT[16-31]:  Channel 2
  56 * VCDT2[0-15]: Channel 3 VCDT2[16-31]: Channel 4
  57 */
  58#define VCDT_REG                        0x10
  59#define VCDT2_REG                       0x14
  60#define VCDT_VCDTN_EN                   BIT(15)
  61#define VCDT_SEL_VC(n)                  (((n) & 0x3) << 8)
  62#define VCDT_SEL_DTN_ON                 BIT(6)
  63#define VCDT_SEL_DT(n)                  (((n) & 0x3f) << 0)
  64
  65/* Frame Data Type Select */
  66#define FRDT_REG                        0x18
  67
  68/* Field Detection Control */
  69#define FLD_REG                         0x1c
  70#define FLD_FLD_NUM(n)                  (((n) & 0xff) << 16)
  71#define FLD_DET_SEL(n)                  (((n) & 0x3) << 4)
  72#define FLD_FLD_EN4                     BIT(3)
  73#define FLD_FLD_EN3                     BIT(2)
  74#define FLD_FLD_EN2                     BIT(1)
  75#define FLD_FLD_EN                      BIT(0)
  76
  77/* Automatic Standby Control */
  78#define ASTBY_REG                       0x20
  79
  80/* Long Data Type Setting 0 */
  81#define LNGDT0_REG                      0x28
  82
  83/* Long Data Type Setting 1 */
  84#define LNGDT1_REG                      0x2c
  85
  86/* Interrupt Enable */
  87#define INTEN_REG                       0x30
  88#define INTEN_INT_AFIFO_OF              BIT(27)
  89#define INTEN_INT_ERRSOTHS              BIT(4)
  90#define INTEN_INT_ERRSOTSYNCHS          BIT(3)
  91
  92/* Interrupt Source Mask */
  93#define INTCLOSE_REG                    0x34
  94
  95/* Interrupt Status Monitor */
  96#define INTSTATE_REG                    0x38
  97#define INTSTATE_INT_ULPS_START         BIT(7)
  98#define INTSTATE_INT_ULPS_END           BIT(6)
  99
 100/* Interrupt Error Status Monitor */
 101#define INTERRSTATE_REG                 0x3c
 102
 103/* Short Packet Data */
 104#define SHPDAT_REG                      0x40
 105
 106/* Short Packet Count */
 107#define SHPCNT_REG                      0x44
 108
 109/* LINK Operation Control */
 110#define LINKCNT_REG                     0x48
 111#define LINKCNT_MONITOR_EN              BIT(31)
 112#define LINKCNT_REG_MONI_PACT_EN        BIT(25)
 113#define LINKCNT_ICLK_NONSTOP            BIT(24)
 114
 115/* Lane Swap */
 116#define LSWAP_REG                       0x4c
 117#define LSWAP_L3SEL(n)                  (((n) & 0x3) << 6)
 118#define LSWAP_L2SEL(n)                  (((n) & 0x3) << 4)
 119#define LSWAP_L1SEL(n)                  (((n) & 0x3) << 2)
 120#define LSWAP_L0SEL(n)                  (((n) & 0x3) << 0)
 121
 122/* PHY Test Interface Write Register */
 123#define PHTW_REG                        0x50
 124#define PHTW_DWEN                       BIT(24)
 125#define PHTW_TESTDIN_DATA(n)            (((n & 0xff)) << 16)
 126#define PHTW_CWEN                       BIT(8)
 127#define PHTW_TESTDIN_CODE(n)            ((n & 0xff))
 128
 129struct phtw_value {
 130        u16 data;
 131        u16 code;
 132};
 133
 134struct rcsi2_mbps_reg {
 135        u16 mbps;
 136        u16 reg;
 137};
 138
 139static const struct rcsi2_mbps_reg phtw_mbps_h3_v3h_m3n[] = {
 140        { .mbps =   80, .reg = 0x86 },
 141        { .mbps =   90, .reg = 0x86 },
 142        { .mbps =  100, .reg = 0x87 },
 143        { .mbps =  110, .reg = 0x87 },
 144        { .mbps =  120, .reg = 0x88 },
 145        { .mbps =  130, .reg = 0x88 },
 146        { .mbps =  140, .reg = 0x89 },
 147        { .mbps =  150, .reg = 0x89 },
 148        { .mbps =  160, .reg = 0x8a },
 149        { .mbps =  170, .reg = 0x8a },
 150        { .mbps =  180, .reg = 0x8b },
 151        { .mbps =  190, .reg = 0x8b },
 152        { .mbps =  205, .reg = 0x8c },
 153        { .mbps =  220, .reg = 0x8d },
 154        { .mbps =  235, .reg = 0x8e },
 155        { .mbps =  250, .reg = 0x8e },
 156        { /* sentinel */ },
 157};
 158
 159static const struct rcsi2_mbps_reg phtw_mbps_v3m_e3[] = {
 160        { .mbps =   80, .reg = 0x00 },
 161        { .mbps =   90, .reg = 0x20 },
 162        { .mbps =  100, .reg = 0x40 },
 163        { .mbps =  110, .reg = 0x02 },
 164        { .mbps =  130, .reg = 0x22 },
 165        { .mbps =  140, .reg = 0x42 },
 166        { .mbps =  150, .reg = 0x04 },
 167        { .mbps =  170, .reg = 0x24 },
 168        { .mbps =  180, .reg = 0x44 },
 169        { .mbps =  200, .reg = 0x06 },
 170        { .mbps =  220, .reg = 0x26 },
 171        { .mbps =  240, .reg = 0x46 },
 172        { .mbps =  250, .reg = 0x08 },
 173        { .mbps =  270, .reg = 0x28 },
 174        { .mbps =  300, .reg = 0x0a },
 175        { .mbps =  330, .reg = 0x2a },
 176        { .mbps =  360, .reg = 0x4a },
 177        { .mbps =  400, .reg = 0x0c },
 178        { .mbps =  450, .reg = 0x2c },
 179        { .mbps =  500, .reg = 0x0e },
 180        { .mbps =  550, .reg = 0x2e },
 181        { .mbps =  600, .reg = 0x10 },
 182        { .mbps =  650, .reg = 0x30 },
 183        { .mbps =  700, .reg = 0x12 },
 184        { .mbps =  750, .reg = 0x32 },
 185        { .mbps =  800, .reg = 0x52 },
 186        { .mbps =  850, .reg = 0x72 },
 187        { .mbps =  900, .reg = 0x14 },
 188        { .mbps =  950, .reg = 0x34 },
 189        { .mbps = 1000, .reg = 0x54 },
 190        { .mbps = 1050, .reg = 0x74 },
 191        { .mbps = 1125, .reg = 0x16 },
 192        { /* sentinel */ },
 193};
 194
 195/* PHY Test Interface Clear */
 196#define PHTC_REG                        0x58
 197#define PHTC_TESTCLR                    BIT(0)
 198
 199/* PHY Frequency Control */
 200#define PHYPLL_REG                      0x68
 201#define PHYPLL_HSFREQRANGE(n)           ((n) << 16)
 202
 203static const struct rcsi2_mbps_reg hsfreqrange_h3_v3h_m3n[] = {
 204        { .mbps =   80, .reg = 0x00 },
 205        { .mbps =   90, .reg = 0x10 },
 206        { .mbps =  100, .reg = 0x20 },
 207        { .mbps =  110, .reg = 0x30 },
 208        { .mbps =  120, .reg = 0x01 },
 209        { .mbps =  130, .reg = 0x11 },
 210        { .mbps =  140, .reg = 0x21 },
 211        { .mbps =  150, .reg = 0x31 },
 212        { .mbps =  160, .reg = 0x02 },
 213        { .mbps =  170, .reg = 0x12 },
 214        { .mbps =  180, .reg = 0x22 },
 215        { .mbps =  190, .reg = 0x32 },
 216        { .mbps =  205, .reg = 0x03 },
 217        { .mbps =  220, .reg = 0x13 },
 218        { .mbps =  235, .reg = 0x23 },
 219        { .mbps =  250, .reg = 0x33 },
 220        { .mbps =  275, .reg = 0x04 },
 221        { .mbps =  300, .reg = 0x14 },
 222        { .mbps =  325, .reg = 0x25 },
 223        { .mbps =  350, .reg = 0x35 },
 224        { .mbps =  400, .reg = 0x05 },
 225        { .mbps =  450, .reg = 0x16 },
 226        { .mbps =  500, .reg = 0x26 },
 227        { .mbps =  550, .reg = 0x37 },
 228        { .mbps =  600, .reg = 0x07 },
 229        { .mbps =  650, .reg = 0x18 },
 230        { .mbps =  700, .reg = 0x28 },
 231        { .mbps =  750, .reg = 0x39 },
 232        { .mbps =  800, .reg = 0x09 },
 233        { .mbps =  850, .reg = 0x19 },
 234        { .mbps =  900, .reg = 0x29 },
 235        { .mbps =  950, .reg = 0x3a },
 236        { .mbps = 1000, .reg = 0x0a },
 237        { .mbps = 1050, .reg = 0x1a },
 238        { .mbps = 1100, .reg = 0x2a },
 239        { .mbps = 1150, .reg = 0x3b },
 240        { .mbps = 1200, .reg = 0x0b },
 241        { .mbps = 1250, .reg = 0x1b },
 242        { .mbps = 1300, .reg = 0x2b },
 243        { .mbps = 1350, .reg = 0x3c },
 244        { .mbps = 1400, .reg = 0x0c },
 245        { .mbps = 1450, .reg = 0x1c },
 246        { .mbps = 1500, .reg = 0x2c },
 247        { /* sentinel */ },
 248};
 249
 250static const struct rcsi2_mbps_reg hsfreqrange_m3w_h3es1[] = {
 251        { .mbps =   80, .reg = 0x00 },
 252        { .mbps =   90, .reg = 0x10 },
 253        { .mbps =  100, .reg = 0x20 },
 254        { .mbps =  110, .reg = 0x30 },
 255        { .mbps =  120, .reg = 0x01 },
 256        { .mbps =  130, .reg = 0x11 },
 257        { .mbps =  140, .reg = 0x21 },
 258        { .mbps =  150, .reg = 0x31 },
 259        { .mbps =  160, .reg = 0x02 },
 260        { .mbps =  170, .reg = 0x12 },
 261        { .mbps =  180, .reg = 0x22 },
 262        { .mbps =  190, .reg = 0x32 },
 263        { .mbps =  205, .reg = 0x03 },
 264        { .mbps =  220, .reg = 0x13 },
 265        { .mbps =  235, .reg = 0x23 },
 266        { .mbps =  250, .reg = 0x33 },
 267        { .mbps =  275, .reg = 0x04 },
 268        { .mbps =  300, .reg = 0x14 },
 269        { .mbps =  325, .reg = 0x05 },
 270        { .mbps =  350, .reg = 0x15 },
 271        { .mbps =  400, .reg = 0x25 },
 272        { .mbps =  450, .reg = 0x06 },
 273        { .mbps =  500, .reg = 0x16 },
 274        { .mbps =  550, .reg = 0x07 },
 275        { .mbps =  600, .reg = 0x17 },
 276        { .mbps =  650, .reg = 0x08 },
 277        { .mbps =  700, .reg = 0x18 },
 278        { .mbps =  750, .reg = 0x09 },
 279        { .mbps =  800, .reg = 0x19 },
 280        { .mbps =  850, .reg = 0x29 },
 281        { .mbps =  900, .reg = 0x39 },
 282        { .mbps =  950, .reg = 0x0a },
 283        { .mbps = 1000, .reg = 0x1a },
 284        { .mbps = 1050, .reg = 0x2a },
 285        { .mbps = 1100, .reg = 0x3a },
 286        { .mbps = 1150, .reg = 0x0b },
 287        { .mbps = 1200, .reg = 0x1b },
 288        { .mbps = 1250, .reg = 0x2b },
 289        { .mbps = 1300, .reg = 0x3b },
 290        { .mbps = 1350, .reg = 0x0c },
 291        { .mbps = 1400, .reg = 0x1c },
 292        { .mbps = 1450, .reg = 0x2c },
 293        { .mbps = 1500, .reg = 0x3c },
 294        { /* sentinel */ },
 295};
 296
 297/* PHY ESC Error Monitor */
 298#define PHEERM_REG                      0x74
 299
 300/* PHY Clock Lane Monitor */
 301#define PHCLM_REG                       0x78
 302#define PHCLM_STOPSTATECKL              BIT(0)
 303
 304/* PHY Data Lane Monitor */
 305#define PHDLM_REG                       0x7c
 306
 307/* CSI0CLK Frequency Configuration Preset Register */
 308#define CSI0CLKFCPR_REG                 0x260
 309#define CSI0CLKFREQRANGE(n)             ((n & 0x3f) << 16)
 310
 311struct rcar_csi2_format {
 312        u32 code;
 313        unsigned int datatype;
 314        unsigned int bpp;
 315};
 316
 317static const struct rcar_csi2_format rcar_csi2_formats[] = {
 318        { .code = MEDIA_BUS_FMT_RGB888_1X24,    .datatype = 0x24, .bpp = 24 },
 319        { .code = MEDIA_BUS_FMT_UYVY8_1X16,     .datatype = 0x1e, .bpp = 16 },
 320        { .code = MEDIA_BUS_FMT_YUYV8_1X16,     .datatype = 0x1e, .bpp = 16 },
 321        { .code = MEDIA_BUS_FMT_UYVY8_2X8,      .datatype = 0x1e, .bpp = 16 },
 322        { .code = MEDIA_BUS_FMT_YUYV10_2X10,    .datatype = 0x1e, .bpp = 20 },
 323};
 324
 325static const struct rcar_csi2_format *rcsi2_code_to_fmt(unsigned int code)
 326{
 327        unsigned int i;
 328
 329        for (i = 0; i < ARRAY_SIZE(rcar_csi2_formats); i++)
 330                if (rcar_csi2_formats[i].code == code)
 331                        return &rcar_csi2_formats[i];
 332
 333        return NULL;
 334}
 335
 336enum rcar_csi2_pads {
 337        RCAR_CSI2_SINK,
 338        RCAR_CSI2_SOURCE_VC0,
 339        RCAR_CSI2_SOURCE_VC1,
 340        RCAR_CSI2_SOURCE_VC2,
 341        RCAR_CSI2_SOURCE_VC3,
 342        NR_OF_RCAR_CSI2_PAD,
 343};
 344
 345struct rcar_csi2_info {
 346        int (*init_phtw)(struct rcar_csi2 *priv, unsigned int mbps);
 347        int (*confirm_start)(struct rcar_csi2 *priv);
 348        const struct rcsi2_mbps_reg *hsfreqrange;
 349        unsigned int csi0clkfreqrange;
 350        unsigned int num_channels;
 351        bool clear_ulps;
 352};
 353
 354struct rcar_csi2 {
 355        struct device *dev;
 356        void __iomem *base;
 357        const struct rcar_csi2_info *info;
 358        struct reset_control *rstc;
 359
 360        struct v4l2_subdev subdev;
 361        struct media_pad pads[NR_OF_RCAR_CSI2_PAD];
 362
 363        struct v4l2_async_notifier notifier;
 364        struct v4l2_async_subdev asd;
 365        struct v4l2_subdev *remote;
 366
 367        struct v4l2_mbus_framefmt mf;
 368
 369        struct mutex lock;
 370        int stream_count;
 371
 372        unsigned short lanes;
 373        unsigned char lane_swap[4];
 374};
 375
 376static inline struct rcar_csi2 *sd_to_csi2(struct v4l2_subdev *sd)
 377{
 378        return container_of(sd, struct rcar_csi2, subdev);
 379}
 380
 381static inline struct rcar_csi2 *notifier_to_csi2(struct v4l2_async_notifier *n)
 382{
 383        return container_of(n, struct rcar_csi2, notifier);
 384}
 385
 386static u32 rcsi2_read(struct rcar_csi2 *priv, unsigned int reg)
 387{
 388        return ioread32(priv->base + reg);
 389}
 390
 391static void rcsi2_write(struct rcar_csi2 *priv, unsigned int reg, u32 data)
 392{
 393        iowrite32(data, priv->base + reg);
 394}
 395
 396static void rcsi2_enter_standby(struct rcar_csi2 *priv)
 397{
 398        rcsi2_write(priv, PHYCNT_REG, 0);
 399        rcsi2_write(priv, PHTC_REG, PHTC_TESTCLR);
 400        reset_control_assert(priv->rstc);
 401        usleep_range(100, 150);
 402        pm_runtime_put(priv->dev);
 403}
 404
 405static void rcsi2_exit_standby(struct rcar_csi2 *priv)
 406{
 407        pm_runtime_get_sync(priv->dev);
 408        reset_control_deassert(priv->rstc);
 409}
 410
 411static int rcsi2_wait_phy_start(struct rcar_csi2 *priv)
 412{
 413        unsigned int timeout;
 414
 415        /* Wait for the clock and data lanes to enter LP-11 state. */
 416        for (timeout = 0; timeout <= 20; timeout++) {
 417                const u32 lane_mask = (1 << priv->lanes) - 1;
 418
 419                if ((rcsi2_read(priv, PHCLM_REG) & PHCLM_STOPSTATECKL)  &&
 420                    (rcsi2_read(priv, PHDLM_REG) & lane_mask) == lane_mask)
 421                        return 0;
 422
 423                usleep_range(1000, 2000);
 424        }
 425
 426        dev_err(priv->dev, "Timeout waiting for LP-11 state\n");
 427
 428        return -ETIMEDOUT;
 429}
 430
 431static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps)
 432{
 433        const struct rcsi2_mbps_reg *hsfreq;
 434
 435        for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++)
 436                if (hsfreq->mbps >= mbps)
 437                        break;
 438
 439        if (!hsfreq->mbps) {
 440                dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps);
 441                return -ERANGE;
 442        }
 443
 444        rcsi2_write(priv, PHYPLL_REG, PHYPLL_HSFREQRANGE(hsfreq->reg));
 445
 446        return 0;
 447}
 448
 449static int rcsi2_calc_mbps(struct rcar_csi2 *priv, unsigned int bpp)
 450{
 451        struct v4l2_subdev *source;
 452        struct v4l2_ctrl *ctrl;
 453        u64 mbps;
 454
 455        if (!priv->remote)
 456                return -ENODEV;
 457
 458        source = priv->remote;
 459
 460        /* Read the pixel rate control from remote. */
 461        ctrl = v4l2_ctrl_find(source->ctrl_handler, V4L2_CID_PIXEL_RATE);
 462        if (!ctrl) {
 463                dev_err(priv->dev, "no pixel rate control in subdev %s\n",
 464                        source->name);
 465                return -EINVAL;
 466        }
 467
 468        /*
 469         * Calculate the phypll in mbps.
 470         * link_freq = (pixel_rate * bits_per_sample) / (2 * nr_of_lanes)
 471         * bps = link_freq * 2
 472         */
 473        mbps = v4l2_ctrl_g_ctrl_int64(ctrl) * bpp;
 474        do_div(mbps, priv->lanes * 1000000);
 475
 476        return mbps;
 477}
 478
 479static int rcsi2_start_receiver(struct rcar_csi2 *priv)
 480{
 481        const struct rcar_csi2_format *format;
 482        u32 phycnt, vcdt = 0, vcdt2 = 0, fld = 0;
 483        unsigned int i;
 484        int mbps, ret;
 485
 486        dev_dbg(priv->dev, "Input size (%ux%u%c)\n",
 487                priv->mf.width, priv->mf.height,
 488                priv->mf.field == V4L2_FIELD_NONE ? 'p' : 'i');
 489
 490        /* Code is validated in set_fmt. */
 491        format = rcsi2_code_to_fmt(priv->mf.code);
 492
 493        /*
 494         * Enable all supported CSI-2 channels with virtual channel and
 495         * data type matching.
 496         *
 497         * NOTE: It's not possible to get individual datatype for each
 498         *       source virtual channel. Once this is possible in V4L2
 499         *       it should be used here.
 500         */
 501        for (i = 0; i < priv->info->num_channels; i++) {
 502                u32 vcdt_part;
 503
 504                vcdt_part = VCDT_SEL_VC(i) | VCDT_VCDTN_EN | VCDT_SEL_DTN_ON |
 505                        VCDT_SEL_DT(format->datatype);
 506
 507                /* Store in correct reg and offset. */
 508                if (i < 2)
 509                        vcdt |= vcdt_part << ((i % 2) * 16);
 510                else
 511                        vcdt2 |= vcdt_part << ((i % 2) * 16);
 512        }
 513
 514        if (priv->mf.field == V4L2_FIELD_ALTERNATE) {
 515                fld = FLD_DET_SEL(1) | FLD_FLD_EN4 | FLD_FLD_EN3 | FLD_FLD_EN2
 516                        | FLD_FLD_EN;
 517
 518                if (priv->mf.height == 240)
 519                        fld |= FLD_FLD_NUM(0);
 520                else
 521                        fld |= FLD_FLD_NUM(1);
 522        }
 523
 524        phycnt = PHYCNT_ENABLECLK;
 525        phycnt |= (1 << priv->lanes) - 1;
 526
 527        mbps = rcsi2_calc_mbps(priv, format->bpp);
 528        if (mbps < 0)
 529                return mbps;
 530
 531        /* Enable interrupts. */
 532        rcsi2_write(priv, INTEN_REG, INTEN_INT_AFIFO_OF | INTEN_INT_ERRSOTHS
 533                    | INTEN_INT_ERRSOTSYNCHS);
 534
 535        /* Init */
 536        rcsi2_write(priv, TREF_REG, TREF_TREF);
 537        rcsi2_write(priv, PHTC_REG, 0);
 538
 539        /* Configure */
 540        rcsi2_write(priv, VCDT_REG, vcdt);
 541        if (vcdt2)
 542                rcsi2_write(priv, VCDT2_REG, vcdt2);
 543        /* Lanes are zero indexed. */
 544        rcsi2_write(priv, LSWAP_REG,
 545                    LSWAP_L0SEL(priv->lane_swap[0] - 1) |
 546                    LSWAP_L1SEL(priv->lane_swap[1] - 1) |
 547                    LSWAP_L2SEL(priv->lane_swap[2] - 1) |
 548                    LSWAP_L3SEL(priv->lane_swap[3] - 1));
 549
 550        /* Start */
 551        if (priv->info->init_phtw) {
 552                ret = priv->info->init_phtw(priv, mbps);
 553                if (ret)
 554                        return ret;
 555        }
 556
 557        if (priv->info->hsfreqrange) {
 558                ret = rcsi2_set_phypll(priv, mbps);
 559                if (ret)
 560                        return ret;
 561        }
 562
 563        if (priv->info->csi0clkfreqrange)
 564                rcsi2_write(priv, CSI0CLKFCPR_REG,
 565                            CSI0CLKFREQRANGE(priv->info->csi0clkfreqrange));
 566
 567        rcsi2_write(priv, PHYCNT_REG, phycnt);
 568        rcsi2_write(priv, LINKCNT_REG, LINKCNT_MONITOR_EN |
 569                    LINKCNT_REG_MONI_PACT_EN | LINKCNT_ICLK_NONSTOP);
 570        rcsi2_write(priv, FLD_REG, fld);
 571        rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ);
 572        rcsi2_write(priv, PHYCNT_REG, phycnt | PHYCNT_SHUTDOWNZ | PHYCNT_RSTZ);
 573
 574        ret = rcsi2_wait_phy_start(priv);
 575        if (ret)
 576                return ret;
 577
 578        /* Confirm start */
 579        if (priv->info->confirm_start) {
 580                ret = priv->info->confirm_start(priv);
 581                if (ret)
 582                        return ret;
 583        }
 584
 585        /* Clear Ultra Low Power interrupt. */
 586        if (priv->info->clear_ulps)
 587                rcsi2_write(priv, INTSTATE_REG,
 588                            INTSTATE_INT_ULPS_START |
 589                            INTSTATE_INT_ULPS_END);
 590        return 0;
 591}
 592
 593static int rcsi2_start(struct rcar_csi2 *priv)
 594{
 595        int ret;
 596
 597        rcsi2_exit_standby(priv);
 598
 599        ret = rcsi2_start_receiver(priv);
 600        if (ret) {
 601                rcsi2_enter_standby(priv);
 602                return ret;
 603        }
 604
 605        ret = v4l2_subdev_call(priv->remote, video, s_stream, 1);
 606        if (ret) {
 607                rcsi2_enter_standby(priv);
 608                return ret;
 609        }
 610
 611        return 0;
 612}
 613
 614static void rcsi2_stop(struct rcar_csi2 *priv)
 615{
 616        rcsi2_enter_standby(priv);
 617        v4l2_subdev_call(priv->remote, video, s_stream, 0);
 618}
 619
 620static int rcsi2_s_stream(struct v4l2_subdev *sd, int enable)
 621{
 622        struct rcar_csi2 *priv = sd_to_csi2(sd);
 623        int ret = 0;
 624
 625        mutex_lock(&priv->lock);
 626
 627        if (!priv->remote) {
 628                ret = -ENODEV;
 629                goto out;
 630        }
 631
 632        if (enable && priv->stream_count == 0) {
 633                ret = rcsi2_start(priv);
 634                if (ret)
 635                        goto out;
 636        } else if (!enable && priv->stream_count == 1) {
 637                rcsi2_stop(priv);
 638        }
 639
 640        priv->stream_count += enable ? 1 : -1;
 641out:
 642        mutex_unlock(&priv->lock);
 643
 644        return ret;
 645}
 646
 647static int rcsi2_set_pad_format(struct v4l2_subdev *sd,
 648                                struct v4l2_subdev_pad_config *cfg,
 649                                struct v4l2_subdev_format *format)
 650{
 651        struct rcar_csi2 *priv = sd_to_csi2(sd);
 652        struct v4l2_mbus_framefmt *framefmt;
 653
 654        if (!rcsi2_code_to_fmt(format->format.code))
 655                format->format.code = rcar_csi2_formats[0].code;
 656
 657        if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
 658                priv->mf = format->format;
 659        } else {
 660                framefmt = v4l2_subdev_get_try_format(sd, cfg, 0);
 661                *framefmt = format->format;
 662        }
 663
 664        return 0;
 665}
 666
 667static int rcsi2_get_pad_format(struct v4l2_subdev *sd,
 668                                struct v4l2_subdev_pad_config *cfg,
 669                                struct v4l2_subdev_format *format)
 670{
 671        struct rcar_csi2 *priv = sd_to_csi2(sd);
 672
 673        if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE)
 674                format->format = priv->mf;
 675        else
 676                format->format = *v4l2_subdev_get_try_format(sd, cfg, 0);
 677
 678        return 0;
 679}
 680
 681static const struct v4l2_subdev_video_ops rcar_csi2_video_ops = {
 682        .s_stream = rcsi2_s_stream,
 683};
 684
 685static const struct v4l2_subdev_pad_ops rcar_csi2_pad_ops = {
 686        .set_fmt = rcsi2_set_pad_format,
 687        .get_fmt = rcsi2_get_pad_format,
 688};
 689
 690static const struct v4l2_subdev_ops rcar_csi2_subdev_ops = {
 691        .video  = &rcar_csi2_video_ops,
 692        .pad    = &rcar_csi2_pad_ops,
 693};
 694
 695static irqreturn_t rcsi2_irq(int irq, void *data)
 696{
 697        struct rcar_csi2 *priv = data;
 698        u32 status, err_status;
 699
 700        status = rcsi2_read(priv, INTSTATE_REG);
 701        err_status = rcsi2_read(priv, INTERRSTATE_REG);
 702
 703        if (!status)
 704                return IRQ_HANDLED;
 705
 706        rcsi2_write(priv, INTSTATE_REG, status);
 707
 708        if (!err_status)
 709                return IRQ_HANDLED;
 710
 711        rcsi2_write(priv, INTERRSTATE_REG, err_status);
 712
 713        dev_info(priv->dev, "Transfer error, restarting CSI-2 receiver\n");
 714
 715        return IRQ_WAKE_THREAD;
 716}
 717
 718static irqreturn_t rcsi2_irq_thread(int irq, void *data)
 719{
 720        struct rcar_csi2 *priv = data;
 721
 722        mutex_lock(&priv->lock);
 723        rcsi2_stop(priv);
 724        usleep_range(1000, 2000);
 725        if (rcsi2_start(priv))
 726                dev_warn(priv->dev, "Failed to restart CSI-2 receiver\n");
 727        mutex_unlock(&priv->lock);
 728
 729        return IRQ_HANDLED;
 730}
 731
 732/* -----------------------------------------------------------------------------
 733 * Async handling and registration of subdevices and links.
 734 */
 735
 736static int rcsi2_notify_bound(struct v4l2_async_notifier *notifier,
 737                              struct v4l2_subdev *subdev,
 738                              struct v4l2_async_subdev *asd)
 739{
 740        struct rcar_csi2 *priv = notifier_to_csi2(notifier);
 741        int pad;
 742
 743        pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode,
 744                                          MEDIA_PAD_FL_SOURCE);
 745        if (pad < 0) {
 746                dev_err(priv->dev, "Failed to find pad for %s\n", subdev->name);
 747                return pad;
 748        }
 749
 750        priv->remote = subdev;
 751
 752        dev_dbg(priv->dev, "Bound %s pad: %d\n", subdev->name, pad);
 753
 754        return media_create_pad_link(&subdev->entity, pad,
 755                                     &priv->subdev.entity, 0,
 756                                     MEDIA_LNK_FL_ENABLED |
 757                                     MEDIA_LNK_FL_IMMUTABLE);
 758}
 759
 760static void rcsi2_notify_unbind(struct v4l2_async_notifier *notifier,
 761                                struct v4l2_subdev *subdev,
 762                                struct v4l2_async_subdev *asd)
 763{
 764        struct rcar_csi2 *priv = notifier_to_csi2(notifier);
 765
 766        priv->remote = NULL;
 767
 768        dev_dbg(priv->dev, "Unbind %s\n", subdev->name);
 769}
 770
 771static const struct v4l2_async_notifier_operations rcar_csi2_notify_ops = {
 772        .bound = rcsi2_notify_bound,
 773        .unbind = rcsi2_notify_unbind,
 774};
 775
 776static int rcsi2_parse_v4l2(struct rcar_csi2 *priv,
 777                            struct v4l2_fwnode_endpoint *vep)
 778{
 779        unsigned int i;
 780
 781        /* Only port 0 endpoint 0 is valid. */
 782        if (vep->base.port || vep->base.id)
 783                return -ENOTCONN;
 784
 785        if (vep->bus_type != V4L2_MBUS_CSI2_DPHY) {
 786                dev_err(priv->dev, "Unsupported bus: %u\n", vep->bus_type);
 787                return -EINVAL;
 788        }
 789
 790        priv->lanes = vep->bus.mipi_csi2.num_data_lanes;
 791        if (priv->lanes != 1 && priv->lanes != 2 && priv->lanes != 4) {
 792                dev_err(priv->dev, "Unsupported number of data-lanes: %u\n",
 793                        priv->lanes);
 794                return -EINVAL;
 795        }
 796
 797        for (i = 0; i < ARRAY_SIZE(priv->lane_swap); i++) {
 798                priv->lane_swap[i] = i < priv->lanes ?
 799                        vep->bus.mipi_csi2.data_lanes[i] : i;
 800
 801                /* Check for valid lane number. */
 802                if (priv->lane_swap[i] < 1 || priv->lane_swap[i] > 4) {
 803                        dev_err(priv->dev, "data-lanes must be in 1-4 range\n");
 804                        return -EINVAL;
 805                }
 806        }
 807
 808        return 0;
 809}
 810
 811static int rcsi2_parse_dt(struct rcar_csi2 *priv)
 812{
 813        struct device_node *ep;
 814        struct v4l2_fwnode_endpoint v4l2_ep = { .bus_type = 0 };
 815        int ret;
 816
 817        ep = of_graph_get_endpoint_by_regs(priv->dev->of_node, 0, 0);
 818        if (!ep) {
 819                dev_err(priv->dev, "Not connected to subdevice\n");
 820                return -EINVAL;
 821        }
 822
 823        ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
 824        if (ret) {
 825                dev_err(priv->dev, "Could not parse v4l2 endpoint\n");
 826                of_node_put(ep);
 827                return -EINVAL;
 828        }
 829
 830        ret = rcsi2_parse_v4l2(priv, &v4l2_ep);
 831        if (ret) {
 832                of_node_put(ep);
 833                return ret;
 834        }
 835
 836        priv->asd.match.fwnode =
 837                fwnode_graph_get_remote_endpoint(of_fwnode_handle(ep));
 838        priv->asd.match_type = V4L2_ASYNC_MATCH_FWNODE;
 839
 840        of_node_put(ep);
 841
 842        v4l2_async_notifier_init(&priv->notifier);
 843
 844        ret = v4l2_async_notifier_add_subdev(&priv->notifier, &priv->asd);
 845        if (ret) {
 846                fwnode_handle_put(priv->asd.match.fwnode);
 847                return ret;
 848        }
 849
 850        priv->notifier.ops = &rcar_csi2_notify_ops;
 851
 852        dev_dbg(priv->dev, "Found '%pOF'\n",
 853                to_of_node(priv->asd.match.fwnode));
 854
 855        ret = v4l2_async_subdev_notifier_register(&priv->subdev,
 856                                                  &priv->notifier);
 857        if (ret)
 858                v4l2_async_notifier_cleanup(&priv->notifier);
 859
 860        return ret;
 861}
 862
 863/* -----------------------------------------------------------------------------
 864 * PHTW initialization sequences.
 865 *
 866 * NOTE: Magic values are from the datasheet and lack documentation.
 867 */
 868
 869static int rcsi2_phtw_write(struct rcar_csi2 *priv, u16 data, u16 code)
 870{
 871        unsigned int timeout;
 872
 873        rcsi2_write(priv, PHTW_REG,
 874                    PHTW_DWEN | PHTW_TESTDIN_DATA(data) |
 875                    PHTW_CWEN | PHTW_TESTDIN_CODE(code));
 876
 877        /* Wait for DWEN and CWEN to be cleared by hardware. */
 878        for (timeout = 0; timeout <= 20; timeout++) {
 879                if (!(rcsi2_read(priv, PHTW_REG) & (PHTW_DWEN | PHTW_CWEN)))
 880                        return 0;
 881
 882                usleep_range(1000, 2000);
 883        }
 884
 885        dev_err(priv->dev, "Timeout waiting for PHTW_DWEN and/or PHTW_CWEN\n");
 886
 887        return -ETIMEDOUT;
 888}
 889
 890static int rcsi2_phtw_write_array(struct rcar_csi2 *priv,
 891                                  const struct phtw_value *values)
 892{
 893        const struct phtw_value *value;
 894        int ret;
 895
 896        for (value = values; value->data || value->code; value++) {
 897                ret = rcsi2_phtw_write(priv, value->data, value->code);
 898                if (ret)
 899                        return ret;
 900        }
 901
 902        return 0;
 903}
 904
 905static int rcsi2_phtw_write_mbps(struct rcar_csi2 *priv, unsigned int mbps,
 906                                 const struct rcsi2_mbps_reg *values, u16 code)
 907{
 908        const struct rcsi2_mbps_reg *value;
 909
 910        for (value = values; value->mbps; value++)
 911                if (value->mbps >= mbps)
 912                        break;
 913
 914        if (!value->mbps) {
 915                dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps);
 916                return -ERANGE;
 917        }
 918
 919        return rcsi2_phtw_write(priv, value->reg, code);
 920}
 921
 922static int __rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv,
 923                                        unsigned int mbps)
 924{
 925        static const struct phtw_value step1[] = {
 926                { .data = 0xcc, .code = 0xe2 },
 927                { .data = 0x01, .code = 0xe3 },
 928                { .data = 0x11, .code = 0xe4 },
 929                { .data = 0x01, .code = 0xe5 },
 930                { .data = 0x10, .code = 0x04 },
 931                { /* sentinel */ },
 932        };
 933
 934        static const struct phtw_value step2[] = {
 935                { .data = 0x38, .code = 0x08 },
 936                { .data = 0x01, .code = 0x00 },
 937                { .data = 0x4b, .code = 0xac },
 938                { .data = 0x03, .code = 0x00 },
 939                { .data = 0x80, .code = 0x07 },
 940                { /* sentinel */ },
 941        };
 942
 943        int ret;
 944
 945        ret = rcsi2_phtw_write_array(priv, step1);
 946        if (ret)
 947                return ret;
 948
 949        if (mbps != 0 && mbps <= 250) {
 950                ret = rcsi2_phtw_write(priv, 0x39, 0x05);
 951                if (ret)
 952                        return ret;
 953
 954                ret = rcsi2_phtw_write_mbps(priv, mbps, phtw_mbps_h3_v3h_m3n,
 955                                            0xf1);
 956                if (ret)
 957                        return ret;
 958        }
 959
 960        return rcsi2_phtw_write_array(priv, step2);
 961}
 962
 963static int rcsi2_init_phtw_h3_v3h_m3n(struct rcar_csi2 *priv, unsigned int mbps)
 964{
 965        return __rcsi2_init_phtw_h3_v3h_m3n(priv, mbps);
 966}
 967
 968static int rcsi2_init_phtw_h3es2(struct rcar_csi2 *priv, unsigned int mbps)
 969{
 970        return __rcsi2_init_phtw_h3_v3h_m3n(priv, 0);
 971}
 972
 973static int rcsi2_init_phtw_v3m_e3(struct rcar_csi2 *priv, unsigned int mbps)
 974{
 975        return rcsi2_phtw_write_mbps(priv, mbps, phtw_mbps_v3m_e3, 0x44);
 976}
 977
 978static int rcsi2_confirm_start_v3m_e3(struct rcar_csi2 *priv)
 979{
 980        static const struct phtw_value step1[] = {
 981                { .data = 0xee, .code = 0x34 },
 982                { .data = 0xee, .code = 0x44 },
 983                { .data = 0xee, .code = 0x54 },
 984                { .data = 0xee, .code = 0x84 },
 985                { .data = 0xee, .code = 0x94 },
 986                { /* sentinel */ },
 987        };
 988
 989        return rcsi2_phtw_write_array(priv, step1);
 990}
 991
 992/* -----------------------------------------------------------------------------
 993 * Platform Device Driver.
 994 */
 995
 996static const struct media_entity_operations rcar_csi2_entity_ops = {
 997        .link_validate = v4l2_subdev_link_validate,
 998};
 999
1000static int rcsi2_probe_resources(struct rcar_csi2 *priv,
1001                                 struct platform_device *pdev)
1002{
1003        struct resource *res;
1004        int irq, ret;
1005
1006        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1007        priv->base = devm_ioremap_resource(&pdev->dev, res);
1008        if (IS_ERR(priv->base))
1009                return PTR_ERR(priv->base);
1010
1011        irq = platform_get_irq(pdev, 0);
1012        if (irq < 0)
1013                return irq;
1014
1015        ret = devm_request_threaded_irq(&pdev->dev, irq, rcsi2_irq,
1016                                        rcsi2_irq_thread, IRQF_SHARED,
1017                                        KBUILD_MODNAME, priv);
1018        if (ret)
1019                return ret;
1020
1021        priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
1022
1023        return PTR_ERR_OR_ZERO(priv->rstc);
1024}
1025
1026static const struct rcar_csi2_info rcar_csi2_info_r8a7795 = {
1027        .init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
1028        .hsfreqrange = hsfreqrange_h3_v3h_m3n,
1029        .csi0clkfreqrange = 0x20,
1030        .num_channels = 4,
1031        .clear_ulps = true,
1032};
1033
1034static const struct rcar_csi2_info rcar_csi2_info_r8a7795es1 = {
1035        .hsfreqrange = hsfreqrange_m3w_h3es1,
1036        .num_channels = 4,
1037};
1038
1039static const struct rcar_csi2_info rcar_csi2_info_r8a7795es2 = {
1040        .init_phtw = rcsi2_init_phtw_h3es2,
1041        .hsfreqrange = hsfreqrange_h3_v3h_m3n,
1042        .csi0clkfreqrange = 0x20,
1043        .num_channels = 4,
1044        .clear_ulps = true,
1045};
1046
1047static const struct rcar_csi2_info rcar_csi2_info_r8a7796 = {
1048        .hsfreqrange = hsfreqrange_m3w_h3es1,
1049        .num_channels = 4,
1050};
1051
1052static const struct rcar_csi2_info rcar_csi2_info_r8a77965 = {
1053        .init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
1054        .hsfreqrange = hsfreqrange_h3_v3h_m3n,
1055        .csi0clkfreqrange = 0x20,
1056        .num_channels = 4,
1057        .clear_ulps = true,
1058};
1059
1060static const struct rcar_csi2_info rcar_csi2_info_r8a77970 = {
1061        .init_phtw = rcsi2_init_phtw_v3m_e3,
1062        .confirm_start = rcsi2_confirm_start_v3m_e3,
1063        .num_channels = 4,
1064};
1065
1066static const struct rcar_csi2_info rcar_csi2_info_r8a77980 = {
1067        .init_phtw = rcsi2_init_phtw_h3_v3h_m3n,
1068        .hsfreqrange = hsfreqrange_h3_v3h_m3n,
1069        .csi0clkfreqrange = 0x20,
1070        .clear_ulps = true,
1071};
1072
1073static const struct rcar_csi2_info rcar_csi2_info_r8a77990 = {
1074        .init_phtw = rcsi2_init_phtw_v3m_e3,
1075        .confirm_start = rcsi2_confirm_start_v3m_e3,
1076        .num_channels = 2,
1077};
1078
1079static const struct of_device_id rcar_csi2_of_table[] = {
1080        {
1081                .compatible = "renesas,r8a774a1-csi2",
1082                .data = &rcar_csi2_info_r8a7796,
1083        },
1084        {
1085                .compatible = "renesas,r8a774c0-csi2",
1086                .data = &rcar_csi2_info_r8a77990,
1087        },
1088        {
1089                .compatible = "renesas,r8a7795-csi2",
1090                .data = &rcar_csi2_info_r8a7795,
1091        },
1092        {
1093                .compatible = "renesas,r8a7796-csi2",
1094                .data = &rcar_csi2_info_r8a7796,
1095        },
1096        {
1097                .compatible = "renesas,r8a77965-csi2",
1098                .data = &rcar_csi2_info_r8a77965,
1099        },
1100        {
1101                .compatible = "renesas,r8a77970-csi2",
1102                .data = &rcar_csi2_info_r8a77970,
1103        },
1104        {
1105                .compatible = "renesas,r8a77980-csi2",
1106                .data = &rcar_csi2_info_r8a77980,
1107        },
1108        {
1109                .compatible = "renesas,r8a77990-csi2",
1110                .data = &rcar_csi2_info_r8a77990,
1111        },
1112        { /* sentinel */ },
1113};
1114MODULE_DEVICE_TABLE(of, rcar_csi2_of_table);
1115
1116static const struct soc_device_attribute r8a7795[] = {
1117        {
1118                .soc_id = "r8a7795", .revision = "ES1.*",
1119                .data = &rcar_csi2_info_r8a7795es1,
1120        },
1121        {
1122                .soc_id = "r8a7795", .revision = "ES2.*",
1123                .data = &rcar_csi2_info_r8a7795es2,
1124        },
1125        { /* sentinel */ },
1126};
1127
1128static int rcsi2_probe(struct platform_device *pdev)
1129{
1130        const struct soc_device_attribute *attr;
1131        struct rcar_csi2 *priv;
1132        unsigned int i;
1133        int ret;
1134
1135        priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1136        if (!priv)
1137                return -ENOMEM;
1138
1139        priv->info = of_device_get_match_data(&pdev->dev);
1140
1141        /*
1142         * The different ES versions of r8a7795 (H3) behave differently but
1143         * share the same compatible string.
1144         */
1145        attr = soc_device_match(r8a7795);
1146        if (attr)
1147                priv->info = attr->data;
1148
1149        priv->dev = &pdev->dev;
1150
1151        mutex_init(&priv->lock);
1152        priv->stream_count = 0;
1153
1154        ret = rcsi2_probe_resources(priv, pdev);
1155        if (ret) {
1156                dev_err(priv->dev, "Failed to get resources\n");
1157                return ret;
1158        }
1159
1160        platform_set_drvdata(pdev, priv);
1161
1162        ret = rcsi2_parse_dt(priv);
1163        if (ret)
1164                return ret;
1165
1166        priv->subdev.owner = THIS_MODULE;
1167        priv->subdev.dev = &pdev->dev;
1168        v4l2_subdev_init(&priv->subdev, &rcar_csi2_subdev_ops);
1169        v4l2_set_subdevdata(&priv->subdev, &pdev->dev);
1170        snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s %s",
1171                 KBUILD_MODNAME, dev_name(&pdev->dev));
1172        priv->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
1173
1174        priv->subdev.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
1175        priv->subdev.entity.ops = &rcar_csi2_entity_ops;
1176
1177        priv->pads[RCAR_CSI2_SINK].flags = MEDIA_PAD_FL_SINK;
1178        for (i = RCAR_CSI2_SOURCE_VC0; i < NR_OF_RCAR_CSI2_PAD; i++)
1179                priv->pads[i].flags = MEDIA_PAD_FL_SOURCE;
1180
1181        ret = media_entity_pads_init(&priv->subdev.entity, NR_OF_RCAR_CSI2_PAD,
1182                                     priv->pads);
1183        if (ret)
1184                goto error;
1185
1186        pm_runtime_enable(&pdev->dev);
1187
1188        ret = v4l2_async_register_subdev(&priv->subdev);
1189        if (ret < 0)
1190                goto error;
1191
1192        dev_info(priv->dev, "%d lanes found\n", priv->lanes);
1193
1194        return 0;
1195
1196error:
1197        v4l2_async_notifier_unregister(&priv->notifier);
1198        v4l2_async_notifier_cleanup(&priv->notifier);
1199
1200        return ret;
1201}
1202
1203static int rcsi2_remove(struct platform_device *pdev)
1204{
1205        struct rcar_csi2 *priv = platform_get_drvdata(pdev);
1206
1207        v4l2_async_notifier_unregister(&priv->notifier);
1208        v4l2_async_notifier_cleanup(&priv->notifier);
1209        v4l2_async_unregister_subdev(&priv->subdev);
1210
1211        pm_runtime_disable(&pdev->dev);
1212
1213        return 0;
1214}
1215
1216static struct platform_driver rcar_csi2_pdrv = {
1217        .remove = rcsi2_remove,
1218        .probe  = rcsi2_probe,
1219        .driver = {
1220                .name   = "rcar-csi2",
1221                .of_match_table = rcar_csi2_of_table,
1222        },
1223};
1224
1225module_platform_driver(rcar_csi2_pdrv);
1226
1227MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>");
1228MODULE_DESCRIPTION("Renesas R-Car MIPI CSI-2 receiver driver");
1229MODULE_LICENSE("GPL");
1230