linux/drivers/media/i2c/imx355.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (C) 2018 Intel Corporation
   3
   4#include <asm/unaligned.h>
   5#include <linux/acpi.h>
   6#include <linux/i2c.h>
   7#include <linux/module.h>
   8#include <linux/pm_runtime.h>
   9#include <media/v4l2-ctrls.h>
  10#include <media/v4l2-device.h>
  11#include <media/v4l2-event.h>
  12#include <media/v4l2-fwnode.h>
  13
  14#define IMX355_REG_MODE_SELECT          0x0100
  15#define IMX355_MODE_STANDBY             0x00
  16#define IMX355_MODE_STREAMING           0x01
  17
  18/* Chip ID */
  19#define IMX355_REG_CHIP_ID              0x0016
  20#define IMX355_CHIP_ID                  0x0355
  21
  22/* V_TIMING internal */
  23#define IMX355_REG_FLL                  0x0340
  24#define IMX355_FLL_MAX                  0xffff
  25
  26/* Exposure control */
  27#define IMX355_REG_EXPOSURE             0x0202
  28#define IMX355_EXPOSURE_MIN             1
  29#define IMX355_EXPOSURE_STEP            1
  30#define IMX355_EXPOSURE_DEFAULT         0x0282
  31
  32/* Analog gain control */
  33#define IMX355_REG_ANALOG_GAIN          0x0204
  34#define IMX355_ANA_GAIN_MIN             0
  35#define IMX355_ANA_GAIN_MAX             960
  36#define IMX355_ANA_GAIN_STEP            1
  37#define IMX355_ANA_GAIN_DEFAULT         0
  38
  39/* Digital gain control */
  40#define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070
  41#define IMX355_REG_DIG_GAIN_GLOBAL      0x020e
  42#define IMX355_DGTL_GAIN_MIN            256
  43#define IMX355_DGTL_GAIN_MAX            4095
  44#define IMX355_DGTL_GAIN_STEP           1
  45#define IMX355_DGTL_GAIN_DEFAULT        256
  46
  47/* Test Pattern Control */
  48#define IMX355_REG_TEST_PATTERN         0x0600
  49#define IMX355_TEST_PATTERN_DISABLED            0
  50#define IMX355_TEST_PATTERN_SOLID_COLOR         1
  51#define IMX355_TEST_PATTERN_COLOR_BARS          2
  52#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS     3
  53#define IMX355_TEST_PATTERN_PN9                 4
  54
  55/* Flip Control */
  56#define IMX355_REG_ORIENTATION          0x0101
  57
  58/* default link frequency and external clock */
  59#define IMX355_LINK_FREQ_DEFAULT        360000000
  60#define IMX355_EXT_CLK                  19200000
  61#define IMX355_LINK_FREQ_INDEX          0
  62
  63struct imx355_reg {
  64        u16 address;
  65        u8 val;
  66};
  67
  68struct imx355_reg_list {
  69        u32 num_of_regs;
  70        const struct imx355_reg *regs;
  71};
  72
  73/* Mode : resolution and related config&values */
  74struct imx355_mode {
  75        /* Frame width */
  76        u32 width;
  77        /* Frame height */
  78        u32 height;
  79
  80        /* V-timing */
  81        u32 fll_def;
  82        u32 fll_min;
  83
  84        /* H-timing */
  85        u32 llp;
  86
  87        /* index of link frequency */
  88        u32 link_freq_index;
  89
  90        /* Default register values */
  91        struct imx355_reg_list reg_list;
  92};
  93
  94struct imx355_hwcfg {
  95        u32 ext_clk;                    /* sensor external clk */
  96        s64 *link_freqs;                /* CSI-2 link frequencies */
  97        unsigned int nr_of_link_freqs;
  98};
  99
 100struct imx355 {
 101        struct v4l2_subdev sd;
 102        struct media_pad pad;
 103
 104        struct v4l2_ctrl_handler ctrl_handler;
 105        /* V4L2 Controls */
 106        struct v4l2_ctrl *link_freq;
 107        struct v4l2_ctrl *pixel_rate;
 108        struct v4l2_ctrl *vblank;
 109        struct v4l2_ctrl *hblank;
 110        struct v4l2_ctrl *exposure;
 111        struct v4l2_ctrl *vflip;
 112        struct v4l2_ctrl *hflip;
 113
 114        /* Current mode */
 115        const struct imx355_mode *cur_mode;
 116
 117        struct imx355_hwcfg *hwcfg;
 118        s64 link_def_freq;      /* CSI-2 link default frequency */
 119
 120        /*
 121         * Mutex for serialized access:
 122         * Protect sensor set pad format and start/stop streaming safely.
 123         * Protect access to sensor v4l2 controls.
 124         */
 125        struct mutex mutex;
 126
 127        /* Streaming on/off */
 128        bool streaming;
 129};
 130
 131static const struct imx355_reg imx355_global_regs[] = {
 132        { 0x0136, 0x13 },
 133        { 0x0137, 0x33 },
 134        { 0x304e, 0x03 },
 135        { 0x4348, 0x16 },
 136        { 0x4350, 0x19 },
 137        { 0x4408, 0x0a },
 138        { 0x440c, 0x0b },
 139        { 0x4411, 0x5f },
 140        { 0x4412, 0x2c },
 141        { 0x4623, 0x00 },
 142        { 0x462c, 0x0f },
 143        { 0x462d, 0x00 },
 144        { 0x462e, 0x00 },
 145        { 0x4684, 0x54 },
 146        { 0x480a, 0x07 },
 147        { 0x4908, 0x07 },
 148        { 0x4909, 0x07 },
 149        { 0x490d, 0x0a },
 150        { 0x491e, 0x0f },
 151        { 0x4921, 0x06 },
 152        { 0x4923, 0x28 },
 153        { 0x4924, 0x28 },
 154        { 0x4925, 0x29 },
 155        { 0x4926, 0x29 },
 156        { 0x4927, 0x1f },
 157        { 0x4928, 0x20 },
 158        { 0x4929, 0x20 },
 159        { 0x492a, 0x20 },
 160        { 0x492c, 0x05 },
 161        { 0x492d, 0x06 },
 162        { 0x492e, 0x06 },
 163        { 0x492f, 0x06 },
 164        { 0x4930, 0x03 },
 165        { 0x4931, 0x04 },
 166        { 0x4932, 0x04 },
 167        { 0x4933, 0x05 },
 168        { 0x595e, 0x01 },
 169        { 0x5963, 0x01 },
 170        { 0x3030, 0x01 },
 171        { 0x3031, 0x01 },
 172        { 0x3045, 0x01 },
 173        { 0x4010, 0x00 },
 174        { 0x4011, 0x00 },
 175        { 0x4012, 0x00 },
 176        { 0x4013, 0x01 },
 177        { 0x68a8, 0xfe },
 178        { 0x68a9, 0xff },
 179        { 0x6888, 0x00 },
 180        { 0x6889, 0x00 },
 181        { 0x68b0, 0x00 },
 182        { 0x3058, 0x00 },
 183        { 0x305a, 0x00 },
 184};
 185
 186static const struct imx355_reg_list imx355_global_setting = {
 187        .num_of_regs = ARRAY_SIZE(imx355_global_regs),
 188        .regs = imx355_global_regs,
 189};
 190
 191static const struct imx355_reg mode_3268x2448_regs[] = {
 192        { 0x0112, 0x0a },
 193        { 0x0113, 0x0a },
 194        { 0x0114, 0x03 },
 195        { 0x0342, 0x0e },
 196        { 0x0343, 0x58 },
 197        { 0x0340, 0x0a },
 198        { 0x0341, 0x37 },
 199        { 0x0344, 0x00 },
 200        { 0x0345, 0x08 },
 201        { 0x0346, 0x00 },
 202        { 0x0347, 0x08 },
 203        { 0x0348, 0x0c },
 204        { 0x0349, 0xcb },
 205        { 0x034a, 0x09 },
 206        { 0x034b, 0x97 },
 207        { 0x0220, 0x00 },
 208        { 0x0222, 0x01 },
 209        { 0x0900, 0x00 },
 210        { 0x0901, 0x11 },
 211        { 0x0902, 0x00 },
 212        { 0x034c, 0x0c },
 213        { 0x034d, 0xc4 },
 214        { 0x034e, 0x09 },
 215        { 0x034f, 0x90 },
 216        { 0x0301, 0x05 },
 217        { 0x0303, 0x01 },
 218        { 0x0305, 0x02 },
 219        { 0x0306, 0x00 },
 220        { 0x0307, 0x78 },
 221        { 0x030b, 0x01 },
 222        { 0x030d, 0x02 },
 223        { 0x030e, 0x00 },
 224        { 0x030f, 0x4b },
 225        { 0x0310, 0x00 },
 226        { 0x0700, 0x00 },
 227        { 0x0701, 0x10 },
 228        { 0x0820, 0x0b },
 229        { 0x0821, 0x40 },
 230        { 0x3088, 0x04 },
 231        { 0x6813, 0x02 },
 232        { 0x6835, 0x07 },
 233        { 0x6836, 0x01 },
 234        { 0x6837, 0x04 },
 235        { 0x684d, 0x07 },
 236        { 0x684e, 0x01 },
 237        { 0x684f, 0x04 },
 238};
 239
 240static const struct imx355_reg mode_3264x2448_regs[] = {
 241        { 0x0112, 0x0a },
 242        { 0x0113, 0x0a },
 243        { 0x0114, 0x03 },
 244        { 0x0342, 0x0e },
 245        { 0x0343, 0x58 },
 246        { 0x0340, 0x0a },
 247        { 0x0341, 0x37 },
 248        { 0x0344, 0x00 },
 249        { 0x0345, 0x08 },
 250        { 0x0346, 0x00 },
 251        { 0x0347, 0x08 },
 252        { 0x0348, 0x0c },
 253        { 0x0349, 0xc7 },
 254        { 0x034a, 0x09 },
 255        { 0x034b, 0x97 },
 256        { 0x0220, 0x00 },
 257        { 0x0222, 0x01 },
 258        { 0x0900, 0x00 },
 259        { 0x0901, 0x11 },
 260        { 0x0902, 0x00 },
 261        { 0x034c, 0x0c },
 262        { 0x034d, 0xc0 },
 263        { 0x034e, 0x09 },
 264        { 0x034f, 0x90 },
 265        { 0x0301, 0x05 },
 266        { 0x0303, 0x01 },
 267        { 0x0305, 0x02 },
 268        { 0x0306, 0x00 },
 269        { 0x0307, 0x78 },
 270        { 0x030b, 0x01 },
 271        { 0x030d, 0x02 },
 272        { 0x030e, 0x00 },
 273        { 0x030f, 0x4b },
 274        { 0x0310, 0x00 },
 275        { 0x0700, 0x00 },
 276        { 0x0701, 0x10 },
 277        { 0x0820, 0x0b },
 278        { 0x0821, 0x40 },
 279        { 0x3088, 0x04 },
 280        { 0x6813, 0x02 },
 281        { 0x6835, 0x07 },
 282        { 0x6836, 0x01 },
 283        { 0x6837, 0x04 },
 284        { 0x684d, 0x07 },
 285        { 0x684e, 0x01 },
 286        { 0x684f, 0x04 },
 287};
 288
 289static const struct imx355_reg mode_3280x2464_regs[] = {
 290        { 0x0112, 0x0a },
 291        { 0x0113, 0x0a },
 292        { 0x0114, 0x03 },
 293        { 0x0342, 0x0e },
 294        { 0x0343, 0x58 },
 295        { 0x0340, 0x0a },
 296        { 0x0341, 0x37 },
 297        { 0x0344, 0x00 },
 298        { 0x0345, 0x00 },
 299        { 0x0346, 0x00 },
 300        { 0x0347, 0x00 },
 301        { 0x0348, 0x0c },
 302        { 0x0349, 0xcf },
 303        { 0x034a, 0x09 },
 304        { 0x034b, 0x9f },
 305        { 0x0220, 0x00 },
 306        { 0x0222, 0x01 },
 307        { 0x0900, 0x00 },
 308        { 0x0901, 0x11 },
 309        { 0x0902, 0x00 },
 310        { 0x034c, 0x0c },
 311        { 0x034d, 0xd0 },
 312        { 0x034e, 0x09 },
 313        { 0x034f, 0xa0 },
 314        { 0x0301, 0x05 },
 315        { 0x0303, 0x01 },
 316        { 0x0305, 0x02 },
 317        { 0x0306, 0x00 },
 318        { 0x0307, 0x78 },
 319        { 0x030b, 0x01 },
 320        { 0x030d, 0x02 },
 321        { 0x030e, 0x00 },
 322        { 0x030f, 0x4b },
 323        { 0x0310, 0x00 },
 324        { 0x0700, 0x00 },
 325        { 0x0701, 0x10 },
 326        { 0x0820, 0x0b },
 327        { 0x0821, 0x40 },
 328        { 0x3088, 0x04 },
 329        { 0x6813, 0x02 },
 330        { 0x6835, 0x07 },
 331        { 0x6836, 0x01 },
 332        { 0x6837, 0x04 },
 333        { 0x684d, 0x07 },
 334        { 0x684e, 0x01 },
 335        { 0x684f, 0x04 },
 336};
 337
 338static const struct imx355_reg mode_1940x1096_regs[] = {
 339        { 0x0112, 0x0a },
 340        { 0x0113, 0x0a },
 341        { 0x0114, 0x03 },
 342        { 0x0342, 0x0e },
 343        { 0x0343, 0x58 },
 344        { 0x0340, 0x05 },
 345        { 0x0341, 0x1a },
 346        { 0x0344, 0x02 },
 347        { 0x0345, 0xa0 },
 348        { 0x0346, 0x02 },
 349        { 0x0347, 0xac },
 350        { 0x0348, 0x0a },
 351        { 0x0349, 0x33 },
 352        { 0x034a, 0x06 },
 353        { 0x034b, 0xf3 },
 354        { 0x0220, 0x00 },
 355        { 0x0222, 0x01 },
 356        { 0x0900, 0x00 },
 357        { 0x0901, 0x11 },
 358        { 0x0902, 0x00 },
 359        { 0x034c, 0x07 },
 360        { 0x034d, 0x94 },
 361        { 0x034e, 0x04 },
 362        { 0x034f, 0x48 },
 363        { 0x0301, 0x05 },
 364        { 0x0303, 0x01 },
 365        { 0x0305, 0x02 },
 366        { 0x0306, 0x00 },
 367        { 0x0307, 0x78 },
 368        { 0x030b, 0x01 },
 369        { 0x030d, 0x02 },
 370        { 0x030e, 0x00 },
 371        { 0x030f, 0x4b },
 372        { 0x0310, 0x00 },
 373        { 0x0700, 0x00 },
 374        { 0x0701, 0x10 },
 375        { 0x0820, 0x0b },
 376        { 0x0821, 0x40 },
 377        { 0x3088, 0x04 },
 378        { 0x6813, 0x02 },
 379        { 0x6835, 0x07 },
 380        { 0x6836, 0x01 },
 381        { 0x6837, 0x04 },
 382        { 0x684d, 0x07 },
 383        { 0x684e, 0x01 },
 384        { 0x684f, 0x04 },
 385};
 386
 387static const struct imx355_reg mode_1936x1096_regs[] = {
 388        { 0x0112, 0x0a },
 389        { 0x0113, 0x0a },
 390        { 0x0114, 0x03 },
 391        { 0x0342, 0x0e },
 392        { 0x0343, 0x58 },
 393        { 0x0340, 0x05 },
 394        { 0x0341, 0x1a },
 395        { 0x0344, 0x02 },
 396        { 0x0345, 0xa0 },
 397        { 0x0346, 0x02 },
 398        { 0x0347, 0xac },
 399        { 0x0348, 0x0a },
 400        { 0x0349, 0x2f },
 401        { 0x034a, 0x06 },
 402        { 0x034b, 0xf3 },
 403        { 0x0220, 0x00 },
 404        { 0x0222, 0x01 },
 405        { 0x0900, 0x00 },
 406        { 0x0901, 0x11 },
 407        { 0x0902, 0x00 },
 408        { 0x034c, 0x07 },
 409        { 0x034d, 0x90 },
 410        { 0x034e, 0x04 },
 411        { 0x034f, 0x48 },
 412        { 0x0301, 0x05 },
 413        { 0x0303, 0x01 },
 414        { 0x0305, 0x02 },
 415        { 0x0306, 0x00 },
 416        { 0x0307, 0x78 },
 417        { 0x030b, 0x01 },
 418        { 0x030d, 0x02 },
 419        { 0x030e, 0x00 },
 420        { 0x030f, 0x4b },
 421        { 0x0310, 0x00 },
 422        { 0x0700, 0x00 },
 423        { 0x0701, 0x10 },
 424        { 0x0820, 0x0b },
 425        { 0x0821, 0x40 },
 426        { 0x3088, 0x04 },
 427        { 0x6813, 0x02 },
 428        { 0x6835, 0x07 },
 429        { 0x6836, 0x01 },
 430        { 0x6837, 0x04 },
 431        { 0x684d, 0x07 },
 432        { 0x684e, 0x01 },
 433        { 0x684f, 0x04 },
 434};
 435
 436static const struct imx355_reg mode_1924x1080_regs[] = {
 437        { 0x0112, 0x0a },
 438        { 0x0113, 0x0a },
 439        { 0x0114, 0x03 },
 440        { 0x0342, 0x0e },
 441        { 0x0343, 0x58 },
 442        { 0x0340, 0x05 },
 443        { 0x0341, 0x1a },
 444        { 0x0344, 0x02 },
 445        { 0x0345, 0xa8 },
 446        { 0x0346, 0x02 },
 447        { 0x0347, 0xb4 },
 448        { 0x0348, 0x0a },
 449        { 0x0349, 0x2b },
 450        { 0x034a, 0x06 },
 451        { 0x034b, 0xeb },
 452        { 0x0220, 0x00 },
 453        { 0x0222, 0x01 },
 454        { 0x0900, 0x00 },
 455        { 0x0901, 0x11 },
 456        { 0x0902, 0x00 },
 457        { 0x034c, 0x07 },
 458        { 0x034d, 0x84 },
 459        { 0x034e, 0x04 },
 460        { 0x034f, 0x38 },
 461        { 0x0301, 0x05 },
 462        { 0x0303, 0x01 },
 463        { 0x0305, 0x02 },
 464        { 0x0306, 0x00 },
 465        { 0x0307, 0x78 },
 466        { 0x030b, 0x01 },
 467        { 0x030d, 0x02 },
 468        { 0x030e, 0x00 },
 469        { 0x030f, 0x4b },
 470        { 0x0310, 0x00 },
 471        { 0x0700, 0x00 },
 472        { 0x0701, 0x10 },
 473        { 0x0820, 0x0b },
 474        { 0x0821, 0x40 },
 475        { 0x3088, 0x04 },
 476        { 0x6813, 0x02 },
 477        { 0x6835, 0x07 },
 478        { 0x6836, 0x01 },
 479        { 0x6837, 0x04 },
 480        { 0x684d, 0x07 },
 481        { 0x684e, 0x01 },
 482        { 0x684f, 0x04 },
 483};
 484
 485static const struct imx355_reg mode_1920x1080_regs[] = {
 486        { 0x0112, 0x0a },
 487        { 0x0113, 0x0a },
 488        { 0x0114, 0x03 },
 489        { 0x0342, 0x0e },
 490        { 0x0343, 0x58 },
 491        { 0x0340, 0x05 },
 492        { 0x0341, 0x1a },
 493        { 0x0344, 0x02 },
 494        { 0x0345, 0xa8 },
 495        { 0x0346, 0x02 },
 496        { 0x0347, 0xb4 },
 497        { 0x0348, 0x0a },
 498        { 0x0349, 0x27 },
 499        { 0x034a, 0x06 },
 500        { 0x034b, 0xeb },
 501        { 0x0220, 0x00 },
 502        { 0x0222, 0x01 },
 503        { 0x0900, 0x00 },
 504        { 0x0901, 0x11 },
 505        { 0x0902, 0x00 },
 506        { 0x034c, 0x07 },
 507        { 0x034d, 0x80 },
 508        { 0x034e, 0x04 },
 509        { 0x034f, 0x38 },
 510        { 0x0301, 0x05 },
 511        { 0x0303, 0x01 },
 512        { 0x0305, 0x02 },
 513        { 0x0306, 0x00 },
 514        { 0x0307, 0x78 },
 515        { 0x030b, 0x01 },
 516        { 0x030d, 0x02 },
 517        { 0x030e, 0x00 },
 518        { 0x030f, 0x4b },
 519        { 0x0310, 0x00 },
 520        { 0x0700, 0x00 },
 521        { 0x0701, 0x10 },
 522        { 0x0820, 0x0b },
 523        { 0x0821, 0x40 },
 524        { 0x3088, 0x04 },
 525        { 0x6813, 0x02 },
 526        { 0x6835, 0x07 },
 527        { 0x6836, 0x01 },
 528        { 0x6837, 0x04 },
 529        { 0x684d, 0x07 },
 530        { 0x684e, 0x01 },
 531        { 0x684f, 0x04 },
 532};
 533
 534static const struct imx355_reg mode_1640x1232_regs[] = {
 535        { 0x0112, 0x0a },
 536        { 0x0113, 0x0a },
 537        { 0x0114, 0x03 },
 538        { 0x0342, 0x07 },
 539        { 0x0343, 0x2c },
 540        { 0x0340, 0x05 },
 541        { 0x0341, 0x1a },
 542        { 0x0344, 0x00 },
 543        { 0x0345, 0x00 },
 544        { 0x0346, 0x00 },
 545        { 0x0347, 0x00 },
 546        { 0x0348, 0x0c },
 547        { 0x0349, 0xcf },
 548        { 0x034a, 0x09 },
 549        { 0x034b, 0x9f },
 550        { 0x0220, 0x00 },
 551        { 0x0222, 0x01 },
 552        { 0x0900, 0x01 },
 553        { 0x0901, 0x22 },
 554        { 0x0902, 0x00 },
 555        { 0x034c, 0x06 },
 556        { 0x034d, 0x68 },
 557        { 0x034e, 0x04 },
 558        { 0x034f, 0xd0 },
 559        { 0x0301, 0x05 },
 560        { 0x0303, 0x01 },
 561        { 0x0305, 0x02 },
 562        { 0x0306, 0x00 },
 563        { 0x0307, 0x78 },
 564        { 0x030b, 0x01 },
 565        { 0x030d, 0x02 },
 566        { 0x030e, 0x00 },
 567        { 0x030f, 0x4b },
 568        { 0x0310, 0x00 },
 569        { 0x0700, 0x00 },
 570        { 0x0701, 0x10 },
 571        { 0x0820, 0x0b },
 572        { 0x0821, 0x40 },
 573        { 0x3088, 0x04 },
 574        { 0x6813, 0x02 },
 575        { 0x6835, 0x07 },
 576        { 0x6836, 0x01 },
 577        { 0x6837, 0x04 },
 578        { 0x684d, 0x07 },
 579        { 0x684e, 0x01 },
 580        { 0x684f, 0x04 },
 581};
 582
 583static const struct imx355_reg mode_1640x922_regs[] = {
 584        { 0x0112, 0x0a },
 585        { 0x0113, 0x0a },
 586        { 0x0114, 0x03 },
 587        { 0x0342, 0x07 },
 588        { 0x0343, 0x2c },
 589        { 0x0340, 0x05 },
 590        { 0x0341, 0x1a },
 591        { 0x0344, 0x00 },
 592        { 0x0345, 0x00 },
 593        { 0x0346, 0x01 },
 594        { 0x0347, 0x30 },
 595        { 0x0348, 0x0c },
 596        { 0x0349, 0xcf },
 597        { 0x034a, 0x08 },
 598        { 0x034b, 0x63 },
 599        { 0x0220, 0x00 },
 600        { 0x0222, 0x01 },
 601        { 0x0900, 0x01 },
 602        { 0x0901, 0x22 },
 603        { 0x0902, 0x00 },
 604        { 0x034c, 0x06 },
 605        { 0x034d, 0x68 },
 606        { 0x034e, 0x03 },
 607        { 0x034f, 0x9a },
 608        { 0x0301, 0x05 },
 609        { 0x0303, 0x01 },
 610        { 0x0305, 0x02 },
 611        { 0x0306, 0x00 },
 612        { 0x0307, 0x78 },
 613        { 0x030b, 0x01 },
 614        { 0x030d, 0x02 },
 615        { 0x030e, 0x00 },
 616        { 0x030f, 0x4b },
 617        { 0x0310, 0x00 },
 618        { 0x0700, 0x00 },
 619        { 0x0701, 0x10 },
 620        { 0x0820, 0x0b },
 621        { 0x0821, 0x40 },
 622        { 0x3088, 0x04 },
 623        { 0x6813, 0x02 },
 624        { 0x6835, 0x07 },
 625        { 0x6836, 0x01 },
 626        { 0x6837, 0x04 },
 627        { 0x684d, 0x07 },
 628        { 0x684e, 0x01 },
 629        { 0x684f, 0x04 },
 630};
 631
 632static const struct imx355_reg mode_1300x736_regs[] = {
 633        { 0x0112, 0x0a },
 634        { 0x0113, 0x0a },
 635        { 0x0114, 0x03 },
 636        { 0x0342, 0x07 },
 637        { 0x0343, 0x2c },
 638        { 0x0340, 0x05 },
 639        { 0x0341, 0x1a },
 640        { 0x0344, 0x01 },
 641        { 0x0345, 0x58 },
 642        { 0x0346, 0x01 },
 643        { 0x0347, 0xf0 },
 644        { 0x0348, 0x0b },
 645        { 0x0349, 0x7f },
 646        { 0x034a, 0x07 },
 647        { 0x034b, 0xaf },
 648        { 0x0220, 0x00 },
 649        { 0x0222, 0x01 },
 650        { 0x0900, 0x01 },
 651        { 0x0901, 0x22 },
 652        { 0x0902, 0x00 },
 653        { 0x034c, 0x05 },
 654        { 0x034d, 0x14 },
 655        { 0x034e, 0x02 },
 656        { 0x034f, 0xe0 },
 657        { 0x0301, 0x05 },
 658        { 0x0303, 0x01 },
 659        { 0x0305, 0x02 },
 660        { 0x0306, 0x00 },
 661        { 0x0307, 0x78 },
 662        { 0x030b, 0x01 },
 663        { 0x030d, 0x02 },
 664        { 0x030e, 0x00 },
 665        { 0x030f, 0x4b },
 666        { 0x0310, 0x00 },
 667        { 0x0700, 0x00 },
 668        { 0x0701, 0x10 },
 669        { 0x0820, 0x0b },
 670        { 0x0821, 0x40 },
 671        { 0x3088, 0x04 },
 672        { 0x6813, 0x02 },
 673        { 0x6835, 0x07 },
 674        { 0x6836, 0x01 },
 675        { 0x6837, 0x04 },
 676        { 0x684d, 0x07 },
 677        { 0x684e, 0x01 },
 678        { 0x684f, 0x04 },
 679};
 680
 681static const struct imx355_reg mode_1296x736_regs[] = {
 682        { 0x0112, 0x0a },
 683        { 0x0113, 0x0a },
 684        { 0x0114, 0x03 },
 685        { 0x0342, 0x07 },
 686        { 0x0343, 0x2c },
 687        { 0x0340, 0x05 },
 688        { 0x0341, 0x1a },
 689        { 0x0344, 0x01 },
 690        { 0x0345, 0x58 },
 691        { 0x0346, 0x01 },
 692        { 0x0347, 0xf0 },
 693        { 0x0348, 0x0b },
 694        { 0x0349, 0x77 },
 695        { 0x034a, 0x07 },
 696        { 0x034b, 0xaf },
 697        { 0x0220, 0x00 },
 698        { 0x0222, 0x01 },
 699        { 0x0900, 0x01 },
 700        { 0x0901, 0x22 },
 701        { 0x0902, 0x00 },
 702        { 0x034c, 0x05 },
 703        { 0x034d, 0x10 },
 704        { 0x034e, 0x02 },
 705        { 0x034f, 0xe0 },
 706        { 0x0301, 0x05 },
 707        { 0x0303, 0x01 },
 708        { 0x0305, 0x02 },
 709        { 0x0306, 0x00 },
 710        { 0x0307, 0x78 },
 711        { 0x030b, 0x01 },
 712        { 0x030d, 0x02 },
 713        { 0x030e, 0x00 },
 714        { 0x030f, 0x4b },
 715        { 0x0310, 0x00 },
 716        { 0x0700, 0x00 },
 717        { 0x0701, 0x10 },
 718        { 0x0820, 0x0b },
 719        { 0x0821, 0x40 },
 720        { 0x3088, 0x04 },
 721        { 0x6813, 0x02 },
 722        { 0x6835, 0x07 },
 723        { 0x6836, 0x01 },
 724        { 0x6837, 0x04 },
 725        { 0x684d, 0x07 },
 726        { 0x684e, 0x01 },
 727        { 0x684f, 0x04 },
 728};
 729
 730static const struct imx355_reg mode_1284x720_regs[] = {
 731        { 0x0112, 0x0a },
 732        { 0x0113, 0x0a },
 733        { 0x0114, 0x03 },
 734        { 0x0342, 0x07 },
 735        { 0x0343, 0x2c },
 736        { 0x0340, 0x05 },
 737        { 0x0341, 0x1a },
 738        { 0x0344, 0x01 },
 739        { 0x0345, 0x68 },
 740        { 0x0346, 0x02 },
 741        { 0x0347, 0x00 },
 742        { 0x0348, 0x0b },
 743        { 0x0349, 0x6f },
 744        { 0x034a, 0x07 },
 745        { 0x034b, 0x9f },
 746        { 0x0220, 0x00 },
 747        { 0x0222, 0x01 },
 748        { 0x0900, 0x01 },
 749        { 0x0901, 0x22 },
 750        { 0x0902, 0x00 },
 751        { 0x034c, 0x05 },
 752        { 0x034d, 0x04 },
 753        { 0x034e, 0x02 },
 754        { 0x034f, 0xd0 },
 755        { 0x0301, 0x05 },
 756        { 0x0303, 0x01 },
 757        { 0x0305, 0x02 },
 758        { 0x0306, 0x00 },
 759        { 0x0307, 0x78 },
 760        { 0x030b, 0x01 },
 761        { 0x030d, 0x02 },
 762        { 0x030e, 0x00 },
 763        { 0x030f, 0x4b },
 764        { 0x0310, 0x00 },
 765        { 0x0700, 0x00 },
 766        { 0x0701, 0x10 },
 767        { 0x0820, 0x0b },
 768        { 0x0821, 0x40 },
 769        { 0x3088, 0x04 },
 770        { 0x6813, 0x02 },
 771        { 0x6835, 0x07 },
 772        { 0x6836, 0x01 },
 773        { 0x6837, 0x04 },
 774        { 0x684d, 0x07 },
 775        { 0x684e, 0x01 },
 776        { 0x684f, 0x04 },
 777};
 778
 779static const struct imx355_reg mode_1280x720_regs[] = {
 780        { 0x0112, 0x0a },
 781        { 0x0113, 0x0a },
 782        { 0x0114, 0x03 },
 783        { 0x0342, 0x07 },
 784        { 0x0343, 0x2c },
 785        { 0x0340, 0x05 },
 786        { 0x0341, 0x1a },
 787        { 0x0344, 0x01 },
 788        { 0x0345, 0x68 },
 789        { 0x0346, 0x02 },
 790        { 0x0347, 0x00 },
 791        { 0x0348, 0x0b },
 792        { 0x0349, 0x67 },
 793        { 0x034a, 0x07 },
 794        { 0x034b, 0x9f },
 795        { 0x0220, 0x00 },
 796        { 0x0222, 0x01 },
 797        { 0x0900, 0x01 },
 798        { 0x0901, 0x22 },
 799        { 0x0902, 0x00 },
 800        { 0x034c, 0x05 },
 801        { 0x034d, 0x00 },
 802        { 0x034e, 0x02 },
 803        { 0x034f, 0xd0 },
 804        { 0x0301, 0x05 },
 805        { 0x0303, 0x01 },
 806        { 0x0305, 0x02 },
 807        { 0x0306, 0x00 },
 808        { 0x0307, 0x78 },
 809        { 0x030b, 0x01 },
 810        { 0x030d, 0x02 },
 811        { 0x030e, 0x00 },
 812        { 0x030f, 0x4b },
 813        { 0x0310, 0x00 },
 814        { 0x0700, 0x00 },
 815        { 0x0701, 0x10 },
 816        { 0x0820, 0x0b },
 817        { 0x0821, 0x40 },
 818        { 0x3088, 0x04 },
 819        { 0x6813, 0x02 },
 820        { 0x6835, 0x07 },
 821        { 0x6836, 0x01 },
 822        { 0x6837, 0x04 },
 823        { 0x684d, 0x07 },
 824        { 0x684e, 0x01 },
 825        { 0x684f, 0x04 },
 826};
 827
 828static const struct imx355_reg mode_820x616_regs[] = {
 829        { 0x0112, 0x0a },
 830        { 0x0113, 0x0a },
 831        { 0x0114, 0x03 },
 832        { 0x0342, 0x0e },
 833        { 0x0343, 0x58 },
 834        { 0x0340, 0x02 },
 835        { 0x0341, 0x8c },
 836        { 0x0344, 0x00 },
 837        { 0x0345, 0x00 },
 838        { 0x0346, 0x00 },
 839        { 0x0347, 0x00 },
 840        { 0x0348, 0x0c },
 841        { 0x0349, 0xcf },
 842        { 0x034a, 0x09 },
 843        { 0x034b, 0x9f },
 844        { 0x0220, 0x00 },
 845        { 0x0222, 0x01 },
 846        { 0x0900, 0x01 },
 847        { 0x0901, 0x44 },
 848        { 0x0902, 0x00 },
 849        { 0x034c, 0x03 },
 850        { 0x034d, 0x34 },
 851        { 0x034e, 0x02 },
 852        { 0x034f, 0x68 },
 853        { 0x0301, 0x05 },
 854        { 0x0303, 0x01 },
 855        { 0x0305, 0x02 },
 856        { 0x0306, 0x00 },
 857        { 0x0307, 0x78 },
 858        { 0x030b, 0x01 },
 859        { 0x030d, 0x02 },
 860        { 0x030e, 0x00 },
 861        { 0x030f, 0x4b },
 862        { 0x0310, 0x00 },
 863        { 0x0700, 0x02 },
 864        { 0x0701, 0x78 },
 865        { 0x0820, 0x0b },
 866        { 0x0821, 0x40 },
 867        { 0x3088, 0x04 },
 868        { 0x6813, 0x02 },
 869        { 0x6835, 0x07 },
 870        { 0x6836, 0x01 },
 871        { 0x6837, 0x04 },
 872        { 0x684d, 0x07 },
 873        { 0x684e, 0x01 },
 874        { 0x684f, 0x04 },
 875};
 876
 877static const char * const imx355_test_pattern_menu[] = {
 878        "Disabled",
 879        "Solid Colour",
 880        "Eight Vertical Colour Bars",
 881        "Colour Bars With Fade to Grey",
 882        "Pseudorandom Sequence (PN9)",
 883};
 884
 885/* supported link frequencies */
 886static const s64 link_freq_menu_items[] = {
 887        IMX355_LINK_FREQ_DEFAULT,
 888};
 889
 890/* Mode configs */
 891static const struct imx355_mode supported_modes[] = {
 892        {
 893                .width = 3280,
 894                .height = 2464,
 895                .fll_def = 2615,
 896                .fll_min = 2615,
 897                .llp = 3672,
 898                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 899                .reg_list = {
 900                        .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
 901                        .regs = mode_3280x2464_regs,
 902                },
 903        },
 904        {
 905                .width = 3268,
 906                .height = 2448,
 907                .fll_def = 2615,
 908                .fll_min = 2615,
 909                .llp = 3672,
 910                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 911                .reg_list = {
 912                        .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
 913                        .regs = mode_3268x2448_regs,
 914                },
 915        },
 916        {
 917                .width = 3264,
 918                .height = 2448,
 919                .fll_def = 2615,
 920                .fll_min = 2615,
 921                .llp = 3672,
 922                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 923                .reg_list = {
 924                        .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
 925                        .regs = mode_3264x2448_regs,
 926                },
 927        },
 928        {
 929                .width = 1940,
 930                .height = 1096,
 931                .fll_def = 1306,
 932                .fll_min = 1306,
 933                .llp = 3672,
 934                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 935                .reg_list = {
 936                        .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
 937                        .regs = mode_1940x1096_regs,
 938                },
 939        },
 940        {
 941                .width = 1936,
 942                .height = 1096,
 943                .fll_def = 1306,
 944                .fll_min = 1306,
 945                .llp = 3672,
 946                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 947                .reg_list = {
 948                        .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
 949                        .regs = mode_1936x1096_regs,
 950                },
 951        },
 952        {
 953                .width = 1924,
 954                .height = 1080,
 955                .fll_def = 1306,
 956                .fll_min = 1306,
 957                .llp = 3672,
 958                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 959                .reg_list = {
 960                        .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
 961                        .regs = mode_1924x1080_regs,
 962                },
 963        },
 964        {
 965                .width = 1920,
 966                .height = 1080,
 967                .fll_def = 1306,
 968                .fll_min = 1306,
 969                .llp = 3672,
 970                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 971                .reg_list = {
 972                        .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
 973                        .regs = mode_1920x1080_regs,
 974                },
 975        },
 976        {
 977                .width = 1640,
 978                .height = 1232,
 979                .fll_def = 1306,
 980                .fll_min = 1306,
 981                .llp = 1836,
 982                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 983                .reg_list = {
 984                        .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
 985                        .regs = mode_1640x1232_regs,
 986                },
 987        },
 988        {
 989                .width = 1640,
 990                .height = 922,
 991                .fll_def = 1306,
 992                .fll_min = 1306,
 993                .llp = 1836,
 994                .link_freq_index = IMX355_LINK_FREQ_INDEX,
 995                .reg_list = {
 996                        .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
 997                        .regs = mode_1640x922_regs,
 998                },
 999        },
1000        {
1001                .width = 1300,
1002                .height = 736,
1003                .fll_def = 1306,
1004                .fll_min = 1306,
1005                .llp = 1836,
1006                .link_freq_index = IMX355_LINK_FREQ_INDEX,
1007                .reg_list = {
1008                        .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
1009                        .regs = mode_1300x736_regs,
1010                },
1011        },
1012        {
1013                .width = 1296,
1014                .height = 736,
1015                .fll_def = 1306,
1016                .fll_min = 1306,
1017                .llp = 1836,
1018                .link_freq_index = IMX355_LINK_FREQ_INDEX,
1019                .reg_list = {
1020                        .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
1021                        .regs = mode_1296x736_regs,
1022                },
1023        },
1024        {
1025                .width = 1284,
1026                .height = 720,
1027                .fll_def = 1306,
1028                .fll_min = 1306,
1029                .llp = 1836,
1030                .link_freq_index = IMX355_LINK_FREQ_INDEX,
1031                .reg_list = {
1032                        .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
1033                        .regs = mode_1284x720_regs,
1034                },
1035        },
1036        {
1037                .width = 1280,
1038                .height = 720,
1039                .fll_def = 1306,
1040                .fll_min = 1306,
1041                .llp = 1836,
1042                .link_freq_index = IMX355_LINK_FREQ_INDEX,
1043                .reg_list = {
1044                        .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
1045                        .regs = mode_1280x720_regs,
1046                },
1047        },
1048        {
1049                .width = 820,
1050                .height = 616,
1051                .fll_def = 652,
1052                .fll_min = 652,
1053                .llp = 3672,
1054                .link_freq_index = IMX355_LINK_FREQ_INDEX,
1055                .reg_list = {
1056                        .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
1057                        .regs = mode_820x616_regs,
1058                },
1059        },
1060};
1061
1062static inline struct imx355 *to_imx355(struct v4l2_subdev *_sd)
1063{
1064        return container_of(_sd, struct imx355, sd);
1065}
1066
1067/* Get bayer order based on flip setting. */
1068static u32 imx355_get_format_code(struct imx355 *imx355)
1069{
1070        /*
1071         * Only one bayer order is supported.
1072         * It depends on the flip settings.
1073         */
1074        u32 code;
1075        static const u32 codes[2][2] = {
1076                { MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SGRBG10_1X10, },
1077                { MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SBGGR10_1X10, },
1078        };
1079
1080        lockdep_assert_held(&imx355->mutex);
1081        code = codes[imx355->vflip->val][imx355->hflip->val];
1082
1083        return code;
1084}
1085
1086/* Read registers up to 4 at a time */
1087static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
1088{
1089        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1090        struct i2c_msg msgs[2];
1091        u8 addr_buf[2];
1092        u8 data_buf[4] = { 0 };
1093        int ret;
1094
1095        if (len > 4)
1096                return -EINVAL;
1097
1098        put_unaligned_be16(reg, addr_buf);
1099        /* Write register address */
1100        msgs[0].addr = client->addr;
1101        msgs[0].flags = 0;
1102        msgs[0].len = ARRAY_SIZE(addr_buf);
1103        msgs[0].buf = addr_buf;
1104
1105        /* Read data from register */
1106        msgs[1].addr = client->addr;
1107        msgs[1].flags = I2C_M_RD;
1108        msgs[1].len = len;
1109        msgs[1].buf = &data_buf[4 - len];
1110
1111        ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
1112        if (ret != ARRAY_SIZE(msgs))
1113                return -EIO;
1114
1115        *val = get_unaligned_be32(data_buf);
1116
1117        return 0;
1118}
1119
1120/* Write registers up to 4 at a time */
1121static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
1122{
1123        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1124        u8 buf[6];
1125
1126        if (len > 4)
1127                return -EINVAL;
1128
1129        put_unaligned_be16(reg, buf);
1130        put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
1131        if (i2c_master_send(client, buf, len + 2) != len + 2)
1132                return -EIO;
1133
1134        return 0;
1135}
1136
1137/* Write a list of registers */
1138static int imx355_write_regs(struct imx355 *imx355,
1139                             const struct imx355_reg *regs, u32 len)
1140{
1141        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1142        int ret;
1143        u32 i;
1144
1145        for (i = 0; i < len; i++) {
1146                ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
1147                if (ret) {
1148                        dev_err_ratelimited(&client->dev,
1149                                            "write reg 0x%4.4x return err %d",
1150                                            regs[i].address, ret);
1151
1152                        return ret;
1153                }
1154        }
1155
1156        return 0;
1157}
1158
1159/* Open sub-device */
1160static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1161{
1162        struct imx355 *imx355 = to_imx355(sd);
1163        struct v4l2_mbus_framefmt *try_fmt =
1164                v4l2_subdev_get_try_format(sd, fh->state, 0);
1165
1166        mutex_lock(&imx355->mutex);
1167
1168        /* Initialize try_fmt */
1169        try_fmt->width = imx355->cur_mode->width;
1170        try_fmt->height = imx355->cur_mode->height;
1171        try_fmt->code = imx355_get_format_code(imx355);
1172        try_fmt->field = V4L2_FIELD_NONE;
1173
1174        mutex_unlock(&imx355->mutex);
1175
1176        return 0;
1177}
1178
1179static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
1180{
1181        struct imx355 *imx355 = container_of(ctrl->handler,
1182                                             struct imx355, ctrl_handler);
1183        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1184        s64 max;
1185        int ret;
1186
1187        /* Propagate change of current control to all related controls */
1188        switch (ctrl->id) {
1189        case V4L2_CID_VBLANK:
1190                /* Update max exposure while meeting expected vblanking */
1191                max = imx355->cur_mode->height + ctrl->val - 10;
1192                __v4l2_ctrl_modify_range(imx355->exposure,
1193                                         imx355->exposure->minimum,
1194                                         max, imx355->exposure->step, max);
1195                break;
1196        }
1197
1198        /*
1199         * Applying V4L2 control value only happens
1200         * when power is up for streaming
1201         */
1202        if (!pm_runtime_get_if_in_use(&client->dev))
1203                return 0;
1204
1205        switch (ctrl->id) {
1206        case V4L2_CID_ANALOGUE_GAIN:
1207                /* Analog gain = 1024/(1024 - ctrl->val) times */
1208                ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
1209                                       ctrl->val);
1210                break;
1211        case V4L2_CID_DIGITAL_GAIN:
1212                ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
1213                                       ctrl->val);
1214                break;
1215        case V4L2_CID_EXPOSURE:
1216                ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
1217                                       ctrl->val);
1218                break;
1219        case V4L2_CID_VBLANK:
1220                /* Update FLL that meets expected vertical blanking */
1221                ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
1222                                       imx355->cur_mode->height + ctrl->val);
1223                break;
1224        case V4L2_CID_TEST_PATTERN:
1225                ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
1226                                       2, ctrl->val);
1227                break;
1228        case V4L2_CID_HFLIP:
1229        case V4L2_CID_VFLIP:
1230                ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
1231                                       imx355->hflip->val |
1232                                       imx355->vflip->val << 1);
1233                break;
1234        default:
1235                ret = -EINVAL;
1236                dev_info(&client->dev, "ctrl(id:0x%x,val:0x%x) is not handled",
1237                         ctrl->id, ctrl->val);
1238                break;
1239        }
1240
1241        pm_runtime_put(&client->dev);
1242
1243        return ret;
1244}
1245
1246static const struct v4l2_ctrl_ops imx355_ctrl_ops = {
1247        .s_ctrl = imx355_set_ctrl,
1248};
1249
1250static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
1251                                 struct v4l2_subdev_state *sd_state,
1252                                 struct v4l2_subdev_mbus_code_enum *code)
1253{
1254        struct imx355 *imx355 = to_imx355(sd);
1255
1256        if (code->index > 0)
1257                return -EINVAL;
1258
1259        mutex_lock(&imx355->mutex);
1260        code->code = imx355_get_format_code(imx355);
1261        mutex_unlock(&imx355->mutex);
1262
1263        return 0;
1264}
1265
1266static int imx355_enum_frame_size(struct v4l2_subdev *sd,
1267                                  struct v4l2_subdev_state *sd_state,
1268                                  struct v4l2_subdev_frame_size_enum *fse)
1269{
1270        struct imx355 *imx355 = to_imx355(sd);
1271
1272        if (fse->index >= ARRAY_SIZE(supported_modes))
1273                return -EINVAL;
1274
1275        mutex_lock(&imx355->mutex);
1276        if (fse->code != imx355_get_format_code(imx355)) {
1277                mutex_unlock(&imx355->mutex);
1278                return -EINVAL;
1279        }
1280        mutex_unlock(&imx355->mutex);
1281
1282        fse->min_width = supported_modes[fse->index].width;
1283        fse->max_width = fse->min_width;
1284        fse->min_height = supported_modes[fse->index].height;
1285        fse->max_height = fse->min_height;
1286
1287        return 0;
1288}
1289
1290static void imx355_update_pad_format(struct imx355 *imx355,
1291                                     const struct imx355_mode *mode,
1292                                     struct v4l2_subdev_format *fmt)
1293{
1294        fmt->format.width = mode->width;
1295        fmt->format.height = mode->height;
1296        fmt->format.code = imx355_get_format_code(imx355);
1297        fmt->format.field = V4L2_FIELD_NONE;
1298}
1299
1300static int imx355_do_get_pad_format(struct imx355 *imx355,
1301                                    struct v4l2_subdev_state *sd_state,
1302                                    struct v4l2_subdev_format *fmt)
1303{
1304        struct v4l2_mbus_framefmt *framefmt;
1305        struct v4l2_subdev *sd = &imx355->sd;
1306
1307        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1308                framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
1309                fmt->format = *framefmt;
1310        } else {
1311                imx355_update_pad_format(imx355, imx355->cur_mode, fmt);
1312        }
1313
1314        return 0;
1315}
1316
1317static int imx355_get_pad_format(struct v4l2_subdev *sd,
1318                                 struct v4l2_subdev_state *sd_state,
1319                                 struct v4l2_subdev_format *fmt)
1320{
1321        struct imx355 *imx355 = to_imx355(sd);
1322        int ret;
1323
1324        mutex_lock(&imx355->mutex);
1325        ret = imx355_do_get_pad_format(imx355, sd_state, fmt);
1326        mutex_unlock(&imx355->mutex);
1327
1328        return ret;
1329}
1330
1331static int
1332imx355_set_pad_format(struct v4l2_subdev *sd,
1333                      struct v4l2_subdev_state *sd_state,
1334                      struct v4l2_subdev_format *fmt)
1335{
1336        struct imx355 *imx355 = to_imx355(sd);
1337        const struct imx355_mode *mode;
1338        struct v4l2_mbus_framefmt *framefmt;
1339        s32 vblank_def;
1340        s32 vblank_min;
1341        s64 h_blank;
1342        u64 pixel_rate;
1343        u32 height;
1344
1345        mutex_lock(&imx355->mutex);
1346
1347        /*
1348         * Only one bayer order is supported.
1349         * It depends on the flip settings.
1350         */
1351        fmt->format.code = imx355_get_format_code(imx355);
1352
1353        mode = v4l2_find_nearest_size(supported_modes,
1354                                      ARRAY_SIZE(supported_modes),
1355                                      width, height,
1356                                      fmt->format.width, fmt->format.height);
1357        imx355_update_pad_format(imx355, mode, fmt);
1358        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1359                framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
1360                *framefmt = fmt->format;
1361        } else {
1362                imx355->cur_mode = mode;
1363                pixel_rate = imx355->link_def_freq * 2 * 4;
1364                do_div(pixel_rate, 10);
1365                __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
1366                /* Update limits and set FPS to default */
1367                height = imx355->cur_mode->height;
1368                vblank_def = imx355->cur_mode->fll_def - height;
1369                vblank_min = imx355->cur_mode->fll_min - height;
1370                height = IMX355_FLL_MAX - height;
1371                __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
1372                                         vblank_def);
1373                __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
1374                h_blank = mode->llp - imx355->cur_mode->width;
1375                /*
1376                 * Currently hblank is not changeable.
1377                 * So FPS control is done only by vblank.
1378                 */
1379                __v4l2_ctrl_modify_range(imx355->hblank, h_blank,
1380                                         h_blank, 1, h_blank);
1381        }
1382
1383        mutex_unlock(&imx355->mutex);
1384
1385        return 0;
1386}
1387
1388/* Start streaming */
1389static int imx355_start_streaming(struct imx355 *imx355)
1390{
1391        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1392        const struct imx355_reg_list *reg_list;
1393        int ret;
1394
1395        /* Global Setting */
1396        reg_list = &imx355_global_setting;
1397        ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
1398        if (ret) {
1399                dev_err(&client->dev, "failed to set global settings");
1400                return ret;
1401        }
1402
1403        /* Apply default values of current mode */
1404        reg_list = &imx355->cur_mode->reg_list;
1405        ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
1406        if (ret) {
1407                dev_err(&client->dev, "failed to set mode");
1408                return ret;
1409        }
1410
1411        /* set digital gain control to all color mode */
1412        ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
1413        if (ret)
1414                return ret;
1415
1416        /* Apply customized values from user */
1417        ret =  __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
1418        if (ret)
1419                return ret;
1420
1421        return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
1422                                1, IMX355_MODE_STREAMING);
1423}
1424
1425/* Stop streaming */
1426static int imx355_stop_streaming(struct imx355 *imx355)
1427{
1428        return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
1429                                1, IMX355_MODE_STANDBY);
1430}
1431
1432static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
1433{
1434        struct imx355 *imx355 = to_imx355(sd);
1435        struct i2c_client *client = v4l2_get_subdevdata(sd);
1436        int ret = 0;
1437
1438        mutex_lock(&imx355->mutex);
1439        if (imx355->streaming == enable) {
1440                mutex_unlock(&imx355->mutex);
1441                return 0;
1442        }
1443
1444        if (enable) {
1445                ret = pm_runtime_resume_and_get(&client->dev);
1446                if (ret < 0)
1447                        goto err_unlock;
1448
1449                /*
1450                 * Apply default & customized values
1451                 * and then start streaming.
1452                 */
1453                ret = imx355_start_streaming(imx355);
1454                if (ret)
1455                        goto err_rpm_put;
1456        } else {
1457                imx355_stop_streaming(imx355);
1458                pm_runtime_put(&client->dev);
1459        }
1460
1461        imx355->streaming = enable;
1462
1463        /* vflip and hflip cannot change during streaming */
1464        __v4l2_ctrl_grab(imx355->vflip, enable);
1465        __v4l2_ctrl_grab(imx355->hflip, enable);
1466
1467        mutex_unlock(&imx355->mutex);
1468
1469        return ret;
1470
1471err_rpm_put:
1472        pm_runtime_put(&client->dev);
1473err_unlock:
1474        mutex_unlock(&imx355->mutex);
1475
1476        return ret;
1477}
1478
1479static int __maybe_unused imx355_suspend(struct device *dev)
1480{
1481        struct v4l2_subdev *sd = dev_get_drvdata(dev);
1482        struct imx355 *imx355 = to_imx355(sd);
1483
1484        if (imx355->streaming)
1485                imx355_stop_streaming(imx355);
1486
1487        return 0;
1488}
1489
1490static int __maybe_unused imx355_resume(struct device *dev)
1491{
1492        struct v4l2_subdev *sd = dev_get_drvdata(dev);
1493        struct imx355 *imx355 = to_imx355(sd);
1494        int ret;
1495
1496        if (imx355->streaming) {
1497                ret = imx355_start_streaming(imx355);
1498                if (ret)
1499                        goto error;
1500        }
1501
1502        return 0;
1503
1504error:
1505        imx355_stop_streaming(imx355);
1506        imx355->streaming = 0;
1507        return ret;
1508}
1509
1510/* Verify chip ID */
1511static int imx355_identify_module(struct imx355 *imx355)
1512{
1513        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1514        int ret;
1515        u32 val;
1516
1517        ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
1518        if (ret)
1519                return ret;
1520
1521        if (val != IMX355_CHIP_ID) {
1522                dev_err(&client->dev, "chip id mismatch: %x!=%x",
1523                        IMX355_CHIP_ID, val);
1524                return -EIO;
1525        }
1526        return 0;
1527}
1528
1529static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = {
1530        .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1531        .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1532};
1533
1534static const struct v4l2_subdev_video_ops imx355_video_ops = {
1535        .s_stream = imx355_set_stream,
1536};
1537
1538static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
1539        .enum_mbus_code = imx355_enum_mbus_code,
1540        .get_fmt = imx355_get_pad_format,
1541        .set_fmt = imx355_set_pad_format,
1542        .enum_frame_size = imx355_enum_frame_size,
1543};
1544
1545static const struct v4l2_subdev_ops imx355_subdev_ops = {
1546        .core = &imx355_subdev_core_ops,
1547        .video = &imx355_video_ops,
1548        .pad = &imx355_pad_ops,
1549};
1550
1551static const struct media_entity_operations imx355_subdev_entity_ops = {
1552        .link_validate = v4l2_subdev_link_validate,
1553};
1554
1555static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
1556        .open = imx355_open,
1557};
1558
1559/* Initialize control handlers */
1560static int imx355_init_controls(struct imx355 *imx355)
1561{
1562        struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1563        struct v4l2_ctrl_handler *ctrl_hdlr;
1564        s64 exposure_max;
1565        s64 vblank_def;
1566        s64 vblank_min;
1567        s64 hblank;
1568        u64 pixel_rate;
1569        const struct imx355_mode *mode;
1570        u32 max;
1571        int ret;
1572
1573        ctrl_hdlr = &imx355->ctrl_handler;
1574        ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
1575        if (ret)
1576                return ret;
1577
1578        ctrl_hdlr->lock = &imx355->mutex;
1579        max = ARRAY_SIZE(link_freq_menu_items) - 1;
1580        imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
1581                                                   V4L2_CID_LINK_FREQ, max, 0,
1582                                                   link_freq_menu_items);
1583        if (imx355->link_freq)
1584                imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1585
1586        /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
1587        pixel_rate = imx355->link_def_freq * 2 * 4;
1588        do_div(pixel_rate, 10);
1589        /* By default, PIXEL_RATE is read only */
1590        imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1591                                               V4L2_CID_PIXEL_RATE, pixel_rate,
1592                                               pixel_rate, 1, pixel_rate);
1593
1594        /* Initialize vblank/hblank/exposure parameters based on current mode */
1595        mode = imx355->cur_mode;
1596        vblank_def = mode->fll_def - mode->height;
1597        vblank_min = mode->fll_min - mode->height;
1598        imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1599                                           V4L2_CID_VBLANK, vblank_min,
1600                                           IMX355_FLL_MAX - mode->height,
1601                                           1, vblank_def);
1602
1603        hblank = mode->llp - mode->width;
1604        imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1605                                           V4L2_CID_HBLANK, hblank, hblank,
1606                                           1, hblank);
1607        if (imx355->hblank)
1608                imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1609
1610        /* fll >= exposure time + adjust parameter (default value is 10) */
1611        exposure_max = mode->fll_def - 10;
1612        imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1613                                             V4L2_CID_EXPOSURE,
1614                                             IMX355_EXPOSURE_MIN, exposure_max,
1615                                             IMX355_EXPOSURE_STEP,
1616                                             IMX355_EXPOSURE_DEFAULT);
1617
1618        imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1619                                          V4L2_CID_HFLIP, 0, 1, 1, 0);
1620        imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1621                                          V4L2_CID_VFLIP, 0, 1, 1, 0);
1622
1623        v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1624                          IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX,
1625                          IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT);
1626
1627        /* Digital gain */
1628        v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1629                          IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX,
1630                          IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT);
1631
1632        v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops,
1633                                     V4L2_CID_TEST_PATTERN,
1634                                     ARRAY_SIZE(imx355_test_pattern_menu) - 1,
1635                                     0, 0, imx355_test_pattern_menu);
1636        if (ctrl_hdlr->error) {
1637                ret = ctrl_hdlr->error;
1638                dev_err(&client->dev, "control init failed: %d", ret);
1639                goto error;
1640        }
1641
1642        imx355->sd.ctrl_handler = ctrl_hdlr;
1643
1644        return 0;
1645
1646error:
1647        v4l2_ctrl_handler_free(ctrl_hdlr);
1648
1649        return ret;
1650}
1651
1652static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
1653{
1654        struct imx355_hwcfg *cfg;
1655        struct v4l2_fwnode_endpoint bus_cfg = {
1656                .bus_type = V4L2_MBUS_CSI2_DPHY
1657        };
1658        struct fwnode_handle *ep;
1659        struct fwnode_handle *fwnode = dev_fwnode(dev);
1660        unsigned int i;
1661        int ret;
1662
1663        if (!fwnode)
1664                return NULL;
1665
1666        ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1667        if (!ep)
1668                return NULL;
1669
1670        ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1671        if (ret)
1672                goto out_err;
1673
1674        cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
1675        if (!cfg)
1676                goto out_err;
1677
1678        ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
1679                                       &cfg->ext_clk);
1680        if (ret) {
1681                dev_err(dev, "can't get clock frequency");
1682                goto out_err;
1683        }
1684
1685        dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
1686        if (cfg->ext_clk != IMX355_EXT_CLK) {
1687                dev_err(dev, "external clock %d is not supported",
1688                        cfg->ext_clk);
1689                goto out_err;
1690        }
1691
1692        dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
1693        if (!bus_cfg.nr_of_link_frequencies) {
1694                dev_warn(dev, "no link frequencies defined");
1695                goto out_err;
1696        }
1697
1698        cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
1699        cfg->link_freqs = devm_kcalloc(dev,
1700                                       bus_cfg.nr_of_link_frequencies + 1,
1701                                       sizeof(*cfg->link_freqs), GFP_KERNEL);
1702        if (!cfg->link_freqs)
1703                goto out_err;
1704
1705        for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
1706                cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
1707                dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
1708        }
1709
1710        v4l2_fwnode_endpoint_free(&bus_cfg);
1711        fwnode_handle_put(ep);
1712        return cfg;
1713
1714out_err:
1715        v4l2_fwnode_endpoint_free(&bus_cfg);
1716        fwnode_handle_put(ep);
1717        return NULL;
1718}
1719
1720static int imx355_probe(struct i2c_client *client)
1721{
1722        struct imx355 *imx355;
1723        int ret;
1724        u32 i;
1725
1726        imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
1727        if (!imx355)
1728                return -ENOMEM;
1729
1730        mutex_init(&imx355->mutex);
1731
1732        /* Initialize subdev */
1733        v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
1734
1735        /* Check module identity */
1736        ret = imx355_identify_module(imx355);
1737        if (ret) {
1738                dev_err(&client->dev, "failed to find sensor: %d", ret);
1739                goto error_probe;
1740        }
1741
1742        imx355->hwcfg = imx355_get_hwcfg(&client->dev);
1743        if (!imx355->hwcfg) {
1744                dev_err(&client->dev, "failed to get hwcfg");
1745                ret = -ENODEV;
1746                goto error_probe;
1747        }
1748
1749        imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
1750        for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
1751                if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
1752                        dev_dbg(&client->dev, "link freq index %d matched", i);
1753                        break;
1754                }
1755        }
1756
1757        if (i == imx355->hwcfg->nr_of_link_freqs) {
1758                dev_err(&client->dev, "no link frequency supported");
1759                ret = -EINVAL;
1760                goto error_probe;
1761        }
1762
1763        /* Set default mode to max resolution */
1764        imx355->cur_mode = &supported_modes[0];
1765
1766        ret = imx355_init_controls(imx355);
1767        if (ret) {
1768                dev_err(&client->dev, "failed to init controls: %d", ret);
1769                goto error_probe;
1770        }
1771
1772        /* Initialize subdev */
1773        imx355->sd.internal_ops = &imx355_internal_ops;
1774        imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1775                V4L2_SUBDEV_FL_HAS_EVENTS;
1776        imx355->sd.entity.ops = &imx355_subdev_entity_ops;
1777        imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1778
1779        /* Initialize source pad */
1780        imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
1781        ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
1782        if (ret) {
1783                dev_err(&client->dev, "failed to init entity pads: %d", ret);
1784                goto error_handler_free;
1785        }
1786
1787        ret = v4l2_async_register_subdev_sensor(&imx355->sd);
1788        if (ret < 0)
1789                goto error_media_entity;
1790
1791        /*
1792         * Device is already turned on by i2c-core with ACPI domain PM.
1793         * Enable runtime PM and turn off the device.
1794         */
1795        pm_runtime_set_active(&client->dev);
1796        pm_runtime_enable(&client->dev);
1797        pm_runtime_idle(&client->dev);
1798
1799        return 0;
1800
1801error_media_entity:
1802        media_entity_cleanup(&imx355->sd.entity);
1803
1804error_handler_free:
1805        v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
1806
1807error_probe:
1808        mutex_destroy(&imx355->mutex);
1809
1810        return ret;
1811}
1812
1813static int imx355_remove(struct i2c_client *client)
1814{
1815        struct v4l2_subdev *sd = i2c_get_clientdata(client);
1816        struct imx355 *imx355 = to_imx355(sd);
1817
1818        v4l2_async_unregister_subdev(sd);
1819        media_entity_cleanup(&sd->entity);
1820        v4l2_ctrl_handler_free(sd->ctrl_handler);
1821
1822        pm_runtime_disable(&client->dev);
1823        pm_runtime_set_suspended(&client->dev);
1824
1825        mutex_destroy(&imx355->mutex);
1826
1827        return 0;
1828}
1829
1830static const struct dev_pm_ops imx355_pm_ops = {
1831        SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume)
1832};
1833
1834static const struct acpi_device_id imx355_acpi_ids[] __maybe_unused = {
1835        { "SONY355A" },
1836        { /* sentinel */ }
1837};
1838MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
1839
1840static struct i2c_driver imx355_i2c_driver = {
1841        .driver = {
1842                .name = "imx355",
1843                .pm = &imx355_pm_ops,
1844                .acpi_match_table = ACPI_PTR(imx355_acpi_ids),
1845        },
1846        .probe_new = imx355_probe,
1847        .remove = imx355_remove,
1848};
1849module_i2c_driver(imx355_i2c_driver);
1850
1851MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
1852MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
1853MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
1854MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
1855MODULE_DESCRIPTION("Sony imx355 sensor driver");
1856MODULE_LICENSE("GPL v2");
1857