1 #include "camsys_cif.h"
3 static const char miscdev_cif0_name[] = CAMSYS_CIF0_DEVNAME;
4 static const char miscdev_cif1_name[] = CAMSYS_CIF1_DEVNAME;
6 static int camsys_cif_iomux_cb(camsys_extdev_t *extdev,void *ptr)
8 unsigned int cif_index;
9 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
11 if (strcmp(dev_name(camsys_dev->miscdev.this_device), CAMSYS_CIF1_DEVNAME)==0) {
17 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
21 iomux_set(CIF0_CLKOUT);
22 write_grf_reg(GRF_IO_CON3, (CIF_DRIVER_STRENGTH_MASK|CIF_DRIVER_STRENGTH_8MA));
23 write_grf_reg(GRF_IO_CON4, (CIF_CLKOUT_AMP_MASK|CIF_CLKOUT_AMP_1V8));
27 camsys_err("Cif index(%d) is invalidate!!!\n",cif_index);
30 #elif defined(CONFIG_ARCH_RK30)
34 rk30_mux_api_set(GPIO1B3_CIF0CLKOUT_NAME, GPIO1B_CIF0_CLKOUT);
39 rk30_mux_api_set(GPIO1C0_CIF1DATA2_RMIICLKOUT_RMIICLKIN_NAME,GPIO1C_CIF1_DATA2);
40 rk30_mux_api_set(GPIO1C1_CIFDATA3_RMIITXEN_NAME,GPIO1C_CIF_DATA3);
41 rk30_mux_api_set(GPIO1C2_CIF1DATA4_RMIITXD1_NAME,GPIO1C_CIF1_DATA4);
42 rk30_mux_api_set(GPIO1C3_CIFDATA5_RMIITXD0_NAME,GPIO1C_CIF_DATA5);
43 rk30_mux_api_set(GPIO1C4_CIFDATA6_RMIIRXERR_NAME,GPIO1C_CIF_DATA6);
44 rk30_mux_api_set(GPIO1C5_CIFDATA7_RMIICRSDVALID_NAME,GPIO1C_CIF_DATA7);
45 rk30_mux_api_set(GPIO1C6_CIFDATA8_RMIIRXD1_NAME,GPIO1C_CIF_DATA8);
46 rk30_mux_api_set(GPIO1C7_CIFDATA9_RMIIRXD0_NAME,GPIO1C_CIF_DATA9);
48 rk30_mux_api_set(GPIO1D0_CIF1VSYNC_MIIMD_NAME,GPIO1D_CIF1_VSYNC);
49 rk30_mux_api_set(GPIO1D1_CIF1HREF_MIIMDCLK_NAME,GPIO1D_CIF1_HREF);
50 rk30_mux_api_set(GPIO1D2_CIF1CLKIN_NAME,GPIO1D_CIF1_CLKIN);
51 rk30_mux_api_set(GPIO1D3_CIF1DATA0_NAME,GPIO1D_CIF1_DATA0);
52 rk30_mux_api_set(GPIO1D4_CIF1DATA1_NAME,GPIO1D_CIF1_DATA1);
53 rk30_mux_api_set(GPIO1D5_CIF1DATA10_NAME,GPIO1D_CIF1_DATA10);
54 rk30_mux_api_set(GPIO1D6_CIF1DATA11_NAME,GPIO1D_CIF1_DATA11);
55 rk30_mux_api_set(GPIO1D7_CIF1CLKOUT_NAME,GPIO1D_CIF1_CLKOUT);
59 camsys_err("Cif index(%d) is invalidate!!!\n", cif_index);
62 #elif defined(CONFIG_ARCH_RK319X)
66 unsigned int cif_vol_sel;
68 cif_vol_sel = __raw_readl(RK30_GRF_BASE+0x018c);
69 __raw_writel( (cif_vol_sel |0x20002),RK30_GRF_BASE+0x018c);
71 __raw_writel(0xffffffff, RK30_GRF_BASE+0x01dc);
73 iomux_set(CIF0_CLKOUT);
74 iomux_set(CIF0_CLKIN);
76 iomux_set(CIF0_VSYNC);
87 camsys_trace(1, "%s cif iomux success\n",dev_name(camsys_dev->miscdev.this_device));
92 camsys_err("Cif index(%d) is invalidate!!!\n", cif_index);
99 static int camsys_cif_clkin_cb(void *ptr, unsigned int on)
101 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
102 camsys_cif_clk_t *clk = (camsys_cif_clk_t*)camsys_dev->clk;
104 spin_lock(&clk->lock);
105 if (on && !clk->in_on) {
106 clk_enable(clk->pd_cif);
107 clk_enable(clk->aclk_cif);
108 clk_enable(clk->hclk_cif);
109 clk_enable(clk->cif_clk_in);
112 camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
113 } else if (!on && clk->in_on) {
114 clk_disable(clk->aclk_cif);
115 clk_disable(clk->hclk_cif);
116 clk_disable(clk->cif_clk_in);
117 clk_disable(clk->pd_cif);
119 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
121 spin_unlock(&clk->lock);
125 static int camsys_cif_clkout_cb(void *ptr, unsigned int on)
127 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
128 camsys_cif_clk_t *clk = (camsys_cif_clk_t*)camsys_dev->clk;
129 struct clk *cif_clk_out_div;
132 spin_lock(&clk->lock);
133 if (on && (clk->out_on != on)) {
134 clk_enable(clk->cif_clk_out);
135 clk_set_rate(clk->cif_clk_out,on);
138 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
140 } else if (!on && clk->out_on) {
141 if (strcmp(dev_name(camsys_dev->miscdev.this_device),miscdev_cif1_name)==0) {
142 cif_clk_out_div = clk_get(NULL, "cif1_out_div");
144 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
145 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
146 cif_clk_out_div = clk_get(NULL, "cif_out_div");
150 if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
151 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
152 clk_put(cif_clk_out_div);
154 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
156 clk_disable(clk->cif_clk_out);
159 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
161 spin_unlock(&clk->lock);
164 // __raw_writel(0x00, CRU_PCLK_REG30+RK30_CRU_BASE);
170 static irqreturn_t camsys_cif_irq(int irq, void *data)
172 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
173 camsys_irqstas_t *irqsta;
174 camsys_irqpool_t *irqpool;
175 unsigned int intsta,frmsta;
177 intsta = __raw_readl(camsys_dev->devmems.registermem->vir_base + CIF_INITSTA);
178 frmsta = __raw_readl(camsys_dev->devmems.registermem->vir_base + CIF_FRAME_STATUS);
179 printk("get oneframe,intsta = 0x%x \n",intsta);
181 if (intsta & 0x200) {
182 __raw_writel(0x200,camsys_dev->devmems.registermem->vir_base + CIF_INITSTA);
183 __raw_writel(0xf000,camsys_dev->devmems.registermem->vir_base + CIF_CTRL);
187 __raw_writel(0x01,camsys_dev->devmems.registermem->vir_base + CIF_INITSTA);
188 __raw_writel(0x02,camsys_dev->devmems.registermem->vir_base + CIF_FRAME_STATUS);
189 __raw_writel(0xf001,camsys_dev->devmems.registermem->vir_base + CIF_CTRL);
192 spin_lock(&camsys_dev->irq.lock);
193 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
194 spin_lock(&irqpool->lock);
195 if (!list_empty(&irqpool->deactive)) {
196 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
197 irqsta->sta.mis = intsta;
198 irqsta->sta.ris = intsta;
199 list_del_init(&irqsta->list);
200 list_add_tail(&irqsta->list,&irqpool->active);
201 irqsta = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
202 //wake_up_all(&camsys_dev->irq.irq_done);
203 wake_up(&irqpool->done);
205 spin_unlock(&irqpool->lock);
207 spin_unlock(&camsys_dev->irq.lock);
212 static int camsys_cif_remove(struct platform_device *pdev)
214 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
215 camsys_cif_clk_t *cif_clk;
217 if (camsys_dev->clk != NULL) {
218 cif_clk = (camsys_cif_clk_t*)camsys_dev->clk;
220 camsys_cif_clkout_cb(camsys_dev->clk, 0);
222 camsys_cif_clkin_cb(camsys_dev->clk, 0);
225 clk_put(cif_clk->pd_cif);
226 if (cif_clk->aclk_cif)
227 clk_put(cif_clk->aclk_cif);
228 if (cif_clk->hclk_cif)
229 clk_put(cif_clk->hclk_cif);
230 if (cif_clk->cif_clk_in)
231 clk_put(cif_clk->cif_clk_in);
232 if (cif_clk->cif_clk_out)
233 clk_put(cif_clk->cif_clk_out);
242 int camsys_cif_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
245 camsys_cif_clk_t *cif_clk;
248 err = request_irq(camsys_dev->irq.irq_id, camsys_cif_irq, 0, CAMSYS_CIF_IRQNAME,camsys_dev);
250 camsys_err("request irq for %s failed",CAMSYS_CIF_IRQNAME);
255 cif_clk = kzalloc(sizeof(camsys_cif_clk_t),GFP_KERNEL);
256 if (cif_clk == NULL) {
257 camsys_err("Allocate camsys_cif_clk_t failed!");
262 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_CIF1_NAME) == 0) {
263 cif_clk->pd_cif = clk_get(NULL, "pd_cif1");
264 cif_clk->aclk_cif = clk_get(NULL, "aclk_cif1");
265 cif_clk->hclk_cif = clk_get(NULL, "hclk_cif1");
266 cif_clk->cif_clk_in = clk_get(NULL, "cif1_in");
267 cif_clk->cif_clk_out = clk_get(NULL, "cif1_out");
268 spin_lock_init(&cif_clk->lock);
269 cif_clk->in_on = false;
270 cif_clk->out_on = false;
272 cif_clk->pd_cif = clk_get(NULL, "pd_cif0");
273 cif_clk->aclk_cif = clk_get(NULL, "aclk_cif0");
274 cif_clk->hclk_cif = clk_get(NULL, "hclk_cif0");
275 cif_clk->cif_clk_in = clk_get(NULL, "pclkin_cif0");
276 cif_clk->cif_clk_out = clk_get(NULL, "cif0_out");
277 spin_lock_init(&cif_clk->lock);
278 cif_clk->in_on = false;
279 cif_clk->out_on = false;
281 camsys_dev->clk = (void*)cif_clk;
282 camsys_dev->clkin_cb = camsys_cif_clkin_cb;
283 camsys_dev->clkout_cb = camsys_cif_clkout_cb;
284 camsys_dev->iomux = camsys_cif_iomux_cb;
287 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
288 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_CIF1_NAME) == 0) {
289 camsys_dev->miscdev.name = miscdev_cif1_name;
290 camsys_dev->miscdev.nodename = miscdev_cif1_name;
292 camsys_dev->miscdev.name = miscdev_cif0_name;
293 camsys_dev->miscdev.nodename = miscdev_cif0_name;
295 camsys_dev->miscdev.fops = &camsys_fops;
296 err = misc_register(&camsys_dev->miscdev);
298 camsys_trace(1,"Register /dev/%s misc device failed",camsys_dev->miscdev.name);
299 goto misc_register_failed;
301 camsys_trace(1,"Register /dev/%s misc device success",camsys_dev->miscdev.name);
305 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_CIF1_NAME) == 0) {
306 camsys_dev->dev_id = CAMSYS_DEVID_CIF_1;
308 camsys_dev->dev_id = CAMSYS_DEVID_CIF_0;
310 camsys_dev->platform_remove = camsys_cif_remove;
314 misc_register_failed:
315 if (!IS_ERR(camsys_dev->miscdev.this_device)) {
316 misc_deregister(&camsys_dev->miscdev);
322 clk_put(cif_clk->pd_cif);
323 if (cif_clk->aclk_cif)
324 clk_put(cif_clk->aclk_cif);
325 if (cif_clk->hclk_cif)
326 clk_put(cif_clk->hclk_cif);
327 if (cif_clk->cif_clk_in)
328 clk_put(cif_clk->cif_clk_in);
329 if (cif_clk->cif_clk_out)
330 clk_put(cif_clk->cif_clk_out);
339 EXPORT_SYMBOL_GPL(camsys_cif_probe_cb);