• 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/drivers/staging/dream/camera/
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
32static struct clk *camio_vfe_mdc_clk;
33static struct clk *camio_mdc_clk;
34static struct clk *camio_vfe_clk;
35
36static struct msm_camera_io_ext camio_ext;
37static struct resource *appio, *mdcio;
38void __iomem *appbase, *mdcbase;
39
40static struct msm_camera_io_ext camio_ext;
41static struct resource *appio, *mdcio;
42void __iomem *appbase, *mdcbase;
43
44extern int clk_set_flags(struct clk *clk, unsigned long flags);
45
46int 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
76int 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
107void 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
115int 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
158mdc_no_mem:
159	release_mem_region(camio_ext.mdcphy, camio_ext.mdcsz);
160mdc_busy:
161	iounmap(appbase);
162apps_no_mem:
163	release_mem_region(camio_ext.appphy, camio_ext.appsz);
164enable_fail:
165	return rc;
166}
167
168void 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
185void 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
222void 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
237void 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
255void 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
277int 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
285int 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}
292