2 * Copyright (c) 2008-2009 QUALCOMM Incorporated
5 #include <linux/delay.h>
9 #include <mach/board.h>
10 #include <mach/camera.h>
12 #define CAMIF_CFG_RMSK 0x1fffff
13 #define CAM_SEL_BMSK 0x2
14 #define CAM_PCLK_SRC_SEL_BMSK 0x60000
15 #define CAM_PCLK_INVERT_BMSK 0x80000
16 #define CAM_PAD_REG_SW_RESET_BMSK 0x100000
18 #define EXT_CAM_HSYNC_POL_SEL_BMSK 0x10000
19 #define EXT_CAM_VSYNC_POL_SEL_BMSK 0x8000
20 #define MDDI_CLK_CHICKEN_BIT_BMSK 0x80
22 #define CAM_SEL_SHFT 0x1
23 #define CAM_PCLK_SRC_SEL_SHFT 0x11
24 #define CAM_PCLK_INVERT_SHFT 0x13
25 #define CAM_PAD_REG_SW_RESET_SHFT 0x14
27 #define EXT_CAM_HSYNC_POL_SEL_SHFT 0x10
28 #define EXT_CAM_VSYNC_POL_SEL_SHFT 0xF
29 #define MDDI_CLK_CHICKEN_BIT_SHFT 0x7
30 #define APPS_RESET_OFFSET 0x00000210
32 static struct clk
*camio_vfe_mdc_clk
;
33 static struct clk
*camio_mdc_clk
;
34 static struct clk
*camio_vfe_clk
;
35 static struct clk
*camio_vfe_axi_clk
;
36 static struct msm_camera_io_ext camio_ext
;
37 static struct resource
*appio
, *mdcio
;
38 void __iomem
*appbase
, *mdcbase
;
40 extern int clk_set_flags(struct clk
*clk
, unsigned long flags
);
42 int msm_camio_clk_enable(enum msm_camio_clk_type clktype
)
45 struct clk
*clk
= NULL
;
48 case CAMIO_VFE_MDC_CLK
:
50 clk
= clk_get(NULL
, "vfe_mdc_clk");
55 clk
= clk_get(NULL
, "mdc_clk");
60 clk
= clk_get(NULL
, "vfe_clk");
63 case CAMIO_VFE_AXI_CLK
:
65 clk
= clk_get(NULL
, "vfe_axi_clk");
80 int msm_camio_clk_disable(enum msm_camio_clk_type clktype
)
83 struct clk
*clk
= NULL
;
86 case CAMIO_VFE_MDC_CLK
:
87 clk
= camio_vfe_mdc_clk
;
98 case CAMIO_VFE_AXI_CLK
:
99 clk
= camio_vfe_axi_clk
;
115 void msm_camio_clk_rate_set(int rate
)
117 struct clk
*clk
= camio_vfe_mdc_clk
;
119 /* TODO: check return */
120 clk_set_rate(clk
, rate
);
123 int msm_camio_enable(struct platform_device
*pdev
)
126 struct msm_camera_sensor_info
*sinfo
= pdev
->dev
.platform_data
;
127 struct msm_camera_device_platform_data
*camdev
= sinfo
->pdata
;
129 camio_ext
= camdev
->ioext
;
131 appio
= request_mem_region(camio_ext
.appphy
,
132 camio_ext
.appsz
, pdev
->name
);
138 appbase
= ioremap(camio_ext
.appphy
,
145 mdcio
= request_mem_region(camio_ext
.mdcphy
,
146 camio_ext
.mdcsz
, pdev
->name
);
152 mdcbase
= ioremap(camio_ext
.mdcphy
,
159 camdev
->camera_gpio_on();
161 msm_camio_clk_enable(CAMIO_VFE_CLK
);
162 msm_camio_clk_enable(CAMIO_MDC_CLK
);
163 msm_camio_clk_enable(CAMIO_VFE_MDC_CLK
);
164 msm_camio_clk_enable(CAMIO_VFE_AXI_CLK
);
168 release_mem_region(camio_ext
.mdcphy
, camio_ext
.mdcsz
);
172 release_mem_region(camio_ext
.appphy
, camio_ext
.appsz
);
177 void msm_camio_disable(struct platform_device
*pdev
)
179 struct msm_camera_sensor_info
*sinfo
= pdev
->dev
.platform_data
;
180 struct msm_camera_device_platform_data
*camdev
= sinfo
->pdata
;
183 release_mem_region(camio_ext
.mdcphy
, camio_ext
.mdcsz
);
185 release_mem_region(camio_ext
.appphy
, camio_ext
.appsz
);
187 camdev
->camera_gpio_off();
189 msm_camio_clk_disable(CAMIO_VFE_MDC_CLK
);
190 msm_camio_clk_disable(CAMIO_MDC_CLK
);
191 msm_camio_clk_disable(CAMIO_VFE_CLK
);
192 msm_camio_clk_disable(CAMIO_VFE_AXI_CLK
);
195 void msm_camio_camif_pad_reg_reset(void)
198 uint32_t mask
, value
;
200 /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
201 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL
);
203 reg
= (readl(mdcbase
)) & CAMIF_CFG_RMSK
;
205 mask
= CAM_SEL_BMSK
|
206 CAM_PCLK_SRC_SEL_BMSK
|
207 CAM_PCLK_INVERT_BMSK
|
208 EXT_CAM_HSYNC_POL_SEL_BMSK
|
209 EXT_CAM_VSYNC_POL_SEL_BMSK
|
210 MDDI_CLK_CHICKEN_BIT_BMSK
;
212 value
= 1 << CAM_SEL_SHFT
|
213 3 << CAM_PCLK_SRC_SEL_SHFT
|
214 0 << CAM_PCLK_INVERT_SHFT
|
215 0 << EXT_CAM_HSYNC_POL_SEL_SHFT
|
216 0 << EXT_CAM_VSYNC_POL_SEL_SHFT
|
217 0 << MDDI_CLK_CHICKEN_BIT_SHFT
;
218 writel((reg
& (~mask
)) | (value
& mask
), mdcbase
);
221 reg
= (readl(mdcbase
)) & CAMIF_CFG_RMSK
;
222 mask
= CAM_PAD_REG_SW_RESET_BMSK
;
223 value
= 1 << CAM_PAD_REG_SW_RESET_SHFT
;
224 writel((reg
& (~mask
)) | (value
& mask
), mdcbase
);
227 reg
= (readl(mdcbase
)) & CAMIF_CFG_RMSK
;
228 mask
= CAM_PAD_REG_SW_RESET_BMSK
;
229 value
= 0 << CAM_PAD_REG_SW_RESET_SHFT
;
230 writel((reg
& (~mask
)) | (value
& mask
), mdcbase
);
233 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL
);
237 /* todo: check return */
239 clk_set_rate(camio_vfe_clk
, 96000000);
242 void msm_camio_vfe_blk_reset(void)
246 val
= readl(appbase
+ 0x00000210);
248 writel(val
, appbase
+ 0x00000210);
251 val
= readl(appbase
+ 0x00000210);
253 writel(val
, appbase
+ 0x00000210);
257 void msm_camio_camif_pad_reg_reset_2(void)
260 uint32_t mask
, value
;
262 reg
= (readl(mdcbase
)) & CAMIF_CFG_RMSK
;
263 mask
= CAM_PAD_REG_SW_RESET_BMSK
;
264 value
= 1 << CAM_PAD_REG_SW_RESET_SHFT
;
265 writel((reg
& (~mask
)) | (value
& mask
), mdcbase
);
268 reg
= (readl(mdcbase
)) & CAMIF_CFG_RMSK
;
269 mask
= CAM_PAD_REG_SW_RESET_BMSK
;
270 value
= 0 << CAM_PAD_REG_SW_RESET_SHFT
;
271 writel((reg
& (~mask
)) | (value
& mask
), mdcbase
);
275 void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype
)
277 struct clk
*clk
= NULL
;
283 case MSM_CAMIO_CLK_SRC_INTERNAL
:
284 clk_set_flags(clk
, 0x00000100 << 1);
287 case MSM_CAMIO_CLK_SRC_EXTERNAL
:
288 clk_set_flags(clk
, 0x00000100);
297 void msm_camio_clk_axi_rate_set(int rate
)
299 struct clk
*clk
= camio_vfe_axi_clk
;
300 /* todo: check return */
301 clk_set_rate(clk
, rate
);
304 int msm_camio_probe_on(struct platform_device
*pdev
)
306 struct msm_camera_sensor_info
*sinfo
= pdev
->dev
.platform_data
;
307 struct msm_camera_device_platform_data
*camdev
= sinfo
->pdata
;
309 camdev
->camera_gpio_on();
310 return msm_camio_clk_enable(CAMIO_VFE_MDC_CLK
);
313 int msm_camio_probe_off(struct platform_device
*pdev
)
315 struct msm_camera_sensor_info
*sinfo
= pdev
->dev
.platform_data
;
316 struct msm_camera_device_platform_data
*camdev
= sinfo
->pdata
;
318 camdev
->camera_gpio_off();
319 return msm_camio_clk_disable(CAMIO_VFE_MDC_CLK
);