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;
36 static struct msm_camera_io_ext camio_ext;
37 static struct resource *appio, *mdcio;
38 void __iomem *appbase, *mdcbase;
40 static struct msm_camera_io_ext camio_ext;
41 static struct resource *appio, *mdcio;
42 void __iomem *appbase, *mdcbase;
44 extern int clk_set_flags(struct clk *clk, unsigned long flags);
46 int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
49 struct clk *clk = NULL;
52 case CAMIO_VFE_MDC_CLK:
53 clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
57 clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
61 clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
76 int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
79 struct clk *clk = NULL;
82 case CAMIO_VFE_MDC_CLK:
83 clk = camio_vfe_mdc_clk;
107 void msm_camio_clk_rate_set(int rate)
109 struct clk *clk = camio_vfe_clk;
111 if (clk != ERR_PTR(-ENOENT))
112 clk_set_rate(clk, rate);
115 int msm_camio_enable(struct platform_device *pdev)
118 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
119 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
121 camio_ext = camdev->ioext;
123 appio = request_mem_region(camio_ext.appphy,
124 camio_ext.appsz, pdev->name);
130 appbase = ioremap(camio_ext.appphy,
137 mdcio = request_mem_region(camio_ext.mdcphy,
138 camio_ext.mdcsz, pdev->name);
144 mdcbase = ioremap(camio_ext.mdcphy,
151 camdev->camera_gpio_on();
153 msm_camio_clk_enable(CAMIO_VFE_CLK);
154 msm_camio_clk_enable(CAMIO_MDC_CLK);
155 msm_camio_clk_enable(CAMIO_VFE_MDC_CLK);
159 release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
163 release_mem_region(camio_ext.appphy, camio_ext.appsz);
168 void msm_camio_disable(struct platform_device *pdev)
170 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
171 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
174 release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
176 release_mem_region(camio_ext.appphy, camio_ext.appsz);
178 camdev->camera_gpio_off();
180 msm_camio_clk_disable(CAMIO_VFE_CLK);
181 msm_camio_clk_disable(CAMIO_MDC_CLK);
182 msm_camio_clk_disable(CAMIO_VFE_MDC_CLK);
185 void msm_camio_camif_pad_reg_reset(void)
188 uint32_t mask, value;
190 /* select CLKRGM_VFE_SRC_CAM_VFE_SRC: internal source */
191 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
193 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
195 mask = CAM_SEL_BMSK |
196 CAM_PCLK_SRC_SEL_BMSK |
197 CAM_PCLK_INVERT_BMSK;
199 value = 1 << CAM_SEL_SHFT |
200 3 << CAM_PCLK_SRC_SEL_SHFT |
201 0 << CAM_PCLK_INVERT_SHFT;
203 writel((reg & (~mask)) | (value & mask), mdcbase);
206 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
207 mask = CAM_PAD_REG_SW_RESET_BMSK;
208 value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
209 writel((reg & (~mask)) | (value & mask), mdcbase);
212 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
213 mask = CAM_PAD_REG_SW_RESET_BMSK;
214 value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
215 writel((reg & (~mask)) | (value & mask), mdcbase);
218 msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
222 void msm_camio_vfe_blk_reset(void)
226 val = readl(appbase + 0x00000210);
228 writel(val, appbase + 0x00000210);
231 val = readl(appbase + 0x00000210);
233 writel(val, appbase + 0x00000210);
237 void msm_camio_camif_pad_reg_reset_2(void)
240 uint32_t mask, value;
242 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
243 mask = CAM_PAD_REG_SW_RESET_BMSK;
244 value = 1 << CAM_PAD_REG_SW_RESET_SHFT;
245 writel((reg & (~mask)) | (value & mask), mdcbase);
248 reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
249 mask = CAM_PAD_REG_SW_RESET_BMSK;
250 value = 0 << CAM_PAD_REG_SW_RESET_SHFT;
251 writel((reg & (~mask)) | (value & mask), mdcbase);
255 void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
257 struct clk *clk = NULL;
261 if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
263 case MSM_CAMIO_CLK_SRC_INTERNAL:
264 clk_set_flags(clk, 0x00000100 << 1);
267 case MSM_CAMIO_CLK_SRC_EXTERNAL:
268 clk_set_flags(clk, 0x00000100);
277 int msm_camio_probe_on(struct platform_device *pdev)
279 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
280 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
281 camdev->camera_gpio_on();
282 return msm_camio_clk_enable(CAMIO_VFE_CLK);
285 int msm_camio_probe_off(struct platform_device *pdev)
287 struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
288 struct msm_camera_device_platform_data *camdev = sinfo->pdata;
289 camdev->camera_gpio_off();
290 return msm_camio_clk_disable(CAMIO_VFE_CLK);