• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/dream/camera/
1/*
2 * Copyright (C) 2008-2009 QUALCOMM Incorporated.
3 */
4
5#include <linux/delay.h>
6#include <linux/types.h>
7#include <linux/slab.h>
8#include <linux/i2c.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>
15#include <asm/mach-types.h>
16#include "mt9t013.h"
17
18/*=============================================================
19	SENSOR REGISTER DEFINES
20==============================================================*/
21#define MT9T013_REG_MODEL_ID 		 0x0000
22#define MT9T013_MODEL_ID     		 0x2600
23#define REG_GROUPED_PARAMETER_HOLD   0x0104
24#define GROUPED_PARAMETER_HOLD       0x0100
25#define GROUPED_PARAMETER_UPDATE     0x0000
26#define REG_COARSE_INT_TIME          0x3012
27#define REG_VT_PIX_CLK_DIV           0x0300
28#define REG_VT_SYS_CLK_DIV           0x0302
29#define REG_PRE_PLL_CLK_DIV          0x0304
30#define REG_PLL_MULTIPLIER           0x0306
31#define REG_OP_PIX_CLK_DIV           0x0308
32#define REG_OP_SYS_CLK_DIV           0x030A
33#define REG_SCALE_M                  0x0404
34#define REG_FRAME_LENGTH_LINES       0x300A
35#define REG_LINE_LENGTH_PCK          0x300C
36#define REG_X_ADDR_START             0x3004
37#define REG_Y_ADDR_START             0x3002
38#define REG_X_ADDR_END               0x3008
39#define REG_Y_ADDR_END               0x3006
40#define REG_X_OUTPUT_SIZE            0x034C
41#define REG_Y_OUTPUT_SIZE            0x034E
42#define REG_FINE_INT_TIME            0x3014
43#define REG_ROW_SPEED                0x3016
44#define MT9T013_REG_RESET_REGISTER   0x301A
45#define MT9T013_RESET_REGISTER_PWON  0x10CC
46#define MT9T013_RESET_REGISTER_PWOFF 0x1008 /* 0x10C8 stop streaming*/
47#define REG_READ_MODE                0x3040
48#define REG_GLOBAL_GAIN              0x305E
49#define REG_TEST_PATTERN_MODE        0x3070
50
51
52enum mt9t013_test_mode {
53	TEST_OFF,
54	TEST_1,
55	TEST_2,
56	TEST_3
57};
58
59enum mt9t013_resolution {
60	QTR_SIZE,
61	FULL_SIZE,
62	INVALID_SIZE
63};
64
65enum mt9t013_reg_update {
66	REG_INIT, /* registers that need to be updated during initialization */
67	UPDATE_PERIODIC, /* registers that needs periodic I2C writes */
68	UPDATE_ALL, /* all registers will be updated */
69	UPDATE_INVALID
70};
71
72enum mt9t013_setting {
73	RES_PREVIEW,
74	RES_CAPTURE
75};
76
77/* actuator's Slave Address */
78#define MT9T013_AF_I2C_ADDR   0x18
79
80/*
81* AF Total steps parameters
82*/
83#define MT9T013_TOTAL_STEPS_NEAR_TO_FAR    30
84
85/*
86 * Time in milisecs for waiting for the sensor to reset.
87 */
88#define MT9T013_RESET_DELAY_MSECS   66
89
90/* for 30 fps preview */
91#define MT9T013_DEFAULT_CLOCK_RATE  24000000
92#define MT9T013_DEFAULT_MAX_FPS     26
93
94
95struct mt9t013_work {
96	struct work_struct work;
97};
98
99static struct  mt9t013_work *mt9t013_sensorw;
100static struct  i2c_client *mt9t013_client;
101
102struct mt9t013_ctrl {
103	const struct msm_camera_sensor_info *sensordata;
104
105	int sensormode;
106	uint32_t fps_divider; 		/* init to 1 * 0x00000400 */
107	uint32_t pict_fps_divider; 	/* init to 1 * 0x00000400 */
108
109	uint16_t curr_lens_pos;
110	uint16_t init_curr_lens_pos;
111	uint16_t my_reg_gain;
112	uint32_t my_reg_line_count;
113
114	enum mt9t013_resolution prev_res;
115	enum mt9t013_resolution pict_res;
116	enum mt9t013_resolution curr_res;
117	enum mt9t013_test_mode  set_test;
118
119	unsigned short imgaddr;
120};
121
122
123static struct mt9t013_ctrl *mt9t013_ctrl;
124static DECLARE_WAIT_QUEUE_HEAD(mt9t013_wait_queue);
125DECLARE_MUTEX(mt9t013_sem);
126
127extern struct mt9t013_reg mt9t013_regs; /* from mt9t013_reg.c */
128
129static int mt9t013_i2c_rxdata(unsigned short saddr,
130	unsigned char *rxdata, int length)
131{
132	struct i2c_msg msgs[] = {
133	{
134		.addr   = saddr,
135		.flags = 0,
136		.len   = 2,
137		.buf   = rxdata,
138	},
139	{
140		.addr  = saddr,
141		.flags = I2C_M_RD,
142		.len   = length,
143		.buf   = rxdata,
144	},
145	};
146
147	if (i2c_transfer(mt9t013_client->adapter, msgs, 2) < 0) {
148		pr_err("mt9t013_i2c_rxdata failed!\n");
149		return -EIO;
150	}
151
152	return 0;
153}
154
155static int32_t mt9t013_i2c_read_w(unsigned short saddr,
156	unsigned short raddr, unsigned short *rdata)
157{
158	int32_t rc = 0;
159	unsigned char buf[4];
160
161	if (!rdata)
162		return -EIO;
163
164	memset(buf, 0, sizeof(buf));
165
166	buf[0] = (raddr & 0xFF00)>>8;
167	buf[1] = (raddr & 0x00FF);
168
169	rc = mt9t013_i2c_rxdata(saddr, buf, 2);
170	if (rc < 0)
171		return rc;
172
173	*rdata = buf[0] << 8 | buf[1];
174
175	if (rc < 0)
176		pr_err("mt9t013_i2c_read failed!\n");
177
178	return rc;
179}
180
181static int32_t mt9t013_i2c_txdata(unsigned short saddr,
182	unsigned char *txdata, int length)
183{
184	struct i2c_msg msg[] = {
185	{
186		.addr = saddr,
187		.flags = 0,
188		.len = length,
189		.buf = txdata,
190	},
191	};
192
193	if (i2c_transfer(mt9t013_client->adapter, msg, 1) < 0) {
194		pr_err("mt9t013_i2c_txdata failed\n");
195		return -EIO;
196	}
197
198	return 0;
199}
200
201static int32_t mt9t013_i2c_write_b(unsigned short saddr,
202	unsigned short waddr, unsigned short wdata)
203{
204	int32_t rc = -EIO;
205	unsigned char buf[2];
206
207	memset(buf, 0, sizeof(buf));
208	buf[0] = waddr;
209	buf[1] = wdata;
210	rc = mt9t013_i2c_txdata(saddr, buf, 2);
211
212	if (rc < 0)
213		pr_err("i2c_write failed, addr = 0x%x, val = 0x%x!\n",
214		waddr, wdata);
215
216	return rc;
217}
218
219static int32_t mt9t013_i2c_write_w(unsigned short saddr,
220	unsigned short waddr, unsigned short wdata)
221{
222	int32_t rc = -EIO;
223	unsigned char buf[4];
224
225	memset(buf, 0, sizeof(buf));
226	buf[0] = (waddr & 0xFF00)>>8;
227	buf[1] = (waddr & 0x00FF);
228	buf[2] = (wdata & 0xFF00)>>8;
229	buf[3] = (wdata & 0x00FF);
230
231	rc = mt9t013_i2c_txdata(saddr, buf, 4);
232
233	if (rc < 0)
234		pr_err("i2c_write_w failed, addr = 0x%x, val = 0x%x!\n",
235		waddr, wdata);
236
237	return rc;
238}
239
240static int32_t mt9t013_i2c_write_w_table(
241	struct mt9t013_i2c_reg_conf *reg_conf_tbl, int num_of_items_in_table)
242{
243	int i;
244	int32_t rc = -EIO;
245
246	for (i = 0; i < num_of_items_in_table; i++) {
247		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
248			reg_conf_tbl->waddr, reg_conf_tbl->wdata);
249		if (rc < 0)
250			break;
251		reg_conf_tbl++;
252	}
253
254	return rc;
255}
256
257static int32_t mt9t013_test(enum mt9t013_test_mode mo)
258{
259	int32_t rc = 0;
260
261	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
262			REG_GROUPED_PARAMETER_HOLD,
263			GROUPED_PARAMETER_HOLD);
264	if (rc < 0)
265		return rc;
266
267	if (mo == TEST_OFF)
268		return 0;
269	else {
270		rc = mt9t013_i2c_write_w_table(mt9t013_regs.ttbl,
271				mt9t013_regs.ttbl_size);
272		if (rc < 0)
273			return rc;
274		rc = mt9t013_i2c_write_w(mt9t013_client->addr,
275				REG_TEST_PATTERN_MODE, (uint16_t)mo);
276		if (rc < 0)
277			return rc;
278	}
279
280	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
281			REG_GROUPED_PARAMETER_HOLD,
282			GROUPED_PARAMETER_UPDATE);
283	if (rc < 0)
284		return rc;
285
286	return rc;
287}
288
289static int32_t mt9t013_set_lc(void)
290{
291	int32_t rc;
292
293	rc = mt9t013_i2c_write_w_table(mt9t013_regs.lctbl, mt9t013_regs.lctbl_size);
294	if (rc < 0)
295		return rc;
296
297	return rc;
298}
299
300static int32_t mt9t013_set_default_focus(uint8_t af_step)
301{
302	int32_t rc = 0;
303	uint8_t code_val_msb, code_val_lsb;
304	code_val_msb = 0x01;
305	code_val_lsb = af_step;
306
307	/* Write the digital code for current to the actuator */
308	rc = mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
309			code_val_msb, code_val_lsb);
310
311	mt9t013_ctrl->curr_lens_pos = 0;
312	mt9t013_ctrl->init_curr_lens_pos = 0;
313	return rc;
314}
315
316static void mt9t013_get_pict_fps(uint16_t fps, uint16_t *pfps)
317{
318	/* input fps is preview fps in Q8 format */
319	uint32_t divider;   /*Q10 */
320	uint32_t pclk_mult; /*Q10 */
321
322	if (mt9t013_ctrl->prev_res == QTR_SIZE) {
323		divider =
324			(uint32_t)(
325		((mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines *
326		mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck) *
327		0x00000400) /
328		(mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines *
329		mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck));
330
331		pclk_mult =
332		(uint32_t) ((mt9t013_regs.reg_pat[RES_CAPTURE].pll_multiplier *
333		0x00000400) /
334		(mt9t013_regs.reg_pat[RES_PREVIEW].pll_multiplier));
335
336	} else {
337		/* full size resolution used for preview. */
338		divider   = 0x00000400;  /*1.0 */
339		pclk_mult = 0x00000400;  /*1.0 */
340	}
341
342	/* Verify PCLK settings and frame sizes. */
343	*pfps =
344		(uint16_t) (fps * divider * pclk_mult /
345		0x00000400 / 0x00000400);
346}
347
348static uint16_t mt9t013_get_prev_lines_pf(void)
349{
350	if (mt9t013_ctrl->prev_res == QTR_SIZE)
351		return mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines;
352	else
353		return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
354}
355
356static uint16_t mt9t013_get_prev_pixels_pl(void)
357{
358	if (mt9t013_ctrl->prev_res == QTR_SIZE)
359		return mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck;
360	else
361		return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
362}
363
364static uint16_t mt9t013_get_pict_lines_pf(void)
365{
366	return mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines;
367}
368
369static uint16_t mt9t013_get_pict_pixels_pl(void)
370{
371	return mt9t013_regs.reg_pat[RES_CAPTURE].line_length_pck;
372}
373
374static uint32_t mt9t013_get_pict_max_exp_lc(void)
375{
376	uint16_t snapshot_lines_per_frame;
377
378	if (mt9t013_ctrl->pict_res == QTR_SIZE) {
379		snapshot_lines_per_frame =
380		mt9t013_regs.reg_pat[RES_PREVIEW].frame_length_lines - 1;
381	} else  {
382		snapshot_lines_per_frame =
383		mt9t013_regs.reg_pat[RES_CAPTURE].frame_length_lines - 1;
384	}
385
386	return snapshot_lines_per_frame * 24;
387}
388
389static int32_t mt9t013_set_fps(struct fps_cfg *fps)
390{
391	/* input is new fps in Q8 format */
392	int32_t rc = 0;
393
394	mt9t013_ctrl->fps_divider = fps->fps_div;
395	mt9t013_ctrl->pict_fps_divider = fps->pict_fps_div;
396
397	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
398			REG_GROUPED_PARAMETER_HOLD,
399			GROUPED_PARAMETER_HOLD);
400	if (rc < 0)
401		return -EBUSY;
402
403	CDBG("mt9t013_set_fps: fps_div is %d, frame_rate is %d\n",
404			fps->fps_div,
405			(uint16_t) (mt9t013_regs.reg_pat[RES_PREVIEW].
406						frame_length_lines *
407					fps->fps_div/0x00000400));
408
409	CDBG("mt9t013_set_fps: fps_mult is %d, frame_rate is %d\n",
410			fps->f_mult,
411			(uint16_t)(mt9t013_regs.reg_pat[RES_PREVIEW].
412					line_length_pck *
413					fps->f_mult / 0x00000400));
414
415	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
416			REG_LINE_LENGTH_PCK,
417			(uint16_t) (
418			mt9t013_regs.reg_pat[RES_PREVIEW].line_length_pck *
419			fps->f_mult / 0x00000400));
420	if (rc < 0)
421		return rc;
422
423	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
424			REG_GROUPED_PARAMETER_HOLD,
425			GROUPED_PARAMETER_UPDATE);
426	if (rc < 0)
427		return rc;
428
429	return rc;
430}
431
432static int32_t mt9t013_write_exp_gain(uint16_t gain, uint32_t line)
433{
434	const uint16_t max_legal_gain = 0x01FF;
435	uint32_t line_length_ratio = 0x00000400;
436	enum mt9t013_setting setting;
437	int32_t rc = 0;
438
439	if (mt9t013_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
440		mt9t013_ctrl->my_reg_gain = gain;
441		mt9t013_ctrl->my_reg_line_count = (uint16_t) line;
442	}
443
444	if (gain > max_legal_gain)
445		gain = max_legal_gain;
446
447	/* Verify no overflow */
448	if (mt9t013_ctrl->sensormode != SENSOR_SNAPSHOT_MODE) {
449		line = (uint32_t) (line * mt9t013_ctrl->fps_divider /
450			0x00000400);
451
452		setting = RES_PREVIEW;
453
454	} else {
455		line = (uint32_t) (line * mt9t013_ctrl->pict_fps_divider /
456			0x00000400);
457
458		setting = RES_CAPTURE;
459	}
460
461	/*Set digital gain to 1 */
462	gain |= 0x0200;
463
464	if ((mt9t013_regs.reg_pat[setting].frame_length_lines - 1) < line) {
465
466		line_length_ratio =
467		(uint32_t) (line * 0x00000400) /
468		(mt9t013_regs.reg_pat[setting].frame_length_lines - 1);
469	} else
470		line_length_ratio = 0x00000400;
471
472	/* There used to be PARAMETER_HOLD register write before and
473	 * after REG_GLOBAL_GAIN & REG_COARSE_INIT_TIME. This causes
474	 * aec oscillation. Hence removed. */
475
476	rc = mt9t013_i2c_write_w(mt9t013_client->addr, REG_GLOBAL_GAIN, gain);
477	if (rc < 0)
478		return rc;
479
480	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
481			REG_COARSE_INT_TIME,
482			(uint16_t)((uint32_t) line * 0x00000400 /
483			line_length_ratio));
484	if (rc < 0)
485		return rc;
486
487	return rc;
488}
489
490static int32_t mt9t013_set_pict_exp_gain(uint16_t gain, uint32_t line)
491{
492	int32_t rc = 0;
493
494	rc = mt9t013_write_exp_gain(gain, line);
495	if (rc < 0)
496		return rc;
497
498	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
499			MT9T013_REG_RESET_REGISTER,
500			0x10CC | 0x0002);
501
502	mdelay(5);
503
504	/* camera_timed_wait(snapshot_wait*exposure_ratio); */
505	return rc;
506}
507
508static int32_t mt9t013_setting(enum mt9t013_reg_update rupdate,
509	enum mt9t013_setting rt)
510{
511	int32_t rc = 0;
512
513	switch (rupdate) {
514	case UPDATE_PERIODIC: {
515
516	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
517
518		rc =
519			mt9t013_i2c_write_w(mt9t013_client->addr,
520				REG_VT_PIX_CLK_DIV,
521				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
522		if (rc < 0)
523			return rc;
524
525		rc =
526			mt9t013_i2c_write_w(mt9t013_client->addr,
527				REG_VT_SYS_CLK_DIV,
528				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
529		if (rc < 0)
530			return rc;
531
532		rc =
533			mt9t013_i2c_write_w(mt9t013_client->addr,
534				REG_PRE_PLL_CLK_DIV,
535				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
536		if (rc < 0)
537			return rc;
538
539		rc =
540			mt9t013_i2c_write_w(mt9t013_client->addr,
541				REG_PLL_MULTIPLIER,
542				mt9t013_regs.reg_pat[rt].pll_multiplier);
543		if (rc < 0)
544			return rc;
545
546		rc =
547			mt9t013_i2c_write_w(mt9t013_client->addr,
548				REG_OP_PIX_CLK_DIV,
549				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
550		if (rc < 0)
551			return rc;
552
553		rc =
554			mt9t013_i2c_write_w(mt9t013_client->addr,
555				REG_OP_SYS_CLK_DIV,
556				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
557		if (rc < 0)
558			return rc;
559
560		mdelay(5);
561
562		rc =
563			mt9t013_i2c_write_w(mt9t013_client->addr,
564				REG_GROUPED_PARAMETER_HOLD,
565				GROUPED_PARAMETER_HOLD);
566		if (rc < 0)
567			return rc;
568
569		rc =
570			mt9t013_i2c_write_w(mt9t013_client->addr,
571				REG_ROW_SPEED,
572				mt9t013_regs.reg_pat[rt].row_speed);
573		if (rc < 0)
574			return rc;
575
576		rc =
577			mt9t013_i2c_write_w(mt9t013_client->addr,
578				REG_X_ADDR_START,
579				mt9t013_regs.reg_pat[rt].x_addr_start);
580		if (rc < 0)
581			return rc;
582
583		rc =
584			mt9t013_i2c_write_w(mt9t013_client->addr,
585				REG_X_ADDR_END,
586				mt9t013_regs.reg_pat[rt].x_addr_end);
587		if (rc < 0)
588			return rc;
589
590		rc =
591			mt9t013_i2c_write_w(mt9t013_client->addr,
592				REG_Y_ADDR_START,
593				mt9t013_regs.reg_pat[rt].y_addr_start);
594		if (rc < 0)
595			return rc;
596
597		rc =
598			mt9t013_i2c_write_w(mt9t013_client->addr,
599				REG_Y_ADDR_END,
600				mt9t013_regs.reg_pat[rt].y_addr_end);
601		if (rc < 0)
602			return rc;
603
604		if (machine_is_sapphire()) {
605			if (rt == 0)
606				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
607					REG_READ_MODE,
608					0x046F);
609			else
610				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
611					REG_READ_MODE,
612					0x0027);
613		} else
614			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
615					REG_READ_MODE,
616					mt9t013_regs.reg_pat[rt].read_mode);
617		if (rc < 0)
618			return rc;
619
620		rc =
621			mt9t013_i2c_write_w(mt9t013_client->addr,
622				REG_SCALE_M,
623				mt9t013_regs.reg_pat[rt].scale_m);
624		if (rc < 0)
625			return rc;
626
627
628		rc =
629			mt9t013_i2c_write_w(mt9t013_client->addr,
630				REG_X_OUTPUT_SIZE,
631				mt9t013_regs.reg_pat[rt].x_output_size);
632		if (rc < 0)
633			return rc;
634
635		rc =
636			mt9t013_i2c_write_w(mt9t013_client->addr,
637				REG_Y_OUTPUT_SIZE,
638				mt9t013_regs.reg_pat[rt].y_output_size);
639		if (rc < 0)
640			return rc;
641
642		rc =
643			mt9t013_i2c_write_w(mt9t013_client->addr,
644				REG_LINE_LENGTH_PCK,
645				mt9t013_regs.reg_pat[rt].line_length_pck);
646		if (rc < 0)
647			return rc;
648
649		rc =
650			mt9t013_i2c_write_w(mt9t013_client->addr,
651			REG_FRAME_LENGTH_LINES,
652			(mt9t013_regs.reg_pat[rt].frame_length_lines *
653			mt9t013_ctrl->fps_divider / 0x00000400));
654		if (rc < 0)
655			return rc;
656
657		rc =
658			mt9t013_i2c_write_w(mt9t013_client->addr,
659			REG_COARSE_INT_TIME,
660			mt9t013_regs.reg_pat[rt].coarse_int_time);
661		if (rc < 0)
662			return rc;
663
664		rc =
665			mt9t013_i2c_write_w(mt9t013_client->addr,
666			REG_FINE_INT_TIME,
667			mt9t013_regs.reg_pat[rt].fine_int_time);
668		if (rc < 0)
669			return rc;
670
671		rc =
672			mt9t013_i2c_write_w(mt9t013_client->addr,
673			REG_GROUPED_PARAMETER_HOLD,
674			GROUPED_PARAMETER_UPDATE);
675		if (rc < 0)
676			return rc;
677
678		rc = mt9t013_test(mt9t013_ctrl->set_test);
679		if (rc < 0)
680			return rc;
681
682		rc =
683			mt9t013_i2c_write_w(mt9t013_client->addr,
684			MT9T013_REG_RESET_REGISTER,
685			MT9T013_RESET_REGISTER_PWON);
686		if (rc < 0)
687			return rc;
688
689		mdelay(5);
690
691		return rc;
692	}
693	}
694		break;
695
696	/*CAMSENSOR_REG_UPDATE_PERIODIC */
697	case REG_INIT: {
698	if (rt == RES_PREVIEW || rt == RES_CAPTURE) {
699
700		rc =
701			mt9t013_i2c_write_w(mt9t013_client->addr,
702				MT9T013_REG_RESET_REGISTER,
703				MT9T013_RESET_REGISTER_PWOFF);
704		if (rc < 0)
705			/* MODE_SELECT, stop streaming */
706			return rc;
707
708		rc =
709			mt9t013_i2c_write_w(mt9t013_client->addr,
710				REG_VT_PIX_CLK_DIV,
711				mt9t013_regs.reg_pat[rt].vt_pix_clk_div);
712		if (rc < 0)
713			return rc;
714
715		rc =
716			mt9t013_i2c_write_w(mt9t013_client->addr,
717				REG_VT_SYS_CLK_DIV,
718				mt9t013_regs.reg_pat[rt].vt_sys_clk_div);
719		if (rc < 0)
720			return rc;
721
722		rc =
723			mt9t013_i2c_write_w(mt9t013_client->addr,
724				REG_PRE_PLL_CLK_DIV,
725				mt9t013_regs.reg_pat[rt].pre_pll_clk_div);
726		if (rc < 0)
727			return rc;
728
729		rc =
730			mt9t013_i2c_write_w(mt9t013_client->addr,
731				REG_PLL_MULTIPLIER,
732				mt9t013_regs.reg_pat[rt].pll_multiplier);
733		if (rc < 0)
734			return rc;
735
736		rc =
737			mt9t013_i2c_write_w(mt9t013_client->addr,
738				REG_OP_PIX_CLK_DIV,
739				mt9t013_regs.reg_pat[rt].op_pix_clk_div);
740		if (rc < 0)
741			return rc;
742
743		rc =
744			mt9t013_i2c_write_w(mt9t013_client->addr,
745				REG_OP_SYS_CLK_DIV,
746				mt9t013_regs.reg_pat[rt].op_sys_clk_div);
747		if (rc < 0)
748			return rc;
749
750		mdelay(5);
751
752		rc =
753			mt9t013_i2c_write_w(mt9t013_client->addr,
754				REG_GROUPED_PARAMETER_HOLD,
755				GROUPED_PARAMETER_HOLD);
756		if (rc < 0)
757			return rc;
758
759		/* additional power saving mode ok around 38.2MHz */
760		rc =
761			mt9t013_i2c_write_w(mt9t013_client->addr,
762				0x3084, 0x2409);
763		if (rc < 0)
764			return rc;
765
766		rc =
767			mt9t013_i2c_write_w(mt9t013_client->addr,
768				0x3092, 0x0A49);
769		if (rc < 0)
770			return rc;
771
772		rc =
773			mt9t013_i2c_write_w(mt9t013_client->addr,
774				0x3094, 0x4949);
775		if (rc < 0)
776			return rc;
777
778		rc =
779			mt9t013_i2c_write_w(mt9t013_client->addr,
780				0x3096, 0x4949);
781		if (rc < 0)
782			return rc;
783
784		/* Set preview or snapshot mode */
785		rc =
786			mt9t013_i2c_write_w(mt9t013_client->addr,
787				REG_ROW_SPEED,
788				mt9t013_regs.reg_pat[rt].row_speed);
789		if (rc < 0)
790			return rc;
791
792		rc =
793			mt9t013_i2c_write_w(mt9t013_client->addr,
794				REG_X_ADDR_START,
795				mt9t013_regs.reg_pat[rt].x_addr_start);
796		if (rc < 0)
797			return rc;
798
799		rc =
800			mt9t013_i2c_write_w(mt9t013_client->addr,
801				REG_X_ADDR_END,
802				mt9t013_regs.reg_pat[rt].x_addr_end);
803		if (rc < 0)
804			return rc;
805
806		rc =
807			mt9t013_i2c_write_w(mt9t013_client->addr,
808				REG_Y_ADDR_START,
809				mt9t013_regs.reg_pat[rt].y_addr_start);
810		if (rc < 0)
811			return rc;
812
813		rc =
814			mt9t013_i2c_write_w(mt9t013_client->addr,
815				REG_Y_ADDR_END,
816				mt9t013_regs.reg_pat[rt].y_addr_end);
817		if (rc < 0)
818			return rc;
819
820		if (machine_is_sapphire()) {
821			if (rt == 0)
822				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
823					REG_READ_MODE,
824					0x046F);
825			else
826				rc = mt9t013_i2c_write_w(mt9t013_client->addr,
827					REG_READ_MODE,
828					0x0027);
829		} else
830			rc = mt9t013_i2c_write_w(mt9t013_client->addr,
831					REG_READ_MODE,
832					mt9t013_regs.reg_pat[rt].read_mode);
833		if (rc < 0)
834			return rc;
835
836		rc =
837			mt9t013_i2c_write_w(mt9t013_client->addr,
838				REG_SCALE_M,
839				mt9t013_regs.reg_pat[rt].scale_m);
840		if (rc < 0)
841			return rc;
842
843		rc =
844			mt9t013_i2c_write_w(mt9t013_client->addr,
845				REG_X_OUTPUT_SIZE,
846				mt9t013_regs.reg_pat[rt].x_output_size);
847		if (rc < 0)
848			return rc;
849
850		rc =
851			mt9t013_i2c_write_w(mt9t013_client->addr,
852				REG_Y_OUTPUT_SIZE,
853				mt9t013_regs.reg_pat[rt].y_output_size);
854		if (rc < 0)
855			return 0;
856
857		rc =
858			mt9t013_i2c_write_w(mt9t013_client->addr,
859				REG_LINE_LENGTH_PCK,
860				mt9t013_regs.reg_pat[rt].line_length_pck);
861		if (rc < 0)
862			return rc;
863
864		rc =
865			mt9t013_i2c_write_w(mt9t013_client->addr,
866				REG_FRAME_LENGTH_LINES,
867				mt9t013_regs.reg_pat[rt].frame_length_lines);
868		if (rc < 0)
869			return rc;
870
871		rc =
872			mt9t013_i2c_write_w(mt9t013_client->addr,
873				REG_COARSE_INT_TIME,
874				mt9t013_regs.reg_pat[rt].coarse_int_time);
875		if (rc < 0)
876			return rc;
877
878		rc =
879			mt9t013_i2c_write_w(mt9t013_client->addr,
880				REG_FINE_INT_TIME,
881				mt9t013_regs.reg_pat[rt].fine_int_time);
882		if (rc < 0)
883			return rc;
884
885		rc =
886			mt9t013_i2c_write_w(mt9t013_client->addr,
887				REG_GROUPED_PARAMETER_HOLD,
888				GROUPED_PARAMETER_UPDATE);
889			if (rc < 0)
890				return rc;
891
892		/* load lens shading */
893		rc =
894			mt9t013_i2c_write_w(mt9t013_client->addr,
895				REG_GROUPED_PARAMETER_HOLD,
896				GROUPED_PARAMETER_HOLD);
897		if (rc < 0)
898			return rc;
899
900		/* most likely needs to be written only once. */
901		rc = mt9t013_set_lc();
902		if (rc < 0)
903			return -EBUSY;
904
905		rc =
906			mt9t013_i2c_write_w(mt9t013_client->addr,
907				REG_GROUPED_PARAMETER_HOLD,
908				GROUPED_PARAMETER_UPDATE);
909		if (rc < 0)
910			return rc;
911
912		rc = mt9t013_test(mt9t013_ctrl->set_test);
913		if (rc < 0)
914			return rc;
915
916		mdelay(5);
917
918		rc =
919			mt9t013_i2c_write_w(mt9t013_client->addr,
920				MT9T013_REG_RESET_REGISTER,
921				MT9T013_RESET_REGISTER_PWON);
922		if (rc < 0)
923			/* MODE_SELECT, stop streaming */
924			return rc;
925
926		CDBG("!!! mt9t013 !!! PowerOn is done!\n");
927		mdelay(5);
928		return rc;
929		}
930	} /* case CAMSENSOR_REG_INIT: */
931	break;
932
933	/*CAMSENSOR_REG_INIT */
934	default:
935		rc = -EINVAL;
936		break;
937	} /* switch (rupdate) */
938
939	return rc;
940}
941
942static int32_t mt9t013_video_config(int mode, int res)
943{
944	int32_t rc;
945
946	switch (res) {
947	case QTR_SIZE:
948		rc = mt9t013_setting(UPDATE_PERIODIC, RES_PREVIEW);
949		if (rc < 0)
950			return rc;
951		CDBG("sensor configuration done!\n");
952		break;
953
954	case FULL_SIZE:
955		rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
956		if (rc < 0)
957			return rc;
958		break;
959
960	default:
961		return -EINVAL;
962	} /* switch */
963
964	mt9t013_ctrl->prev_res = res;
965	mt9t013_ctrl->curr_res = res;
966	mt9t013_ctrl->sensormode = mode;
967
968	return mt9t013_write_exp_gain(mt9t013_ctrl->my_reg_gain,
969			mt9t013_ctrl->my_reg_line_count);
970}
971
972static int32_t mt9t013_snapshot_config(int mode)
973{
974	int32_t rc = 0;
975
976	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
977	if (rc < 0)
978		return rc;
979
980	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
981	mt9t013_ctrl->sensormode = mode;
982	return rc;
983}
984
985static int32_t mt9t013_raw_snapshot_config(int mode)
986{
987	int32_t rc = 0;
988
989	rc = mt9t013_setting(UPDATE_PERIODIC, RES_CAPTURE);
990	if (rc < 0)
991		return rc;
992
993	mt9t013_ctrl->curr_res = mt9t013_ctrl->pict_res;
994	mt9t013_ctrl->sensormode = mode;
995	return rc;
996}
997
998static int32_t mt9t013_power_down(void)
999{
1000	int32_t rc = 0;
1001
1002	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1003			MT9T013_REG_RESET_REGISTER,
1004			MT9T013_RESET_REGISTER_PWOFF);
1005	if (rc >= 0)
1006		mdelay(5);
1007	return rc;
1008}
1009
1010static int32_t mt9t013_move_focus(int direction, int32_t num_steps)
1011{
1012	int16_t step_direction;
1013	int16_t actual_step;
1014	int16_t next_position;
1015	int16_t break_steps[4];
1016	uint8_t code_val_msb, code_val_lsb;
1017	int16_t i;
1018
1019	if (num_steps > MT9T013_TOTAL_STEPS_NEAR_TO_FAR)
1020		num_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
1021	else if (num_steps == 0)
1022		return -EINVAL;
1023
1024	if (direction == MOVE_NEAR)
1025		step_direction = 4;
1026	else if (direction == MOVE_FAR)
1027		step_direction = -4;
1028	else
1029		return -EINVAL;
1030
1031	if (mt9t013_ctrl->curr_lens_pos < mt9t013_ctrl->init_curr_lens_pos)
1032		mt9t013_ctrl->curr_lens_pos = mt9t013_ctrl->init_curr_lens_pos;
1033
1034	actual_step =
1035		(int16_t) (step_direction *
1036		(int16_t) num_steps);
1037
1038	for (i = 0; i < 4; i++)
1039		break_steps[i] =
1040			actual_step / 4 * (i + 1) - actual_step / 4 * i;
1041
1042	for (i = 0; i < 4; i++) {
1043		next_position =
1044		(int16_t)
1045		(mt9t013_ctrl->curr_lens_pos + break_steps[i]);
1046
1047		if (next_position > 255)
1048			next_position = 255;
1049		else if (next_position < 0)
1050			next_position = 0;
1051
1052		code_val_msb =
1053		((next_position >> 4) << 2) |
1054		((next_position << 4) >> 6);
1055
1056		code_val_lsb =
1057		((next_position & 0x03) << 6);
1058
1059		/* Writing the digital code for current to the actuator */
1060		if (mt9t013_i2c_write_b(MT9T013_AF_I2C_ADDR>>1,
1061				code_val_msb, code_val_lsb) < 0)
1062			return -EBUSY;
1063
1064		/* Storing the current lens Position */
1065		mt9t013_ctrl->curr_lens_pos = next_position;
1066
1067		if (i < 3)
1068			mdelay(1);
1069	} /* for */
1070
1071	return 0;
1072}
1073
1074static int mt9t013_sensor_init_done(const struct msm_camera_sensor_info *data)
1075{
1076	gpio_direction_output(data->sensor_reset, 0);
1077	gpio_free(data->sensor_reset);
1078	return 0;
1079}
1080
1081static int mt9t013_probe_init_sensor(const struct msm_camera_sensor_info *data)
1082{
1083	int rc;
1084	uint16_t chipid;
1085
1086	rc = gpio_request(data->sensor_reset, "mt9t013");
1087	if (!rc)
1088		gpio_direction_output(data->sensor_reset, 1);
1089	else
1090		goto init_probe_done;
1091
1092	mdelay(20);
1093
1094	/* RESET the sensor image part via I2C command */
1095	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1096		MT9T013_REG_RESET_REGISTER, 0x1009);
1097	if (rc < 0)
1098		goto init_probe_fail;
1099
1100	/* 3. Read sensor Model ID: */
1101	rc = mt9t013_i2c_read_w(mt9t013_client->addr,
1102		MT9T013_REG_MODEL_ID, &chipid);
1103
1104	if (rc < 0)
1105		goto init_probe_fail;
1106
1107	CDBG("mt9t013 model_id = 0x%x\n", chipid);
1108
1109	/* 4. Compare sensor ID to MT9T012VC ID: */
1110	if (chipid != MT9T013_MODEL_ID) {
1111		rc = -ENODEV;
1112		goto init_probe_fail;
1113	}
1114
1115	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1116		0x3064, 0x0805);
1117	if (rc < 0)
1118		goto init_probe_fail;
1119
1120	mdelay(MT9T013_RESET_DELAY_MSECS);
1121
1122	goto init_probe_done;
1123
1124	/* sensor: output enable */
1125
1126init_probe_fail:
1127	gpio_direction_output(data->sensor_reset, 0);
1128	gpio_free(data->sensor_reset);
1129init_probe_done:
1130	return rc;
1131}
1132
1133static int32_t mt9t013_poweron_af(void)
1134{
1135	int32_t rc = 0;
1136
1137	/* enable AF actuator */
1138	CDBG("enable AF actuator, gpio = %d\n",
1139			mt9t013_ctrl->sensordata->vcm_pwd);
1140	rc = gpio_request(mt9t013_ctrl->sensordata->vcm_pwd, "mt9t013");
1141	if (!rc) {
1142		gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 0);
1143		mdelay(20);
1144		rc = mt9t013_set_default_focus(0);
1145	} else
1146		pr_err("%s, gpio_request failed (%d)!\n", __func__, rc);
1147	return rc;
1148}
1149
1150static void mt9t013_poweroff_af(void)
1151{
1152	gpio_direction_output(mt9t013_ctrl->sensordata->vcm_pwd, 1);
1153	gpio_free(mt9t013_ctrl->sensordata->vcm_pwd);
1154}
1155
1156int mt9t013_sensor_open_init(const struct msm_camera_sensor_info *data)
1157{
1158	int32_t  rc;
1159
1160	mt9t013_ctrl = kzalloc(sizeof(struct mt9t013_ctrl), GFP_KERNEL);
1161	if (!mt9t013_ctrl) {
1162		pr_err("mt9t013_init failed!\n");
1163		rc = -ENOMEM;
1164		goto init_done;
1165	}
1166
1167	mt9t013_ctrl->fps_divider = 1 * 0x00000400;
1168	mt9t013_ctrl->pict_fps_divider = 1 * 0x00000400;
1169	mt9t013_ctrl->set_test = TEST_OFF;
1170	mt9t013_ctrl->prev_res = QTR_SIZE;
1171	mt9t013_ctrl->pict_res = FULL_SIZE;
1172
1173	if (data)
1174		mt9t013_ctrl->sensordata = data;
1175
1176	/* enable mclk first */
1177	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
1178	mdelay(20);
1179
1180	msm_camio_camif_pad_reg_reset();
1181	mdelay(20);
1182
1183	rc = mt9t013_probe_init_sensor(data);
1184	if (rc < 0)
1185		goto init_fail;
1186
1187	if (mt9t013_ctrl->prev_res == QTR_SIZE)
1188		rc = mt9t013_setting(REG_INIT, RES_PREVIEW);
1189	else
1190		rc = mt9t013_setting(REG_INIT, RES_CAPTURE);
1191
1192	if (rc >= 0)
1193		rc = mt9t013_poweron_af();
1194
1195	if (rc < 0)
1196		goto init_fail;
1197	else
1198		goto init_done;
1199
1200init_fail:
1201	kfree(mt9t013_ctrl);
1202init_done:
1203	return rc;
1204}
1205
1206static int mt9t013_init_client(struct i2c_client *client)
1207{
1208	/* Initialize the MSM_CAMI2C Chip */
1209	init_waitqueue_head(&mt9t013_wait_queue);
1210	return 0;
1211}
1212
1213
1214static int32_t mt9t013_set_sensor_mode(int mode, int res)
1215{
1216	int32_t rc = 0;
1217	rc = mt9t013_i2c_write_w(mt9t013_client->addr,
1218			REG_GROUPED_PARAMETER_HOLD,
1219			GROUPED_PARAMETER_HOLD);
1220	if (rc < 0)
1221		return rc;
1222
1223	switch (mode) {
1224	case SENSOR_PREVIEW_MODE:
1225		rc = mt9t013_video_config(mode, res);
1226		break;
1227
1228	case SENSOR_SNAPSHOT_MODE:
1229		rc = mt9t013_snapshot_config(mode);
1230		break;
1231
1232	case SENSOR_RAW_SNAPSHOT_MODE:
1233		rc = mt9t013_raw_snapshot_config(mode);
1234		break;
1235
1236	default:
1237		return -EINVAL;
1238	}
1239
1240	if (rc >= 0)
1241		return mt9t013_i2c_write_w(mt9t013_client->addr,
1242				REG_GROUPED_PARAMETER_HOLD,
1243				GROUPED_PARAMETER_UPDATE);
1244	return rc;
1245}
1246
1247int mt9t013_sensor_config(void __user *argp)
1248{
1249	struct sensor_cfg_data cdata;
1250	long   rc = 0;
1251
1252	if (copy_from_user(&cdata, (void *)argp,
1253			sizeof(struct sensor_cfg_data)))
1254		return -EFAULT;
1255
1256	down(&mt9t013_sem);
1257
1258	CDBG("mt9t013_sensor_config: cfgtype = %d\n", cdata.cfgtype);
1259	switch (cdata.cfgtype) {
1260	case CFG_GET_PICT_FPS:
1261		mt9t013_get_pict_fps(cdata.cfg.gfps.prevfps,
1262				&(cdata.cfg.gfps.pictfps));
1263		if (copy_to_user((void *)argp,
1264				&cdata,
1265				sizeof(struct sensor_cfg_data)))
1266			rc = -EFAULT;
1267		break;
1268
1269	case CFG_GET_PREV_L_PF:
1270		cdata.cfg.prevl_pf = mt9t013_get_prev_lines_pf();
1271		if (copy_to_user((void *)argp,
1272				&cdata,
1273				sizeof(struct sensor_cfg_data)))
1274			rc = -EFAULT;
1275		break;
1276
1277	case CFG_GET_PREV_P_PL:
1278		cdata.cfg.prevp_pl = mt9t013_get_prev_pixels_pl();
1279		if (copy_to_user((void *)argp,
1280				&cdata,
1281				sizeof(struct sensor_cfg_data)))
1282			rc = -EFAULT;
1283		break;
1284
1285	case CFG_GET_PICT_L_PF:
1286		cdata.cfg.pictl_pf = mt9t013_get_pict_lines_pf();
1287		if (copy_to_user((void *)argp,
1288				&cdata,
1289				sizeof(struct sensor_cfg_data)))
1290			rc = -EFAULT;
1291		break;
1292
1293	case CFG_GET_PICT_P_PL:
1294		cdata.cfg.pictp_pl =
1295			mt9t013_get_pict_pixels_pl();
1296
1297		if (copy_to_user((void *)argp,
1298				&cdata,
1299				sizeof(struct sensor_cfg_data)))
1300			rc = -EFAULT;
1301		break;
1302
1303	case CFG_GET_PICT_MAX_EXP_LC:
1304		cdata.cfg.pict_max_exp_lc =
1305			mt9t013_get_pict_max_exp_lc();
1306
1307		if (copy_to_user((void *)argp,
1308				&cdata,
1309				sizeof(struct sensor_cfg_data)))
1310			rc = -EFAULT;
1311		break;
1312
1313	case CFG_SET_FPS:
1314	case CFG_SET_PICT_FPS:
1315		rc = mt9t013_set_fps(&(cdata.cfg.fps));
1316		break;
1317
1318	case CFG_SET_EXP_GAIN:
1319		rc = mt9t013_write_exp_gain(cdata.cfg.exp_gain.gain,
1320				cdata.cfg.exp_gain.line);
1321		break;
1322
1323	case CFG_SET_PICT_EXP_GAIN:
1324		rc = mt9t013_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
1325				cdata.cfg.exp_gain.line);
1326		break;
1327
1328	case CFG_SET_MODE:
1329		rc = mt9t013_set_sensor_mode(cdata.mode, cdata.rs);
1330		break;
1331
1332	case CFG_PWR_DOWN:
1333		rc = mt9t013_power_down();
1334		break;
1335
1336	case CFG_MOVE_FOCUS:
1337		rc = mt9t013_move_focus(cdata.cfg.focus.dir,
1338				cdata.cfg.focus.steps);
1339		break;
1340
1341	case CFG_SET_DEFAULT_FOCUS:
1342		rc = mt9t013_set_default_focus(cdata.cfg.focus.steps);
1343		break;
1344
1345	case CFG_GET_AF_MAX_STEPS:
1346		cdata.max_steps = MT9T013_TOTAL_STEPS_NEAR_TO_FAR;
1347		if (copy_to_user((void *)argp,
1348				&cdata,
1349				sizeof(struct sensor_cfg_data)))
1350			rc = -EFAULT;
1351		break;
1352
1353	case CFG_SET_EFFECT:
1354	default:
1355		rc = -EINVAL;
1356		break;
1357	}
1358
1359	up(&mt9t013_sem);
1360	return rc;
1361}
1362
1363int mt9t013_sensor_release(void)
1364{
1365	int rc = -EBADF;
1366
1367	down(&mt9t013_sem);
1368
1369	mt9t013_poweroff_af();
1370	mt9t013_power_down();
1371
1372	gpio_direction_output(mt9t013_ctrl->sensordata->sensor_reset,
1373			0);
1374	gpio_free(mt9t013_ctrl->sensordata->sensor_reset);
1375
1376	kfree(mt9t013_ctrl);
1377
1378	up(&mt9t013_sem);
1379	CDBG("mt9t013_release completed!\n");
1380	return rc;
1381}
1382
1383static int mt9t013_i2c_probe(struct i2c_client *client,
1384	const struct i2c_device_id *id)
1385{
1386	int rc = 0;
1387	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1388		rc = -ENOTSUPP;
1389		goto probe_failure;
1390	}
1391
1392	mt9t013_sensorw =
1393		kzalloc(sizeof(struct mt9t013_work), GFP_KERNEL);
1394
1395	if (!mt9t013_sensorw) {
1396		rc = -ENOMEM;
1397		goto probe_failure;
1398	}
1399
1400	i2c_set_clientdata(client, mt9t013_sensorw);
1401	mt9t013_init_client(client);
1402	mt9t013_client = client;
1403	mt9t013_client->addr = mt9t013_client->addr >> 1;
1404	mdelay(50);
1405
1406	CDBG("i2c probe ok\n");
1407	return 0;
1408
1409probe_failure:
1410	kfree(mt9t013_sensorw);
1411	mt9t013_sensorw = NULL;
1412	pr_err("i2c probe failure %d\n", rc);
1413	return rc;
1414}
1415
1416static const struct i2c_device_id mt9t013_i2c_id[] = {
1417	{ "mt9t013", 0},
1418	{ }
1419};
1420
1421static struct i2c_driver mt9t013_i2c_driver = {
1422	.id_table = mt9t013_i2c_id,
1423	.probe  = mt9t013_i2c_probe,
1424	.remove = __exit_p(mt9t013_i2c_remove),
1425	.driver = {
1426		.name = "mt9t013",
1427	},
1428};
1429
1430static int mt9t013_sensor_probe(
1431		const struct msm_camera_sensor_info *info,
1432		struct msm_sensor_ctrl *s)
1433{
1434	/* We expect this driver to match with the i2c device registered
1435	 * in the board file immediately. */
1436	int rc = i2c_add_driver(&mt9t013_i2c_driver);
1437	if (rc < 0 || mt9t013_client == NULL) {
1438		rc = -ENOTSUPP;
1439		goto probe_done;
1440	}
1441
1442	/* enable mclk first */
1443	msm_camio_clk_rate_set(MT9T013_DEFAULT_CLOCK_RATE);
1444	mdelay(20);
1445
1446	rc = mt9t013_probe_init_sensor(info);
1447	if (rc < 0) {
1448		i2c_del_driver(&mt9t013_i2c_driver);
1449		goto probe_done;
1450	}
1451
1452	s->s_init = mt9t013_sensor_open_init;
1453	s->s_release = mt9t013_sensor_release;
1454	s->s_config  = mt9t013_sensor_config;
1455	mt9t013_sensor_init_done(info);
1456
1457probe_done:
1458	return rc;
1459}
1460
1461static int __mt9t013_probe(struct platform_device *pdev)
1462{
1463	return msm_camera_drv_start(pdev, mt9t013_sensor_probe);
1464}
1465
1466static struct platform_driver msm_camera_driver = {
1467	.probe = __mt9t013_probe,
1468	.driver = {
1469		.name = "msm_camera_mt9t013",
1470		.owner = THIS_MODULE,
1471	},
1472};
1473
1474static int __init mt9t013_init(void)
1475{
1476	return platform_driver_register(&msm_camera_driver);
1477}
1478
1479module_init(mt9t013_init);
1480