1 #include "camsys_marvin.h"
3 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
5 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
7 unsigned int cif_vol_sel;
9 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
10 iomux_set(ISP_FLASH_TRIG);
11 if (extdev->fl.fl.io != 0xffffffff) {
12 iomux_set(ISP_FL_TRIG);
16 if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
17 iomux_set(ISP_PRELIGHT_TRIG);
20 if (extdev->dev_cfg & CAMSYS_DEVCFG_SHUTTER) {
21 iomux_set(ISP_SHUTTER_OPEN);
22 iomux_set(ISP_SHUTTER_TRIG);
25 iomux_set(CIF0_CLKOUT);
28 struct pinctrl *pinctrl;
29 struct pinctrl_state *state;
31 char state_str[20] = {0};
33 struct device *dev = &(extdev->pdev->dev);
35 if (extdev->phy.type == CamSys_Phy_Cif) {
36 if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_8b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
38 strcpy(state_str,"isp_dvp8bit");
42 if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b)&& (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
43 strcpy(state_str,"isp_dvp10bit");
46 if (extdev->phy.info.cif.fmt == CamSys_Fmt_Raw_12b) {
47 strcpy(state_str,"isp_dvp12bit");
51 strcpy(state_str,"default");
56 pinctrl = devm_pinctrl_get(dev);
57 if (IS_ERR(pinctrl)) {
58 camsys_err("%s:Get pinctrl failed!\n",__func__);
61 state = pinctrl_lookup_state(pinctrl,
64 dev_err(dev, "%s:could not get %s pinstate\n",__func__,state_str);
69 retval = pinctrl_select_state(pinctrl, state);
72 "%s:could not set %s pins\n",__func__,state_str);
78 //set 1.8v vol domain for rk32
79 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
80 __raw_writel(0xffffffff, RK_GRF_VIRT+0x01d4);
83 if (extdev->phy.type == CamSys_Phy_Cif) {
86 if (!IS_ERR_OR_NULL(extdev->dovdd.ldo)) {
87 if (extdev->dovdd.max_uv >= 25000000) {
88 __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
90 __raw_writel((1<<(1+16)),RK30_GRF_BASE+0x018c);
93 __raw_writel(((1<<1)|(1<<(1+16))),RK30_GRF_BASE+0x018c);
98 __raw_writel(((1<<1)|(1<<(1+16))),RK_GRF_VIRT+0x0380);
101 //set driver strength
102 // __raw_writel(0xffffffff, RK_GRF_VIRT+0x01dc);
108 static int camsys_mrv_reset_cb(void *ptr)
110 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
111 #if 0 //do nothing ,zyc
112 cru_set_soft_reset(SOFT_RST_ISP,true);
114 cru_set_soft_reset(SOFT_RST_ISP,false);
116 camsys_trace(1, "%s soft reset\n",dev_name(camsys_dev->miscdev.this_device));
120 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
122 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
123 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
124 struct clk *cif_clk_out_div;
125 // spin_lock(&clk->lock);
126 if (on && !clk->in_on) {
128 clk_set_rate(clk->isp,180000000);
129 clk_set_rate(clk->isp_jpe, 180000000);
130 // clk_set_rate(clk->aclk_isp,24000000);
131 // clk_set_rate(clk->hclk_isp,24000000);
134 clk_prepare_enable(clk->aclk_isp);
135 clk_prepare_enable(clk->hclk_isp);
136 clk_prepare_enable(clk->isp);
137 clk_prepare_enable(clk->isp_jpe);
138 clk_prepare_enable(clk->clk_mipi_24m);
139 clk_prepare_enable(clk->pclkin_isp);
140 clk_prepare_enable(clk->pd_isp);
143 // clk_enable(clk->pd_isp);
144 // clk_enable(clk->aclk_isp);
145 // clk_enable(clk->hclk_isp);
146 // clk_enable(clk->isp);
147 // clk_enable(clk->isp_jpe);
148 // clk_enable(clk->pclkin_isp);
152 camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
153 camsys_mrv_reset_cb(ptr);
155 } else if (!on && clk->in_on) {
158 clk_disable_unprepare(clk->aclk_isp);
159 clk_disable_unprepare(clk->hclk_isp);
160 clk_disable_unprepare(clk->isp);
161 clk_disable_unprepare(clk->isp_jpe);
162 clk_disable_unprepare(clk->clk_mipi_24m);
163 clk_disable_unprepare(clk->pclkin_isp);
164 clk_disable_unprepare(clk->pd_isp);
165 // clk_disable(clk->pd_isp);
166 // clk_disable(clk->aclk_isp);
167 // clk_disable(clk->hclk_isp);
168 // clk_disable(clk->isp);
169 // clk_disable(clk->isp_jpe);
170 // clk_disable(clk->pclkin_isp);
174 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
176 // spin_unlock(&clk->lock);
180 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on,unsigned int inclk)
182 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
183 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
184 struct clk *cif_clk_out_div;
186 spin_lock(&clk->lock);
187 if (on && (clk->out_on != on)) {
189 clk_set_rate(clk->cif_clk_out,inclk);
190 clk_prepare_enable(clk->cif_clk_out);
193 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
195 } else if (!on && clk->out_on) {
196 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
197 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
198 cif_clk_out_div = clk_get(NULL, "cif_out_div");
199 printk("can't get clk_cif_pll");
202 if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
203 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
204 clk_put(cif_clk_out_div);
206 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
209 clk_disable_unprepare( clk->cif_clk_out);
210 // clk_disable(clk->cif_clk_out);
214 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
216 spin_unlock(&clk->lock);
220 static irqreturn_t camsys_mrv_irq(int irq, void *data)
222 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
223 camsys_irqstas_t *irqsta;
224 camsys_irqpool_t *irqpool;
225 unsigned int isp_mis,mipi_mis,mi_mis,*mis;
227 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
228 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
229 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
231 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
232 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
233 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
235 spin_lock(&camsys_dev->irq.lock);
236 if (!list_empty(&camsys_dev->irq.irq_pool)) {
237 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
238 if (irqpool->pid != 0) {
260 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
266 spin_lock(&irqpool->lock);
267 if (!list_empty(&irqpool->deactive)) {
268 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
269 irqsta->sta.mis = *mis;
270 list_del_init(&irqsta->list);
271 list_add_tail(&irqsta->list,&irqpool->active);
272 wake_up(&irqpool->done);
274 spin_unlock(&irqpool->lock);
280 spin_unlock(&camsys_dev->irq.lock);
284 static int camsys_mrv_remove_cb(struct platform_device *pdev)
286 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
287 camsys_mrv_clk_t *mrv_clk=NULL;
289 if (camsys_dev->clk != NULL) {
291 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
293 camsys_mrv_clkout_cb(mrv_clk,0,0);
295 camsys_mrv_clkin_cb(mrv_clk,0);
297 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
298 clk_put(mrv_clk->pd_isp);
300 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
301 clk_put(mrv_clk->aclk_isp);
303 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
304 clk_put(mrv_clk->hclk_isp);
306 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
307 clk_put(mrv_clk->isp);
309 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
310 clk_put(mrv_clk->isp_jpe);
312 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
313 clk_put(mrv_clk->pclkin_isp);
315 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
316 clk_put(mrv_clk->cif_clk_out);
325 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
328 camsys_mrv_clk_t *mrv_clk=NULL;
329 //struct clk *clk_parent;
330 struct clk *cif_clk_out_div;
332 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
334 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
339 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
340 if (mrv_clk == NULL) {
341 camsys_err("Allocate camsys_mrv_clk_t failed!");
346 mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
347 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
348 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
349 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
350 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
351 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
352 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_vipout");
353 mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m");
355 if (IS_ERR_OR_NULL(mrv_clk->pd_isp) || IS_ERR_OR_NULL(mrv_clk->aclk_isp) || IS_ERR_OR_NULL(mrv_clk->hclk_isp) ||
356 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) ||
357 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
358 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
364 // clk_set_rate(mrv_clk->isp,1800000000);
365 // clk_set_rate(mrv_clk->isp_jpe,180000000);
367 spin_lock_init(&mrv_clk->lock);
369 mrv_clk->in_on = false;
372 camsys_dev->clk = (void*)mrv_clk;
373 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
374 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
375 camsys_dev->reset_cb = camsys_mrv_reset_cb;
376 camsys_dev->iomux = camsys_mrv_iomux_cb;
378 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
379 camsys_dev->miscdev.name = miscdev_name;
380 camsys_dev->miscdev.nodename = miscdev_name;
381 camsys_dev->miscdev.fops = &camsys_fops;
383 err = misc_register(&camsys_dev->miscdev);
385 camsys_err("misc register %s failed!",miscdev_name);
386 goto misc_register_failed;
390 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
391 camsys_dev->platform_remove = camsys_mrv_remove_cb;
395 misc_register_failed:
396 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
397 misc_deregister(&camsys_dev->miscdev);
401 if (mrv_clk != NULL) {
402 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
403 clk_put(mrv_clk->pd_isp);
405 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
406 clk_put(mrv_clk->aclk_isp);
408 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
409 clk_put(mrv_clk->hclk_isp);
411 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
412 clk_put(mrv_clk->isp);
414 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
415 clk_put(mrv_clk->isp_jpe);
417 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
418 clk_put(mrv_clk->pclkin_isp);
420 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
421 clk_put(mrv_clk->cif_clk_out);
431 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);