hc
2023-03-21 4b55d97acc464242bcd6a8ae77b8ff37c22dec58
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,
   RSET,
   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_ */