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