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_vol_sel;
10 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
11 iomux_set(ISP_FLASH_TRIG);
12 if (extdev->fl.fl.io != 0xffffffff) {
13 iomux_set(ISP_FL_TRIG);
17 if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
18 iomux_set(ISP_PRELIGHT_TRIG);
21 if (extdev->dev_cfg & CAMSYS_DEVCFG_SHUTTER) {
22 iomux_set(ISP_SHUTTER_OPEN);
23 iomux_set(ISP_SHUTTER_TRIG);
26 iomux_set(CIF0_CLKOUT);
29 struct pinctrl *pinctrl;
30 struct pinctrl_state *state;
32 char state_str[20] = {0};
34 struct device *dev = &(extdev->pdev->dev);
36 if (extdev->phy.type == CamSys_Phy_Cif) {
37 if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_8b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
39 strcpy(state_str,"isp_dvp8bit");
43 if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
44 strcpy(state_str,"isp_dvp10bit");
47 if (extdev->phy.info.cif.fmt == CamSys_Fmt_Raw_12b) {
48 strcpy(state_str,"isp_dvp12bit");
52 strcpy(state_str,"default");
57 pinctrl = devm_pinctrl_get(dev);
58 if (IS_ERR(pinctrl)) {
59 camsys_err("%s:Get pinctrl failed!\n",__func__);
62 state = pinctrl_lookup_state(pinctrl,
65 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
70 retval = pinctrl_select_state(pinctrl, state);
73 "%s:could not set %s pins\n",__func__,state_str);
79 //set 1.8v vol domain for rk32
80 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
81 __raw_writel(0xffffffff, RK_GRF_VIRT+0x01d4);
84 if (extdev->phy.type == CamSys_Phy_Cif) {
87 if (!IS_ERR_OR_NULL(extdev->dovdd.ldo)) {
88 if (extdev->dovdd.max_uv >= 25000000) {
89 __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
91 __raw_writel((1<<(1+16)),RK30_GRF_BASE+0x018c);
94 __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
99 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
102 //set driver strength
103 // __raw_writel(0xffffffff, RK_GRF_VIRT+0x01dc);
109 static int camsys_cif_clkin_cb(void *ptr, unsigned int on)
111 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
112 camsys_cif_clk_t *clk = (camsys_cif_clk_t*)camsys_dev->clk;
114 spin_lock(&clk->lock);
115 if (on && !clk->in_on) {
116 clk_prepare_enable(clk->aclk_cif);
117 clk_prepare_enable(clk->hclk_cif);
118 clk_prepare_enable(clk->cif_clk_in);
121 camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
122 } else if (!on && clk->in_on) {
123 clk_disable_unprepare(clk->hclk_cif);
124 clk_disable_unprepare(clk->cif_clk_in);
125 clk_disable_unprepare(clk->pd_cif);
127 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
129 spin_unlock(&clk->lock);
133 static int camsys_cif_clkout_cb(void *ptr, unsigned int on,unsigned int clkin)
135 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
136 camsys_cif_clk_t *clk = (camsys_cif_clk_t*)camsys_dev->clk;
137 struct clk *cif_clk_out_div;
140 spin_lock(&clk->lock);
141 if (on && (clk->out_on != on)) {
142 clk_prepare_enable(clk->cif_clk_out);
143 clk_set_rate(clk->cif_clk_out,clkin);
146 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
148 } else if (!on && clk->out_on) {
149 if (strcmp(dev_name(camsys_dev->miscdev.this_device),miscdev_cif1_name)==0) {
150 cif_clk_out_div = clk_get(NULL, "cif1_out_div");
152 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
153 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
154 cif_clk_out_div = clk_get(NULL, "cif_out_div");
158 if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
159 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
160 clk_put(cif_clk_out_div);
162 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
164 clk_disable_unprepare(clk->cif_clk_out);
167 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
169 spin_unlock(&clk->lock);
172 // __raw_writel(0x00, CRU_PCLK_REG30+RK30_CRU_BASE);
178 static irqreturn_t camsys_cif_irq(int irq, void *data)
180 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
181 camsys_irqstas_t *irqsta;
182 camsys_irqpool_t *irqpool;
183 unsigned int intsta,frmsta;
185 intsta = __raw_readl(camsys_dev->devmems.registermem->vir_base + CIF_INITSTA);
186 frmsta = __raw_readl(camsys_dev->devmems.registermem->vir_base + CIF_FRAME_STATUS);
187 printk("get oneframe,intsta = 0x%x \n",intsta);
189 if (intsta & 0x200) {
190 __raw_writel(0x200,camsys_dev->devmems.registermem->vir_base + CIF_INITSTA);
191 __raw_writel(0xf000,camsys_dev->devmems.registermem->vir_base + CIF_CTRL);
195 __raw_writel(0x01,camsys_dev->devmems.registermem->vir_base + CIF_INITSTA);
196 __raw_writel(0x02,camsys_dev->devmems.registermem->vir_base + CIF_FRAME_STATUS);
197 __raw_writel(0xf001,camsys_dev->devmems.registermem->vir_base + CIF_CTRL);
200 spin_lock(&camsys_dev->irq.lock);
201 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
202 spin_lock(&irqpool->lock);
203 if (!list_empty(&irqpool->deactive)) {
204 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
205 irqsta->sta.mis = intsta;
206 irqsta->sta.ris = intsta;
207 list_del_init(&irqsta->list);
208 list_add_tail(&irqsta->list,&irqpool->active);
209 irqsta = list_first_entry(&irqpool->active, camsys_irqstas_t, list);
210 //wake_up_all(&camsys_dev->irq.irq_done);
211 wake_up(&irqpool->done);
213 spin_unlock(&irqpool->lock);
215 spin_unlock(&camsys_dev->irq.lock);
220 static int camsys_cif_remove(struct platform_device *pdev)
222 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
223 camsys_cif_clk_t *cif_clk;
225 if (camsys_dev->clk != NULL) {
226 cif_clk = (camsys_cif_clk_t*)camsys_dev->clk;
228 camsys_cif_clkout_cb(camsys_dev->clk, 0,0);
230 camsys_cif_clkin_cb(camsys_dev->clk, 0);
233 clk_put(cif_clk->pd_cif);
234 if (cif_clk->aclk_cif)
235 clk_put(cif_clk->aclk_cif);
236 if (cif_clk->hclk_cif)
237 clk_put(cif_clk->hclk_cif);
238 if (cif_clk->cif_clk_in)
239 clk_put(cif_clk->cif_clk_in);
240 if (cif_clk->cif_clk_out)
241 clk_put(cif_clk->cif_clk_out);
250 int camsys_cif_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
253 camsys_cif_clk_t *cif_clk;
256 err = request_irq(camsys_dev->irq.irq_id, camsys_cif_irq, 0, CAMSYS_CIF_IRQNAME,camsys_dev);
258 camsys_err("request irq for %s failed",CAMSYS_CIF_IRQNAME);
263 cif_clk = kzalloc(sizeof(camsys_cif_clk_t),GFP_KERNEL);
264 if (cif_clk == NULL) {
265 camsys_err("Allocate camsys_cif_clk_t failed!");
270 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_CIF1_NAME) == 0) {
271 cif_clk->aclk_cif = devm_clk_get(&pdev->dev, "g_aclk_vip");
272 cif_clk->hclk_cif = devm_clk_get(&pdev->dev, "g_hclk_vip");
273 cif_clk->cif_clk_in = devm_clk_get(&pdev->dev, "g_pclkin_cif");
274 cif_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
275 spin_lock_init(&cif_clk->lock);
276 cif_clk->in_on = false;
277 cif_clk->out_on = false;
279 cif_clk->aclk_cif = devm_clk_get(&pdev->dev, "g_aclk_vip");
280 cif_clk->hclk_cif = devm_clk_get(&pdev->dev, "g_hclk_vip");
281 cif_clk->cif_clk_in = devm_clk_get(&pdev->dev, "g_pclkin_ci");
282 cif_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
283 spin_lock_init(&cif_clk->lock);
284 cif_clk->in_on = false;
285 cif_clk->out_on = false;
288 // clk_prepare_enable(cif_clk->aclk_cif);
289 // clk_prepare_enable(cif_clk->hclk_cif);
290 // clk_prepare_enable(cif_clk->cif_clk_in);
291 // clk_prepare_enable(cif_clk->cif_clk_out);
295 camsys_dev->clk = (void*)cif_clk;
296 camsys_dev->clkin_cb = camsys_cif_clkin_cb;
297 camsys_dev->clkout_cb = camsys_cif_clkout_cb;
298 camsys_dev->iomux = camsys_cif_iomux_cb;
301 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
302 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_CIF1_NAME) == 0) {
303 camsys_dev->miscdev.name = miscdev_cif1_name;
304 camsys_dev->miscdev.nodename = miscdev_cif1_name;
306 camsys_dev->miscdev.name = miscdev_cif0_name;
307 camsys_dev->miscdev.nodename = miscdev_cif0_name;
309 camsys_dev->miscdev.fops = &camsys_fops;
310 err = misc_register(&camsys_dev->miscdev);
312 camsys_trace(1,"Register /dev/%s misc device failed",camsys_dev->miscdev.name);
313 goto misc_register_failed;
315 camsys_trace(1,"Register /dev/%s misc device success",camsys_dev->miscdev.name);
319 if (strcmp(dev_name(&pdev->dev),CAMSYS_PLATFORM_CIF1_NAME) == 0) {
320 camsys_dev->dev_id = CAMSYS_DEVID_CIF_1;
322 camsys_dev->dev_id = CAMSYS_DEVID_CIF_0;
324 camsys_dev->platform_remove = camsys_cif_remove;
328 misc_register_failed:
329 if (!IS_ERR(camsys_dev->miscdev.this_device)) {
330 misc_deregister(&camsys_dev->miscdev);
336 clk_put(cif_clk->pd_cif);
337 if (cif_clk->aclk_cif)
338 clk_put(cif_clk->aclk_cif);
339 if (cif_clk->hclk_cif)
340 clk_put(cif_clk->hclk_cif);
341 if (cif_clk->cif_clk_in)
342 clk_put(cif_clk->cif_clk_in);
343 if (cif_clk->cif_clk_out)
344 clk_put(cif_clk->cif_clk_out);
353 EXPORT_SYMBOL_GPL(camsys_cif_probe_cb);