linux/drivers/media/i2c/hi556.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2// Copyright (c) 2019 Intel Corporation.
   3
   4#include <asm/unaligned.h>
   5#include <linux/acpi.h>
   6#include <linux/delay.h>
   7#include <linux/i2c.h>
   8#include <linux/module.h>
   9#include <linux/pm_runtime.h>
  10#include <media/v4l2-ctrls.h>
  11#include <media/v4l2-device.h>
  12#include <media/v4l2-fwnode.h>
  13
  14#define HI556_REG_VALUE_08BIT           1
  15#define HI556_REG_VALUE_16BIT           2
  16#define HI556_REG_VALUE_24BIT           3
  17
  18#define HI556_LINK_FREQ_437MHZ          437000000ULL
  19#define HI556_MCLK                      19200000
  20#define HI556_DATA_LANES                2
  21#define HI556_RGB_DEPTH                 10
  22
  23#define HI556_REG_CHIP_ID               0x0f16
  24#define HI556_CHIP_ID                   0x0556
  25
  26#define HI556_REG_MODE_SELECT           0x0a00
  27#define HI556_MODE_STANDBY              0x0000
  28#define HI556_MODE_STREAMING            0x0100
  29
  30/* vertical-timings from sensor */
  31#define HI556_REG_FLL                   0x0006
  32#define HI556_FLL_30FPS                 0x0814
  33#define HI556_FLL_30FPS_MIN             0x0814
  34#define HI556_FLL_MAX                   0x7fff
  35
  36/* horizontal-timings from sensor */
  37#define HI556_REG_LLP                   0x0008
  38
  39/* Exposure controls from sensor */
  40#define HI556_REG_EXPOSURE              0x0074
  41#define HI556_EXPOSURE_MIN              6
  42#define HI556_EXPOSURE_MAX_MARGIN       2
  43#define HI556_EXPOSURE_STEP             1
  44
  45/* Analog gain controls from sensor */
  46#define HI556_REG_ANALOG_GAIN           0x0077
  47#define HI556_ANAL_GAIN_MIN             0
  48#define HI556_ANAL_GAIN_MAX             240
  49#define HI556_ANAL_GAIN_STEP            1
  50
  51/* Digital gain controls from sensor */
  52#define HI556_REG_MWB_GR_GAIN           0x0078
  53#define HI556_REG_MWB_GB_GAIN           0x007a
  54#define HI556_REG_MWB_R_GAIN            0x007c
  55#define HI556_REG_MWB_B_GAIN            0x007e
  56#define HI556_DGTL_GAIN_MIN             0
  57#define HI556_DGTL_GAIN_MAX             2048
  58#define HI556_DGTL_GAIN_STEP            1
  59#define HI556_DGTL_GAIN_DEFAULT         256
  60
  61/* Test Pattern Control */
  62#define HI556_REG_ISP                   0X0a05
  63#define HI556_REG_ISP_TPG_EN            0x01
  64#define HI556_REG_TEST_PATTERN          0x0201
  65
  66enum {
  67        HI556_LINK_FREQ_437MHZ_INDEX,
  68};
  69
  70struct hi556_reg {
  71        u16 address;
  72        u16 val;
  73};
  74
  75struct hi556_reg_list {
  76        u32 num_of_regs;
  77        const struct hi556_reg *regs;
  78};
  79
  80struct hi556_link_freq_config {
  81        const struct hi556_reg_list reg_list;
  82};
  83
  84struct hi556_mode {
  85        /* Frame width in pixels */
  86        u32 width;
  87
  88        /* Frame height in pixels */
  89        u32 height;
  90
  91        /* Horizontal timining size */
  92        u32 llp;
  93
  94        /* Default vertical timining size */
  95        u32 fll_def;
  96
  97        /* Min vertical timining size */
  98        u32 fll_min;
  99
 100        /* Link frequency needed for this resolution */
 101        u32 link_freq_index;
 102
 103        /* Sensor register settings for this resolution */
 104        const struct hi556_reg_list reg_list;
 105};
 106
 107#define to_hi556(_sd) container_of(_sd, struct hi556, sd)
 108
 109//SENSOR_INITIALIZATION
 110static const struct hi556_reg mipi_data_rate_874mbps[] = {
 111        {0x0e00, 0x0102},
 112        {0x0e02, 0x0102},
 113        {0x0e0c, 0x0100},
 114        {0x2000, 0x7400},
 115        {0x2002, 0x001c},
 116        {0x2004, 0x0242},
 117        {0x2006, 0x0942},
 118        {0x2008, 0x7007},
 119        {0x200a, 0x0fd9},
 120        {0x200c, 0x0259},
 121        {0x200e, 0x7008},
 122        {0x2010, 0x160e},
 123        {0x2012, 0x0047},
 124        {0x2014, 0x2118},
 125        {0x2016, 0x0041},
 126        {0x2018, 0x00d8},
 127        {0x201a, 0x0145},
 128        {0x201c, 0x0006},
 129        {0x201e, 0x0181},
 130        {0x2020, 0x13cc},
 131        {0x2022, 0x2057},
 132        {0x2024, 0x7001},
 133        {0x2026, 0x0fca},
 134        {0x2028, 0x00cb},
 135        {0x202a, 0x009f},
 136        {0x202c, 0x7002},
 137        {0x202e, 0x13cc},
 138        {0x2030, 0x019b},
 139        {0x2032, 0x014d},
 140        {0x2034, 0x2987},
 141        {0x2036, 0x2766},
 142        {0x2038, 0x0020},
 143        {0x203a, 0x2060},
 144        {0x203c, 0x0e5d},
 145        {0x203e, 0x181d},
 146        {0x2040, 0x2066},
 147        {0x2042, 0x20c4},
 148        {0x2044, 0x5000},
 149        {0x2046, 0x0005},
 150        {0x2048, 0x0000},
 151        {0x204a, 0x01db},
 152        {0x204c, 0x025a},
 153        {0x204e, 0x00c0},
 154        {0x2050, 0x0005},
 155        {0x2052, 0x0006},
 156        {0x2054, 0x0ad9},
 157        {0x2056, 0x0259},
 158        {0x2058, 0x0618},
 159        {0x205a, 0x0258},
 160        {0x205c, 0x2266},
 161        {0x205e, 0x20c8},
 162        {0x2060, 0x2060},
 163        {0x2062, 0x707b},
 164        {0x2064, 0x0fdd},
 165        {0x2066, 0x81b8},
 166        {0x2068, 0x5040},
 167        {0x206a, 0x0020},
 168        {0x206c, 0x5060},
 169        {0x206e, 0x3143},
 170        {0x2070, 0x5081},
 171        {0x2072, 0x025c},
 172        {0x2074, 0x7800},
 173        {0x2076, 0x7400},
 174        {0x2078, 0x001c},
 175        {0x207a, 0x0242},
 176        {0x207c, 0x0942},
 177        {0x207e, 0x0bd9},
 178        {0x2080, 0x0259},
 179        {0x2082, 0x7008},
 180        {0x2084, 0x160e},
 181        {0x2086, 0x0047},
 182        {0x2088, 0x2118},
 183        {0x208a, 0x0041},
 184        {0x208c, 0x00d8},
 185        {0x208e, 0x0145},
 186        {0x2090, 0x0006},
 187        {0x2092, 0x0181},
 188        {0x2094, 0x13cc},
 189        {0x2096, 0x2057},
 190        {0x2098, 0x7001},
 191        {0x209a, 0x0fca},
 192        {0x209c, 0x00cb},
 193        {0x209e, 0x009f},
 194        {0x20a0, 0x7002},
 195        {0x20a2, 0x13cc},
 196        {0x20a4, 0x019b},
 197        {0x20a6, 0x014d},
 198        {0x20a8, 0x2987},
 199        {0x20aa, 0x2766},
 200        {0x20ac, 0x0020},
 201        {0x20ae, 0x2060},
 202        {0x20b0, 0x0e5d},
 203        {0x20b2, 0x181d},
 204        {0x20b4, 0x2066},
 205        {0x20b6, 0x20c4},
 206        {0x20b8, 0x50a0},
 207        {0x20ba, 0x0005},
 208        {0x20bc, 0x0000},
 209        {0x20be, 0x01db},
 210        {0x20c0, 0x025a},
 211        {0x20c2, 0x00c0},
 212        {0x20c4, 0x0005},
 213        {0x20c6, 0x0006},
 214        {0x20c8, 0x0ad9},
 215        {0x20ca, 0x0259},
 216        {0x20cc, 0x0618},
 217        {0x20ce, 0x0258},
 218        {0x20d0, 0x2266},
 219        {0x20d2, 0x20c8},
 220        {0x20d4, 0x2060},
 221        {0x20d6, 0x707b},
 222        {0x20d8, 0x0fdd},
 223        {0x20da, 0x86b8},
 224        {0x20dc, 0x50e0},
 225        {0x20de, 0x0020},
 226        {0x20e0, 0x5100},
 227        {0x20e2, 0x3143},
 228        {0x20e4, 0x5121},
 229        {0x20e6, 0x7800},
 230        {0x20e8, 0x3140},
 231        {0x20ea, 0x01c4},
 232        {0x20ec, 0x01c1},
 233        {0x20ee, 0x01c0},
 234        {0x20f0, 0x01c4},
 235        {0x20f2, 0x2700},
 236        {0x20f4, 0x3d40},
 237        {0x20f6, 0x7800},
 238        {0x20f8, 0xffff},
 239        {0x27fe, 0xe000},
 240        {0x3000, 0x60f8},
 241        {0x3002, 0x187f},
 242        {0x3004, 0x7060},
 243        {0x3006, 0x0114},
 244        {0x3008, 0x60b0},
 245        {0x300a, 0x1473},
 246        {0x300c, 0x0013},
 247        {0x300e, 0x140f},
 248        {0x3010, 0x0040},
 249        {0x3012, 0x100f},
 250        {0x3014, 0x60f8},
 251        {0x3016, 0x187f},
 252        {0x3018, 0x7060},
 253        {0x301a, 0x0114},
 254        {0x301c, 0x60b0},
 255        {0x301e, 0x1473},
 256        {0x3020, 0x0013},
 257        {0x3022, 0x140f},
 258        {0x3024, 0x0040},
 259        {0x3026, 0x000f},
 260
 261        {0x0b00, 0x0000},
 262        {0x0b02, 0x0045},
 263        {0x0b04, 0xb405},
 264        {0x0b06, 0xc403},
 265        {0x0b08, 0x0081},
 266        {0x0b0a, 0x8252},
 267        {0x0b0c, 0xf814},
 268        {0x0b0e, 0xc618},
 269        {0x0b10, 0xa828},
 270        {0x0b12, 0x004c},
 271        {0x0b14, 0x4068},
 272        {0x0b16, 0x0000},
 273        {0x0f30, 0x5b15},
 274        {0x0f32, 0x7067},
 275        {0x0954, 0x0009},
 276        {0x0956, 0x0000},
 277        {0x0958, 0xbb80},
 278        {0x095a, 0x5140},
 279        {0x0c00, 0x1110},
 280        {0x0c02, 0x0011},
 281        {0x0c04, 0x0000},
 282        {0x0c06, 0x0200},
 283        {0x0c10, 0x0040},
 284        {0x0c12, 0x0040},
 285        {0x0c14, 0x0040},
 286        {0x0c16, 0x0040},
 287        {0x0a10, 0x4000},
 288        {0x3068, 0xf800},
 289        {0x306a, 0xf876},
 290        {0x006c, 0x0000},
 291        {0x005e, 0x0200},
 292        {0x000e, 0x0100},
 293        {0x0e0a, 0x0001},
 294        {0x004a, 0x0100},
 295        {0x004c, 0x0000},
 296        {0x004e, 0x0100},
 297        {0x000c, 0x0022},
 298        {0x0008, 0x0b00},
 299        {0x005a, 0x0202},
 300        {0x0012, 0x000e},
 301        {0x0018, 0x0a33},
 302        {0x0022, 0x0008},
 303        {0x0028, 0x0017},
 304        {0x0024, 0x0028},
 305        {0x002a, 0x002d},
 306        {0x0026, 0x0030},
 307        {0x002c, 0x07c9},
 308        {0x002e, 0x1111},
 309        {0x0030, 0x1111},
 310        {0x0032, 0x1111},
 311        {0x0006, 0x07bc},
 312        {0x0a22, 0x0000},
 313        {0x0a12, 0x0a20},
 314        {0x0a14, 0x0798},
 315        {0x003e, 0x0000},
 316        {0x0074, 0x080e},
 317        {0x0070, 0x0407},
 318        {0x0002, 0x0000},
 319        {0x0a02, 0x0100},
 320        {0x0a24, 0x0100},
 321        {0x0046, 0x0000},
 322        {0x0076, 0x0000},
 323        {0x0060, 0x0000},
 324        {0x0062, 0x0530},
 325        {0x0064, 0x0500},
 326        {0x0066, 0x0530},
 327        {0x0068, 0x0500},
 328        {0x0122, 0x0300},
 329        {0x015a, 0xff08},
 330        {0x0804, 0x0300},
 331        {0x0806, 0x0100},
 332        {0x005c, 0x0102},
 333        {0x0a1a, 0x0800},
 334};
 335
 336static const struct hi556_reg mode_2592x1944_regs[] = {
 337        {0x0a00, 0x0000},
 338        {0x0b0a, 0x8252},
 339        {0x0f30, 0x5b15},
 340        {0x0f32, 0x7067},
 341        {0x004a, 0x0100},
 342        {0x004c, 0x0000},
 343        {0x004e, 0x0100},
 344        {0x000c, 0x0022},
 345        {0x0008, 0x0b00},
 346        {0x005a, 0x0202},
 347        {0x0012, 0x000e},
 348        {0x0018, 0x0a33},
 349        {0x0022, 0x0008},
 350        {0x0028, 0x0017},
 351        {0x0024, 0x0028},
 352        {0x002a, 0x002d},
 353        {0x0026, 0x0030},
 354        {0x002c, 0x07c9},
 355        {0x002e, 0x1111},
 356        {0x0030, 0x1111},
 357        {0x0032, 0x1111},
 358        {0x0006, 0x0814},
 359        {0x0a22, 0x0000},
 360        {0x0a12, 0x0a20},
 361        {0x0a14, 0x0798},
 362        {0x003e, 0x0000},
 363        {0x0074, 0x0812},
 364        {0x0070, 0x0409},
 365        {0x0804, 0x0300},
 366        {0x0806, 0x0100},
 367        {0x0a04, 0x014a},
 368        {0x090c, 0x0fdc},
 369        {0x090e, 0x002d},
 370
 371        {0x0902, 0x4319},
 372        {0x0914, 0xc10a},
 373        {0x0916, 0x071f},
 374        {0x0918, 0x0408},
 375        {0x091a, 0x0c0d},
 376        {0x091c, 0x0f09},
 377        {0x091e, 0x0a00},
 378        {0x0958, 0xbb80},
 379};
 380
 381static const struct hi556_reg mode_1296x972_regs[] = {
 382        {0x0a00, 0x0000},
 383        {0x0b0a, 0x8259},
 384        {0x0f30, 0x5b15},
 385        {0x0f32, 0x7167},
 386        {0x004a, 0x0100},
 387        {0x004c, 0x0000},
 388        {0x004e, 0x0100},
 389        {0x000c, 0x0122},
 390        {0x0008, 0x0b00},
 391        {0x005a, 0x0404},
 392        {0x0012, 0x000c},
 393        {0x0018, 0x0a33},
 394        {0x0022, 0x0008},
 395        {0x0028, 0x0017},
 396        {0x0024, 0x0022},
 397        {0x002a, 0x002b},
 398        {0x0026, 0x0030},
 399        {0x002c, 0x07c9},
 400        {0x002e, 0x3311},
 401        {0x0030, 0x3311},
 402        {0x0032, 0x3311},
 403        {0x0006, 0x0814},
 404        {0x0a22, 0x0000},
 405        {0x0a12, 0x0510},
 406        {0x0a14, 0x03cc},
 407        {0x003e, 0x0000},
 408        {0x0074, 0x0812},
 409        {0x0070, 0x0409},
 410        {0x0804, 0x0308},
 411        {0x0806, 0x0100},
 412        {0x0a04, 0x016a},
 413        {0x090e, 0x0010},
 414        {0x090c, 0x09c0},
 415
 416        {0x0902, 0x4319},
 417        {0x0914, 0xc106},
 418        {0x0916, 0x040e},
 419        {0x0918, 0x0304},
 420        {0x091a, 0x0708},
 421        {0x091c, 0x0e06},
 422        {0x091e, 0x0300},
 423        {0x0958, 0xbb80},
 424};
 425
 426static const char * const hi556_test_pattern_menu[] = {
 427        "Disabled",
 428        "Solid Colour",
 429        "100% Colour Bars",
 430        "Fade To Grey Colour Bars",
 431        "PN9",
 432        "Gradient Horizontal",
 433        "Gradient Vertical",
 434        "Check Board",
 435        "Slant Pattern",
 436};
 437
 438static const s64 link_freq_menu_items[] = {
 439        HI556_LINK_FREQ_437MHZ,
 440};
 441
 442static const struct hi556_link_freq_config link_freq_configs[] = {
 443        [HI556_LINK_FREQ_437MHZ_INDEX] = {
 444                .reg_list = {
 445                        .num_of_regs = ARRAY_SIZE(mipi_data_rate_874mbps),
 446                        .regs = mipi_data_rate_874mbps,
 447                }
 448        }
 449};
 450
 451static const struct hi556_mode supported_modes[] = {
 452        {
 453                .width = 2592,
 454                .height = 1944,
 455                .fll_def = HI556_FLL_30FPS,
 456                .fll_min = HI556_FLL_30FPS_MIN,
 457                .llp = 0x0b00,
 458                .reg_list = {
 459                        .num_of_regs = ARRAY_SIZE(mode_2592x1944_regs),
 460                        .regs = mode_2592x1944_regs,
 461                },
 462                .link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,
 463        },
 464        {
 465                .width = 1296,
 466                .height = 972,
 467                .fll_def = HI556_FLL_30FPS,
 468                .fll_min = HI556_FLL_30FPS_MIN,
 469                .llp = 0x0b00,
 470                .reg_list = {
 471                        .num_of_regs = ARRAY_SIZE(mode_1296x972_regs),
 472                        .regs = mode_1296x972_regs,
 473                },
 474                .link_freq_index = HI556_LINK_FREQ_437MHZ_INDEX,
 475        }
 476};
 477
 478struct hi556 {
 479        struct v4l2_subdev sd;
 480        struct media_pad pad;
 481        struct v4l2_ctrl_handler ctrl_handler;
 482
 483        /* V4L2 Controls */
 484        struct v4l2_ctrl *link_freq;
 485        struct v4l2_ctrl *pixel_rate;
 486        struct v4l2_ctrl *vblank;
 487        struct v4l2_ctrl *hblank;
 488        struct v4l2_ctrl *exposure;
 489
 490        /* Current mode */
 491        const struct hi556_mode *cur_mode;
 492
 493        /* To serialize asynchronus callbacks */
 494        struct mutex mutex;
 495
 496        /* Streaming on/off */
 497        bool streaming;
 498};
 499
 500static u64 to_pixel_rate(u32 f_index)
 501{
 502        u64 pixel_rate = link_freq_menu_items[f_index] * 2 * HI556_DATA_LANES;
 503
 504        do_div(pixel_rate, HI556_RGB_DEPTH);
 505
 506        return pixel_rate;
 507}
 508
 509static int hi556_read_reg(struct hi556 *hi556, u16 reg, u16 len, u32 *val)
 510{
 511        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
 512        struct i2c_msg msgs[2];
 513        u8 addr_buf[2];
 514        u8 data_buf[4] = {0};
 515        int ret;
 516
 517        if (len > 4)
 518                return -EINVAL;
 519
 520        put_unaligned_be16(reg, addr_buf);
 521        msgs[0].addr = client->addr;
 522        msgs[0].flags = 0;
 523        msgs[0].len = sizeof(addr_buf);
 524        msgs[0].buf = addr_buf;
 525        msgs[1].addr = client->addr;
 526        msgs[1].flags = I2C_M_RD;
 527        msgs[1].len = len;
 528        msgs[1].buf = &data_buf[4 - len];
 529
 530        ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
 531        if (ret != ARRAY_SIZE(msgs))
 532                return -EIO;
 533
 534        *val = get_unaligned_be32(data_buf);
 535
 536        return 0;
 537}
 538
 539static int hi556_write_reg(struct hi556 *hi556, u16 reg, u16 len, u32 val)
 540{
 541        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
 542        u8 buf[6];
 543
 544        if (len > 4)
 545                return -EINVAL;
 546
 547        put_unaligned_be16(reg, buf);
 548        put_unaligned_be32(val << 8 * (4 - len), buf + 2);
 549        if (i2c_master_send(client, buf, len + 2) != len + 2)
 550                return -EIO;
 551
 552        return 0;
 553}
 554
 555static int hi556_write_reg_list(struct hi556 *hi556,
 556                                const struct hi556_reg_list *r_list)
 557{
 558        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
 559        unsigned int i;
 560        int ret;
 561
 562        for (i = 0; i < r_list->num_of_regs; i++) {
 563                ret = hi556_write_reg(hi556, r_list->regs[i].address,
 564                                      HI556_REG_VALUE_16BIT,
 565                                      r_list->regs[i].val);
 566                if (ret) {
 567                        dev_err_ratelimited(&client->dev,
 568                                            "failed to write reg 0x%4.4x. error = %d",
 569                                            r_list->regs[i].address, ret);
 570                        return ret;
 571                }
 572        }
 573
 574        return 0;
 575}
 576
 577static int hi556_update_digital_gain(struct hi556 *hi556, u32 d_gain)
 578{
 579        int ret;
 580
 581        ret = hi556_write_reg(hi556, HI556_REG_MWB_GR_GAIN,
 582                              HI556_REG_VALUE_16BIT, d_gain);
 583        if (ret)
 584                return ret;
 585
 586        ret = hi556_write_reg(hi556, HI556_REG_MWB_GB_GAIN,
 587                              HI556_REG_VALUE_16BIT, d_gain);
 588        if (ret)
 589                return ret;
 590
 591        ret = hi556_write_reg(hi556, HI556_REG_MWB_R_GAIN,
 592                              HI556_REG_VALUE_16BIT, d_gain);
 593        if (ret)
 594                return ret;
 595
 596        return hi556_write_reg(hi556, HI556_REG_MWB_B_GAIN,
 597                               HI556_REG_VALUE_16BIT, d_gain);
 598}
 599
 600static int hi556_test_pattern(struct hi556 *hi556, u32 pattern)
 601{
 602        int ret;
 603        u32 val;
 604
 605        if (pattern) {
 606                ret = hi556_read_reg(hi556, HI556_REG_ISP,
 607                                     HI556_REG_VALUE_08BIT, &val);
 608                if (ret)
 609                        return ret;
 610
 611                ret = hi556_write_reg(hi556, HI556_REG_ISP,
 612                                      HI556_REG_VALUE_08BIT,
 613                                      val | HI556_REG_ISP_TPG_EN);
 614                if (ret)
 615                        return ret;
 616        }
 617
 618        return hi556_write_reg(hi556, HI556_REG_TEST_PATTERN,
 619                               HI556_REG_VALUE_08BIT, pattern);
 620}
 621
 622static int hi556_set_ctrl(struct v4l2_ctrl *ctrl)
 623{
 624        struct hi556 *hi556 = container_of(ctrl->handler,
 625                                             struct hi556, ctrl_handler);
 626        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
 627        s64 exposure_max;
 628        int ret = 0;
 629
 630        /* Propagate change of current control to all related controls */
 631        if (ctrl->id == V4L2_CID_VBLANK) {
 632                /* Update max exposure while meeting expected vblanking */
 633                exposure_max = hi556->cur_mode->height + ctrl->val -
 634                               HI556_EXPOSURE_MAX_MARGIN;
 635                __v4l2_ctrl_modify_range(hi556->exposure,
 636                                         hi556->exposure->minimum,
 637                                         exposure_max, hi556->exposure->step,
 638                                         exposure_max);
 639        }
 640
 641        /* V4L2 controls values will be applied only when power is already up */
 642        if (!pm_runtime_get_if_in_use(&client->dev))
 643                return 0;
 644
 645        switch (ctrl->id) {
 646        case V4L2_CID_ANALOGUE_GAIN:
 647                ret = hi556_write_reg(hi556, HI556_REG_ANALOG_GAIN,
 648                                      HI556_REG_VALUE_16BIT, ctrl->val);
 649                break;
 650
 651        case V4L2_CID_DIGITAL_GAIN:
 652                ret = hi556_update_digital_gain(hi556, ctrl->val);
 653                break;
 654
 655        case V4L2_CID_EXPOSURE:
 656                ret = hi556_write_reg(hi556, HI556_REG_EXPOSURE,
 657                                      HI556_REG_VALUE_16BIT, ctrl->val);
 658                break;
 659
 660        case V4L2_CID_VBLANK:
 661                /* Update FLL that meets expected vertical blanking */
 662                ret = hi556_write_reg(hi556, HI556_REG_FLL,
 663                                      HI556_REG_VALUE_16BIT,
 664                                      hi556->cur_mode->height + ctrl->val);
 665                break;
 666
 667        case V4L2_CID_TEST_PATTERN:
 668                ret = hi556_test_pattern(hi556, ctrl->val);
 669                break;
 670
 671        default:
 672                ret = -EINVAL;
 673                break;
 674        }
 675
 676        pm_runtime_put(&client->dev);
 677
 678        return ret;
 679}
 680
 681static const struct v4l2_ctrl_ops hi556_ctrl_ops = {
 682        .s_ctrl = hi556_set_ctrl,
 683};
 684
 685static int hi556_init_controls(struct hi556 *hi556)
 686{
 687        struct v4l2_ctrl_handler *ctrl_hdlr;
 688        s64 exposure_max, h_blank;
 689        int ret;
 690
 691        ctrl_hdlr = &hi556->ctrl_handler;
 692        ret = v4l2_ctrl_handler_init(ctrl_hdlr, 8);
 693        if (ret)
 694                return ret;
 695
 696        ctrl_hdlr->lock = &hi556->mutex;
 697        hi556->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &hi556_ctrl_ops,
 698                                                  V4L2_CID_LINK_FREQ,
 699                                        ARRAY_SIZE(link_freq_menu_items) - 1,
 700                                        0, link_freq_menu_items);
 701        if (hi556->link_freq)
 702                hi556->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 703
 704        hi556->pixel_rate = v4l2_ctrl_new_std
 705                            (ctrl_hdlr, &hi556_ctrl_ops,
 706                             V4L2_CID_PIXEL_RATE, 0,
 707                             to_pixel_rate(HI556_LINK_FREQ_437MHZ_INDEX),
 708                             1,
 709                             to_pixel_rate(HI556_LINK_FREQ_437MHZ_INDEX));
 710        hi556->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops,
 711                                          V4L2_CID_VBLANK,
 712                                          hi556->cur_mode->fll_min -
 713                                          hi556->cur_mode->height,
 714                                          HI556_FLL_MAX -
 715                                          hi556->cur_mode->height, 1,
 716                                          hi556->cur_mode->fll_def -
 717                                          hi556->cur_mode->height);
 718
 719        h_blank = hi556->cur_mode->llp - hi556->cur_mode->width;
 720
 721        hi556->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops,
 722                                          V4L2_CID_HBLANK, h_blank, h_blank, 1,
 723                                          h_blank);
 724        if (hi556->hblank)
 725                hi556->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 726
 727        v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, V4L2_CID_ANALOGUE_GAIN,
 728                          HI556_ANAL_GAIN_MIN, HI556_ANAL_GAIN_MAX,
 729                          HI556_ANAL_GAIN_STEP, HI556_ANAL_GAIN_MIN);
 730        v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
 731                          HI556_DGTL_GAIN_MIN, HI556_DGTL_GAIN_MAX,
 732                          HI556_DGTL_GAIN_STEP, HI556_DGTL_GAIN_DEFAULT);
 733        exposure_max = hi556->cur_mode->fll_def - HI556_EXPOSURE_MAX_MARGIN;
 734        hi556->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops,
 735                                            V4L2_CID_EXPOSURE,
 736                                            HI556_EXPOSURE_MIN, exposure_max,
 737                                            HI556_EXPOSURE_STEP,
 738                                            exposure_max);
 739        v4l2_ctrl_new_std_menu_items(ctrl_hdlr, &hi556_ctrl_ops,
 740                                     V4L2_CID_TEST_PATTERN,
 741                                     ARRAY_SIZE(hi556_test_pattern_menu) - 1,
 742                                     0, 0, hi556_test_pattern_menu);
 743        if (ctrl_hdlr->error)
 744                return ctrl_hdlr->error;
 745
 746        hi556->sd.ctrl_handler = ctrl_hdlr;
 747
 748        return 0;
 749}
 750
 751static void hi556_assign_pad_format(const struct hi556_mode *mode,
 752                                    struct v4l2_mbus_framefmt *fmt)
 753{
 754        fmt->width = mode->width;
 755        fmt->height = mode->height;
 756        fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10;
 757        fmt->field = V4L2_FIELD_NONE;
 758}
 759
 760static int hi556_start_streaming(struct hi556 *hi556)
 761{
 762        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
 763        const struct hi556_reg_list *reg_list;
 764        int link_freq_index, ret;
 765
 766        link_freq_index = hi556->cur_mode->link_freq_index;
 767        reg_list = &link_freq_configs[link_freq_index].reg_list;
 768        ret = hi556_write_reg_list(hi556, reg_list);
 769        if (ret) {
 770                dev_err(&client->dev, "failed to set plls");
 771                return ret;
 772        }
 773
 774        reg_list = &hi556->cur_mode->reg_list;
 775        ret = hi556_write_reg_list(hi556, reg_list);
 776        if (ret) {
 777                dev_err(&client->dev, "failed to set mode");
 778                return ret;
 779        }
 780
 781        ret = __v4l2_ctrl_handler_setup(hi556->sd.ctrl_handler);
 782        if (ret)
 783                return ret;
 784
 785        ret = hi556_write_reg(hi556, HI556_REG_MODE_SELECT,
 786                              HI556_REG_VALUE_16BIT, HI556_MODE_STREAMING);
 787
 788        if (ret) {
 789                dev_err(&client->dev, "failed to set stream");
 790                return ret;
 791        }
 792
 793        return 0;
 794}
 795
 796static void hi556_stop_streaming(struct hi556 *hi556)
 797{
 798        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
 799
 800        if (hi556_write_reg(hi556, HI556_REG_MODE_SELECT,
 801                            HI556_REG_VALUE_16BIT, HI556_MODE_STANDBY))
 802                dev_err(&client->dev, "failed to set stream");
 803}
 804
 805static int hi556_set_stream(struct v4l2_subdev *sd, int enable)
 806{
 807        struct hi556 *hi556 = to_hi556(sd);
 808        struct i2c_client *client = v4l2_get_subdevdata(sd);
 809        int ret = 0;
 810
 811        if (hi556->streaming == enable)
 812                return 0;
 813
 814        mutex_lock(&hi556->mutex);
 815        if (enable) {
 816                ret = pm_runtime_resume_and_get(&client->dev);
 817                if (ret < 0) {
 818                        mutex_unlock(&hi556->mutex);
 819                        return ret;
 820                }
 821
 822                ret = hi556_start_streaming(hi556);
 823                if (ret) {
 824                        enable = 0;
 825                        hi556_stop_streaming(hi556);
 826                        pm_runtime_put(&client->dev);
 827                }
 828        } else {
 829                hi556_stop_streaming(hi556);
 830                pm_runtime_put(&client->dev);
 831        }
 832
 833        hi556->streaming = enable;
 834        mutex_unlock(&hi556->mutex);
 835
 836        return ret;
 837}
 838
 839static int __maybe_unused hi556_suspend(struct device *dev)
 840{
 841        struct v4l2_subdev *sd = dev_get_drvdata(dev);
 842        struct hi556 *hi556 = to_hi556(sd);
 843
 844        mutex_lock(&hi556->mutex);
 845        if (hi556->streaming)
 846                hi556_stop_streaming(hi556);
 847
 848        mutex_unlock(&hi556->mutex);
 849
 850        return 0;
 851}
 852
 853static int __maybe_unused hi556_resume(struct device *dev)
 854{
 855        struct v4l2_subdev *sd = dev_get_drvdata(dev);
 856        struct hi556 *hi556 = to_hi556(sd);
 857        int ret;
 858
 859        mutex_lock(&hi556->mutex);
 860        if (hi556->streaming) {
 861                ret = hi556_start_streaming(hi556);
 862                if (ret)
 863                        goto error;
 864        }
 865
 866        mutex_unlock(&hi556->mutex);
 867
 868        return 0;
 869
 870error:
 871        hi556_stop_streaming(hi556);
 872        hi556->streaming = 0;
 873        mutex_unlock(&hi556->mutex);
 874        return ret;
 875}
 876
 877static int hi556_set_format(struct v4l2_subdev *sd,
 878                            struct v4l2_subdev_state *sd_state,
 879                            struct v4l2_subdev_format *fmt)
 880{
 881        struct hi556 *hi556 = to_hi556(sd);
 882        const struct hi556_mode *mode;
 883        s32 vblank_def, h_blank;
 884
 885        mode = v4l2_find_nearest_size(supported_modes,
 886                                      ARRAY_SIZE(supported_modes), width,
 887                                      height, fmt->format.width,
 888                                      fmt->format.height);
 889
 890        mutex_lock(&hi556->mutex);
 891        hi556_assign_pad_format(mode, &fmt->format);
 892        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
 893                *v4l2_subdev_get_try_format(sd, sd_state, fmt->pad) = fmt->format;
 894        } else {
 895                hi556->cur_mode = mode;
 896                __v4l2_ctrl_s_ctrl(hi556->link_freq, mode->link_freq_index);
 897                __v4l2_ctrl_s_ctrl_int64(hi556->pixel_rate,
 898                                         to_pixel_rate(mode->link_freq_index));
 899
 900                /* Update limits and set FPS to default */
 901                vblank_def = mode->fll_def - mode->height;
 902                __v4l2_ctrl_modify_range(hi556->vblank,
 903                                         mode->fll_min - mode->height,
 904                                         HI556_FLL_MAX - mode->height, 1,
 905                                         vblank_def);
 906                __v4l2_ctrl_s_ctrl(hi556->vblank, vblank_def);
 907
 908                h_blank = hi556->cur_mode->llp - hi556->cur_mode->width;
 909
 910                __v4l2_ctrl_modify_range(hi556->hblank, h_blank, h_blank, 1,
 911                                         h_blank);
 912        }
 913
 914        mutex_unlock(&hi556->mutex);
 915
 916        return 0;
 917}
 918
 919static int hi556_get_format(struct v4l2_subdev *sd,
 920                            struct v4l2_subdev_state *sd_state,
 921                            struct v4l2_subdev_format *fmt)
 922{
 923        struct hi556 *hi556 = to_hi556(sd);
 924
 925        mutex_lock(&hi556->mutex);
 926        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
 927                fmt->format = *v4l2_subdev_get_try_format(&hi556->sd,
 928                                                          sd_state,
 929                                                          fmt->pad);
 930        else
 931                hi556_assign_pad_format(hi556->cur_mode, &fmt->format);
 932
 933        mutex_unlock(&hi556->mutex);
 934
 935        return 0;
 936}
 937
 938static int hi556_enum_mbus_code(struct v4l2_subdev *sd,
 939                                struct v4l2_subdev_state *sd_state,
 940                                struct v4l2_subdev_mbus_code_enum *code)
 941{
 942        if (code->index > 0)
 943                return -EINVAL;
 944
 945        code->code = MEDIA_BUS_FMT_SGRBG10_1X10;
 946
 947        return 0;
 948}
 949
 950static int hi556_enum_frame_size(struct v4l2_subdev *sd,
 951                                 struct v4l2_subdev_state *sd_state,
 952                                 struct v4l2_subdev_frame_size_enum *fse)
 953{
 954        if (fse->index >= ARRAY_SIZE(supported_modes))
 955                return -EINVAL;
 956
 957        if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10)
 958                return -EINVAL;
 959
 960        fse->min_width = supported_modes[fse->index].width;
 961        fse->max_width = fse->min_width;
 962        fse->min_height = supported_modes[fse->index].height;
 963        fse->max_height = fse->min_height;
 964
 965        return 0;
 966}
 967
 968static int hi556_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
 969{
 970        struct hi556 *hi556 = to_hi556(sd);
 971
 972        mutex_lock(&hi556->mutex);
 973        hi556_assign_pad_format(&supported_modes[0],
 974                                v4l2_subdev_get_try_format(sd, fh->state, 0));
 975        mutex_unlock(&hi556->mutex);
 976
 977        return 0;
 978}
 979
 980static const struct v4l2_subdev_video_ops hi556_video_ops = {
 981        .s_stream = hi556_set_stream,
 982};
 983
 984static const struct v4l2_subdev_pad_ops hi556_pad_ops = {
 985        .set_fmt = hi556_set_format,
 986        .get_fmt = hi556_get_format,
 987        .enum_mbus_code = hi556_enum_mbus_code,
 988        .enum_frame_size = hi556_enum_frame_size,
 989};
 990
 991static const struct v4l2_subdev_ops hi556_subdev_ops = {
 992        .video = &hi556_video_ops,
 993        .pad = &hi556_pad_ops,
 994};
 995
 996static const struct media_entity_operations hi556_subdev_entity_ops = {
 997        .link_validate = v4l2_subdev_link_validate,
 998};
 999
1000static const struct v4l2_subdev_internal_ops hi556_internal_ops = {
1001        .open = hi556_open,
1002};
1003
1004static int hi556_identify_module(struct hi556 *hi556)
1005{
1006        struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd);
1007        int ret;
1008        u32 val;
1009
1010        ret = hi556_read_reg(hi556, HI556_REG_CHIP_ID,
1011                             HI556_REG_VALUE_16BIT, &val);
1012        if (ret)
1013                return ret;
1014
1015        if (val != HI556_CHIP_ID) {
1016                dev_err(&client->dev, "chip id mismatch: %x!=%x",
1017                        HI556_CHIP_ID, val);
1018                return -ENXIO;
1019        }
1020
1021        return 0;
1022}
1023
1024static int hi556_check_hwcfg(struct device *dev)
1025{
1026        struct fwnode_handle *ep;
1027        struct fwnode_handle *fwnode = dev_fwnode(dev);
1028        struct v4l2_fwnode_endpoint bus_cfg = {
1029                .bus_type = V4L2_MBUS_CSI2_DPHY
1030        };
1031        u32 mclk;
1032        int ret = 0;
1033        unsigned int i, j;
1034
1035        if (!fwnode)
1036                return -ENXIO;
1037
1038        ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk);
1039        if (ret) {
1040                dev_err(dev, "can't get clock frequency");
1041                return ret;
1042        }
1043
1044        if (mclk != HI556_MCLK) {
1045                dev_err(dev, "external clock %d is not supported", mclk);
1046                return -EINVAL;
1047        }
1048
1049        ep = fwnode_graph_get_next_endpoint(fwnode, NULL);
1050        if (!ep)
1051                return -ENXIO;
1052
1053        ret = v4l2_fwnode_endpoint_alloc_parse(ep, &bus_cfg);
1054        fwnode_handle_put(ep);
1055        if (ret)
1056                return ret;
1057
1058        if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2) {
1059                dev_err(dev, "number of CSI2 data lanes %d is not supported",
1060                        bus_cfg.bus.mipi_csi2.num_data_lanes);
1061                ret = -EINVAL;
1062                goto check_hwcfg_error;
1063        }
1064
1065        if (!bus_cfg.nr_of_link_frequencies) {
1066                dev_err(dev, "no link frequencies defined");
1067                ret = -EINVAL;
1068                goto check_hwcfg_error;
1069        }
1070
1071        for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) {
1072                for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) {
1073                        if (link_freq_menu_items[i] ==
1074                                bus_cfg.link_frequencies[j])
1075                                break;
1076                }
1077
1078                if (j == bus_cfg.nr_of_link_frequencies) {
1079                        dev_err(dev, "no link frequency %lld supported",
1080                                link_freq_menu_items[i]);
1081                        ret = -EINVAL;
1082                        goto check_hwcfg_error;
1083                }
1084        }
1085
1086check_hwcfg_error:
1087        v4l2_fwnode_endpoint_free(&bus_cfg);
1088
1089        return ret;
1090}
1091
1092static int hi556_remove(struct i2c_client *client)
1093{
1094        struct v4l2_subdev *sd = i2c_get_clientdata(client);
1095        struct hi556 *hi556 = to_hi556(sd);
1096
1097        v4l2_async_unregister_subdev(sd);
1098        media_entity_cleanup(&sd->entity);
1099        v4l2_ctrl_handler_free(sd->ctrl_handler);
1100        pm_runtime_disable(&client->dev);
1101        mutex_destroy(&hi556->mutex);
1102
1103        return 0;
1104}
1105
1106static int hi556_probe(struct i2c_client *client)
1107{
1108        struct hi556 *hi556;
1109        int ret;
1110
1111        ret = hi556_check_hwcfg(&client->dev);
1112        if (ret) {
1113                dev_err(&client->dev, "failed to check HW configuration: %d",
1114                        ret);
1115                return ret;
1116        }
1117
1118        hi556 = devm_kzalloc(&client->dev, sizeof(*hi556), GFP_KERNEL);
1119        if (!hi556)
1120                return -ENOMEM;
1121
1122        v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops);
1123        ret = hi556_identify_module(hi556);
1124        if (ret) {
1125                dev_err(&client->dev, "failed to find sensor: %d", ret);
1126                return ret;
1127        }
1128
1129        mutex_init(&hi556->mutex);
1130        hi556->cur_mode = &supported_modes[0];
1131        ret = hi556_init_controls(hi556);
1132        if (ret) {
1133                dev_err(&client->dev, "failed to init controls: %d", ret);
1134                goto probe_error_v4l2_ctrl_handler_free;
1135        }
1136
1137        hi556->sd.internal_ops = &hi556_internal_ops;
1138        hi556->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1139        hi556->sd.entity.ops = &hi556_subdev_entity_ops;
1140        hi556->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1141        hi556->pad.flags = MEDIA_PAD_FL_SOURCE;
1142        ret = media_entity_pads_init(&hi556->sd.entity, 1, &hi556->pad);
1143        if (ret) {
1144                dev_err(&client->dev, "failed to init entity pads: %d", ret);
1145                goto probe_error_v4l2_ctrl_handler_free;
1146        }
1147
1148        ret = v4l2_async_register_subdev_sensor(&hi556->sd);
1149        if (ret < 0) {
1150                dev_err(&client->dev, "failed to register V4L2 subdev: %d",
1151                        ret);
1152                goto probe_error_media_entity_cleanup;
1153        }
1154
1155        pm_runtime_set_active(&client->dev);
1156        pm_runtime_enable(&client->dev);
1157        pm_runtime_idle(&client->dev);
1158
1159        return 0;
1160
1161probe_error_media_entity_cleanup:
1162        media_entity_cleanup(&hi556->sd.entity);
1163
1164probe_error_v4l2_ctrl_handler_free:
1165        v4l2_ctrl_handler_free(hi556->sd.ctrl_handler);
1166        mutex_destroy(&hi556->mutex);
1167
1168        return ret;
1169}
1170
1171static const struct dev_pm_ops hi556_pm_ops = {
1172        SET_SYSTEM_SLEEP_PM_OPS(hi556_suspend, hi556_resume)
1173};
1174
1175#ifdef CONFIG_ACPI
1176static const struct acpi_device_id hi556_acpi_ids[] = {
1177        {"INT3537"},
1178        {}
1179};
1180
1181MODULE_DEVICE_TABLE(acpi, hi556_acpi_ids);
1182#endif
1183
1184static struct i2c_driver hi556_i2c_driver = {
1185        .driver = {
1186                .name = "hi556",
1187                .pm = &hi556_pm_ops,
1188                .acpi_match_table = ACPI_PTR(hi556_acpi_ids),
1189        },
1190        .probe_new = hi556_probe,
1191        .remove = hi556_remove,
1192};
1193
1194module_i2c_driver(hi556_i2c_driver);
1195
1196MODULE_AUTHOR("Shawn Tu <shawnx.tu@intel.com>");
1197MODULE_DESCRIPTION("Hynix HI556 sensor driver");
1198MODULE_LICENSE("GPL v2");
1199