File Index
Files and directories
Sign in
FILE

hi556.c

File preview with syntax highlighting.

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