root/drivers/media/i2c/imx355.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_imx355
  2. imx355_get_format_code
  3. imx355_read_reg
  4. imx355_write_reg
  5. imx355_write_regs
  6. imx355_open
  7. imx355_set_ctrl
  8. imx355_enum_mbus_code
  9. imx355_enum_frame_size
  10. imx355_update_pad_format
  11. imx355_do_get_pad_format
  12. imx355_get_pad_format
  13. imx355_set_pad_format
  14. imx355_start_streaming
  15. imx355_stop_streaming
  16. imx355_set_stream
  17. imx355_suspend
  18. imx355_resume
  19. imx355_identify_module
  20. imx355_init_controls
  21. imx355_get_hwcfg
  22. imx355_probe
  23. imx355_remove

   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 
  63 struct imx355_reg {
  64         u16 address;
  65         u8 val;
  66 };
  67 
  68 struct imx355_reg_list {
  69         u32 num_of_regs;
  70         const struct imx355_reg *regs;
  71 };
  72 
  73 /* Mode : resolution and related config&values */
  74 struct 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 
  94 struct 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 
 100 struct 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 
 131 static 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 
 186 static const struct imx355_reg_list imx355_global_setting = {
 187         .num_of_regs = ARRAY_SIZE(imx355_global_regs),
 188         .regs = imx355_global_regs,
 189 };
 190 
 191 static 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 
 240 static 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 
 289 static 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 
 338 static 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 
 387 static 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 
 436 static 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 
 485 static 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 
 534 static 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 
 583 static 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 
 632 static 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 
 681 static 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 
 730 static 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 
 779 static 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 
 828 static 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 
 877 static 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 */
 886 static const s64 link_freq_menu_items[] = {
 887         IMX355_LINK_FREQ_DEFAULT,
 888 };
 889 
 890 /* Mode configs */
 891 static 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 
1062 static 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. */
1068 static 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 */
1087 static 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 */
1121 static 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 */
1138 static 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 */
1160 static 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->pad, 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 
1179 static 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 
1246 static const struct v4l2_ctrl_ops imx355_ctrl_ops = {
1247         .s_ctrl = imx355_set_ctrl,
1248 };
1249 
1250 static int imx355_enum_mbus_code(struct v4l2_subdev *sd,
1251                                  struct v4l2_subdev_pad_config *cfg,
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 
1266 static int imx355_enum_frame_size(struct v4l2_subdev *sd,
1267                                   struct v4l2_subdev_pad_config *cfg,
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 
1290 static 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 
1300 static int imx355_do_get_pad_format(struct imx355 *imx355,
1301                                     struct v4l2_subdev_pad_config *cfg,
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, cfg, 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 
1317 static int imx355_get_pad_format(struct v4l2_subdev *sd,
1318                                  struct v4l2_subdev_pad_config *cfg,
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, cfg, fmt);
1326         mutex_unlock(&imx355->mutex);
1327 
1328         return ret;
1329 }
1330 
1331 static int
1332 imx355_set_pad_format(struct v4l2_subdev *sd,
1333                       struct v4l2_subdev_pad_config *cfg,
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, cfg, 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 */
1389 static 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 */
1426 static 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 
1432 static 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_get_sync(&client->dev);
1446                 if (ret < 0) {
1447                         pm_runtime_put_noidle(&client->dev);
1448                         goto err_unlock;
1449                 }
1450 
1451                 /*
1452                  * Apply default & customized values
1453                  * and then start streaming.
1454                  */
1455                 ret = imx355_start_streaming(imx355);
1456                 if (ret)
1457                         goto err_rpm_put;
1458         } else {
1459                 imx355_stop_streaming(imx355);
1460                 pm_runtime_put(&client->dev);
1461         }
1462 
1463         imx355->streaming = enable;
1464 
1465         /* vflip and hflip cannot change during streaming */
1466         __v4l2_ctrl_grab(imx355->vflip, enable);
1467         __v4l2_ctrl_grab(imx355->hflip, enable);
1468 
1469         mutex_unlock(&imx355->mutex);
1470 
1471         return ret;
1472 
1473 err_rpm_put:
1474         pm_runtime_put(&client->dev);
1475 err_unlock:
1476         mutex_unlock(&imx355->mutex);
1477 
1478         return ret;
1479 }
1480 
1481 static int __maybe_unused imx355_suspend(struct device *dev)
1482 {
1483         struct i2c_client *client = to_i2c_client(dev);
1484         struct v4l2_subdev *sd = i2c_get_clientdata(client);
1485         struct imx355 *imx355 = to_imx355(sd);
1486 
1487         if (imx355->streaming)
1488                 imx355_stop_streaming(imx355);
1489 
1490         return 0;
1491 }
1492 
1493 static int __maybe_unused imx355_resume(struct device *dev)
1494 {
1495         struct i2c_client *client = to_i2c_client(dev);
1496         struct v4l2_subdev *sd = i2c_get_clientdata(client);
1497         struct imx355 *imx355 = to_imx355(sd);
1498         int ret;
1499 
1500         if (imx355->streaming) {
1501                 ret = imx355_start_streaming(imx355);
1502                 if (ret)
1503                         goto error;
1504         }
1505 
1506         return 0;
1507 
1508 error:
1509         imx355_stop_streaming(imx355);
1510         imx355->streaming = 0;
1511         return ret;
1512 }
1513 
1514 /* Verify chip ID */
1515 static int imx355_identify_module(struct imx355 *imx355)
1516 {
1517         struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1518         int ret;
1519         u32 val;
1520 
1521         ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
1522         if (ret)
1523                 return ret;
1524 
1525         if (val != IMX355_CHIP_ID) {
1526                 dev_err(&client->dev, "chip id mismatch: %x!=%x",
1527                         IMX355_CHIP_ID, val);
1528                 return -EIO;
1529         }
1530         return 0;
1531 }
1532 
1533 static const struct v4l2_subdev_core_ops imx355_subdev_core_ops = {
1534         .subscribe_event = v4l2_ctrl_subdev_subscribe_event,
1535         .unsubscribe_event = v4l2_event_subdev_unsubscribe,
1536 };
1537 
1538 static const struct v4l2_subdev_video_ops imx355_video_ops = {
1539         .s_stream = imx355_set_stream,
1540 };
1541 
1542 static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
1543         .enum_mbus_code = imx355_enum_mbus_code,
1544         .get_fmt = imx355_get_pad_format,
1545         .set_fmt = imx355_set_pad_format,
1546         .enum_frame_size = imx355_enum_frame_size,
1547 };
1548 
1549 static const struct v4l2_subdev_ops imx355_subdev_ops = {
1550         .core = &imx355_subdev_core_ops,
1551         .video = &imx355_video_ops,
1552         .pad = &imx355_pad_ops,
1553 };
1554 
1555 static const struct media_entity_operations imx355_subdev_entity_ops = {
1556         .link_validate = v4l2_subdev_link_validate,
1557 };
1558 
1559 static const struct v4l2_subdev_internal_ops imx355_internal_ops = {
1560         .open = imx355_open,
1561 };
1562 
1563 /* Initialize control handlers */
1564 static int imx355_init_controls(struct imx355 *imx355)
1565 {
1566         struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
1567         struct v4l2_ctrl_handler *ctrl_hdlr;
1568         s64 exposure_max;
1569         s64 vblank_def;
1570         s64 vblank_min;
1571         s64 hblank;
1572         u64 pixel_rate;
1573         const struct imx355_mode *mode;
1574         u32 max;
1575         int ret;
1576 
1577         ctrl_hdlr = &imx355->ctrl_handler;
1578         ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10);
1579         if (ret)
1580                 return ret;
1581 
1582         ctrl_hdlr->lock = &imx355->mutex;
1583         max = ARRAY_SIZE(link_freq_menu_items) - 1;
1584         imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
1585                                                    V4L2_CID_LINK_FREQ, max, 0,
1586                                                    link_freq_menu_items);
1587         if (imx355->link_freq)
1588                 imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1589 
1590         /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
1591         pixel_rate = imx355->link_def_freq * 2 * 4;
1592         do_div(pixel_rate, 10);
1593         /* By default, PIXEL_RATE is read only */
1594         imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1595                                                V4L2_CID_PIXEL_RATE, pixel_rate,
1596                                                pixel_rate, 1, pixel_rate);
1597 
1598         /* Initialize vblank/hblank/exposure parameters based on current mode */
1599         mode = imx355->cur_mode;
1600         vblank_def = mode->fll_def - mode->height;
1601         vblank_min = mode->fll_min - mode->height;
1602         imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1603                                            V4L2_CID_VBLANK, vblank_min,
1604                                            IMX355_FLL_MAX - mode->height,
1605                                            1, vblank_def);
1606 
1607         hblank = mode->llp - mode->width;
1608         imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1609                                            V4L2_CID_HBLANK, hblank, hblank,
1610                                            1, hblank);
1611         if (imx355->hblank)
1612                 imx355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1613 
1614         /* fll >= exposure time + adjust parameter (default value is 10) */
1615         exposure_max = mode->fll_def - 10;
1616         imx355->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1617                                              V4L2_CID_EXPOSURE,
1618                                              IMX355_EXPOSURE_MIN, exposure_max,
1619                                              IMX355_EXPOSURE_STEP,
1620                                              IMX355_EXPOSURE_DEFAULT);
1621 
1622         imx355->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1623                                           V4L2_CID_HFLIP, 0, 1, 1, 0);
1624         imx355->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
1625                                           V4L2_CID_VFLIP, 0, 1, 1, 0);
1626 
1627         v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
1628                           IMX355_ANA_GAIN_MIN, IMX355_ANA_GAIN_MAX,
1629                           IMX355_ANA_GAIN_STEP, IMX355_ANA_GAIN_DEFAULT);
1630 
1631         /* Digital gain */
1632         v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
1633                           IMX355_DGTL_GAIN_MIN, IMX355_DGTL_GAIN_MAX,
1634                           IMX355_DGTL_GAIN_STEP, IMX355_DGTL_GAIN_DEFAULT);
1635 
1636         v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &imx355_ctrl_ops,
1637                                      V4L2_CID_TEST_PATTERN,
1638                                      ARRAY_SIZE(imx355_test_pattern_menu) - 1,
1639                                      0, 0, imx355_test_pattern_menu);
1640         if (ctrl_hdlr->error) {
1641                 ret = ctrl_hdlr->error;
1642                 dev_err(&client->dev, "control init failed: %d", ret);
1643                 goto error;
1644         }
1645 
1646         imx355->sd.ctrl_handler = ctrl_hdlr;
1647 
1648         return 0;
1649 
1650 error:
1651         v4l2_ctrl_handler_free(ctrl_hdlr);
1652 
1653         return ret;
1654 }
1655 
1656 static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
1657 {
1658         struct imx355_hwcfg *cfg;
1659         struct v4l2_fwnode_endpoint bus_cfg = {
1660                 .bus_type = V4L2_MBUS_CSI2_DPHY
1661         };
1662         struct fwnode_handle *ep;
1663         struct fwnode_handle *fwnode = dev_fwnode(dev);
1664         unsigned int i;
1665         int ret;
1666 
1667         if (!fwnode)
1668                 return NULL;
1669 
1670         ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1671         if (!ep)
1672                 return NULL;
1673 
1674         ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1675         if (ret)
1676                 goto out_err;
1677 
1678         cfg = devm_kzalloc(dev, sizeof(*cfg), GFP_KERNEL);
1679         if (!cfg)
1680                 goto out_err;
1681 
1682         ret = fwnode_property_read_u32(dev_fwnode(dev), "clock-frequency",
1683                                        &cfg->ext_clk);
1684         if (ret) {
1685                 dev_err(dev, "can't get clock frequency");
1686                 goto out_err;
1687         }
1688 
1689         dev_dbg(dev, "ext clk: %d", cfg->ext_clk);
1690         if (cfg->ext_clk != IMX355_EXT_CLK) {
1691                 dev_err(dev, "external clock %d is not supported",
1692                         cfg->ext_clk);
1693                 goto out_err;
1694         }
1695 
1696         dev_dbg(dev, "num of link freqs: %d", bus_cfg.nr_of_link_frequencies);
1697         if (!bus_cfg.nr_of_link_frequencies) {
1698                 dev_warn(dev, "no link frequencies defined");
1699                 goto out_err;
1700         }
1701 
1702         cfg->nr_of_link_freqs = bus_cfg.nr_of_link_frequencies;
1703         cfg->link_freqs = devm_kcalloc(dev,
1704                                        bus_cfg.nr_of_link_frequencies + 1,
1705                                        sizeof(*cfg->link_freqs), GFP_KERNEL);
1706         if (!cfg->link_freqs)
1707                 goto out_err;
1708 
1709         for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) {
1710                 cfg->link_freqs[i] = bus_cfg.link_frequencies[i];
1711                 dev_dbg(dev, "link_freq[%d] = %lld", i, cfg->link_freqs[i]);
1712         }
1713 
1714         v4l2_fwnode_endpoint_free(&bus_cfg);
1715         fwnode_handle_put(ep);
1716         return cfg;
1717 
1718 out_err:
1719         v4l2_fwnode_endpoint_free(&bus_cfg);
1720         fwnode_handle_put(ep);
1721         return NULL;
1722 }
1723 
1724 static int imx355_probe(struct i2c_client *client)
1725 {
1726         struct imx355 *imx355;
1727         int ret;
1728         u32 i;
1729 
1730         imx355 = devm_kzalloc(&client->dev, sizeof(*imx355), GFP_KERNEL);
1731         if (!imx355)
1732                 return -ENOMEM;
1733 
1734         mutex_init(&imx355->mutex);
1735 
1736         /* Initialize subdev */
1737         v4l2_i2c_subdev_init(&imx355->sd, client, &imx355_subdev_ops);
1738 
1739         /* Check module identity */
1740         ret = imx355_identify_module(imx355);
1741         if (ret) {
1742                 dev_err(&client->dev, "failed to find sensor: %d", ret);
1743                 goto error_probe;
1744         }
1745 
1746         imx355->hwcfg = imx355_get_hwcfg(&client->dev);
1747         if (!imx355->hwcfg) {
1748                 dev_err(&client->dev, "failed to get hwcfg");
1749                 ret = -ENODEV;
1750                 goto error_probe;
1751         }
1752 
1753         imx355->link_def_freq = link_freq_menu_items[IMX355_LINK_FREQ_INDEX];
1754         for (i = 0; i < imx355->hwcfg->nr_of_link_freqs; i++) {
1755                 if (imx355->hwcfg->link_freqs[i] == imx355->link_def_freq) {
1756                         dev_dbg(&client->dev, "link freq index %d matched", i);
1757                         break;
1758                 }
1759         }
1760 
1761         if (i == imx355->hwcfg->nr_of_link_freqs) {
1762                 dev_err(&client->dev, "no link frequency supported");
1763                 ret = -EINVAL;
1764                 goto error_probe;
1765         }
1766 
1767         /* Set default mode to max resolution */
1768         imx355->cur_mode = &supported_modes[0];
1769 
1770         ret = imx355_init_controls(imx355);
1771         if (ret) {
1772                 dev_err(&client->dev, "failed to init controls: %d", ret);
1773                 goto error_probe;
1774         }
1775 
1776         /* Initialize subdev */
1777         imx355->sd.internal_ops = &imx355_internal_ops;
1778         imx355->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1779                 V4L2_SUBDEV_FL_HAS_EVENTS;
1780         imx355->sd.entity.ops = &imx355_subdev_entity_ops;
1781         imx355->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1782 
1783         /* Initialize source pad */
1784         imx355->pad.flags = MEDIA_PAD_FL_SOURCE;
1785         ret = media_entity_pads_init(&imx355->sd.entity, 1, &imx355->pad);
1786         if (ret) {
1787                 dev_err(&client->dev, "failed to init entity pads: %d", ret);
1788                 goto error_handler_free;
1789         }
1790 
1791         ret = v4l2_async_register_subdev_sensor_common(&imx355->sd);
1792         if (ret < 0)
1793                 goto error_media_entity;
1794 
1795         /*
1796          * Device is already turned on by i2c-core with ACPI domain PM.
1797          * Enable runtime PM and turn off the device.
1798          */
1799         pm_runtime_set_active(&client->dev);
1800         pm_runtime_enable(&client->dev);
1801         pm_runtime_idle(&client->dev);
1802 
1803         return 0;
1804 
1805 error_media_entity:
1806         media_entity_cleanup(&imx355->sd.entity);
1807 
1808 error_handler_free:
1809         v4l2_ctrl_handler_free(imx355->sd.ctrl_handler);
1810 
1811 error_probe:
1812         mutex_destroy(&imx355->mutex);
1813 
1814         return ret;
1815 }
1816 
1817 static int imx355_remove(struct i2c_client *client)
1818 {
1819         struct v4l2_subdev *sd = i2c_get_clientdata(client);
1820         struct imx355 *imx355 = to_imx355(sd);
1821 
1822         v4l2_async_unregister_subdev(sd);
1823         media_entity_cleanup(&sd->entity);
1824         v4l2_ctrl_handler_free(sd->ctrl_handler);
1825 
1826         pm_runtime_disable(&client->dev);
1827         pm_runtime_set_suspended(&client->dev);
1828 
1829         mutex_destroy(&imx355->mutex);
1830 
1831         return 0;
1832 }
1833 
1834 static const struct dev_pm_ops imx355_pm_ops = {
1835         SET_SYSTEM_SLEEP_PM_OPS(imx355_suspend, imx355_resume)
1836 };
1837 
1838 static const struct acpi_device_id imx355_acpi_ids[] = {
1839         { "SONY355A" },
1840         { /* sentinel */ }
1841 };
1842 MODULE_DEVICE_TABLE(acpi, imx355_acpi_ids);
1843 
1844 static struct i2c_driver imx355_i2c_driver = {
1845         .driver = {
1846                 .name = "imx355",
1847                 .pm = &imx355_pm_ops,
1848                 .acpi_match_table = ACPI_PTR(imx355_acpi_ids),
1849         },
1850         .probe_new = imx355_probe,
1851         .remove = imx355_remove,
1852 };
1853 module_i2c_driver(imx355_i2c_driver);
1854 
1855 MODULE_AUTHOR("Qiu, Tianshu <tian.shu.qiu@intel.com>");
1856 MODULE_AUTHOR("Rapolu, Chiranjeevi <chiranjeevi.rapolu@intel.com>");
1857 MODULE_AUTHOR("Bingbu Cao <bingbu.cao@intel.com>");
1858 MODULE_AUTHOR("Yang, Hyungwoo <hyungwoo.yang@intel.com>");
1859 MODULE_DESCRIPTION("Sony imx355 sensor driver");
1860 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */