2 * Copyright (C) 2007-2008 HTC Corporation.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/interrupt.h>
16 #include <linux/i2c.h>
17 #include <linux/slab.h>
18 #include <linux/irq.h>
19 #include <linux/miscdevice.h>
20 #include <linux/delay.h>
21 #include <linux/input.h>
22 #include <linux/workqueue.h>
23 #include <linux/freezer.h>
24 #include <linux/netlink.h>
25 #include <linux/skbuff.h>
26 #include <linux/clk.h>
27 #include <linux/wakelock.h>
30 #include <asm/uaccess.h>
32 #include <asm/mach-types.h>
33 #include <mach/msm_iomap.h>
34 #include <mach/msm_rpcrouter.h>
35 #include <mach/vreg.h>
36 #include <mach/board.h>
37 #include <linux/mt9t013.h> /* define ioctls */
40 #define ALLOW_USPACE_RW 0
42 static const uint32_t fps_divider
= 1;
44 #define AF_I2C_ID 0x18 /* actuator's slave address */
46 static struct i2c_client
*pclient
;
48 /* we need this to set the clock rate */
49 static struct clk
*vfe_clk
;
52 static struct clk
*vfe_mdc_clk
;
53 static struct clk
*mdc_clk
;
55 static int mdc_clk_enabled
;
56 static int vfe_mdc_clk_enabled
;
57 static int vfe_clk_enabled
;
61 static const struct mt9t013_reg_pat mt9t013_reg_pattern
= { .reg
= {
62 { /* preview 2x2 binning 20fps, pclk MHz, MCLK 24MHz */
63 10, /*vt_pix_clk_div REG=0x0300*/
64 /*update get_snapshot_fps if this change*/
65 1, /*vt_sys_clk_div REG=0x0302*/
66 /*update get_snapshot_fps if this change*/
67 3, /*2, pre_pll_clk_div REG=0x0304*/
68 /*update get_snapshot_fps if this change*/
69 80, /*40, pll_multiplier REG=0x0306*/
70 /*60 for 30fps preview, 40 for 20fps preview*/
71 10, /*op_pix_clk_div REG=0x0308*/
72 1, /*op_sys_clk_div REG=0x030A*/
73 16, /*scale_m REG=0x0404*/
74 0x0111, /*row_speed REG=0x3016*/
75 8, /*x_addr_start REG=0x3004*/
76 2053, /*x_addr_end REG=0x3008*/
77 8, /*y_addr_start REG=0x3002*/
78 1541, /*y_addr_end REG=0x3006*/
79 0x046C, /*read_mode REG=0x3040*/
80 1024, /*x_output_size REG=0x034C*/
81 768, /*y_output_size REG=0x034E*/
82 3540, /*2616, line_length_pck REG=0x300C*/
83 861, /*916, frame_length_lines REG=0x300A*/
84 16, /*coarse_integration_time REG=0x3012*/
85 1461 /*fine_integration_time REG=0x3014*/
88 10, /*vt_pix_clk_div REG=0x0300*/
89 /*update get_snapshot_fps if this change*/
90 1, /*vt_sys_clk_div REG=0x0302*/
91 /*update get_snapshot_fps if this change*/
92 3, /*2, pre_pll_clk_div REG=0x0304*/
93 /*update get_snapshot_fps if this change*/
94 80, /*40, pll_multiplier REG=0x0306*/
95 /*50 for 15fps snapshot, 40 for 10fps snapshot*/
96 10, /*op_pix_clk_div REG=0x0308*/
97 1, /*op_sys_clk_div REG=0x030A*/
98 16, /*scale_m REG=0x0404*/
99 0x0111, /*row_speed REG=0x3016*/
100 8, /*0, x_addr_start REG=0x3004*/
101 2063, /*2061, x_addr_end REG=0x3008*/
102 8, /*2, y_addr_start REG=0x3002*/
103 1551, /*1545, y_addr_end REG=0x3006*/
104 0x0024, /*read_mode REG=0x3040*/
105 2063, /*output_size REG=0x034C*/
106 1544, /*y_output_size REG=0x034E*/
107 4800, /*2952, line_length_pck REG=0x300C*/
108 1629, /*frame_length_lines REG=0x300A*/
109 16, /*coarse_integration_time REG=0x3012*/
110 733 /*fine_integration_time REG=0x3014*/
114 #define MT9T013_MU3M0VC_REG_MODEL_ID 0x0000
115 #define MT9T013_MU3M0VC_MODEL_ID 0x2600
116 #define REG_GROUPED_PARAMETER_HOLD 0x0104
117 #define GROUPED_PARAMETER_HOLD 0x0100
118 #define GROUPED_PARAMETER_UPDATE 0x0000
119 #define REG_COARSE_INTEGRATION_TIME 0x3012
120 #define REG_VT_PIX_CLK_DIV 0x0300
121 #define REG_VT_SYS_CLK_DIV 0x0302
122 #define REG_PRE_PLL_CLK_DIV 0x0304
123 #define REG_PLL_MULTIPLIER 0x0306
124 #define REG_OP_PIX_CLK_DIV 0x0308
125 #define REG_OP_SYS_CLK_DIV 0x030A
126 #define REG_SCALE_M 0x0404
127 #define REG_FRAME_LENGTH_LINES 0x300A
128 #define REG_LINE_LENGTH_PCK 0x300C
129 #define REG_X_ADDR_START 0x3004
130 #define REG_Y_ADDR_START 0x3002
131 #define REG_X_ADDR_END 0x3008
132 #define REG_Y_ADDR_END 0x3006
133 #define REG_X_OUTPUT_SIZE 0x034C
134 #define REG_Y_OUTPUT_SIZE 0x034E
135 #define REG_FINE_INTEGRATION_TIME 0x3014
136 #define REG_ROW_SPEED 0x3016
137 #define MT9T013_REG_RESET_REGISTER 0x301A
138 #define MT9T013_RESET_REGISTER_PWON 0x10CC /*enable paralled and start streaming*/
139 #define MT9T013_RESET_REGISTER_PWOFF 0x1008 //0x10C8 /*stop streaming*/
140 #define REG_READ_MODE 0x3040
141 #define REG_GLOBAL_GAIN 0x305E
142 #define REG_TEST_PATTERN_MODE 0x3070
144 static struct wake_lock mt9t013_wake_lock
;
146 static inline void init_suspend(void)
148 wake_lock_init(&mt9t013_wake_lock
, WAKE_LOCK_IDLE
, "mt9t013");
151 static inline void deinit_suspend(void)
153 wake_lock_destroy(&mt9t013_wake_lock
);
156 static inline void prevent_suspend(void)
158 wake_lock(&mt9t013_wake_lock
);
161 static inline void allow_suspend(void)
163 wake_unlock(&mt9t013_wake_lock
);
166 #define CLK_GET(clk) do { \
168 clk = clk_get(NULL, #clk); \
170 "mt9t013: clk_get(%s): %p\n", #clk, clk); \
176 static struct msm_camera_legacy_device_platform_data
*cam
;
178 #define out_dword(addr, val) \
179 (*((volatile unsigned long *)(addr)) = ((unsigned long)(val)))
181 #define out_dword_masked_ns(io, mask, val, current_reg_content) \
182 (void) out_dword(io, ((current_reg_content & (uint32_t)(~(mask))) | \
183 ((uint32_t)((val) & (mask)))))
185 #define __inpdw(port) (*((volatile uint32_t *) (port)))
186 #define in_dword_masked(addr, mask) (__inpdw(addr) & (uint32_t)mask )
188 #define HWIO_MDDI_CAMIF_CFG_ADDR MSM_MDC_BASE
189 #define HWIO_MDDI_CAMIF_CFG_RMSK 0x1fffff
190 #define HWIO_MDDI_CAMIF_CFG_IN \
191 in_dword_masked(HWIO_MDDI_CAMIF_CFG_ADDR, HWIO_MDDI_CAMIF_CFG_RMSK)
193 #define HWIO_MDDI_CAMIF_CFG_OUTM(m,v) \
194 out_dword_masked_ns(HWIO_MDDI_CAMIF_CFG_ADDR,m,v,HWIO_MDDI_CAMIF_CFG_IN);
195 #define __msmhwio_outm(hwiosym, mask, val) HWIO_##hwiosym##_OUTM(mask, val)
196 #define HWIO_OUTM(hwiosym, mask, val) __msmhwio_outm(hwiosym, mask, val)
198 #define HWIO_MDDI_CAMIF_CFG_CAM_SEL_BMSK 0x2
199 #define HWIO_MDDI_CAMIF_CFG_CAM_PCLK_SRC_SEL_BMSK 0x60000
200 #define HWIO_MDDI_CAMIF_CFG_CAM_PCLK_INVERT_BMSK 0x80000
201 #define HWIO_MDDI_CAMIF_CFG_CAM_PAD_REG_SW_RESET_BMSK 0x100000
203 #define HWIO_MDDI_CAMIF_CFG_CAM_SEL_SHFT 0x1
204 #define HWIO_MDDI_CAMIF_CFG_CAM_PCLK_SRC_SEL_SHFT 0x11
205 #define HWIO_MDDI_CAMIF_CFG_CAM_PCLK_INVERT_SHFT 0x13
206 #define HWIO_MDDI_CAMIF_CFG_CAM_PAD_REG_SW_RESET_SHFT 0x14
208 #define __msmhwio_shft(hwio_regsym, hwio_fldsym) HWIO_##hwio_regsym##_##hwio_fldsym##_SHFT
209 #define HWIO_SHFT(hwio_regsym, hwio_fldsym) __msmhwio_shft(hwio_regsym, hwio_fldsym)
211 #define __msmhwio_fmsk(hwio_regsym, hwio_fldsym) HWIO_##hwio_regsym##_##hwio_fldsym##_BMSK
212 #define HWIO_FMSK(hwio_regsym, hwio_fldsym) __msmhwio_fmsk(hwio_regsym, hwio_fldsym)
214 #define HWIO_APPS_RESET_ADDR (MSM_CLK_CTL_BASE + 0x00000210)
215 #define HWIO_APPS_RESET_RMSK 0x1fff
216 #define HWIO_APPS_RESET_VFE_BMSK 1
217 #define HWIO_APPS_RESET_VFE_SHFT 0
218 #define HWIO_APPS_RESET_IN in_dword_masked(HWIO_APPS_RESET_ADDR, HWIO_APPS_RESET_RMSK)
219 #define HWIO_APPS_RESET_OUTM(m,v) out_dword_masked_ns(HWIO_APPS_RESET_ADDR,m,v,HWIO_APPS_RESET_IN)
221 struct mt9t013_data
{
222 struct work_struct work
;
225 static DECLARE_WAIT_QUEUE_HEAD(g_data_ready_wait_queue
);
227 static int mt9t013_i2c_sensor_init(struct mt9t013_init
*init
);
228 static int mt9t013_i2c_sensor_setting(unsigned long arg
);
229 static int mt9t013_i2c_exposure_gain(uint32_t mode
, uint16_t line
,
231 static int mt9t013_i2c_move_focus(uint16_t position
);
232 static int mt9t013_i2c_set_default_focus(uint8_t step
);
233 static int mt9t013_i2c_power_up(void);
234 static int mt9t013_i2c_power_down(void);
235 static int mt9t013_camif_pad_reg_reset(void);
236 static int mt9t013_lens_power(int on
);
238 int mt_i2c_lens_tx_data(unsigned char slave_addr
, char* txData
, int length
)
241 struct i2c_msg msg
[] = {
253 /* printk(KERN_INFO "mt_i2c_lens_tx_data: af i2c client addr = %x,"
254 " register addr = 0x%02x%02x:\n", slave_addr, txData[0], txData[1]);
256 for (i
= 0; i
< length
- 2; i
++)
257 printk(KERN_INFO
"\tdata[%d]: 0x%02x\n", i
, txData
[i
+2]);
261 rc
= i2c_transfer(pclient
->adapter
, msg
, 1);
263 printk(KERN_ERR
"mt_i2c_lens_tx_data: i2c_transfer error %d\n", rc
);
269 static int mt9t013_i2c_lens_write(unsigned char slave_addr
, unsigned char u_addr
, unsigned char u_data
)
271 unsigned char buf
[2] = { u_addr
, u_data
};
272 return mt_i2c_lens_tx_data(slave_addr
, buf
, sizeof(buf
));
275 static int mt_i2c_rx_data(char* rxData
, int length
)
278 struct i2c_msg msgs
[] = {
280 .addr
= pclient
->addr
,
286 .addr
= pclient
->addr
,
293 rc
= i2c_transfer(pclient
->adapter
, msgs
, 2);
295 printk(KERN_ERR
"mt9t013: mt_i2c_rx_data error %d\n", rc
);
301 for (i
= 0; i
< length
; i
++)
302 printk(KERN_INFO
"\tdata[%d]: 0x%02x\n", i
, rxData
[i
]);
309 int mt_i2c_tx_data(char* txData
, int length
)
313 struct i2c_msg msg
[] = {
315 .addr
= pclient
->addr
,
322 rc
= i2c_transfer(pclient
->adapter
, msg
, 1);
324 printk(KERN_ERR
"mt9t013: mt_i2c_tx_data error %d\n", rc
);
330 static int mt9t013_i2c_write(unsigned short u_addr
, unsigned short u_data
)
333 unsigned char buf
[4];
335 buf
[0] = (u_addr
& 0xFF00) >> 8;
336 buf
[1] = u_addr
& 0x00FF;
337 buf
[2] = (u_data
& 0xFF00) >> 8;
338 buf
[3] = u_data
& 0x00FF;
340 rc
= mt_i2c_tx_data(buf
, sizeof(buf
));
342 printk(KERN_ERR
"mt9t013: txdata error %d add:0x%02x data:0x%02x\n",
347 static int mt9t013_i2c_read(unsigned short u_addr
, unsigned short *pu_data
)
350 unsigned char buf
[2];
352 buf
[0] = (u_addr
& 0xFF00)>>8;
353 buf
[1] = (u_addr
& 0x00FF);
354 rc
= mt_i2c_rx_data(buf
, 2);
356 *pu_data
= buf
[0]<<8 | buf
[1];
357 else printk(KERN_ERR
"mt9t013: i2c read failed\n");
361 static int msm_camio_clk_enable (int clk_type
)
363 struct clk
*clk
= NULL
;
367 case CAMIO_VFE_MDC_CLK
:
368 CLK_GET(vfe_mdc_clk
);
370 enabled
= &vfe_mdc_clk_enabled
;
375 enabled
= &mdc_clk_enabled
;
381 if (clk
!= NULL
&& !*enabled
) {
382 int rc
= clk_enable(clk
);
390 static int msm_camio_clk_disable(int clk_type
)
393 struct clk
*clk
= NULL
;
397 case CAMIO_VFE_MDC_CLK
:
399 enabled
= &vfe_mdc_clk_enabled
;
403 enabled
= &mdc_clk_enabled
;
410 if (clk
!= NULL
&& *enabled
) {
419 static int msm_camio_vfe_clk_enable(void)
422 if (vfe_clk
&& !vfe_clk_enabled
) {
423 vfe_clk_enabled
= !clk_enable(vfe_clk
);
424 printk(KERN_INFO
"mt9t013: enable vfe_clk\n");
426 return vfe_clk_enabled
? 0 : -EIO
;
429 static int msm_camio_clk_rate_set(int rate
)
431 int rc
= msm_camio_vfe_clk_enable();
432 if (!rc
&& vfe_clk_enabled
)
433 rc
= clk_set_rate(vfe_clk
, rate
);
437 static int clk_select(int internal
)
440 printk(KERN_INFO
"mt9t013: clk select %d\n", internal
);
442 if (vfe_clk
!= NULL
) {
443 extern int clk_set_flags(struct clk
*clk
, unsigned long flags
);
444 rc
= clk_set_flags(vfe_clk
, 0x00000100 << internal
);
445 if (!rc
&& internal
) rc
= msm_camio_vfe_clk_enable();
450 static void mt9t013_sensor_init(void)
453 printk(KERN_INFO
"mt9t013: init\n");
458 printk(KERN_INFO
"mt9t013: mt9t013_register_init\n");
459 ret
= gpio_request(cam
->sensor_reset
, "mt9t013");
461 gpio_direction_output(cam
->sensor_reset
, 1);
462 printk(KERN_INFO
"mt9t013: camera sensor_reset set as 1\n");
464 printk(KERN_ERR
"mt9t013 error: request gpio %d failed: "
465 "%d\n", cam
->sensor_reset
, ret
);
468 /* pull down power down */
469 ret
= gpio_request(cam
->sensor_pwd
, "mt9t013");
470 if (!ret
|| ret
== -EBUSY
)
471 gpio_direction_output(cam
->sensor_pwd
, 0);
472 else printk(KERN_ERR
"mt913t013 error: request gpio %d failed: "
473 "%d\n", cam
->sensor_pwd
, ret
);
474 gpio_free(cam
->sensor_pwd
);
477 msm_camio_clk_enable(CAMIO_VFE_MDC_CLK
);
478 msm_camio_clk_enable(CAMIO_MDC_CLK
);
481 mt9t013_camif_pad_reg_reset();
484 ret
= msm_camio_clk_rate_set(24000000);
486 printk(KERN_ERR
"camio clk rate select error\n");
490 cam
->config_gpio_on();
494 /* reset sensor sequency */
495 gpio_direction_output(cam
->sensor_reset
, 0);
497 gpio_direction_output(cam
->sensor_reset
, 1);
498 gpio_free(cam
->sensor_reset
);
501 printk(KERN_INFO
"mt9t013: camera sensor init sequence done\n");
504 #define CLK_DISABLE_AND_PUT(clk) do { \
506 if (clk##_enabled) { \
507 printk(KERN_INFO "mt9t013: disabling "#clk"\n");\
512 "mt9t013: clk_put(%s): %p\n", #clk, clk); \
518 static void mt9t013_sensor_suspend(void)
520 printk(KERN_INFO
"mt9t013: camera sensor suspend sequence\n");
525 msm_camio_clk_disable(CAMIO_VFE_MDC_CLK
);
526 msm_camio_clk_disable(CAMIO_MDC_CLK
);
527 CLK_DISABLE_AND_PUT(vfe_clk
); /* this matches clk_select(1) */
529 cam
->config_gpio_off();
530 printk(KERN_INFO
"mt9t013: camera sensor suspend sequence done\n");
533 static int mt9t013_open(struct inode
*ip
, struct file
*fp
)
537 printk(KERN_INFO
"mt9t013: open\n");
539 printk(KERN_INFO
"mt9t013: prevent collapse on idle\n");
541 cam
->config_gpio_on();
549 static int mt9t013_release(struct inode
*ip
, struct file
*fp
)
552 printk(KERN_INFO
"mt9t013: release\n");
555 printk(KERN_INFO
"mt9t013: release clocks\n");
558 /* mt9t013_i2c_power_down() should be called before closing MCLK */
559 /* otherwise I2C_WRITE will always fail */
560 mt9t013_i2c_power_down();
562 CLK_DISABLE_AND_PUT(mdc_clk
);
563 CLK_DISABLE_AND_PUT(vfe_mdc_clk
);
564 CLK_DISABLE_AND_PUT(vfe_clk
);
565 mt9t013_lens_power(0);
567 cam
->config_gpio_off();
569 printk(KERN_INFO
"mt9t013: allow collapse on idle\n");
571 rc
= pclk_set
= opened
= 0;
577 #undef CLK_DISABLE_AND_PUT
580 if (!mdc_clk_enabled || !vfe_mdc_clk_enabled) { \
581 printk(KERN_ERR "mt9t013 error: one or more clocks" \
587 static int mt9t013_camif_pad_reg_reset(void)
589 int rc
= clk_select(1);
591 printk(KERN_ERR
"mt9t013 error switching to internal clock\n");
594 HWIO_OUTM (MDDI_CAMIF_CFG
,
595 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_SEL
) |
596 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_PCLK_SRC_SEL
) |
597 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_PCLK_INVERT
),
598 1 << HWIO_SHFT (MDDI_CAMIF_CFG
, CAM_SEL
) |
599 3 << HWIO_SHFT (MDDI_CAMIF_CFG
, CAM_PCLK_SRC_SEL
) |
600 0 << HWIO_SHFT (MDDI_CAMIF_CFG
, CAM_PCLK_INVERT
));
602 HWIO_OUTM (MDDI_CAMIF_CFG
,
603 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_PAD_REG_SW_RESET
),
604 1 << HWIO_SHFT (MDDI_CAMIF_CFG
,
605 CAM_PAD_REG_SW_RESET
));
607 HWIO_OUTM (MDDI_CAMIF_CFG
,
608 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_PAD_REG_SW_RESET
),
609 0 << HWIO_SHFT (MDDI_CAMIF_CFG
,
610 CAM_PAD_REG_SW_RESET
));
612 rc
= clk_select(0); /* external */
614 printk(KERN_ERR
"mt9t013 error switching to external clock\n");
622 #define COPY_FROM_USER(size) ({ \
623 if (copy_from_user(rwbuf, argp, size)) rc = -EFAULT; \
627 static long mt9t013_ioctl(struct file
*filp
, unsigned int cmd
, unsigned long arg
)
629 void __user
*argp
= (void __user
*)arg
;
633 unsigned short addr
= 0;
634 unsigned short data
= 0;
642 case MT9T013_I2C_IOCTL_W
:
643 if (/* CHECK() && */ COPY_FROM_USER(4)) {
644 addr
= *((unsigned short *)rwbuf
);
645 data
= *((unsigned short *)(rwbuf
+2));
646 rc
= mt9t013_i2c_write(addr
, data
);
648 printk(KERN_ERR
"mt9t013: write: err %d\n", rc
);
651 case MT9T013_I2C_IOCTL_R
:
652 if (/* CHECK() && */ COPY_FROM_USER(4)) {
653 addr
= *((unsigned short*) rwbuf
);
654 rc
= mt9t013_i2c_read(addr
, (unsigned short *)(rwbuf
+2));
656 if (copy_to_user(argp
, rwbuf
, 4)) {
657 printk(KERN_ERR
"mt9t013: read: err " \
658 "writeback -EFAULT\n");
663 printk(KERN_ERR
"mt9t013: read: err %d\n", rc
);
666 case MT9T013_I2C_IOCTL_AF_W
:
667 if (/* CHECK() && */ COPY_FROM_USER(3))
668 rc
= mt9t013_i2c_lens_write(*rwbuf
, *(rwbuf
+ 1), *(rwbuf
+ 2));
670 printk(KERN_ERR
"mt9t013: af write: err %d\n", rc
);
672 #endif /* ALLOW_USPACE_RW */
674 case MT9T013_I2C_IOCTL_CAMIF_PAD_REG_RESET
:
675 printk(KERN_INFO
"mt9t013: CAMIF_PAD_REG_RESET\n");
677 rc
= mt9t013_camif_pad_reg_reset();
680 case MT9T013_I2C_IOCTL_CAMIF_PAD_REG_RESET_2
:
681 printk(KERN_INFO
"mt9t013: CAMIF_PAD_REG_RESET_2 (pclk_set %d)\n",
686 HWIO_OUTM (MDDI_CAMIF_CFG
,
687 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_PAD_REG_SW_RESET
),
688 1 << HWIO_SHFT (MDDI_CAMIF_CFG
,
689 CAM_PAD_REG_SW_RESET
));
691 HWIO_OUTM (MDDI_CAMIF_CFG
,
692 HWIO_FMSK (MDDI_CAMIF_CFG
, CAM_PAD_REG_SW_RESET
),
693 0 << HWIO_SHFT (MDDI_CAMIF_CFG
,
694 CAM_PAD_REG_SW_RESET
));
699 case MT9T013_I2C_IOCTL_CAMIF_APPS_RESET
:
700 printk(KERN_INFO
"mt9t013: CAMIF_APPS_RESET\n");
704 printk(KERN_ERR
"mt9t013 error switching to internal clock\n");
707 HWIO_OUTM (APPS_RESET
,
708 HWIO_FMSK(APPS_RESET
,VFE
),
709 1 << HWIO_SHFT(APPS_RESET
,VFE
));
711 HWIO_OUTM (APPS_RESET
,
712 HWIO_FMSK(APPS_RESET
,VFE
),
713 0 << HWIO_SHFT(APPS_RESET
,VFE
));
715 rc
= clk_select(0); /* external */
717 printk(KERN_ERR
"mt9t013 error switching to external clock\n");
723 case CAMERA_LENS_POWER_ON
:
724 rc
= mt9t013_lens_power(1);
727 case CAMERA_LENS_POWER_OFF
:
728 rc
= mt9t013_lens_power(0);
731 case MT9T013_I2C_IOCTL_CLK_ENABLE
:
732 printk(KERN_INFO
"mt9t013: clk enable %ld\n", arg
);
733 rc
= msm_camio_clk_enable(arg
);
736 case MT9T013_I2C_IOCTL_CLK_DISABLE
:
737 printk(KERN_INFO
"mt9t013: clk disable %ld\n", arg
);
738 rc
= msm_camio_clk_disable(arg
);
741 case MT9T013_I2C_IOCTL_CLK_SELECT
:
742 printk(KERN_INFO
"mt9t013: clk select %ld\n", arg
);
743 rc
= clk_select(!!arg
);
746 case MT9T013_I2C_IOCTL_CLK_FREQ_PROG
:
747 printk(KERN_INFO
"mt9t013: clk rate select %ld\n", arg
);
748 rc
= msm_camio_clk_rate_set(arg
);
751 case MT9T013_I2C_IOCTL_GET_REGISTERS
:
752 printk(KERN_INFO
"mt9t013: get registers\n");
753 if (copy_to_user(argp
, &mt9t013_reg_pattern
.reg
, sizeof(mt9t013_reg_pattern
.reg
)))
757 case MT9T013_I2C_IOCTL_SENSOR_SETTING
:
758 printk(KERN_INFO
"mt9t013: sensor setting 0x%lx\n", arg
);
759 rc
= mt9t013_i2c_sensor_setting(arg
);
762 case MT9T013_I2C_IOCTL_EXPOSURE_GAIN
: {
763 struct mt9t013_exposure_gain exp
;
764 if (copy_from_user(&exp
, argp
, sizeof(exp
))) {
765 printk(KERN_ERR
"mt9t013: (exposure gain) invalid user pointer\n");
769 rc
= mt9t013_i2c_exposure_gain(exp
.mode
, exp
.line
, exp
.gain
);
773 case MT9T013_I2C_IOCTL_MOVE_FOCUS
:
774 printk(KERN_INFO
"mt9t013: move focus %ld\n", arg
);
775 rc
= mt9t013_i2c_move_focus((uint16_t)arg
);
778 case MT9T013_I2C_IOCTL_SET_DEFAULT_FOCUS
:
779 printk(KERN_INFO
"mt9t013: set default focus %ld\n", arg
);
780 rc
= mt9t013_i2c_set_default_focus((uint8_t)arg
);
783 case MT9T013_I2C_IOCTL_POWER_DOWN
:
784 rc
= mt9t013_i2c_power_down();
787 case MT9T013_I2C_IOCTL_INIT
: {
788 struct mt9t013_init init
;
789 printk(KERN_INFO
"mt9t013: init\n");
790 if (copy_from_user(&init
, argp
, sizeof(init
))) {
791 printk(KERN_ERR
"mt9t013: (init) invalid user pointer\n");
795 rc
= mt9t013_i2c_sensor_init(&init
);
796 if (copy_to_user(argp
, &init
, sizeof(init
)))
801 case CAMERA_CONFIGURE_GPIOS
:
802 case CAMERA_UNCONFIGURE_GPIOS
:
806 printk(KERN_INFO
"mt9t013: unknown ioctl %d\n", cmd
);
817 static int mt9t013_lens_power(int on
)
820 printk(KERN_INFO
"mt9t013: lens power %d\n", on
);
821 rc
= gpio_request(cam
->vcm_pwd
, "mt9t013");
823 gpio_direction_output(cam
->vcm_pwd
, !on
);
824 else printk(KERN_ERR
"mt9t013 error: request gpio %d failed:"
825 " %d\n", cam
->vcm_pwd
, rc
);
826 gpio_free(cam
->vcm_pwd
);
830 #define I2C_WRITE(reg,data) if (!mt9t013_i2c_write(reg, data) < 0) return -EIO
831 #define MT9T013_MU3M0VC_RESET_DELAY_MSECS 66
833 static int mt9t013_i2c_sensor_init(struct mt9t013_init
*init
)
837 /* RESET the sensor via I2C register */
838 I2C_WRITE(MT9T013_REG_RESET_REGISTER
, 0x10cc & 0xfffe);
839 msleep(MT9T013_MU3M0VC_RESET_DELAY_MSECS
);
841 if ((rc
= mt9t013_i2c_read(MT9T013_MU3M0VC_REG_MODEL_ID
, &init
->chipid
)) < 0) {
842 printk(KERN_ERR
"mt9t013: could not read chip id: %d\n", rc
);
845 printk(KERN_INFO
"mt9t013: chip id: %d\n", init
->chipid
);
847 if (init
->chipid
!= MT9T013_MU3M0VC_MODEL_ID
) {
848 printk(KERN_INFO
"mt9t013: chip id %d is invalid\n",
853 I2C_WRITE(0x306E, 0x9080);
854 I2C_WRITE(0x301A, 0x10CC);
855 I2C_WRITE(0x3064, 0x0805);
856 msleep(MT9T013_MU3M0VC_RESET_DELAY_MSECS
);
858 if ((rc
= mt9t013_i2c_sensor_setting(CAMSENSOR_REG_INIT
|
859 ((init
->preview
? 0 : 1) << 1))) < 0) {
860 printk(KERN_INFO
"mt9t013: failed to configure the sensor\n");
864 mt9t013_i2c_power_up();
869 static int mt9t013_mu3m0vc_set_lc(void)
871 /* lens shading 85% TL84 */
872 I2C_WRITE(0x360A, 0x0290); // P_RD_P0Q0
873 I2C_WRITE(0x360C, 0xC92D); // P_RD_P0Q1
874 I2C_WRITE(0x360E, 0x0771); // P_RD_P0Q2
875 I2C_WRITE(0x3610, 0xE38C); // P_RD_P0Q3
876 I2C_WRITE(0x3612, 0xD74F); // P_RD_P0Q4
877 I2C_WRITE(0x364A, 0x168C); // P_RD_P1Q0
878 I2C_WRITE(0x364C, 0xCACB); // P_RD_P1Q1
879 I2C_WRITE(0x364E, 0x8C4C); // P_RD_P1Q2
880 I2C_WRITE(0x3650, 0x0BEA); // P_RD_P1Q3
881 I2C_WRITE(0x3652, 0xDC0F); // P_RD_P1Q4
882 I2C_WRITE(0x368A, 0x70B0); // P_RD_P2Q0
883 I2C_WRITE(0x368C, 0x200B); // P_RD_P2Q1
884 I2C_WRITE(0x368E, 0x30B2); // P_RD_P2Q2
885 I2C_WRITE(0x3690, 0xD04F); // P_RD_P2Q3
886 I2C_WRITE(0x3692, 0xACF5); // P_RD_P2Q4
887 I2C_WRITE(0x36CA, 0xF7C9); // P_RD_P3Q0
888 I2C_WRITE(0x36CC, 0x2AED); // P_RD_P3Q1
889 I2C_WRITE(0x36CE, 0xA652); // P_RD_P3Q2
890 I2C_WRITE(0x36D0, 0x8192); // P_RD_P3Q3
891 I2C_WRITE(0x36D2, 0x3A15); // P_RD_P3Q4
892 I2C_WRITE(0x370A, 0xDA30); // P_RD_P4Q0
893 I2C_WRITE(0x370C, 0x2E2F); // P_RD_P4Q1
894 I2C_WRITE(0x370E, 0xBB56); // P_RD_P4Q2
895 I2C_WRITE(0x3710, 0x8195); // P_RD_P4Q3
896 I2C_WRITE(0x3712, 0x02F9); // P_RD_P4Q4
897 I2C_WRITE(0x3600, 0x0230); // P_GR_P0Q0
898 I2C_WRITE(0x3602, 0x58AD); // P_GR_P0Q1
899 I2C_WRITE(0x3604, 0x18D1); // P_GR_P0Q2
900 I2C_WRITE(0x3606, 0x260D); // P_GR_P0Q3
901 I2C_WRITE(0x3608, 0xF530); // P_GR_P0Q4
902 I2C_WRITE(0x3640, 0x17EB); // P_GR_P1Q0
903 I2C_WRITE(0x3642, 0x3CAB); // P_GR_P1Q1
904 I2C_WRITE(0x3644, 0x87CE); // P_GR_P1Q2
905 I2C_WRITE(0x3646, 0xC02E); // P_GR_P1Q3
906 I2C_WRITE(0x3648, 0xF48F); // P_GR_P1Q4
907 I2C_WRITE(0x3680, 0x5350); // P_GR_P2Q0
908 I2C_WRITE(0x3682, 0x7EAF); // P_GR_P2Q1
909 I2C_WRITE(0x3684, 0x4312); // P_GR_P2Q2
910 I2C_WRITE(0x3686, 0xC652); // P_GR_P2Q3
911 I2C_WRITE(0x3688, 0xBC15); // P_GR_P2Q4
912 I2C_WRITE(0x36C0, 0xB8AD); // P_GR_P3Q0
913 I2C_WRITE(0x36C2, 0xBDCD); // P_GR_P3Q1
914 I2C_WRITE(0x36C4, 0xE4B2); // P_GR_P3Q2
915 I2C_WRITE(0x36C6, 0xB50F); // P_GR_P3Q3
916 I2C_WRITE(0x36C8, 0x5B95); // P_GR_P3Q4
917 I2C_WRITE(0x3700, 0xFC90); // P_GR_P4Q0
918 I2C_WRITE(0x3702, 0x8C51); // P_GR_P4Q1
919 I2C_WRITE(0x3704, 0xCED6); // P_GR_P4Q2
920 I2C_WRITE(0x3706, 0xB594); // P_GR_P4Q3
921 I2C_WRITE(0x3708, 0x0A39); // P_GR_P4Q4
922 I2C_WRITE(0x3614, 0x0230); // P_BL_P0Q0
923 I2C_WRITE(0x3616, 0x160D); // P_BL_P0Q1
924 I2C_WRITE(0x3618, 0x08D1); // P_BL_P0Q2
925 I2C_WRITE(0x361A, 0x98AB); // P_BL_P0Q3
926 I2C_WRITE(0x361C, 0xEA50); // P_BL_P0Q4
927 I2C_WRITE(0x3654, 0xB4EA); // P_BL_P1Q0
928 I2C_WRITE(0x3656, 0xEA6C); // P_BL_P1Q1
929 I2C_WRITE(0x3658, 0xFE08); // P_BL_P1Q2
930 I2C_WRITE(0x365A, 0x2C6E); // P_BL_P1Q3
931 I2C_WRITE(0x365C, 0xEB0E); // P_BL_P1Q4
932 I2C_WRITE(0x3694, 0x6DF0); // P_BL_P2Q0
933 I2C_WRITE(0x3696, 0x3ACF); // P_BL_P2Q1
934 I2C_WRITE(0x3698, 0x3E0F); // P_BL_P2Q2
935 I2C_WRITE(0x369A, 0xB2B1); // P_BL_P2Q3
936 I2C_WRITE(0x369C, 0xC374); // P_BL_P2Q4
937 I2C_WRITE(0x36D4, 0xF2AA); // P_BL_P3Q0
938 I2C_WRITE(0x36D6, 0x8CCC); // P_BL_P3Q1
939 I2C_WRITE(0x36D8, 0xDEF2); // P_BL_P3Q2
940 I2C_WRITE(0x36DA, 0xFA11); // P_BL_P3Q3
941 I2C_WRITE(0x36DC, 0x42F5); // P_BL_P3Q4
942 I2C_WRITE(0x3714, 0xF4F1); // P_BL_P4Q0
943 I2C_WRITE(0x3716, 0xF6F0); // P_BL_P4Q1
944 I2C_WRITE(0x3718, 0x8FD6); // P_BL_P4Q2
945 I2C_WRITE(0x371A, 0xEA14); // P_BL_P4Q3
946 I2C_WRITE(0x371C, 0x6338); // P_BL_P4Q4
947 I2C_WRITE(0x361E, 0x0350); // P_GB_P0Q0
948 I2C_WRITE(0x3620, 0x91AE); // P_GB_P0Q1
949 I2C_WRITE(0x3622, 0x0571); // P_GB_P0Q2
950 I2C_WRITE(0x3624, 0x100D); // P_GB_P0Q3
951 I2C_WRITE(0x3626, 0xCA70); // P_GB_P0Q4
952 I2C_WRITE(0x365E, 0xE6CB); // P_GB_P1Q0
953 I2C_WRITE(0x3660, 0x50ED); // P_GB_P1Q1
954 I2C_WRITE(0x3662, 0x3DAE); // P_GB_P1Q2
955 I2C_WRITE(0x3664, 0xAA4F); // P_GB_P1Q3
956 I2C_WRITE(0x3666, 0xDC50); // P_GB_P1Q4
957 I2C_WRITE(0x369E, 0x5470); // P_GB_P2Q0
958 I2C_WRITE(0x36A0, 0x1F6E); // P_GB_P2Q1
959 I2C_WRITE(0x36A2, 0x6671); // P_GB_P2Q2
960 I2C_WRITE(0x36A4, 0xC010); // P_GB_P2Q3
961 I2C_WRITE(0x36A6, 0x8DF5); // P_GB_P2Q4
962 I2C_WRITE(0x36DE, 0x0B0C); // P_GB_P3Q0
963 I2C_WRITE(0x36E0, 0x84CE); // P_GB_P3Q1
964 I2C_WRITE(0x36E2, 0x8493); // P_GB_P3Q2
965 I2C_WRITE(0x36E4, 0xA610); // P_GB_P3Q3
966 I2C_WRITE(0x36E6, 0x50B5); // P_GB_P3Q4
967 I2C_WRITE(0x371E, 0x9651); // P_GB_P4Q0
968 I2C_WRITE(0x3720, 0x1EAB); // P_GB_P4Q1
969 I2C_WRITE(0x3722, 0xAF76); // P_GB_P4Q2
970 I2C_WRITE(0x3724, 0xE4F4); // P_GB_P4Q3
971 I2C_WRITE(0x3726, 0x79F8); // P_GB_P4Q4
972 I2C_WRITE(0x3782, 0x0410); // Original LC 2 // POLY_ORIGIN_C
973 I2C_WRITE(0x3784, 0x0320); // POLY_ORIGIN_R
974 I2C_WRITE(0x3780, 0x8000); // POLY_SC_ENABLE
979 static int mt9t013_set_pclk(int rt
, int div_adj
)
982 if ((rc
= mt9t013_i2c_power_down()) < 0) return rc
;
983 I2C_WRITE(REG_VT_PIX_CLK_DIV
, mt9t013_reg_pattern
.reg
[rt
].vt_pix_clk_div
);
984 I2C_WRITE(REG_VT_SYS_CLK_DIV
, mt9t013_reg_pattern
.reg
[rt
].vt_sys_clk_div
);
985 I2C_WRITE(REG_PRE_PLL_CLK_DIV
, mt9t013_reg_pattern
.reg
[rt
].pre_pll_clk_div
* div_adj
);
986 I2C_WRITE(REG_PLL_MULTIPLIER
, mt9t013_reg_pattern
.reg
[rt
].pll_multiplier
);
987 I2C_WRITE(REG_OP_PIX_CLK_DIV
, mt9t013_reg_pattern
.reg
[rt
].op_pix_clk_div
);
988 I2C_WRITE(REG_OP_SYS_CLK_DIV
, mt9t013_reg_pattern
.reg
[rt
].op_sys_clk_div
);
989 if ((rc
= mt9t013_i2c_power_up()) < 0) return rc
;
994 static int mt9t013_i2c_sensor_setting(unsigned long arg
)
996 uint32_t update
= arg
& 1;
997 uint32_t rt
= (arg
& 2) >> 1;
999 if (rt
> 1 || update
> 1) {
1000 printk(KERN_ERR
"mt9t013: invalid values %d of rt or %d of update\n",
1006 case CAMSENSOR_REG_UPDATE_PERIODIC
: {
1007 uint16_t pclk_div_adj
= arg
>> 16;
1009 printk(KERN_INFO
"CAMSENSOR_REG_UPDATE_PERIODIC (rt %d)\n", rt
);
1011 if (!pclk_div_adj
|| pclk_div_adj
> 2) {
1012 printk(KERN_ERR
"mt9t013: invalid value %d of pclk_div_adj\n",
1017 if (mt9t013_set_pclk(rt
, pclk_div_adj
) < 0)
1020 I2C_WRITE(REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
);
1021 I2C_WRITE(REG_ROW_SPEED
, mt9t013_reg_pattern
.reg
[rt
].row_speed
);
1022 I2C_WRITE(REG_X_ADDR_START
, mt9t013_reg_pattern
.reg
[rt
].x_addr_start
);
1023 I2C_WRITE(REG_X_ADDR_END
, mt9t013_reg_pattern
.reg
[rt
].x_addr_end
);
1024 I2C_WRITE(REG_Y_ADDR_START
, mt9t013_reg_pattern
.reg
[rt
].y_addr_start
);
1025 I2C_WRITE(REG_Y_ADDR_END
, mt9t013_reg_pattern
.reg
[rt
].y_addr_end
);
1027 if (machine_is_sapphire()) {
1029 I2C_WRITE(REG_READ_MODE
, 0x046F);
1031 I2C_WRITE(REG_READ_MODE
, 0x0027);
1034 I2C_WRITE(REG_READ_MODE
,
1035 mt9t013_reg_pattern
.reg
[rt
].read_mode
);
1038 I2C_WRITE(REG_SCALE_M
, mt9t013_reg_pattern
.reg
[rt
].scale_m
);
1039 I2C_WRITE(REG_X_OUTPUT_SIZE
, mt9t013_reg_pattern
.reg
[rt
].x_output_size
);
1040 I2C_WRITE(REG_Y_OUTPUT_SIZE
, mt9t013_reg_pattern
.reg
[rt
].y_output_size
);
1041 I2C_WRITE(REG_LINE_LENGTH_PCK
, mt9t013_reg_pattern
.reg
[rt
].line_length_pck
);
1042 I2C_WRITE(REG_FRAME_LENGTH_LINES
, (uint16_t) (mt9t013_reg_pattern
.reg
[rt
].frame_length_lines
* fps_divider
));
1043 I2C_WRITE(REG_COARSE_INTEGRATION_TIME
, mt9t013_reg_pattern
.reg
[rt
].coarse_integration_time
);
1044 I2C_WRITE(REG_FINE_INTEGRATION_TIME
, mt9t013_reg_pattern
.reg
[rt
].fine_integration_time
);
1045 I2C_WRITE(REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
);
1049 case CAMSENSOR_REG_INIT
:
1050 printk(KERN_INFO
"CAMSENSOR_REG_INIT (rt %d)\n", rt
);
1052 if (mt9t013_set_pclk(rt
, 1) < 0) return -EIO
;
1054 I2C_WRITE(REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
);
1056 /* additional power saving mode ok around 38.2MHz */
1057 I2C_WRITE(0x3084, 0x2409);
1058 I2C_WRITE(0x3092, 0x0A49);
1059 I2C_WRITE(0x3094, 0x4949);
1060 I2C_WRITE(0x3096, 0x4949);
1062 /* set preview or snapshot mode */
1063 I2C_WRITE(REG_ROW_SPEED
,
1064 mt9t013_reg_pattern
.reg
[rt
].row_speed
);
1065 I2C_WRITE(REG_X_ADDR_START
,
1066 mt9t013_reg_pattern
.reg
[rt
].x_addr_start
);
1067 I2C_WRITE(REG_X_ADDR_END
,
1068 mt9t013_reg_pattern
.reg
[rt
].x_addr_end
);
1069 I2C_WRITE(REG_Y_ADDR_START
,
1070 mt9t013_reg_pattern
.reg
[rt
].y_addr_start
);
1071 I2C_WRITE(REG_Y_ADDR_END
,
1072 mt9t013_reg_pattern
.reg
[rt
].y_addr_end
);
1074 if (machine_is_sapphire()) {
1076 I2C_WRITE(REG_READ_MODE
, 0x046F);
1078 I2C_WRITE(REG_READ_MODE
, 0x0027);
1081 I2C_WRITE(REG_READ_MODE
,
1082 mt9t013_reg_pattern
.reg
[rt
].read_mode
);
1085 I2C_WRITE(REG_SCALE_M
, mt9t013_reg_pattern
.reg
[rt
].scale_m
);
1086 I2C_WRITE(REG_X_OUTPUT_SIZE
, mt9t013_reg_pattern
.reg
[rt
].x_output_size
);
1087 I2C_WRITE(REG_Y_OUTPUT_SIZE
, mt9t013_reg_pattern
.reg
[rt
].y_output_size
);
1088 I2C_WRITE(REG_LINE_LENGTH_PCK
, mt9t013_reg_pattern
.reg
[rt
].line_length_pck
);
1089 I2C_WRITE(REG_FRAME_LENGTH_LINES
, mt9t013_reg_pattern
.reg
[rt
].frame_length_lines
);
1090 I2C_WRITE(REG_COARSE_INTEGRATION_TIME
, mt9t013_reg_pattern
.reg
[rt
].coarse_integration_time
);
1091 I2C_WRITE(REG_FINE_INTEGRATION_TIME
, mt9t013_reg_pattern
.reg
[rt
].fine_integration_time
);
1093 I2C_WRITE(REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
);
1095 /* load lens shading */
1096 I2C_WRITE(REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_HOLD
);
1097 if(mt9t013_mu3m0vc_set_lc() < 0) return -EIO
;
1098 I2C_WRITE(REG_GROUPED_PARAMETER_HOLD
, GROUPED_PARAMETER_UPDATE
);
1108 static int mt9t013_i2c_exposure_gain(uint32_t mode
, uint16_t line
,
1111 static const uint16_t max_legal_gain
= 0x01FF;
1113 if (gain
> max_legal_gain
) gain
= max_legal_gain
;
1115 gain
|= 0x200; /* set digital gain */
1117 /*I2C_WRITE(REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_HOLD);*/
1118 I2C_WRITE(REG_GLOBAL_GAIN
, gain
);
1119 I2C_WRITE(REG_COARSE_INTEGRATION_TIME
, line
);
1120 /*I2C_WRITE(REG_GROUPED_PARAMETER_HOLD, GROUPED_PARAMETER_UPDATE);*/
1122 /* RESET REGISTER RESTART */
1123 I2C_WRITE(MT9T013_REG_RESET_REGISTER
, 0x10cc|0x0002);
1128 #define I2C_AF_WRITE(command, data) if (mt9t013_i2c_lens_write(AF_I2C_ID >> 1, command, data) < 0) return -EIO;
1130 static int mt9t013_i2c_move_focus(uint16_t position
)
1132 uint8_t code_val_msb
= (position
>> 2) | ((position
<< 4) >> 6);
1133 uint8_t code_val_lsb
= (position
& 0x03) << 6;
1135 I2C_AF_WRITE(code_val_msb
, code_val_lsb
);
1139 static int mt9t013_i2c_set_default_focus(uint8_t step
)
1141 I2C_AF_WRITE(0x01, step
);
1147 static int mt9t013_i2c_power_up(void)
1149 printk(KERN_INFO
"mt9t013: power up\n");
1151 printk(KERN_INFO
"mt9t013: already powered up\n");
1154 I2C_WRITE(MT9T013_REG_RESET_REGISTER
, MT9T013_RESET_REGISTER_PWON
);
1160 static int mt9t013_i2c_power_down(void)
1162 int i
= 0, try_more
= 100;
1164 printk(KERN_INFO
"mt9t013: power down\n");
1166 printk(KERN_INFO
"mt9t013: already powered down\n");
1170 /* I2C_WRITE(MT9T013_REG_RESET_REGISTER, MT9T013_RESET_REGISTER_PWOFF); */
1171 /* Modified by Horng for more tries while I2C write fail */
1172 /* -------------------------------------------------------------------- */
1173 while(mt9t013_i2c_write(MT9T013_REG_RESET_REGISTER
, MT9T013_RESET_REGISTER_PWOFF
) < 0)
1179 printk(KERN_INFO
"mt9p012: in mt9p012_i2c_power_down() call mt9p012_i2c_write() failed !!! (try %d times)\n", i
);
1183 /* -------------------------------------------------------------------- */
1185 powered
= pclk_set
= 0;
1192 static int mt9t013_init_client(struct i2c_client
*client
)
1194 /* Initialize the MT9T013 Chip */
1195 init_waitqueue_head(&g_data_ready_wait_queue
);
1199 static struct file_operations mt9t013_fops
= {
1200 .owner
= THIS_MODULE
,
1201 .open
= mt9t013_open
,
1202 .release
= mt9t013_release
,
1203 .unlocked_ioctl
= mt9t013_ioctl
,
1206 static struct miscdevice mt9t013_device
= {
1207 .minor
= MISC_DYNAMIC_MINOR
,
1209 .fops
= &mt9t013_fops
,
1212 static const char *MT9T013Vendor
= "micron";
1213 static const char *MT9T013NAME
= "mt9t013";
1214 static const char *MT9T013Size
= "3M";
1218 static ssize_t
sensor_vendor_show(struct device
*dev
,
1219 struct device_attribute
*attr
, char *buf
)
1223 sprintf(buf
, "%s %s %s\n", MT9T013Vendor
, MT9T013NAME
, MT9T013Size
);
1224 ret
= strlen(buf
) + 1;
1229 static DEVICE_ATTR(sensor
, 0444, sensor_vendor_show
, NULL
);
1232 static struct kobject
*android_mt9t013
= NULL
;
1234 static int mt9t013_sysfs_init(void)
1237 printk(KERN_INFO
"mt9t013:kobject creat and add\n");
1238 android_mt9t013
= kobject_create_and_add("android_camera", NULL
);
1239 if (android_mt9t013
== NULL
) {
1240 printk(KERN_INFO
"mt9t013_sysfs_init: subsystem_register " \
1245 printk(KERN_INFO
"mt9t013:sysfs_create_file\n");
1246 ret
= sysfs_create_file(android_mt9t013
, &dev_attr_sensor
.attr
);
1248 printk(KERN_INFO
"mt9t013_sysfs_init: sysfs_create_file " \
1250 kobject_del(android_mt9t013
);
1257 static int mt9t013_probe(
1258 struct i2c_client
*client
, const struct i2c_device_id
*id
)
1260 struct mt9t013_data
*mt
;
1262 printk(KERN_INFO
"mt9t013: probe\n");
1264 if(!i2c_check_functionality(client
->adapter
, I2C_FUNC_I2C
))
1265 goto exit_check_functionality_failed
;
1267 if(!(mt
= kzalloc( sizeof(struct mt9t013_data
), GFP_KERNEL
))) {
1269 goto exit_alloc_data_failed
;
1272 i2c_set_clientdata(client
, mt
);
1273 mt9t013_init_client(client
);
1275 mt9t013_sensor_init();
1276 mt9t013_sensor_suspend();
1278 /* Register a misc device */
1279 err
= misc_register(&mt9t013_device
);
1281 printk(KERN_ERR
"mt9t013_probe: misc_register failed \n");
1282 goto exit_misc_device_register_failed
;
1285 mt9t013_sysfs_init();
1288 exit_misc_device_register_failed
:
1289 exit_alloc_data_failed
:
1290 exit_check_functionality_failed
:
1296 static int mt9t013_remove(struct i2c_client
*client
)
1298 struct mt9t013_data
*mt
= i2c_get_clientdata(client
);
1299 free_irq(client
->irq
, mt
);
1302 misc_deregister(&mt9t013_device
);
1307 static const struct i2c_device_id mt9t013_id
[] = {
1312 static struct i2c_driver mt9t013_driver
= {
1313 .probe
= mt9t013_probe
,
1314 .remove
= mt9t013_remove
,
1315 .id_table
= mt9t013_id
,
1321 static int mt9t013_plat_probe(struct platform_device
*pdev
__attribute__((unused
)))
1325 if(pdev
->dev
.platform_data
)
1327 printk(KERN_INFO
"pdev->dev.platform_data is not NULL\n");
1328 cam
= pdev
->dev
.platform_data
;
1329 rc
= i2c_add_driver(&mt9t013_driver
);
1334 static struct platform_driver mt9t013_plat_driver
= {
1335 .probe
= mt9t013_plat_probe
,
1338 .owner
= THIS_MODULE
,
1342 static int __init
mt9t013_init(void)
1344 return platform_driver_register(&mt9t013_plat_driver
);
1347 module_init(mt9t013_init
);
1349 MODULE_AUTHOR("Kidd Chen");
1350 MODULE_DESCRIPTION("MT9T013 Driver");
1351 MODULE_LICENSE("GPL");