xref: /linux/drivers/staging/media/atomisp/i2c/gc2235.h (revision 164666fa66669d437bdcc8d5f1744a2aee73be41)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Support for GalaxyCore GC2235 2M camera sensor.
4  *
5  * Copyright (c) 2014 Intel Corporation. All Rights Reserved.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License version
9  * 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.
18  *
19  */
20 
21 #ifndef __GC2235_H__
22 #define __GC2235_H__
23 #include <linux/kernel.h>
24 #include <linux/types.h>
25 #include <linux/i2c.h>
26 #include <linux/delay.h>
27 #include <linux/videodev2.h>
28 #include <linux/spinlock.h>
29 #include <media/v4l2-subdev.h>
30 #include <media/v4l2-device.h>
31 #include <media/v4l2-ctrls.h>
32 #include <linux/v4l2-mediabus.h>
33 #include <media/media-entity.h>
34 
35 #include "../include/linux/atomisp_platform.h"
36 
37 /*
38  * FIXME: non-preview resolutions are currently broken
39  */
40 #define ENABLE_NON_PREVIEW     0
41 
42 /* Defines for register writes and register array processing */
43 #define I2C_MSG_LENGTH		0x2
44 #define I2C_RETRY_COUNT		5
45 
46 #define GC2235_FOCAL_LENGTH_NUM	278	/*2.78mm*/
47 #define GC2235_FOCAL_LENGTH_DEM	100
48 #define GC2235_F_NUMBER_DEFAULT_NUM	26
49 #define GC2235_F_NUMBER_DEM	10
50 
51 #define MAX_FMTS		1
52 
53 /*
54  * focal length bits definition:
55  * bits 31-16: numerator, bits 15-0: denominator
56  */
57 #define GC2235_FOCAL_LENGTH_DEFAULT 0x1160064
58 
59 /*
60  * current f-number bits definition:
61  * bits 31-16: numerator, bits 15-0: denominator
62  */
63 #define GC2235_F_NUMBER_DEFAULT 0x1a000a
64 
65 /*
66  * f-number range bits definition:
67  * bits 31-24: max f-number numerator
68  * bits 23-16: max f-number denominator
69  * bits 15-8: min f-number numerator
70  * bits 7-0: min f-number denominator
71  */
72 #define GC2235_F_NUMBER_RANGE 0x1a0a1a0a
73 #define GC2235_ID	0x2235
74 
75 #define GC2235_FINE_INTG_TIME_MIN 0
76 #define GC2235_FINE_INTG_TIME_MAX_MARGIN 0
77 #define GC2235_COARSE_INTG_TIME_MIN 1
78 #define GC2235_COARSE_INTG_TIME_MAX_MARGIN 6
79 
80 /*
81  * GC2235 System control registers
82  */
83 /*
84  * GC2235 System control registers
85  */
86 #define GC2235_SENSOR_ID_H		0xF0
87 #define GC2235_SENSOR_ID_L		0xF1
88 #define GC2235_RESET_RELATED		0xFE
89 #define GC2235_SW_RESET			0x8
90 #define GC2235_MIPI_RESET		0x3
91 #define GC2235_RESET_BIT		0x4
92 #define GC2235_REGISTER_PAGE_0		0x0
93 #define GC2235_REGISTER_PAGE_3		0x3
94 
95 #define GC2235_V_CROP_START_H		0x91
96 #define GC2235_V_CROP_START_L		0x92
97 #define GC2235_H_CROP_START_H		0x93
98 #define GC2235_H_CROP_START_L		0x94
99 #define GC2235_V_OUTSIZE_H		0x95
100 #define GC2235_V_OUTSIZE_L		0x96
101 #define GC2235_H_OUTSIZE_H		0x97
102 #define GC2235_H_OUTSIZE_L		0x98
103 
104 #define GC2235_HB_H			0x5
105 #define GC2235_HB_L			0x6
106 #define GC2235_VB_H			0x7
107 #define GC2235_VB_L			0x8
108 #define GC2235_SH_DELAY_H		0x11
109 #define GC2235_SH_DELAY_L		0x12
110 
111 #define GC2235_CSI2_MODE		0x10
112 
113 #define GC2235_EXPOSURE_H		0x3
114 #define GC2235_EXPOSURE_L		0x4
115 #define GC2235_GLOBAL_GAIN		0xB0
116 #define GC2235_PRE_GAIN			0xB1
117 #define GC2235_AWB_R_GAIN		0xB3
118 #define GC2235_AWB_G_GAIN		0xB4
119 #define GC2235_AWB_B_GAIN		0xB5
120 
121 #define GC2235_START_STREAMING		0x91
122 #define GC2235_STOP_STREAMING		0x0
123 
124 struct regval_list {
125 	u16 reg_num;
126 	u8 value;
127 };
128 
129 struct gc2235_resolution {
130 	u8 *desc;
131 	const struct gc2235_reg *regs;
132 	int res;
133 	int width;
134 	int height;
135 	int fps;
136 	int pix_clk_freq;
137 	u32 skip_frames;
138 	u16 pixels_per_line;
139 	u16 lines_per_frame;
140 	u8 bin_factor_x;
141 	u8 bin_factor_y;
142 	u8 bin_mode;
143 	bool used;
144 };
145 
146 struct gc2235_format {
147 	u8 *desc;
148 	u32 pixelformat;
149 	struct gc2235_reg *regs;
150 };
151 
152 /*
153  * gc2235 device structure.
154  */
155 struct gc2235_device {
156 	struct v4l2_subdev sd;
157 	struct media_pad pad;
158 	struct v4l2_mbus_framefmt format;
159 	struct mutex input_lock;
160 	struct v4l2_ctrl_handler ctrl_handler;
161 	struct gc2235_resolution *res;
162 
163 	struct camera_sensor_platform_data *platform_data;
164 	int vt_pix_clk_freq_mhz;
165 	u8 type;
166 };
167 
168 enum gc2235_tok_type {
169 	GC2235_8BIT  = 0x0001,
170 	GC2235_16BIT = 0x0002,
171 	GC2235_32BIT = 0x0004,
172 	GC2235_TOK_TERM   = 0xf000,	/* terminating token for reg list */
173 	GC2235_TOK_DELAY  = 0xfe00,	/* delay token for reg list */
174 	GC2235_TOK_MASK = 0xfff0
175 };
176 
177 /**
178  * struct gc2235_reg - MI sensor  register format
179  * @type: type of the register
180  * @reg: 8-bit offset to register
181  * @val: 8/16/32-bit register value
182  *
183  * Define a structure for sensor register initialization values
184  */
185 struct gc2235_reg {
186 	enum gc2235_tok_type type;
187 	u8 reg;
188 	u32 val;	/* @set value for read/mod/write, @mask */
189 };
190 
191 #define to_gc2235_sensor(x) container_of(x, struct gc2235_device, sd)
192 
193 #define GC2235_MAX_WRITE_BUF_SIZE	30
194 
195 struct gc2235_write_buffer {
196 	u8 addr;
197 	u8 data[GC2235_MAX_WRITE_BUF_SIZE];
198 };
199 
200 struct gc2235_write_ctrl {
201 	int index;
202 	struct gc2235_write_buffer buffer;
203 };
204 
205 static struct gc2235_reg const gc2235_stream_on[] = {
206 	{ GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */
207 	{ GC2235_8BIT, 0x10, 0x91}, /* start mipi */
208 	{ GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */
209 	{ GC2235_TOK_TERM, 0, 0 }
210 };
211 
212 static struct gc2235_reg const gc2235_stream_off[] = {
213 	{ GC2235_8BIT, 0xfe, 0x03}, /* switch to P3 */
214 	{ GC2235_8BIT, 0x10, 0x01}, /* stop mipi */
215 	{ GC2235_8BIT, 0xfe, 0x00}, /* switch to P0 */
216 	{ GC2235_TOK_TERM, 0, 0 }
217 };
218 
219 static struct gc2235_reg const gc2235_init_settings[] = {
220 	/* System */
221 	{ GC2235_8BIT, 0xfe, 0x80 },
222 	{ GC2235_8BIT, 0xfe, 0x80 },
223 	{ GC2235_8BIT, 0xfe, 0x80 },
224 	{ GC2235_8BIT, 0xf2, 0x00 },
225 	{ GC2235_8BIT, 0xf6, 0x00 },
226 	{ GC2235_8BIT, 0xfc, 0x06 },
227 	{ GC2235_8BIT, 0xf7, 0x15 },
228 	{ GC2235_8BIT, 0xf8, 0x84 },
229 	{ GC2235_8BIT, 0xf9, 0xfe },
230 	{ GC2235_8BIT, 0xfa, 0x00 },
231 	{ GC2235_8BIT, 0xfe, 0x00 },
232 	/* Analog & cisctl */
233 	{ GC2235_8BIT, 0x03, 0x04 },
234 	{ GC2235_8BIT, 0x04, 0x9E },
235 	{ GC2235_8BIT, 0x05, 0x00 },
236 	{ GC2235_8BIT, 0x06, 0xfd },
237 	{ GC2235_8BIT, 0x07, 0x00 },
238 	{ GC2235_8BIT, 0x08, 0x14 },
239 	{ GC2235_8BIT, 0x0a, 0x02 }, /* row start */
240 	{ GC2235_8BIT, 0x0c, 0x00 }, /* col start */
241 	{ GC2235_8BIT, 0x0d, 0x04 }, /* win height 1232 */
242 	{ GC2235_8BIT, 0x0e, 0xd0 },
243 	{ GC2235_8BIT, 0x0f, 0x06 }, /* win width: 1616 */
244 	{ GC2235_8BIT, 0x10, 0x60 },
245 	{ GC2235_8BIT, 0x17, 0x15 }, /* mirror flip */
246 	{ GC2235_8BIT, 0x18, 0x1a },
247 	{ GC2235_8BIT, 0x19, 0x06 },
248 	{ GC2235_8BIT, 0x1a, 0x01 },
249 	{ GC2235_8BIT, 0x1b, 0x4d },
250 	{ GC2235_8BIT, 0x1e, 0x88 },
251 	{ GC2235_8BIT, 0x1f, 0x48 },
252 	{ GC2235_8BIT, 0x20, 0x03 },
253 	{ GC2235_8BIT, 0x21, 0x7f },
254 	{ GC2235_8BIT, 0x22, 0x83 },
255 	{ GC2235_8BIT, 0x23, 0x42 },
256 	{ GC2235_8BIT, 0x24, 0x16 },
257 	{ GC2235_8BIT, 0x26, 0x01 }, /*analog gain*/
258 	{ GC2235_8BIT, 0x27, 0x30 },
259 	{ GC2235_8BIT, 0x3f, 0x00 }, /* PRC */
260 	/* blk */
261 	{ GC2235_8BIT, 0x40, 0xa3 },
262 	{ GC2235_8BIT, 0x41, 0x82 },
263 	{ GC2235_8BIT, 0x43, 0x20 },
264 	{ GC2235_8BIT, 0x5e, 0x18 },
265 	{ GC2235_8BIT, 0x5f, 0x18 },
266 	{ GC2235_8BIT, 0x60, 0x18 },
267 	{ GC2235_8BIT, 0x61, 0x18 },
268 	{ GC2235_8BIT, 0x62, 0x18 },
269 	{ GC2235_8BIT, 0x63, 0x18 },
270 	{ GC2235_8BIT, 0x64, 0x18 },
271 	{ GC2235_8BIT, 0x65, 0x18 },
272 	{ GC2235_8BIT, 0x66, 0x20 },
273 	{ GC2235_8BIT, 0x67, 0x20 },
274 	{ GC2235_8BIT, 0x68, 0x20 },
275 	{ GC2235_8BIT, 0x69, 0x20 },
276 	/* Gain */
277 	{ GC2235_8BIT, 0xb2, 0x00 },
278 	{ GC2235_8BIT, 0xb3, 0x40 },
279 	{ GC2235_8BIT, 0xb4, 0x40 },
280 	{ GC2235_8BIT, 0xb5, 0x40 },
281 	/* Dark sun */
282 	{ GC2235_8BIT, 0xbc, 0x00 },
283 
284 	{ GC2235_8BIT, 0xfe, 0x03 },
285 	{ GC2235_8BIT, 0x10, 0x01 }, /* disable mipi */
286 	{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */
287 	{ GC2235_TOK_TERM, 0, 0 }
288 };
289 
290 /*
291  * Register settings for various resolution
292  */
293 #if ENABLE_NON_PREVIEW
294 static struct gc2235_reg const gc2235_1296_736_30fps[] = {
295 	{ GC2235_8BIT, 0x8b, 0xa0 },
296 	{ GC2235_8BIT, 0x8c, 0x02 },
297 
298 	{ GC2235_8BIT, 0x07, 0x01 }, /* VBI */
299 	{ GC2235_8BIT, 0x08, 0x44 },
300 	{ GC2235_8BIT, 0x09, 0x00 }, /* row start */
301 	{ GC2235_8BIT, 0x0a, 0xf0 },
302 	{ GC2235_8BIT, 0x0b, 0x00 }, /* col start */
303 	{ GC2235_8BIT, 0x0c, 0xa0 },
304 	{ GC2235_8BIT, 0x0d, 0x02 }, /* win height 736 */
305 	{ GC2235_8BIT, 0x0e, 0xf0 },
306 	{ GC2235_8BIT, 0x0f, 0x05 }, /* win width: 1296 */
307 	{ GC2235_8BIT, 0x10, 0x20 },
308 
309 	{ GC2235_8BIT, 0x90, 0x01 },
310 	{ GC2235_8BIT, 0x92, 0x08 },
311 	{ GC2235_8BIT, 0x94, 0x08 },
312 	{ GC2235_8BIT, 0x95, 0x02 }, /* crop win height 736 */
313 	{ GC2235_8BIT, 0x96, 0xe0 },
314 	{ GC2235_8BIT, 0x97, 0x05 }, /* crop win width 1296 */
315 	{ GC2235_8BIT, 0x98, 0x10 },
316 	/* mimi init */
317 	{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */
318 	{ GC2235_8BIT, 0x01, 0x07 },
319 	{ GC2235_8BIT, 0x02, 0x11 },
320 	{ GC2235_8BIT, 0x03, 0x11 },
321 	{ GC2235_8BIT, 0x06, 0x80 },
322 	{ GC2235_8BIT, 0x11, 0x2b },
323 	/* set mipi buffer */
324 	{ GC2235_8BIT, 0x12, 0x54 }, /* val_low = (width * 10 / 8) & 0xFF */
325 	{ GC2235_8BIT, 0x13, 0x06 }, /* val_high = (width * 10 / 8) >> 8 */
326 
327 	{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/
328 	{ GC2235_8BIT, 0x04, 0x10 },
329 	{ GC2235_8BIT, 0x05, 0x00 },
330 	{ GC2235_8BIT, 0x17, 0x01 },
331 
332 	{ GC2235_8BIT, 0x22, 0x01 },
333 	{ GC2235_8BIT, 0x23, 0x05 },
334 	{ GC2235_8BIT, 0x24, 0x10 },
335 	{ GC2235_8BIT, 0x25, 0x10 },
336 	{ GC2235_8BIT, 0x26, 0x02 },
337 	{ GC2235_8BIT, 0x21, 0x10 },
338 	{ GC2235_8BIT, 0x29, 0x01 },
339 	{ GC2235_8BIT, 0x2a, 0x02 },
340 	{ GC2235_8BIT, 0x2b, 0x02 },
341 
342 	{ GC2235_8BIT, 0x10, 0x01 }, /* disable mipi */
343 	{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */
344 	{ GC2235_TOK_TERM, 0, 0 }
345 };
346 
347 static struct gc2235_reg const gc2235_960_640_30fps[] = {
348 	{ GC2235_8BIT, 0x8b, 0xa0 },
349 	{ GC2235_8BIT, 0x8c, 0x02 },
350 
351 	{ GC2235_8BIT, 0x07, 0x02 }, /* VBI */
352 	{ GC2235_8BIT, 0x08, 0xA4 },
353 	{ GC2235_8BIT, 0x09, 0x01 }, /* row start */
354 	{ GC2235_8BIT, 0x0a, 0x18 },
355 	{ GC2235_8BIT, 0x0b, 0x01 }, /* col start */
356 	{ GC2235_8BIT, 0x0c, 0x40 },
357 	{ GC2235_8BIT, 0x0d, 0x02 }, /* win height 656 */
358 	{ GC2235_8BIT, 0x0e, 0x90 },
359 	{ GC2235_8BIT, 0x0f, 0x03 }, /* win width: 976 */
360 	{ GC2235_8BIT, 0x10, 0xd0 },
361 
362 	{ GC2235_8BIT, 0x90, 0x01 },
363 	{ GC2235_8BIT, 0x92, 0x02 },
364 	{ GC2235_8BIT, 0x94, 0x06 },
365 	{ GC2235_8BIT, 0x95, 0x02 }, /* crop win height 640 */
366 	{ GC2235_8BIT, 0x96, 0x80 },
367 	{ GC2235_8BIT, 0x97, 0x03 }, /* crop win width 960 */
368 	{ GC2235_8BIT, 0x98, 0xc0 },
369 	/* mimp init */
370 	{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */
371 	{ GC2235_8BIT, 0x01, 0x07 },
372 	{ GC2235_8BIT, 0x02, 0x11 },
373 	{ GC2235_8BIT, 0x03, 0x11 },
374 	{ GC2235_8BIT, 0x06, 0x80 },
375 	{ GC2235_8BIT, 0x11, 0x2b },
376 	/* set mipi buffer */
377 	{ GC2235_8BIT, 0x12, 0xb0 }, /* val_low = (width * 10 / 8) & 0xFF */
378 	{ GC2235_8BIT, 0x13, 0x04 }, /* val_high = (width * 10 / 8) >> 8 */
379 
380 	{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/
381 	{ GC2235_8BIT, 0x04, 0x10 },
382 	{ GC2235_8BIT, 0x05, 0x00 },
383 	{ GC2235_8BIT, 0x17, 0x01 },
384 	{ GC2235_8BIT, 0x22, 0x01 },
385 	{ GC2235_8BIT, 0x23, 0x05 },
386 	{ GC2235_8BIT, 0x24, 0x10 },
387 	{ GC2235_8BIT, 0x25, 0x10 },
388 	{ GC2235_8BIT, 0x26, 0x02 },
389 	{ GC2235_8BIT, 0x21, 0x10 },
390 	{ GC2235_8BIT, 0x29, 0x01 },
391 	{ GC2235_8BIT, 0x2a, 0x02 },
392 	{ GC2235_8BIT, 0x2b, 0x02 },
393 	{ GC2235_8BIT, 0x10, 0x01 }, /* disable mipi */
394 	{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */
395 	{ GC2235_TOK_TERM, 0, 0 }
396 };
397 #endif
398 
399 static struct gc2235_reg const gc2235_1600_900_30fps[] = {
400 	{ GC2235_8BIT, 0x8b, 0xa0 },
401 	{ GC2235_8BIT, 0x8c, 0x02 },
402 
403 	{ GC2235_8BIT, 0x0d, 0x03 }, /* win height 932 */
404 	{ GC2235_8BIT, 0x0e, 0xa4 },
405 	{ GC2235_8BIT, 0x0f, 0x06 }, /* win width: 1632 */
406 	{ GC2235_8BIT, 0x10, 0x50 },
407 
408 	{ GC2235_8BIT, 0x90, 0x01 },
409 	{ GC2235_8BIT, 0x92, 0x02 },
410 	{ GC2235_8BIT, 0x94, 0x06 },
411 	{ GC2235_8BIT, 0x95, 0x03 }, /* crop win height 900 */
412 	{ GC2235_8BIT, 0x96, 0x84 },
413 	{ GC2235_8BIT, 0x97, 0x06 }, /* crop win width 1600 */
414 	{ GC2235_8BIT, 0x98, 0x40 },
415 	/* mimi init */
416 	{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */
417 	{ GC2235_8BIT, 0x01, 0x07 },
418 	{ GC2235_8BIT, 0x02, 0x11 },
419 	{ GC2235_8BIT, 0x03, 0x11 },
420 	{ GC2235_8BIT, 0x06, 0x80 },
421 	{ GC2235_8BIT, 0x11, 0x2b },
422 	/* set mipi buffer */
423 	{ GC2235_8BIT, 0x12, 0xd0 }, /* val_low = (width * 10 / 8) & 0xFF */
424 	{ GC2235_8BIT, 0x13, 0x07 }, /* val_high = (width * 10 / 8) >> 8 */
425 
426 	{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/
427 	{ GC2235_8BIT, 0x04, 0x10 },
428 	{ GC2235_8BIT, 0x05, 0x00 },
429 	{ GC2235_8BIT, 0x17, 0x01 },
430 	{ GC2235_8BIT, 0x22, 0x01 },
431 	{ GC2235_8BIT, 0x23, 0x05 },
432 	{ GC2235_8BIT, 0x24, 0x10 },
433 	{ GC2235_8BIT, 0x25, 0x10 },
434 	{ GC2235_8BIT, 0x26, 0x02 },
435 	{ GC2235_8BIT, 0x21, 0x10 },
436 	{ GC2235_8BIT, 0x29, 0x01 },
437 	{ GC2235_8BIT, 0x2a, 0x02 },
438 	{ GC2235_8BIT, 0x2b, 0x02 },
439 	{ GC2235_8BIT, 0x10, 0x01 }, /* disable mipi */
440 	{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */
441 	{ GC2235_TOK_TERM, 0, 0 }
442 };
443 
444 static struct gc2235_reg const gc2235_1616_1082_30fps[] = {
445 	{ GC2235_8BIT, 0x8b, 0xa0 },
446 	{ GC2235_8BIT, 0x8c, 0x02 },
447 
448 	{ GC2235_8BIT, 0x0d, 0x04 }, /* win height 1232 */
449 	{ GC2235_8BIT, 0x0e, 0xd0 },
450 	{ GC2235_8BIT, 0x0f, 0x06 }, /* win width: 1616 */
451 	{ GC2235_8BIT, 0x10, 0x50 },
452 
453 	{ GC2235_8BIT, 0x90, 0x01 },
454 	{ GC2235_8BIT, 0x92, 0x4a },
455 	{ GC2235_8BIT, 0x94, 0x00 },
456 	{ GC2235_8BIT, 0x95, 0x04 }, /* crop win height 1082 */
457 	{ GC2235_8BIT, 0x96, 0x3a },
458 	{ GC2235_8BIT, 0x97, 0x06 }, /* crop win width 1616 */
459 	{ GC2235_8BIT, 0x98, 0x50 },
460 	/* mimp init */
461 	{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */
462 	{ GC2235_8BIT, 0x01, 0x07 },
463 	{ GC2235_8BIT, 0x02, 0x11 },
464 	{ GC2235_8BIT, 0x03, 0x11 },
465 	{ GC2235_8BIT, 0x06, 0x80 },
466 	{ GC2235_8BIT, 0x11, 0x2b },
467 	/* set mipi buffer */
468 	{ GC2235_8BIT, 0x12, 0xe4 }, /* val_low = (width * 10 / 8) & 0xFF */
469 	{ GC2235_8BIT, 0x13, 0x07 }, /* val_high = (width * 10 / 8) >> 8 */
470 
471 	{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/
472 	{ GC2235_8BIT, 0x04, 0x10 },
473 	{ GC2235_8BIT, 0x05, 0x00 },
474 	{ GC2235_8BIT, 0x17, 0x01 },
475 	{ GC2235_8BIT, 0x22, 0x01 },
476 	{ GC2235_8BIT, 0x23, 0x05 },
477 	{ GC2235_8BIT, 0x24, 0x10 },
478 	{ GC2235_8BIT, 0x25, 0x10 },
479 	{ GC2235_8BIT, 0x26, 0x02 },
480 	{ GC2235_8BIT, 0x21, 0x10 },
481 	{ GC2235_8BIT, 0x29, 0x01 },
482 	{ GC2235_8BIT, 0x2a, 0x02 },
483 	{ GC2235_8BIT, 0x2b, 0x02 },
484 	{ GC2235_8BIT, 0x10, 0x01 }, /* disable mipi */
485 	{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */
486 	{ GC2235_TOK_TERM, 0, 0 }
487 };
488 
489 static struct gc2235_reg const gc2235_1616_1216_30fps[] = {
490 	{ GC2235_8BIT, 0x8b, 0xa0 },
491 	{ GC2235_8BIT, 0x8c, 0x02 },
492 
493 	{ GC2235_8BIT, 0x0d, 0x04 }, /* win height 1232 */
494 	{ GC2235_8BIT, 0x0e, 0xd0 },
495 	{ GC2235_8BIT, 0x0f, 0x06 }, /* win width: 1616 */
496 	{ GC2235_8BIT, 0x10, 0x50 },
497 
498 	{ GC2235_8BIT, 0x90, 0x01 },
499 	{ GC2235_8BIT, 0x92, 0x02 },
500 	{ GC2235_8BIT, 0x94, 0x00 },
501 	{ GC2235_8BIT, 0x95, 0x04 }, /* crop win height 1216 */
502 	{ GC2235_8BIT, 0x96, 0xc0 },
503 	{ GC2235_8BIT, 0x97, 0x06 }, /* crop win width 1616 */
504 	{ GC2235_8BIT, 0x98, 0x50 },
505 	/* mimi init */
506 	{ GC2235_8BIT, 0xfe, 0x03 }, /* switch to P3 */
507 	{ GC2235_8BIT, 0x01, 0x07 },
508 	{ GC2235_8BIT, 0x02, 0x11 },
509 	{ GC2235_8BIT, 0x03, 0x11 },
510 	{ GC2235_8BIT, 0x06, 0x80 },
511 	{ GC2235_8BIT, 0x11, 0x2b },
512 	/* set mipi buffer */
513 	{ GC2235_8BIT, 0x12, 0xe4 }, /* val_low = (width * 10 / 8) & 0xFF */
514 	{ GC2235_8BIT, 0x13, 0x07 }, /* val_high = (width * 10 / 8) >> 8 */
515 	{ GC2235_8BIT, 0x15, 0x12 }, /* DPHY mode*/
516 	{ GC2235_8BIT, 0x04, 0x10 },
517 	{ GC2235_8BIT, 0x05, 0x00 },
518 	{ GC2235_8BIT, 0x17, 0x01 },
519 	{ GC2235_8BIT, 0x22, 0x01 },
520 	{ GC2235_8BIT, 0x23, 0x05 },
521 	{ GC2235_8BIT, 0x24, 0x10 },
522 	{ GC2235_8BIT, 0x25, 0x10 },
523 	{ GC2235_8BIT, 0x26, 0x02 },
524 	{ GC2235_8BIT, 0x21, 0x10 },
525 	{ GC2235_8BIT, 0x29, 0x01 },
526 	{ GC2235_8BIT, 0x2a, 0x02 },
527 	{ GC2235_8BIT, 0x2b, 0x02 },
528 	{ GC2235_8BIT, 0x10, 0x01 }, /* disable mipi */
529 	{ GC2235_8BIT, 0xfe, 0x00 }, /* switch to P0 */
530 	{ GC2235_TOK_TERM, 0, 0 }
531 };
532 
533 static struct gc2235_resolution gc2235_res_preview[] = {
534 	{
535 		.desc = "gc2235_1600_900_30fps",
536 		.width = 1600,
537 		.height = 900,
538 		.pix_clk_freq = 30,
539 		.fps = 30,
540 		.used = 0,
541 		.pixels_per_line = 2132,
542 		.lines_per_frame = 1068,
543 		.bin_factor_x = 0,
544 		.bin_factor_y = 0,
545 		.bin_mode = 0,
546 		.skip_frames = 3,
547 		.regs = gc2235_1600_900_30fps,
548 	},
549 
550 	{
551 		.desc = "gc2235_1600_1066_30fps",
552 		.width = 1616,
553 		.height = 1082,
554 		.pix_clk_freq = 30,
555 		.fps = 30,
556 		.used = 0,
557 		.pixels_per_line = 2132,
558 		.lines_per_frame = 1368,
559 		.bin_factor_x = 0,
560 		.bin_factor_y = 0,
561 		.bin_mode = 0,
562 		.skip_frames = 3,
563 		.regs = gc2235_1616_1082_30fps,
564 	},
565 	{
566 		.desc = "gc2235_1600_1200_30fps",
567 		.width = 1616,
568 		.height = 1216,
569 		.pix_clk_freq = 30,
570 		.fps = 30,
571 		.used = 0,
572 		.pixels_per_line = 2132,
573 		.lines_per_frame = 1368,
574 		.bin_factor_x = 0,
575 		.bin_factor_y = 0,
576 		.bin_mode = 0,
577 		.skip_frames = 3,
578 		.regs = gc2235_1616_1216_30fps,
579 	},
580 
581 };
582 
583 #define N_RES_PREVIEW (ARRAY_SIZE(gc2235_res_preview))
584 
585 /*
586  * Disable non-preview configurations until the configuration selection is
587  * improved.
588  */
589 #if ENABLE_NON_PREVIEW
590 static struct gc2235_resolution gc2235_res_still[] = {
591 	{
592 		.desc = "gc2235_1600_900_30fps",
593 		.width = 1600,
594 		.height = 900,
595 		.pix_clk_freq = 30,
596 		.fps = 30,
597 		.used = 0,
598 		.pixels_per_line = 2132,
599 		.lines_per_frame = 1068,
600 		.bin_factor_x = 0,
601 		.bin_factor_y = 0,
602 		.bin_mode = 0,
603 		.skip_frames = 3,
604 		.regs = gc2235_1600_900_30fps,
605 	},
606 	{
607 		.desc = "gc2235_1600_1066_30fps",
608 		.width = 1616,
609 		.height = 1082,
610 		.pix_clk_freq = 30,
611 		.fps = 30,
612 		.used = 0,
613 		.pixels_per_line = 2132,
614 		.lines_per_frame = 1368,
615 		.bin_factor_x = 0,
616 		.bin_factor_y = 0,
617 		.bin_mode = 0,
618 		.skip_frames = 3,
619 		.regs = gc2235_1616_1082_30fps,
620 	},
621 	{
622 		.desc = "gc2235_1600_1200_30fps",
623 		.width = 1616,
624 		.height = 1216,
625 		.pix_clk_freq = 30,
626 		.fps = 30,
627 		.used = 0,
628 		.pixels_per_line = 2132,
629 		.lines_per_frame = 1368,
630 		.bin_factor_x = 0,
631 		.bin_factor_y = 0,
632 		.bin_mode = 0,
633 		.skip_frames = 3,
634 		.regs = gc2235_1616_1216_30fps,
635 	},
636 
637 };
638 
639 #define N_RES_STILL (ARRAY_SIZE(gc2235_res_still))
640 
641 static struct gc2235_resolution gc2235_res_video[] = {
642 	{
643 		.desc = "gc2235_1296_736_30fps",
644 		.width = 1296,
645 		.height = 736,
646 		.pix_clk_freq = 30,
647 		.fps = 30,
648 		.used = 0,
649 		.pixels_per_line = 1828,
650 		.lines_per_frame = 888,
651 		.bin_factor_x = 0,
652 		.bin_factor_y = 0,
653 		.bin_mode = 0,
654 		.skip_frames = 3,
655 		.regs = gc2235_1296_736_30fps,
656 	},
657 	{
658 		.desc = "gc2235_960_640_30fps",
659 		.width = 960,
660 		.height = 640,
661 		.pix_clk_freq = 30,
662 		.fps = 30,
663 		.used = 0,
664 		.pixels_per_line = 1492,
665 		.lines_per_frame = 792,
666 		.bin_factor_x = 0,
667 		.bin_factor_y = 0,
668 		.bin_mode = 0,
669 		.skip_frames = 3,
670 		.regs = gc2235_960_640_30fps,
671 	},
672 
673 };
674 
675 #define N_RES_VIDEO (ARRAY_SIZE(gc2235_res_video))
676 #endif
677 
678 static struct gc2235_resolution *gc2235_res = gc2235_res_preview;
679 static unsigned long N_RES = N_RES_PREVIEW;
680 #endif
681