upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / staging / dream / camera / msm_io7x.c
1 /*
2  * Copyright (c) 2008-2009 QUALCOMM Incorporated
3  */
4
5 #include <linux/delay.h>
6 #include <linux/clk.h>
7 #include <linux/io.h>
8 #include <mach/gpio.h>
9 #include <mach/board.h>
10 #include <mach/camera.h>
11
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
17
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
21
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
26
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
31
32 static struct clk *camio_vfe_mdc_clk;
33 static struct clk *camio_mdc_clk;
34 static struct clk *camio_vfe_clk;
35
36 static struct msm_camera_io_ext camio_ext;
37 static struct resource *appio, *mdcio;
38 void __iomem *appbase, *mdcbase;
39
40 static struct msm_camera_io_ext camio_ext;
41 static struct resource *appio, *mdcio;
42 void __iomem *appbase, *mdcbase;
43
44 extern int clk_set_flags(struct clk *clk, unsigned long flags);
45
46 int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
47 {
48         int rc = -1;
49         struct clk *clk = NULL;
50
51         switch (clktype) {
52         case CAMIO_VFE_MDC_CLK:
53                 clk = camio_vfe_mdc_clk = clk_get(NULL, "vfe_mdc_clk");
54                 break;
55
56         case CAMIO_MDC_CLK:
57                 clk = camio_mdc_clk = clk_get(NULL, "mdc_clk");
58                 break;
59
60         case CAMIO_VFE_CLK:
61                 clk = camio_vfe_clk = clk_get(NULL, "vfe_clk");
62                 break;
63
64         default:
65                 break;
66         }
67
68         if (!IS_ERR(clk)) {
69                 clk_enable(clk);
70                 rc = 0;
71         }
72
73         return rc;
74 }
75
76 int msm_camio_clk_disable(enum msm_camio_clk_type clktype)
77 {
78         int rc = -1;
79         struct clk *clk = NULL;
80
81         switch (clktype) {
82         case CAMIO_VFE_MDC_CLK:
83                 clk = camio_vfe_mdc_clk;
84                 break;
85
86         case CAMIO_MDC_CLK:
87                 clk = camio_mdc_clk;
88                 break;
89
90         case CAMIO_VFE_CLK:
91                 clk = camio_vfe_clk;
92                 break;
93
94         default:
95                 break;
96         }
97
98         if (!IS_ERR(clk)) {
99                 clk_disable(clk);
100                 clk_put(clk);
101                 rc = 0;
102         }
103
104         return rc;
105 }
106
107 void msm_camio_clk_rate_set(int rate)
108 {
109         struct clk *clk = camio_vfe_clk;
110
111         if (clk != ERR_PTR(-ENOENT))
112                 clk_set_rate(clk, rate);
113 }
114
115 int msm_camio_enable(struct platform_device *pdev)
116 {
117         int rc = 0;
118         struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
119         struct msm_camera_device_platform_data *camdev = sinfo->pdata;
120
121         camio_ext = camdev->ioext;
122
123         appio = request_mem_region(camio_ext.appphy,
124                 camio_ext.appsz, pdev->name);
125         if (!appio) {
126                 rc = -EBUSY;
127                 goto enable_fail;
128         }
129
130         appbase = ioremap(camio_ext.appphy,
131                 camio_ext.appsz);
132         if (!appbase) {
133                 rc = -ENOMEM;
134                 goto apps_no_mem;
135         }
136
137         mdcio = request_mem_region(camio_ext.mdcphy,
138                 camio_ext.mdcsz, pdev->name);
139         if (!mdcio) {
140                 rc = -EBUSY;
141                 goto mdc_busy;
142         }
143
144         mdcbase = ioremap(camio_ext.mdcphy,
145                 camio_ext.mdcsz);
146         if (!mdcbase) {
147                 rc = -ENOMEM;
148                 goto mdc_no_mem;
149         }
150
151         camdev->camera_gpio_on();
152
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);
156         return 0;
157
158 mdc_no_mem:
159         release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
160 mdc_busy:
161         iounmap(appbase);
162 apps_no_mem:
163         release_mem_region(camio_ext.appphy, camio_ext.appsz);
164 enable_fail:
165         return rc;
166 }
167
168 void msm_camio_disable(struct platform_device *pdev)
169 {
170         struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
171         struct msm_camera_device_platform_data *camdev = sinfo->pdata;
172
173         iounmap(mdcbase);
174         release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
175         iounmap(appbase);
176         release_mem_region(camio_ext.appphy, camio_ext.appsz);
177
178         camdev->camera_gpio_off();
179
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);
183 }
184
185 void msm_camio_camif_pad_reg_reset(void)
186 {
187         uint32_t reg;
188         uint32_t mask, value;
189
190         /* select CLKRGM_VFE_SRC_CAM_VFE_SRC:  internal source */
191         msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_INTERNAL);
192
193         reg = (readl(mdcbase)) & CAMIF_CFG_RMSK;
194
195         mask = CAM_SEL_BMSK |
196                 CAM_PCLK_SRC_SEL_BMSK |
197                 CAM_PCLK_INVERT_BMSK;
198
199         value = 1 << CAM_SEL_SHFT |
200                 3 << CAM_PCLK_SRC_SEL_SHFT |
201                 0 << CAM_PCLK_INVERT_SHFT;
202
203         writel((reg & (~mask)) | (value & mask), mdcbase);
204         mdelay(10);
205
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);
210         mdelay(10);
211
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);
216         mdelay(10);
217
218         msm_camio_clk_sel(MSM_CAMIO_CLK_SRC_EXTERNAL);
219         mdelay(10);
220 }
221
222 void msm_camio_vfe_blk_reset(void)
223 {
224         uint32_t val;
225
226         val = readl(appbase + 0x00000210);
227         val |= 0x1;
228         writel(val, appbase + 0x00000210);
229         mdelay(10);
230
231         val = readl(appbase + 0x00000210);
232         val &= ~0x1;
233         writel(val, appbase + 0x00000210);
234         mdelay(10);
235 }
236
237 void msm_camio_camif_pad_reg_reset_2(void)
238 {
239         uint32_t reg;
240         uint32_t mask, value;
241
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);
246         mdelay(10);
247
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);
252         mdelay(10);
253 }
254
255 void msm_camio_clk_sel(enum msm_camio_clk_src_type srctype)
256 {
257         struct clk *clk = NULL;
258
259         clk = camio_vfe_clk;
260
261         if (clk != NULL && clk != ERR_PTR(-ENOENT)) {
262                 switch (srctype) {
263                 case MSM_CAMIO_CLK_SRC_INTERNAL:
264                         clk_set_flags(clk, 0x00000100 << 1);
265                         break;
266
267                 case MSM_CAMIO_CLK_SRC_EXTERNAL:
268                         clk_set_flags(clk, 0x00000100);
269                         break;
270
271                 default:
272                         break;
273                 }
274         }
275 }
276
277 int msm_camio_probe_on(struct platform_device *pdev)
278 {
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);
283 }
284
285 int msm_camio_probe_off(struct platform_device *pdev)
286 {
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);
291 }