summaryrefslogtreecommitdiffstats
path: root/drivers/media/i2c/s5c73m3/s5c73m3.h
blob: 653f68e7ea07b5ec9841f2d24eb3e414e179ed61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
/*
 * Samsung LSI S5C73M3 8M pixel camera driver
 *
 * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
 * Sylwester Nawrocki <s.nawrocki@samsung.com>
 * Andrzej Hajda <a.hajda@samsung.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */
#ifndef S5C73M3_H_
#define S5C73M3_H_

#include <linux/clk.h>
#include <linux/kernel.h>
#include <linux/regulator/consumer.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-subdev.h>
#include <media/i2c/s5c73m3.h>

#define DRIVER_NAME			"S5C73M3"

#define S5C73M3_ISP_FMT			MEDIA_BUS_FMT_VYUY8_2X8
#define S5C73M3_JPEG_FMT		MEDIA_BUS_FMT_S5C_UYVY_JPEG_1X8

/* Subdevs pad index definitions */
enum s5c73m3_pads {
	S5C73M3_ISP_PAD,
	S5C73M3_JPEG_PAD,
	S5C73M3_NUM_PADS
};

enum s5c73m3_oif_pads {
	OIF_ISP_PAD,
	OIF_JPEG_PAD,
	OIF_SOURCE_PAD,
	OIF_NUM_PADS
};

#define S5C73M3_SENSOR_FW_LEN		6
#define S5C73M3_SENSOR_TYPE_LEN		12

#define S5C73M3_REG(_addrh, _addrl) (((_addrh) << 16) | _addrl)

#define AHB_MSB_ADDR_PTR			0xfcfc
#define REG_CMDWR_ADDRH				0x0050
#define REG_CMDWR_ADDRL				0x0054
#define REG_CMDRD_ADDRH				0x0058
#define REG_CMDRD_ADDRL				0x005c
#define REG_CMDBUF_ADDR				0x0f14

#define REG_I2C_SEQ_STATUS			S5C73M3_REG(0x0009, 0x59A6)
#define  SEQ_END_PLL				(1<<0x0)
#define  SEQ_END_SENSOR				(1<<0x1)
#define  SEQ_END_GPIO				(1<<0x2)
#define  SEQ_END_FROM				(1<<0x3)
#define  SEQ_END_STABLE_AE_AWB			(1<<0x4)
#define  SEQ_END_READY_I2C_CMD			(1<<0x5)

#define REG_I2C_STATUS				S5C73M3_REG(0x0009, 0x599E)
#define  I2C_STATUS_CIS_I2C			(1<<0x0)
#define  I2C_STATUS_AF_INIT			(1<<0x1)
#define  I2C_STATUS_CAL_DATA			(1<<0x2)
#define  I2C_STATUS_FRAME_COUNT			(1<<0x3)
#define  I2C_STATUS_FROM_INIT			(1<<0x4)
#define  I2C_STATUS_I2C_CIS_STREAM_OFF		(1<<0x5)
#define  I2C_STATUS_I2C_N_CMD_OVER		(1<<0x6)
#define  I2C_STATUS_I2C_N_CMD_MISMATCH		(1<<0x7)
#define  I2C_STATUS_CHECK_BIN_CRC		(1<<0x8)
#define  I2C_STATUS_EXCEPTION			(1<<0x9)
#define  I2C_STATUS_INIF_INIT_STATE		(0x8)

#define REG_STATUS				S5C73M3_REG(0x0009, 0x5080)
#define  REG_STATUS_BOOT_SUB_MAIN_ENTER		0xff01
#define  REG_STATUS_BOOT_SRAM_TIMING_OK		0xff02
#define  REG_STATUS_BOOT_INTERRUPTS_EN		0xff03
#define  REG_STATUS_BOOT_R_PLL_DONE		0xff04
#define  REG_STATUS_BOOT_R_PLL_LOCKTIME_DONE	0xff05
#define  REG_STATUS_BOOT_DELAY_COUNT_DONE	0xff06
#define  REG_STATUS_BOOT_I_PLL_DONE		0xff07
#define  REG_STATUS_BOOT_I_PLL_LOCKTIME_DONE	0xff08
#define  REG_STATUS_BOOT_PLL_INIT_OK		0xff09
#define  REG_STATUS_BOOT_SENSOR_INIT_OK		0xff0a
#define  REG_STATUS_BOOT_GPIO_SETTING_OK	0xff0b
#define  REG_STATUS_BOOT_READ_CAL_DATA_OK	0xff0c
#define  REG_STATUS_BOOT_STABLE_AE_AWB_OK	0xff0d
#define  REG_STATUS_ISP_COMMAND_COMPLETED	0xffff
#define  REG_STATUS_EXCEPTION_OCCURED		0xdead

#define COMM_RESULT_OFFSET			S5C73M3_REG(0x0009, 0x5000)

#define COMM_IMG_OUTPUT				0x0902
#define  COMM_IMG_OUTPUT_HDR			0x0008
#define  COMM_IMG_OUTPUT_YUV			0x0009
#define  COMM_IMG_OUTPUT_INTERLEAVED		0x000d

#define COMM_STILL_PRE_FLASH			0x0a00
#define  COMM_STILL_PRE_FLASH_FIRE		0x0000
#define  COMM_STILL_PRE_FLASH_NON_FIRED		0x0000
#define  COMM_STILL_PRE_FLASH_FIRED		0x0001

#define COMM_STILL_MAIN_FLASH			0x0a02
#define  COMM_STILL_MAIN_FLASH_CANCEL		0x0001
#define  COMM_STILL_MAIN_FLASH_FIRE		0x0002

#define COMM_ZOOM_STEP				0x0b00

#define COMM_IMAGE_EFFECT			0x0b0a
#define  COMM_IMAGE_EFFECT_NONE			0x0001
#define  COMM_IMAGE_EFFECT_NEGATIVE		0x0002
#define  COMM_IMAGE_EFFECT_AQUA			0x0003
#define  COMM_IMAGE_EFFECT_SEPIA		0x0004
#define  COMM_IMAGE_EFFECT_MONO			0x0005

#define COMM_IMAGE_QUALITY			0x0b0c
#define  COMM_IMAGE_QUALITY_SUPERFINE		0x0000
#define  COMM_IMAGE_QUALITY_FINE		0x0001
#define  COMM_IMAGE_QUALITY_NORMAL		0x0002

#define COMM_FLASH_MODE				0x0b0e
#define  COMM_FLASH_MODE_OFF			0x0000
#define  COMM_FLASH_MODE_ON			0x0001
#define  COMM_FLASH_MODE_AUTO			0x0002

#define COMM_FLASH_STATUS			0x0b80
#define  COMM_FLASH_STATUS_OFF			0x0001
#define  COMM_FLASH_STATUS_ON			0x0002
#define  COMM_FLASH_STATUS_AUTO			0x0003

#define COMM_FLASH_TORCH			0x0b12
#define  COMM_FLASH_TORCH_OFF			0x0000
#define  COMM_FLASH_TORCH_ON			0x0001

#define COMM_AE_NEEDS_FLASH			0x0cba
#define  COMM_AE_NEEDS_FLASH_OFF		0x0000
#define  COMM_AE_NEEDS_FLASH_ON			0x0001

#define COMM_CHG_MODE				0x0b10
#define  COMM_CHG_MODE_NEW			0x8000
#define  COMM_CHG_MODE_SUBSAMPLING_HALF		0x2000
#define  COMM_CHG_MODE_SUBSAMPLING_QUARTER	0x4000

#define  COMM_CHG_MODE_YUV_320_240		0x0001
#define  COMM_CHG_MODE_YUV_640_480		0x0002
#define  COMM_CHG_MODE_YUV_880_720		0x0003
#define  COMM_CHG_MODE_YUV_960_720		0x0004
#define  COMM_CHG_MODE_YUV_1184_666		0x0005
#define  COMM_CHG_MODE_YUV_1280_720		0x0006
#define  COMM_CHG_MODE_YUV_1536_864		0x0007
#define  COMM_CHG_MODE_YUV_1600_1200		0x0008
#define  COMM_CHG_MODE_YUV_1632_1224		0x0009
#define  COMM_CHG_MODE_YUV_1920_1080		0x000a
#define  COMM_CHG_MODE_YUV_1920_1440		0x000b
#define  COMM_CHG_MODE_YUV_2304_1296		0x000c
#define  COMM_CHG_MODE_YUV_3264_2448		0x000d
#define  COMM_CHG_MODE_YUV_352_288		0x000e
#define  COMM_CHG_MODE_YUV_1008_672		0x000f

#define  COMM_CHG_MODE_JPEG_640_480		0x0010
#define  COMM_CHG_MODE_JPEG_800_450		0x0020
#define  COMM_CHG_MODE_JPEG_800_600		0x0030
#define  COMM_CHG_MODE_JPEG_1280_720		0x0040
#define  COMM_CHG_MODE_JPEG_1280_960		0x0050
#define  COMM_CHG_MODE_JPEG_1600_900		0x0060
#define  COMM_CHG_MODE_JPEG_1600_1200		0x0070
#define  COMM_CHG_MODE_JPEG_2048_1152		0x0080
#define  COMM_CHG_MODE_JPEG_2048_1536		0x0090
#define  COMM_CHG_MODE_JPEG_2560_1440		0x00a0
#define  COMM_CHG_MODE_JPEG_2560_1920		0x00b0
#define  COMM_CHG_MODE_JPEG_3264_2176		0x00c0
#define  COMM_CHG_MODE_JPEG_1024_768		0x00d0
#define  COMM_CHG_MODE_JPEG_3264_1836		0x00e0
#define  COMM_CHG_MODE_JPEG_3264_2448		0x00f0

#define COMM_AF_CON				0x0e00
#define  COMM_AF_CON_STOP			0x0000
#define  COMM_AF_CON_SCAN			0x0001 /* Full Search */
#define  COMM_AF_CON_START			0x0002 /* Fast Search */

#define COMM_AF_CAL				0x0e06
#define COMM_AF_TOUCH_AF			0x0e0a

#define REG_AF_STATUS				S5C73M3_REG(0x0009, 0x5e80)
#define  REG_CAF_STATUS_FIND_SEARCH_DIR		0x0001
#define  REG_CAF_STATUS_FOCUSING		0x0002
#define  REG_CAF_STATUS_FOCUSED			0x0003
#define  REG_CAF_STATUS_UNFOCUSED		0x0004
#define  REG_AF_STATUS_INVALID			0x0010
#define  REG_AF_STATUS_FOCUSING			0x0020
#define  REG_AF_STATUS_FOCUSED			0x0030
#define  REG_AF_STATUS_UNFOCUSED		0x0040

#define REG_AF_TOUCH_POSITION			S5C73M3_REG(0x0009, 0x5e8e)
#define COMM_AF_FACE_ZOOM			0x0e10

#define COMM_AF_MODE				0x0e02
#define  COMM_AF_MODE_NORMAL			0x0000
#define  COMM_AF_MODE_MACRO			0x0001
#define  COMM_AF_MODE_MOVIE_CAF_START		0x0002
#define  COMM_AF_MODE_MOVIE_CAF_STOP		0x0003
#define  COMM_AF_MODE_PREVIEW_CAF_START		0x0004
#define  COMM_AF_MODE_PREVIEW_CAF_STOP		0x0005

#define COMM_AF_SOFTLANDING			0x0e16
#define  COMM_AF_SOFTLANDING_ON			0x0000
#define  COMM_AF_SOFTLANDING_RES_COMPLETE	0x0001

#define COMM_FACE_DET				0x0e0c
#define  COMM_FACE_DET_OFF			0x0000
#define  COMM_FACE_DET_ON			0x0001

#define COMM_FACE_DET_OSD			0x0e0e
#define  COMM_FACE_DET_OSD_OFF			0x0000
#define  COMM_FACE_DET_OSD_ON			0x0001

#define COMM_AE_CON				0x0c00
#define  COMM_AE_STOP				0x0000 /* lock */
#define  COMM_AE_START				0x0001 /* unlock */

#define COMM_ISO				0x0c02
#define  COMM_ISO_AUTO				0x0000
#define  COMM_ISO_100				0x0001
#define  COMM_ISO_200				0x0002
#define  COMM_ISO_400				0x0003
#define  COMM_ISO_800				0x0004
#define  COMM_ISO_SPORTS			0x0005
#define  COMM_ISO_NIGHT				0x0006
#define  COMM_ISO_INDOOR			0x0007

/* 0x00000 (-2.0 EV)...0x0008 (2.0 EV), 0.5EV step */
#define COMM_EV					0x0c04

#define COMM_METERING				0x0c06
#define  COMM_METERING_CENTER			0x0000
#define  COMM_METERING_SPOT			0x0001
#define  COMM_METERING_AVERAGE			0x0002
#define  COMM_METERING_SMART			0x0003

#define COMM_WDR				0x0c08
#define  COMM_WDR_OFF				0x0000
#define  COMM_WDR_ON				0x0001

#define COMM_FLICKER_MODE			0x0c12
#define  COMM_FLICKER_NONE			0x0000
#define  COMM_FLICKER_MANUAL_50HZ		0x0001
#define  COMM_FLICKER_MANUAL_60HZ		0x0002
#define  COMM_FLICKER_AUTO			0x0003
#define  COMM_FLICKER_AUTO_50HZ			0x0004
#define  COMM_FLICKER_AUTO_60HZ			0x0005

#define COMM_FRAME_RATE				0x0c1e
#define  COMM_FRAME_RATE_AUTO_SET		0x0000
#define  COMM_FRAME_RATE_FIXED_30FPS		0x0002
#define  COMM_FRAME_RATE_FIXED_20FPS		0x0003
#define  COMM_FRAME_RATE_FIXED_15FPS		0x0004
#define  COMM_FRAME_RATE_FIXED_60FPS		0x0007
#define  COMM_FRAME_RATE_FIXED_120FPS		0x0008
#define  COMM_FRAME_RATE_FIXED_7FPS		0x0009
#define  COMM_FRAME_RATE_FIXED_10FPS		0x000a
#define  COMM_FRAME_RATE_FIXED_90FPS		0x000b
#define  COMM_FRAME_RATE_ANTI_SHAKE		0x0013

/* 0x0000...0x0004 -> sharpness: 0, 1, 2, -1, -2 */
#define COMM_SHARPNESS				0x0c14

/* 0x0000...0x0004 -> saturation: 0, 1, 2, -1, -2 */
#define COMM_SATURATION				0x0c16

/* 0x0000...0x0004 -> contrast: 0, 1, 2, -1, -2 */
#define COMM_CONTRAST				0x0c18

#define COMM_SCENE_MODE				0x0c1a
#define  COMM_SCENE_MODE_NONE			0x0000
#define  COMM_SCENE_MODE_PORTRAIT		0x0001
#define  COMM_SCENE_MODE_LANDSCAPE		0x0002
#define  COMM_SCENE_MODE_SPORTS			0x0003
#define  COMM_SCENE_MODE_INDOOR			0x0004
#define  COMM_SCENE_MODE_BEACH			0x0005
#define  COMM_SCENE_MODE_SUNSET			0x0006
#define  COMM_SCENE_MODE_DAWN			0x0007
#define  COMM_SCENE_MODE_FALL			0x0008
#define  COMM_SCENE_MODE_NIGHT			0x0009
#define  COMM_SCENE_MODE_AGAINST_LIGHT		0x000a
#define  COMM_SCENE_MODE_FIRE			0x000b
#define  COMM_SCENE_MODE_TEXT			0x000c
#define  COMM_SCENE_MODE_CANDLE			0x000d

#define COMM_AE_AUTO_BRACKET			0x0b14
#define  COMM_AE_AUTO_BRAKET_EV05		0x0080
#define  COMM_AE_AUTO_BRAKET_EV10		0x0100
#define  COMM_AE_AUTO_BRAKET_EV15		0x0180
#define  COMM_AE_AUTO_BRAKET_EV20		0x0200

#define COMM_SENSOR_STREAMING			0x090a
#define  COMM_SENSOR_STREAMING_OFF		0x0000
#define  COMM_SENSOR_STREAMING_ON		0x0001

#define COMM_AWB_MODE				0x0d02
#define  COMM_AWB_MODE_INCANDESCENT		0x0000
#define  COMM_AWB_MODE_FLUORESCENT1		0x0001
#define  COMM_AWB_MODE_FLUORESCENT2		0x0002
#define  COMM_AWB_MODE_DAYLIGHT			0x0003
#define  COMM_AWB_MODE_CLOUDY			0x0004
#define  COMM_AWB_MODE_AUTO			0x0005

#define COMM_AWB_CON				0x0d00
#define  COMM_AWB_STOP				0x0000 /* lock */
#define  COMM_AWB_START				0x0001 /* unlock */

#define COMM_FW_UPDATE				0x0906
#define  COMM_FW_UPDATE_NOT_READY		0x0000
#define  COMM_FW_UPDATE_SUCCESS			0x0005
#define  COMM_FW_UPDATE_FAIL			0x0007
#define  COMM_FW_UPDATE_BUSY			0xffff


#define S5C73M3_MAX_SUPPLIES			6
#define S5C73M3_DEFAULT_MCLK_FREQ		24000000U

struct s5c73m3_ctrls {
	struct v4l2_ctrl_handler handler;
	struct {
		/* exposure/exposure bias cluster */
		struct v4l2_ctrl *auto_exposure;
		struct v4l2_ctrl *exposure_bias;
		struct v4l2_ctrl *exposure_metering;
	};
	struct {
		/* iso/auto iso cluster */
		struct v4l2_ctrl *auto_iso;
		struct v4l2_ctrl *iso;
	};
	struct v4l2_ctrl *auto_wb;
	struct {
		/* continuous auto focus/auto focus cluster */
		struct v4l2_ctrl *focus_auto;
		struct v4l2_ctrl *af_start;
		struct v4l2_ctrl *af_stop;
		struct v4l2_ctrl *af_status;
		struct v4l2_ctrl *af_distance;
	};

	struct v4l2_ctrl *aaa_lock;
	struct v4l2_ctrl *colorfx;
	struct v4l2_ctrl *contrast;
	struct v4l2_ctrl *saturation;
	struct v4l2_ctrl *sharpness;
	struct v4l2_ctrl *zoom;
	struct v4l2_ctrl *wdr;
	struct v4l2_ctrl *stabilization;
	struct v4l2_ctrl *jpeg_quality;
	struct v4l2_ctrl *scene_mode;
};

enum s5c73m3_gpio_id {
	STBY,
	RST,
	GPIO_NUM,
};

enum s5c73m3_resolution_types {
	RES_ISP,
	RES_JPEG,
};

struct s5c73m3_interval {
	u16 fps_reg;
	struct v4l2_fract interval;
	/* Maximum rectangle for the interval */
	struct v4l2_frmsize_discrete size;
};

struct s5c73m3 {
	struct v4l2_subdev sensor_sd;
	struct media_pad sensor_pads[S5C73M3_NUM_PADS];

	struct v4l2_subdev oif_sd;
	struct media_pad oif_pads[OIF_NUM_PADS];

	struct spi_driver spidrv;
	struct spi_device *spi_dev;
	struct i2c_client *i2c_client;
	u32 i2c_write_address;
	u32 i2c_read_address;

	struct regulator_bulk_data supplies[S5C73M3_MAX_SUPPLIES];
	struct s5c73m3_gpio gpio[GPIO_NUM];

	struct clk *clock;

	/* External master clock frequency */
	u32 mclk_frequency;
	/* Video bus type - MIPI-CSI2/parallel */
	enum v4l2_mbus_type bus_type;

	const struct s5c73m3_frame_size *sensor_pix_size[2];
	const struct s5c73m3_frame_size *oif_pix_size[2];
	u32 mbus_code;

	const struct s5c73m3_interval *fiv;

	struct v4l2_mbus_frame_desc frame_desc;
	/* protects the struct members below */
	struct mutex lock;

	struct s5c73m3_ctrls ctrls;

	u8 streaming:1;
	u8 apply_fmt:1;
	u8 apply_fiv:1;
	u8 isp_ready:1;

	short power;

	char sensor_fw[S5C73M3_SENSOR_FW_LEN + 2];
	char sensor_type[S5C73M3_SENSOR_TYPE_LEN + 2];
	char fw_file_version[2];
	unsigned int fw_size;
};

struct s5c73m3_frame_size {
	u32 width;
	u32 height;
	u8 reg_val;
};

extern int s5c73m3_dbg;

int s5c73m3_register_spi_driver(struct s5c73m3 *state);
void s5c73m3_unregister_spi_driver(struct s5c73m3 *state);
int s5c73m3_spi_write(struct s5c73m3 *state, const void *addr,
		      const unsigned int len, const unsigned int tx_size);
int s5c73m3_spi_read(struct s5c73m3 *state, void *addr,
		      const unsigned int len, const unsigned int tx_size);

int s5c73m3_read(struct s5c73m3 *state, u32 addr, u16 *data);
int s5c73m3_write(struct s5c73m3 *state, u32 addr, u16 data);
int s5c73m3_isp_command(struct s5c73m3 *state, u16 command, u16 data);
int s5c73m3_init_controls(struct s5c73m3 *state);

static inline struct v4l2_subdev *ctrl_to_sensor_sd(struct v4l2_ctrl *ctrl)
{
	return &container_of(ctrl->handler, struct s5c73m3,
			     ctrls.handler)->sensor_sd;
}

static inline struct s5c73m3 *sensor_sd_to_s5c73m3(struct v4l2_subdev *sd)
{
	return container_of(sd, struct s5c73m3, sensor_sd);
}

static inline struct s5c73m3 *oif_sd_to_s5c73m3(struct v4l2_subdev *sd)
{
	return container_of(sd, struct s5c73m3, oif_sd);
}
#endif	/* S5C73M3_H_ */