Linux Audio

Check our new training course

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