2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
5 #include <linux/delay.h>
6 #include <linux/types.h>
7 #include <linux/slab.h>
9 #include <linux/uaccess.h>
10 #include <linux/miscdevice.h>
11 #include <linux/kernel.h>
12 #include <media/msm_camera.h>
13 #include <mach/gpio.h>
14 #include <mach/camera.h>
17 /*=============================================================
18 SENSOR REGISTER DEFINES
19 ==============================================================*/
20 #define MT9P012_REG_MODEL_ID 0x0000
21 #define MT9P012_MODEL_ID 0x2801
22 #define REG_GROUPED_PARAMETER_HOLD 0x0104
23 #define GROUPED_PARAMETER_HOLD 0x0100
24 #define GROUPED_PARAMETER_UPDATE 0x0000
25 #define REG_COARSE_INT_TIME 0x3012
26 #define REG_VT_PIX_CLK_DIV 0x0300
27 #define REG_VT_SYS_CLK_DIV 0x0302
28 #define REG_PRE_PLL_CLK_DIV 0x0304
29 #define REG_PLL_MULTIPLIER 0x0306
30 #define REG_OP_PIX_CLK_DIV 0x0308
31 #define REG_OP_SYS_CLK_DIV 0x030A
32 #define REG_SCALE_M 0x0404
33 #define REG_FRAME_LENGTH_LINES 0x300A
34 #define REG_LINE_LENGTH_PCK 0x300C
35 #define REG_X_ADDR_START 0x3004
36 #define REG_Y_ADDR_START 0x3002
37 #define REG_X_ADDR_END 0x3008
38 #define REG_Y_ADDR_END 0x3006
39 #define REG_X_OUTPUT_SIZE 0x034C
40 #define REG_Y_OUTPUT_SIZE 0x034E
41 #define REG_FINE_INTEGRATION_TIME 0x3014
42 #define REG_ROW_SPEED 0x3016
43 #define MT9P012_REG_RESET_REGISTER 0x301A
44 #define MT9P012_RESET_REGISTER_PWON 0x10CC
45 #define MT9P012_RESET_REGISTER_PWOFF 0x10C8
46 #define REG_READ_MODE 0x3040
47 #define REG_GLOBAL_GAIN 0x305E
48 #define REG_TEST_PATTERN_MODE 0x3070
53 enum mt9p012_test_mode
{
60 enum mt9p012_resolution
{
66 enum mt9p012_reg_update
{
67 /* Sensor egisters that need to be updated during initialization */
69 /* Sensor egisters that needs periodic I2C writes */
71 /* All the sensor Registers will be updated */
73 /* Not valid update */
77 enum mt9p012_setting
{
82 /* actuator's Slave Address */
83 #define MT9P012_AF_I2C_ADDR 0x18
85 /* AF Total steps parameters */
86 #define MT9P012_STEPS_NEAR_TO_CLOSEST_INF 32
87 #define MT9P012_TOTAL_STEPS_NEAR_TO_FAR 32
89 #define MT9P012_MU5M0_PREVIEW_DUMMY_PIXELS 0
90 #define MT9P012_MU5M0_PREVIEW_DUMMY_LINES 0
92 /* Time in milisecs for waiting for the sensor to reset.*/
93 #define MT9P012_RESET_DELAY_MSECS 66
95 /* for 20 fps preview */
96 #define MT9P012_DEFAULT_CLOCK_RATE 24000000
97 #define MT9P012_DEFAULT_MAX_FPS 26 /* ???? */
100 struct work_struct work
;
102 static struct mt9p012_work
*mt9p012_sensorw
;
103 static struct i2c_client
*mt9p012_client
;
105 struct mt9p012_ctrl
{
106 const struct msm_camera_sensor_info
*sensordata
;
109 uint32_t fps_divider
; /* init to 1 * 0x00000400 */
110 uint32_t pict_fps_divider
; /* init to 1 * 0x00000400 */
112 uint16_t curr_lens_pos
;
113 uint16_t init_curr_lens_pos
;
114 uint16_t my_reg_gain
;
115 uint32_t my_reg_line_count
;
117 enum mt9p012_resolution prev_res
;
118 enum mt9p012_resolution pict_res
;
119 enum mt9p012_resolution curr_res
;
120 enum mt9p012_test_mode set_test
;
124 static struct mt9p012_ctrl
*mt9p012_ctrl
;
125 static DECLARE_WAIT_QUEUE_HEAD(mt9p012_wait_queue
);
126 DECLARE_MUTEX(mt9p012_sem
);
128 /*=============================================================
129 EXTERNAL DECLARATIONS
130 ==============================================================*/
131 extern struct mt9p012_reg mt9p012_regs
; /* from mt9p012_reg.c */
135 /*=============================================================*/
137 static int mt9p012_i2c_rxdata(unsigned short saddr
, unsigned char *rxdata
,
140 struct i2c_msg msgs
[] = {
155 if (i2c_transfer(mt9p012_client
->adapter
, msgs
, 2) < 0) {
156 CDBG("mt9p012_i2c_rxdata failed!\n");
163 static int32_t mt9p012_i2c_read_w(unsigned short saddr
, unsigned short raddr
,
164 unsigned short *rdata
)
167 unsigned char buf
[4];
172 memset(buf
, 0, sizeof(buf
));
174 buf
[0] = (raddr
& 0xFF00)>>8;
175 buf
[1] = (raddr
& 0x00FF);
177 rc
= mt9p012_i2c_rxdata(saddr
, buf
, 2);
181 *rdata
= buf
[0] << 8 | buf
[1];
184 CDBG("mt9p012_i2c_read failed!\n");
189 static int32_t mt9p012_i2c_txdata(unsigned short saddr
, unsigned char *txdata
,
192 struct i2c_msg msg
[] = {
201 if (i2c_transfer(mt9p012_client
->adapter
, msg
, 1) < 0) {
202 CDBG("mt9p012_i2c_txdata failed\n");
209 static int32_t mt9p012_i2c_write_b(unsigned short saddr
, unsigned short baddr
,
210 unsigned short bdata
)
213 unsigned char buf
[2];
215 memset(buf
, 0, sizeof(buf
));
218 rc
= mt9p012_i2c_txdata(saddr
, buf
, 2);
221 CDBG("i2c_write failed, saddr = 0x%x addr = 0x%x, val =0x%x!\n",
222 saddr
, baddr
, bdata
);
227 static int32_t mt9p012_i2c_write_w(unsigned short saddr
, unsigned short waddr
,
228 unsigned short wdata
)
231 unsigned char buf
[4];
233 memset(buf
, 0, sizeof(buf
));
234 buf
[0] = (waddr
& 0xFF00)>>8;
235 buf
[1] = (waddr
& 0x00FF);
236 buf
[2] = (wdata
& 0xFF00)>>8;
237 buf
[3] = (wdata
& 0x00FF);
239 rc
= mt9p012_i2c_txdata(saddr
, buf
, 4);
242 CDBG("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
248 static int32_t mt9p012_i2c_write_w_table(
249 struct mt9p012_i2c_reg_conf
*reg_conf_tbl
, int num
)
254 for (i
= 0; i
< num
; i
++) {
255 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
256 reg_conf_tbl
->waddr
, reg_conf_tbl
->wdata
);
265 static int32_t mt9p012_test(enum mt9p012_test_mode mo
)
269 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
270 REG_GROUPED_PARAMETER_HOLD
,
271 GROUPED_PARAMETER_HOLD
);
278 rc
= mt9p012_i2c_write_w_table(mt9p012_regs
.ttbl
, mt9p012_regs
.ttbl_size
);
282 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
283 REG_TEST_PATTERN_MODE
, (uint16_t)mo
);
288 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
289 REG_GROUPED_PARAMETER_HOLD
,
290 GROUPED_PARAMETER_UPDATE
);
297 static int32_t mt9p012_lens_shading_enable(uint8_t is_enable
)
301 CDBG("%s: entered. enable = %d\n", __func__
, is_enable
);
303 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
304 REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
);
308 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
, 0x3780,
309 ((uint16_t) is_enable
) << 15);
313 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
314 REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
);
316 CDBG("%s: exiting. rc = %d\n", __func__
, rc
);
320 static int32_t mt9p012_set_lc(void)
324 rc
= mt9p012_i2c_write_w_table(mt9p012_regs
.lctbl
, mt9p012_regs
.lctbl_size
);
328 rc
= mt9p012_i2c_write_w_table(mt9p012_regs
.rftbl
, mt9p012_regs
.rftbl_size
);
333 static void mt9p012_get_pict_fps(uint16_t fps
, uint16_t *pfps
)
335 /* input fps is preview fps in Q8 format */
336 uint32_t divider
; /*Q10 */
337 uint32_t pclk_mult
; /*Q10 */
339 if (mt9p012_ctrl
->prev_res
== QTR_SIZE
) {
341 (((mt9p012_regs
.reg_pat
[RES_PREVIEW
].frame_length_lines
*
342 mt9p012_regs
.reg_pat
[RES_PREVIEW
].line_length_pck
) * 0x00000400) /
343 (mt9p012_regs
.reg_pat
[RES_CAPTURE
].frame_length_lines
*
344 mt9p012_regs
.reg_pat
[RES_CAPTURE
].line_length_pck
));
347 (uint32_t) ((mt9p012_regs
.reg_pat
[RES_CAPTURE
].pll_multiplier
*
348 0x00000400) / (mt9p012_regs
.reg_pat
[RES_PREVIEW
].pll_multiplier
));
350 /* full size resolution used for preview. */
351 divider
= 0x00000400; /*1.0 */
352 pclk_mult
= 0x00000400; /*1.0 */
355 /* Verify PCLK settings and frame sizes. */
356 *pfps
= (uint16_t) (fps
* divider
* pclk_mult
/ 0x00000400 /
360 static uint16_t mt9p012_get_prev_lines_pf(void)
362 if (mt9p012_ctrl
->prev_res
== QTR_SIZE
)
363 return mt9p012_regs
.reg_pat
[RES_PREVIEW
].frame_length_lines
;
365 return mt9p012_regs
.reg_pat
[RES_CAPTURE
].frame_length_lines
;
368 static uint16_t mt9p012_get_prev_pixels_pl(void)
370 if (mt9p012_ctrl
->prev_res
== QTR_SIZE
)
371 return mt9p012_regs
.reg_pat
[RES_PREVIEW
].line_length_pck
;
373 return mt9p012_regs
.reg_pat
[RES_CAPTURE
].line_length_pck
;
376 static uint16_t mt9p012_get_pict_lines_pf(void)
378 return mt9p012_regs
.reg_pat
[RES_CAPTURE
].frame_length_lines
;
381 static uint16_t mt9p012_get_pict_pixels_pl(void)
383 return mt9p012_regs
.reg_pat
[RES_CAPTURE
].line_length_pck
;
386 static uint32_t mt9p012_get_pict_max_exp_lc(void)
388 uint16_t snapshot_lines_per_frame
;
390 if (mt9p012_ctrl
->pict_res
== QTR_SIZE
)
391 snapshot_lines_per_frame
=
392 mt9p012_regs
.reg_pat
[RES_PREVIEW
].frame_length_lines
- 1;
394 snapshot_lines_per_frame
=
395 mt9p012_regs
.reg_pat
[RES_CAPTURE
].frame_length_lines
- 1;
397 return snapshot_lines_per_frame
* 24;
400 static int32_t mt9p012_set_fps(struct fps_cfg
*fps
)
402 /* input is new fps in Q10 format */
405 mt9p012_ctrl
->fps_divider
= fps
->fps_div
;
406 mt9p012_ctrl
->pict_fps_divider
= fps
->pict_fps_div
;
409 mt9p012_i2c_write_w(mt9p012_client
->addr
,
410 REG_GROUPED_PARAMETER_HOLD
,
411 GROUPED_PARAMETER_HOLD
);
416 mt9p012_i2c_write_w(mt9p012_client
->addr
,
418 (mt9p012_regs
.reg_pat
[RES_PREVIEW
].line_length_pck
*
419 fps
->f_mult
/ 0x00000400));
424 mt9p012_i2c_write_w(mt9p012_client
->addr
,
425 REG_GROUPED_PARAMETER_HOLD
,
426 GROUPED_PARAMETER_UPDATE
);
431 static int32_t mt9p012_write_exp_gain(uint16_t gain
, uint32_t line
)
433 uint16_t max_legal_gain
= 0x01FF;
434 uint32_t line_length_ratio
= 0x00000400;
435 enum mt9p012_setting setting
;
438 CDBG("Line:%d mt9p012_write_exp_gain \n", __LINE__
);
440 if (mt9p012_ctrl
->sensormode
== SENSOR_PREVIEW_MODE
) {
441 mt9p012_ctrl
->my_reg_gain
= gain
;
442 mt9p012_ctrl
->my_reg_line_count
= (uint16_t)line
;
445 if (gain
> max_legal_gain
) {
446 CDBG("Max legal gain Line:%d \n", __LINE__
);
447 gain
= max_legal_gain
;
450 /* Verify no overflow */
451 if (mt9p012_ctrl
->sensormode
!= SENSOR_SNAPSHOT_MODE
) {
452 line
= (uint32_t)(line
* mt9p012_ctrl
->fps_divider
/
454 setting
= RES_PREVIEW
;
456 line
= (uint32_t)(line
* mt9p012_ctrl
->pict_fps_divider
/
458 setting
= RES_CAPTURE
;
461 /* Set digital gain to 1 */
468 if ((mt9p012_regs
.reg_pat
[setting
].frame_length_lines
- 1) < line
) {
469 line_length_ratio
= (uint32_t) (line
* 0x00000400) /
470 (mt9p012_regs
.reg_pat
[setting
].frame_length_lines
- 1);
472 line_length_ratio
= 0x00000400;
475 mt9p012_i2c_write_w(mt9p012_client
->addr
,
476 REG_GROUPED_PARAMETER_HOLD
,
477 GROUPED_PARAMETER_HOLD
);
479 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__
);
485 mt9p012_client
->addr
,
486 REG_GLOBAL_GAIN
, gain
);
488 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__
);
493 mt9p012_i2c_write_w(mt9p012_client
->addr
,
497 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__
);
501 CDBG("mt9p012_write_exp_gain: gain = %d, line = %d\n", gain
, line
);
504 mt9p012_i2c_write_w(mt9p012_client
->addr
,
505 REG_GROUPED_PARAMETER_HOLD
,
506 GROUPED_PARAMETER_UPDATE
);
508 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__
);
513 static int32_t mt9p012_set_pict_exp_gain(uint16_t gain
, uint32_t line
)
517 CDBG("Line:%d mt9p012_set_pict_exp_gain \n", __LINE__
);
520 mt9p012_write_exp_gain(gain
, line
);
522 CDBG("Line:%d mt9p012_set_pict_exp_gain failed... \n",
528 mt9p012_i2c_write_w(mt9p012_client
->addr
,
529 MT9P012_REG_RESET_REGISTER
,
532 CDBG("mt9p012_i2c_write_w failed... Line:%d \n", __LINE__
);
538 /* camera_timed_wait(snapshot_wait*exposure_ratio); */
542 static int32_t mt9p012_setting(enum mt9p012_reg_update rupdate
,
543 enum mt9p012_setting rt
)
548 case UPDATE_PERIODIC
:
549 if (rt
== RES_PREVIEW
|| rt
== RES_CAPTURE
) {
551 struct mt9p012_i2c_reg_conf ppc_tbl
[] = {
552 {REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
},
553 {REG_ROW_SPEED
, mt9p012_regs
.reg_pat
[rt
].row_speed
},
554 {REG_X_ADDR_START
, mt9p012_regs
.reg_pat
[rt
].x_addr_start
},
555 {REG_X_ADDR_END
, mt9p012_regs
.reg_pat
[rt
].x_addr_end
},
556 {REG_Y_ADDR_START
, mt9p012_regs
.reg_pat
[rt
].y_addr_start
},
557 {REG_Y_ADDR_END
, mt9p012_regs
.reg_pat
[rt
].y_addr_end
},
558 {REG_READ_MODE
, mt9p012_regs
.reg_pat
[rt
].read_mode
},
559 {REG_SCALE_M
, mt9p012_regs
.reg_pat
[rt
].scale_m
},
560 {REG_X_OUTPUT_SIZE
, mt9p012_regs
.reg_pat
[rt
].x_output_size
},
561 {REG_Y_OUTPUT_SIZE
, mt9p012_regs
.reg_pat
[rt
].y_output_size
},
563 {REG_LINE_LENGTH_PCK
, mt9p012_regs
.reg_pat
[rt
].line_length_pck
},
564 {REG_FRAME_LENGTH_LINES
,
565 (mt9p012_regs
.reg_pat
[rt
].frame_length_lines
*
566 mt9p012_ctrl
->fps_divider
/ 0x00000400)},
567 {REG_COARSE_INT_TIME
, mt9p012_regs
.reg_pat
[rt
].coarse_int_time
},
568 {REG_FINE_INTEGRATION_TIME
, mt9p012_regs
.reg_pat
[rt
].fine_int_time
},
569 {REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
},
572 rc
= mt9p012_i2c_write_w_table(&ppc_tbl
[0],
573 ARRAY_SIZE(ppc_tbl
));
577 rc
= mt9p012_test(mt9p012_ctrl
->set_test
);
582 mt9p012_i2c_write_w(mt9p012_client
->addr
,
583 MT9P012_REG_RESET_REGISTER
,
584 MT9P012_RESET_REGISTER_PWON
| 0x0002);
588 mdelay(5); /* 15? wait for sensor to transition*/
592 break; /* UPDATE_PERIODIC */
595 if (rt
== RES_PREVIEW
|| rt
== RES_CAPTURE
) {
596 struct mt9p012_i2c_reg_conf ipc_tbl1
[] = {
597 {MT9P012_REG_RESET_REGISTER
, MT9P012_RESET_REGISTER_PWOFF
},
598 {REG_VT_PIX_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].vt_pix_clk_div
},
599 {REG_VT_SYS_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].vt_sys_clk_div
},
600 {REG_PRE_PLL_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].pre_pll_clk_div
},
601 {REG_PLL_MULTIPLIER
, mt9p012_regs
.reg_pat
[rt
].pll_multiplier
},
602 {REG_OP_PIX_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].op_pix_clk_div
},
603 {REG_OP_SYS_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].op_sys_clk_div
},
615 /* optimized settings for noise */
625 {MT9P012_REG_RESET_REGISTER
, MT9P012_RESET_REGISTER_PWON
},
628 struct mt9p012_i2c_reg_conf ipc_tbl2
[] = {
629 {MT9P012_REG_RESET_REGISTER
, MT9P012_RESET_REGISTER_PWOFF
},
630 {REG_VT_PIX_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].vt_pix_clk_div
},
631 {REG_VT_SYS_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].vt_sys_clk_div
},
632 {REG_PRE_PLL_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].pre_pll_clk_div
},
633 {REG_PLL_MULTIPLIER
, mt9p012_regs
.reg_pat
[rt
].pll_multiplier
},
634 {REG_OP_PIX_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].op_pix_clk_div
},
635 {REG_OP_SYS_CLK_DIV
, mt9p012_regs
.reg_pat
[rt
].op_sys_clk_div
},
647 /* optimized settings for noise */
657 {MT9P012_REG_RESET_REGISTER
, MT9P012_RESET_REGISTER_PWON
},
660 struct mt9p012_i2c_reg_conf ipc_tbl3
[] = {
661 {REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
},
662 /* Set preview or snapshot mode */
663 {REG_ROW_SPEED
, mt9p012_regs
.reg_pat
[rt
].row_speed
},
664 {REG_X_ADDR_START
, mt9p012_regs
.reg_pat
[rt
].x_addr_start
},
665 {REG_X_ADDR_END
, mt9p012_regs
.reg_pat
[rt
].x_addr_end
},
666 {REG_Y_ADDR_START
, mt9p012_regs
.reg_pat
[rt
].y_addr_start
},
667 {REG_Y_ADDR_END
, mt9p012_regs
.reg_pat
[rt
].y_addr_end
},
668 {REG_READ_MODE
, mt9p012_regs
.reg_pat
[rt
].read_mode
},
669 {REG_SCALE_M
, mt9p012_regs
.reg_pat
[rt
].scale_m
},
670 {REG_X_OUTPUT_SIZE
, mt9p012_regs
.reg_pat
[rt
].x_output_size
},
671 {REG_Y_OUTPUT_SIZE
, mt9p012_regs
.reg_pat
[rt
].y_output_size
},
672 {REG_LINE_LENGTH_PCK
, mt9p012_regs
.reg_pat
[rt
].line_length_pck
},
673 {REG_FRAME_LENGTH_LINES
,
674 mt9p012_regs
.reg_pat
[rt
].frame_length_lines
},
675 {REG_COARSE_INT_TIME
, mt9p012_regs
.reg_pat
[rt
].coarse_int_time
},
676 {REG_FINE_INTEGRATION_TIME
, mt9p012_regs
.reg_pat
[rt
].fine_int_time
},
677 {REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
},
680 /* reset fps_divider */
681 mt9p012_ctrl
->fps_divider
= 1 * 0x0400;
683 rc
= mt9p012_i2c_write_w_table(&ipc_tbl1
[0],
684 ARRAY_SIZE(ipc_tbl1
));
688 rc
= mt9p012_i2c_write_w_table(&ipc_tbl2
[0],
689 ARRAY_SIZE(ipc_tbl2
));
695 rc
= mt9p012_i2c_write_w_table(&ipc_tbl3
[0],
696 ARRAY_SIZE(ipc_tbl3
));
700 /* load lens shading */
701 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
702 REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
);
706 rc
= mt9p012_set_lc();
710 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
711 REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
);
716 break; /* case REG_INIT: */
721 } /* switch (rupdate) */
726 static int32_t mt9p012_video_config(int mode
, int res
)
732 rc
= mt9p012_setting(UPDATE_PERIODIC
, RES_PREVIEW
);
736 CDBG("mt9p012 sensor configuration done!\n");
741 mt9p012_setting(UPDATE_PERIODIC
, RES_CAPTURE
);
751 mt9p012_ctrl
->prev_res
= res
;
752 mt9p012_ctrl
->curr_res
= res
;
753 mt9p012_ctrl
->sensormode
= mode
;
756 mt9p012_write_exp_gain(mt9p012_ctrl
->my_reg_gain
,
757 mt9p012_ctrl
->my_reg_line_count
);
760 mt9p012_i2c_write_w(mt9p012_client
->addr
,
761 MT9P012_REG_RESET_REGISTER
,
767 static int32_t mt9p012_snapshot_config(int mode
)
771 rc
= mt9p012_setting(UPDATE_PERIODIC
, RES_CAPTURE
);
775 mt9p012_ctrl
->curr_res
= mt9p012_ctrl
->pict_res
;
777 mt9p012_ctrl
->sensormode
= mode
;
782 static int32_t mt9p012_raw_snapshot_config(int mode
)
786 rc
= mt9p012_setting(UPDATE_PERIODIC
, RES_CAPTURE
);
790 mt9p012_ctrl
->curr_res
= mt9p012_ctrl
->pict_res
;
792 mt9p012_ctrl
->sensormode
= mode
;
797 static int32_t mt9p012_power_down(void)
801 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
802 MT9P012_REG_RESET_REGISTER
,
803 MT9P012_RESET_REGISTER_PWOFF
);
809 static int32_t mt9p012_move_focus(int direction
, int32_t num_steps
)
811 int16_t step_direction
;
813 int16_t next_position
;
814 uint8_t code_val_msb
, code_val_lsb
;
816 if (num_steps
> MT9P012_TOTAL_STEPS_NEAR_TO_FAR
)
817 num_steps
= MT9P012_TOTAL_STEPS_NEAR_TO_FAR
;
818 else if (num_steps
== 0) {
819 CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__
);
823 if (direction
== MOVE_NEAR
)
824 step_direction
= 16; /* 10bit */
825 else if (direction
== MOVE_FAR
)
826 step_direction
= -16; /* 10 bit */
828 CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__
);
832 if (mt9p012_ctrl
->curr_lens_pos
< mt9p012_ctrl
->init_curr_lens_pos
)
833 mt9p012_ctrl
->curr_lens_pos
=
834 mt9p012_ctrl
->init_curr_lens_pos
;
836 actual_step
= (int16_t)(step_direction
* (int16_t)num_steps
);
837 next_position
= (int16_t)(mt9p012_ctrl
->curr_lens_pos
+ actual_step
);
839 if (next_position
> 1023)
840 next_position
= 1023;
841 else if (next_position
< 0)
844 code_val_msb
= next_position
>> 4;
845 code_val_lsb
= (next_position
& 0x000F) << 4;
846 /* code_val_lsb |= mode_mask; */
848 /* Writing the digital code for current to the actuator */
849 if (mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR
>> 1,
850 code_val_msb
, code_val_lsb
) < 0) {
851 CDBG("mt9p012_move_focus failed at line %d ...\n", __LINE__
);
855 /* Storing the current lens Position */
856 mt9p012_ctrl
->curr_lens_pos
= next_position
;
861 static int32_t mt9p012_set_default_focus(void)
864 uint8_t code_val_msb
, code_val_lsb
;
869 /* Write the digital code for current to the actuator */
870 rc
= mt9p012_i2c_write_b(MT9P012_AF_I2C_ADDR
>> 1,
871 code_val_msb
, code_val_lsb
);
873 mt9p012_ctrl
->curr_lens_pos
= 0;
874 mt9p012_ctrl
->init_curr_lens_pos
= 0;
879 static int mt9p012_probe_init_done(const struct msm_camera_sensor_info
*data
)
881 gpio_direction_output(data
->sensor_reset
, 0);
882 gpio_free(data
->sensor_reset
);
886 static int mt9p012_probe_init_sensor(const struct msm_camera_sensor_info
*data
)
891 rc
= gpio_request(data
->sensor_reset
, "mt9p012");
893 gpio_direction_output(data
->sensor_reset
, 1);
895 goto init_probe_done
;
899 /* RESET the sensor image part via I2C command */
900 CDBG("mt9p012_sensor_init(): reseting sensor.\n");
901 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
902 MT9P012_REG_RESET_REGISTER
, 0x10CC|0x0001);
904 CDBG("sensor reset failed. rc = %d\n", rc
);
905 goto init_probe_fail
;
908 mdelay(MT9P012_RESET_DELAY_MSECS
);
910 /* 3. Read sensor Model ID: */
911 rc
= mt9p012_i2c_read_w(mt9p012_client
->addr
,
912 MT9P012_REG_MODEL_ID
, &chipid
);
914 goto init_probe_fail
;
916 /* 4. Compare sensor ID to MT9T012VC ID: */
917 if (chipid
!= MT9P012_MODEL_ID
) {
918 CDBG("mt9p012 wrong model_id = 0x%x\n", chipid
);
920 goto init_probe_fail
;
923 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
, 0x306E, 0x9000);
925 CDBG("REV_7 write failed. rc = %d\n", rc
);
926 goto init_probe_fail
;
929 /* RESET_REGISTER, enable parallel interface and disable serialiser */
930 CDBG("mt9p012_sensor_init(): enabling parallel interface.\n");
931 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
, 0x301A, 0x10CC);
933 CDBG("enable parallel interface failed. rc = %d\n", rc
);
934 goto init_probe_fail
;
937 /* To disable the 2 extra lines */
938 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
942 CDBG("disable the 2 extra lines failed. rc = %d\n", rc
);
943 goto init_probe_fail
;
946 mdelay(MT9P012_RESET_DELAY_MSECS
);
947 goto init_probe_done
;
950 mt9p012_probe_init_done(data
);
955 static int mt9p012_sensor_open_init(const struct msm_camera_sensor_info
*data
)
959 mt9p012_ctrl
= kzalloc(sizeof(struct mt9p012_ctrl
), GFP_KERNEL
);
961 CDBG("mt9p012_init failed!\n");
966 mt9p012_ctrl
->fps_divider
= 1 * 0x00000400;
967 mt9p012_ctrl
->pict_fps_divider
= 1 * 0x00000400;
968 mt9p012_ctrl
->set_test
= TEST_OFF
;
969 mt9p012_ctrl
->prev_res
= QTR_SIZE
;
970 mt9p012_ctrl
->pict_res
= FULL_SIZE
;
973 mt9p012_ctrl
->sensordata
= data
;
975 /* enable mclk first */
976 msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE
);
979 msm_camio_camif_pad_reg_reset();
982 rc
= mt9p012_probe_init_sensor(data
);
986 if (mt9p012_ctrl
->prev_res
== QTR_SIZE
)
987 rc
= mt9p012_setting(REG_INIT
, RES_PREVIEW
);
989 rc
= mt9p012_setting(REG_INIT
, RES_CAPTURE
);
992 CDBG("mt9p012_setting failed. rc = %d\n", rc
);
996 /* sensor : output enable */
997 CDBG("mt9p012_sensor_open_init(): enabling output.\n");
998 rc
= mt9p012_i2c_write_w(mt9p012_client
->addr
,
999 MT9P012_REG_RESET_REGISTER
, MT9P012_RESET_REGISTER_PWON
);
1001 CDBG("sensor output enable failed. rc = %d\n", rc
);
1005 /* TODO: enable AF actuator */
1007 CDBG("enable AF actuator, gpio = %d\n",
1008 mt9p012_ctrl
->sensordata
->vcm_pwd
);
1009 rc
= gpio_request(mt9p012_ctrl
->sensordata
->vcm_pwd
, "mt9p012");
1011 gpio_direction_output(mt9p012_ctrl
->sensordata
->vcm_pwd
, 1);
1013 CDBG("mt9p012_ctrl gpio request failed!\n");
1018 rc
= mt9p012_set_default_focus();
1024 * gpio_direction_output(mt9p012_ctrl->sensordata->vcm_pwd, 0);
1025 * gpio_free(mt9p012_ctrl->sensordata->vcm_pwd); */
1027 mt9p012_probe_init_done(data
);
1028 kfree(mt9p012_ctrl
);
1033 static int mt9p012_init_client(struct i2c_client
*client
)
1035 /* Initialize the MSM_CAMI2C Chip */
1036 init_waitqueue_head(&mt9p012_wait_queue
);
1040 static int32_t mt9p012_set_sensor_mode(int mode
, int res
)
1045 case SENSOR_PREVIEW_MODE
:
1046 rc
= mt9p012_video_config(mode
, res
);
1049 case SENSOR_SNAPSHOT_MODE
:
1050 rc
= mt9p012_snapshot_config(mode
);
1053 case SENSOR_RAW_SNAPSHOT_MODE
:
1054 rc
= mt9p012_raw_snapshot_config(mode
);
1065 int mt9p012_sensor_config(void __user
*argp
)
1067 struct sensor_cfg_data cdata
;
1070 if (copy_from_user(&cdata
,
1072 sizeof(struct sensor_cfg_data
)))
1077 CDBG("%s: cfgtype = %d\n", __func__
, cdata
.cfgtype
);
1078 switch (cdata
.cfgtype
) {
1079 case CFG_GET_PICT_FPS
:
1080 mt9p012_get_pict_fps(cdata
.cfg
.gfps
.prevfps
,
1081 &(cdata
.cfg
.gfps
.pictfps
));
1083 if (copy_to_user((void *)argp
, &cdata
,
1084 sizeof(struct sensor_cfg_data
)))
1088 case CFG_GET_PREV_L_PF
:
1089 cdata
.cfg
.prevl_pf
= mt9p012_get_prev_lines_pf();
1091 if (copy_to_user((void *)argp
,
1093 sizeof(struct sensor_cfg_data
)))
1097 case CFG_GET_PREV_P_PL
:
1098 cdata
.cfg
.prevp_pl
= mt9p012_get_prev_pixels_pl();
1100 if (copy_to_user((void *)argp
,
1102 sizeof(struct sensor_cfg_data
)))
1106 case CFG_GET_PICT_L_PF
:
1107 cdata
.cfg
.pictl_pf
= mt9p012_get_pict_lines_pf();
1109 if (copy_to_user((void *)argp
,
1111 sizeof(struct sensor_cfg_data
)))
1115 case CFG_GET_PICT_P_PL
:
1116 cdata
.cfg
.pictp_pl
= mt9p012_get_pict_pixels_pl();
1118 if (copy_to_user((void *)argp
,
1120 sizeof(struct sensor_cfg_data
)))
1124 case CFG_GET_PICT_MAX_EXP_LC
:
1125 cdata
.cfg
.pict_max_exp_lc
=
1126 mt9p012_get_pict_max_exp_lc();
1128 if (copy_to_user((void *)argp
,
1130 sizeof(struct sensor_cfg_data
)))
1135 case CFG_SET_PICT_FPS
:
1136 rc
= mt9p012_set_fps(&(cdata
.cfg
.fps
));
1139 case CFG_SET_EXP_GAIN
:
1140 rc
= mt9p012_write_exp_gain(cdata
.cfg
.exp_gain
.gain
,
1141 cdata
.cfg
.exp_gain
.line
);
1144 case CFG_SET_PICT_EXP_GAIN
:
1145 CDBG("Line:%d CFG_SET_PICT_EXP_GAIN \n", __LINE__
);
1146 rc
= mt9p012_set_pict_exp_gain(cdata
.cfg
.exp_gain
.gain
,
1147 cdata
.cfg
.exp_gain
.line
);
1151 rc
= mt9p012_set_sensor_mode(cdata
.mode
, cdata
.rs
);
1155 rc
= mt9p012_power_down();
1158 case CFG_MOVE_FOCUS
:
1159 CDBG("mt9p012_ioctl: CFG_MOVE_FOCUS: cdata.cfg.focus.dir=%d cdata.cfg.focus.steps=%d\n",
1160 cdata
.cfg
.focus
.dir
, cdata
.cfg
.focus
.steps
);
1161 rc
= mt9p012_move_focus(cdata
.cfg
.focus
.dir
,
1162 cdata
.cfg
.focus
.steps
);
1165 case CFG_SET_DEFAULT_FOCUS
:
1166 rc
= mt9p012_set_default_focus();
1169 case CFG_SET_LENS_SHADING
:
1170 CDBG("%s: CFG_SET_LENS_SHADING\n", __func__
);
1171 rc
= mt9p012_lens_shading_enable(cdata
.cfg
.lens_shading
);
1174 case CFG_GET_AF_MAX_STEPS
:
1175 cdata
.max_steps
= MT9P012_STEPS_NEAR_TO_CLOSEST_INF
;
1176 if (copy_to_user((void *)argp
,
1178 sizeof(struct sensor_cfg_data
)))
1182 case CFG_SET_EFFECT
:
1192 int mt9p012_sensor_release(void)
1198 mt9p012_power_down();
1200 gpio_direction_output(mt9p012_ctrl
->sensordata
->sensor_reset
,
1202 gpio_free(mt9p012_ctrl
->sensordata
->sensor_reset
);
1204 gpio_direction_output(mt9p012_ctrl
->sensordata
->vcm_pwd
, 0);
1205 gpio_free(mt9p012_ctrl
->sensordata
->vcm_pwd
);
1207 kfree(mt9p012_ctrl
);
1208 mt9p012_ctrl
= NULL
;
1210 CDBG("mt9p012_release completed\n");
1216 static int mt9p012_i2c_probe(struct i2c_client
*client
,
1217 const struct i2c_device_id
*id
)
1220 CDBG("mt9p012_probe called!\n");
1222 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
)) {
1223 CDBG("i2c_check_functionality failed\n");
1227 mt9p012_sensorw
= kzalloc(sizeof(struct mt9p012_work
), GFP_KERNEL
);
1228 if (!mt9p012_sensorw
) {
1229 CDBG("kzalloc failed.\n");
1234 i2c_set_clientdata(client
, mt9p012_sensorw
);
1235 mt9p012_init_client(client
);
1236 mt9p012_client
= client
;
1240 CDBG("mt9p012_probe successed! rc = %d\n", rc
);
1244 CDBG("mt9p012_probe failed! rc = %d\n", rc
);
1248 static const struct i2c_device_id mt9p012_i2c_id
[] = {
1253 static struct i2c_driver mt9p012_i2c_driver
= {
1254 .id_table
= mt9p012_i2c_id
,
1255 .probe
= mt9p012_i2c_probe
,
1256 .remove
= __exit_p(mt9p012_i2c_remove
),
1262 static int mt9p012_sensor_probe(const struct msm_camera_sensor_info
*info
,
1263 struct msm_sensor_ctrl
*s
)
1265 int rc
= i2c_add_driver(&mt9p012_i2c_driver
);
1266 if (rc
< 0 || mt9p012_client
== NULL
) {
1271 msm_camio_clk_rate_set(MT9P012_DEFAULT_CLOCK_RATE
);
1274 rc
= mt9p012_probe_init_sensor(info
);
1278 s
->s_init
= mt9p012_sensor_open_init
;
1279 s
->s_release
= mt9p012_sensor_release
;
1280 s
->s_config
= mt9p012_sensor_config
;
1281 mt9p012_probe_init_done(info
);
1284 CDBG("%s %s:%d\n", __FILE__
, __func__
, __LINE__
);
1288 static int __mt9p012_probe(struct platform_device
*pdev
)
1290 return msm_camera_drv_start(pdev
, mt9p012_sensor_probe
);
1293 static struct platform_driver msm_camera_driver
= {
1294 .probe
= __mt9p012_probe
,
1296 .name
= "msm_camera_mt9p012",
1297 .owner
= THIS_MODULE
,
1301 static int __init
mt9p012_init(void)
1303 return platform_driver_register(&msm_camera_driver
);
1306 module_init(mt9p012_init
);