1 #include "camsys_marvin.h"
2 #include "camsys_soc_priv.h"
3 #include "camsys_gpio.h"
5 #include <linux/rockchip/common.h>
6 #include <dt-bindings/clock/rk_system_status.h>
8 extern int rockchip_set_system_status(unsigned long status);
9 extern int rockchip_clear_system_status(unsigned long status);
11 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
14 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
16 struct pinctrl *pinctrl;
17 struct pinctrl_state *state;
19 char state_str[20] = {0};
20 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
21 struct device *dev = &(extdev->pdev->dev);
22 camsys_soc_priv_t *soc;
26 if (extdev->phy.type == CamSys_Phy_Cif) {
28 switch (extdev->phy.info.cif.fmt)
30 case CamSys_Fmt_Raw_8b:
31 case CamSys_Fmt_Yuv420_8b:
32 case CamSys_Fmt_Yuv422_8b:
34 if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit0) {
35 strcpy(state_str,"isp_dvp8bit0");
36 } else if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit2) {
37 strcpy(state_str,"isp_dvp8bit2");
39 camsys_err("extdev->phy.info.cif.cifio: 0x%x is invalidate!", extdev->phy.info.cif.cifio);
46 case CamSys_Fmt_Raw_10b:
48 strcpy(state_str,"isp_dvp10bit");
52 case CamSys_Fmt_Raw_12b:
54 strcpy(state_str,"isp_dvp12bit");
60 camsys_err("extdev->phy.info.cif.fmt: 0x%x is invalidate!",extdev->phy.info.cif.fmt);
65 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
66 if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
67 strcpy(state_str,"isp_mipi_fl_prefl");
69 strcpy(state_str,"isp_mipi_fl");
72 //mux triggerout as gpio
74 int flash_trigger_io ;
75 enum of_gpio_flags flags;
76 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
77 if(gpio_is_valid(flash_trigger_io)){
78 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
79 gpio_request(flash_trigger_io,"camsys_gpio");
80 gpio_direction_output(flash_trigger_io, (~(extdev->fl.fl.active) & 0x1));
84 strcpy(state_str,"default");
88 camsys_trace(1,"marvin pinctrl select: %s", state_str);
90 pinctrl = devm_pinctrl_get(dev);
91 if (IS_ERR(pinctrl)) {
92 camsys_err("devm_pinctrl_get failed!");
95 state = pinctrl_lookup_state(pinctrl,
98 camsys_err("pinctrl_lookup_state failed!");
102 if (!IS_ERR(state)) {
103 retval = pinctrl_select_state(pinctrl, state);
105 camsys_err("pinctrl_select_state failed!");
110 if (camsys_dev->soc) {
111 soc = (camsys_soc_priv_t*)camsys_dev->soc;
113 (soc->soc_cfg)(Cif_IoDomain_Cfg,(void*)&extdev->dovdd.min_uv);
114 (soc->soc_cfg)(Clk_DriverStrength_Cfg,(void*)&extdev->clk.driver_strength);
116 camsys_err("camsys_dev->soc->soc_cfg is NULL!");
119 camsys_err("camsys_dev->soc is NULL!");
127 static int camsys_mrv_flash_trigger_cb(void *ptr,unsigned int on)
129 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
130 struct device *dev = &(camsys_dev->pdev->dev);
131 int flash_trigger_io ;
132 struct pinctrl *pinctrl;
133 struct pinctrl_state *state;
134 char state_str[20] = {0};
136 enum of_gpio_flags flags;
137 camsys_extdev_t *extdev = NULL;
140 strcpy(state_str,"isp_flash_as_gpio");
141 pinctrl = devm_pinctrl_get(dev);
142 if (IS_ERR(pinctrl)) {
143 camsys_err("devm_pinctrl_get failed!");
145 state = pinctrl_lookup_state(pinctrl,
148 camsys_err("pinctrl_lookup_state failed!");
151 if (!IS_ERR(state)) {
152 retval = pinctrl_select_state(pinctrl, state);
154 camsys_err("pinctrl_select_state failed!");
160 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
161 if(gpio_is_valid(flash_trigger_io)){
162 flash_trigger_io = of_get_named_gpio_flags(camsys_dev->pdev->dev.of_node, "rockchip,gpios", 0, &flags);
163 gpio_request(flash_trigger_io,"camsys_gpio");
164 //get flash io active pol
165 if (!list_empty(&camsys_dev->extdevs.list)) {
166 list_for_each_entry(extdev, &camsys_dev->extdevs.list, list) {
167 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
168 gpio_direction_output(flash_trigger_io, (~(extdev->fl.fl.active) & 0x1));
174 strcpy(state_str,"isp_flash_as_trigger_out");
175 pinctrl = devm_pinctrl_get(dev);
176 if (IS_ERR(pinctrl)) {
177 camsys_err("devm_pinctrl_get failed!");
179 state = pinctrl_lookup_state(pinctrl,
182 camsys_err("pinctrl_lookup_state failed!");
185 if (!IS_ERR(state)) {
186 retval = pinctrl_select_state(pinctrl, state);
188 camsys_err("pinctrl_select_state failed!");
197 static int camsys_mrv_reset_cb(void *ptr,unsigned int on)
199 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
200 camsys_soc_priv_t *soc;
203 if (camsys_dev->soc) {
204 soc = (camsys_soc_priv_t*)camsys_dev->soc;
206 (soc->soc_cfg)(Isp_SoftRst,(void*)on);
208 camsys_err("camsys_dev->soc->soc_cfg is NULL!");
211 camsys_err("camsys_dev->soc is NULL!");
217 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
219 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
220 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
221 unsigned long isp_clk;
223 if (on && !clk->in_on) {
224 rockchip_set_system_status(SYS_STATUS_ISP);
232 clk_set_rate(clk->isp,isp_clk);
233 clk_set_rate(clk->isp_jpe, isp_clk);
235 clk_prepare_enable(clk->aclk_isp);
236 clk_prepare_enable(clk->hclk_isp);
237 clk_prepare_enable(clk->isp);
238 clk_prepare_enable(clk->isp_jpe);
239 clk_prepare_enable(clk->clk_mipi_24m);
240 clk_prepare_enable(clk->pclkin_isp);
241 clk_prepare_enable(clk->pd_isp);
245 camsys_trace(1, "%s clock(f: %ld Hz) in turn on",dev_name(camsys_dev->miscdev.this_device),isp_clk);
246 camsys_mrv_reset_cb(ptr,1);
248 camsys_mrv_reset_cb(ptr,0);
250 } else if (!on && clk->in_on) {
252 clk_disable_unprepare(clk->aclk_isp);
253 clk_disable_unprepare(clk->hclk_isp);
254 clk_disable_unprepare(clk->isp);
255 clk_disable_unprepare(clk->isp_jpe);
256 clk_disable_unprepare(clk->clk_mipi_24m);
257 clk_disable_unprepare(clk->pclkin_isp);
258 clk_disable_unprepare(clk->pd_isp);
260 rockchip_clear_system_status(SYS_STATUS_ISP);
262 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
267 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on,unsigned int inclk)
269 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
270 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
272 mutex_lock(&clk->lock);
273 if (on && (clk->out_on != on)) {
275 clk_set_rate(clk->cif_clk_out,inclk);
276 clk_prepare_enable(clk->cif_clk_out);
279 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
281 } else if (!on && clk->out_on) {
282 if(!IS_ERR_OR_NULL(clk->cif_clk_pll)) {
283 clk_set_parent(clk->cif_clk_out, clk->cif_clk_pll);
285 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
288 clk_disable_unprepare( clk->cif_clk_out);
292 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
294 mutex_unlock(&clk->lock);
298 static irqreturn_t camsys_mrv_irq(int irq, void *data)
300 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
301 camsys_irqstas_t *irqsta;
302 camsys_irqpool_t *irqpool;
303 unsigned int isp_mis,mipi_mis,mi_mis,*mis;
305 unsigned int mi_ris,mi_imis;
307 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
308 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
310 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
312 mi_ris = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_RIS));
313 mi_imis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_IMIS));
314 while((mi_ris & mi_imis) != mi_mis){
315 camsys_trace(2,"mi_mis status erro,mi_mis 0x%x,mi_ris 0x%x,imis 0x%x\n",mi_mis,mi_ris,mi_imis);
316 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
317 mi_ris = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_RIS));
318 mi_imis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_IMIS));
323 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
324 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
325 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
327 spin_lock(&camsys_dev->irq.lock);
328 if (!list_empty(&camsys_dev->irq.irq_pool)) {
329 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
330 if (irqpool->pid != 0) {
352 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
358 spin_lock(&irqpool->lock);
359 if (!list_empty(&irqpool->deactive)) {
360 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
361 irqsta->sta.mis = *mis;
362 list_del_init(&irqsta->list);
363 list_add_tail(&irqsta->list,&irqpool->active);
364 wake_up(&irqpool->done);
366 spin_unlock(&irqpool->lock);
372 spin_unlock(&camsys_dev->irq.lock);
376 static int camsys_mrv_remove_cb(struct platform_device *pdev)
378 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
379 camsys_mrv_clk_t *mrv_clk=NULL;
381 if (camsys_dev->clk != NULL) {
383 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
385 camsys_mrv_clkout_cb(mrv_clk,0,0);
387 camsys_mrv_clkin_cb(mrv_clk,0);
389 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
390 devm_clk_put(&pdev->dev,mrv_clk->pd_isp);
392 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
393 devm_clk_put(&pdev->dev,mrv_clk->aclk_isp);
395 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
396 devm_clk_put(&pdev->dev,mrv_clk->hclk_isp);
398 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
399 devm_clk_put(&pdev->dev,mrv_clk->isp);
401 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
402 devm_clk_put(&pdev->dev,mrv_clk->isp_jpe);
404 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
405 devm_clk_put(&pdev->dev,mrv_clk->pclkin_isp);
407 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
408 devm_clk_put(&pdev->dev,mrv_clk->cif_clk_out);
417 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
420 camsys_mrv_clk_t *mrv_clk=NULL;
422 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
424 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
429 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
430 if (mrv_clk == NULL) {
431 camsys_err("Allocate camsys_mrv_clk_t failed!");
436 mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
437 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
438 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
439 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
440 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
441 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
442 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
443 mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll");
444 mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m");
446 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) ||
447 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) ||
448 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
449 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
454 clk_set_rate(mrv_clk->isp,210000000);
455 clk_set_rate(mrv_clk->isp_jpe, 210000000);
457 mutex_init(&mrv_clk->lock);
459 mrv_clk->in_on = false;
462 camsys_dev->clk = (void*)mrv_clk;
463 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
464 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
465 camsys_dev->reset_cb = camsys_mrv_reset_cb;
466 camsys_dev->iomux = camsys_mrv_iomux_cb;
467 camsys_dev->flash_trigger_cb = camsys_mrv_flash_trigger_cb;
469 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
470 camsys_dev->miscdev.name = miscdev_name;
471 camsys_dev->miscdev.nodename = miscdev_name;
472 camsys_dev->miscdev.fops = &camsys_fops;
474 err = misc_register(&camsys_dev->miscdev);
476 camsys_err("misc register %s failed!",miscdev_name);
477 goto misc_register_failed;
481 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
482 camsys_dev->platform_remove = camsys_mrv_remove_cb;
486 misc_register_failed:
487 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
488 misc_deregister(&camsys_dev->miscdev);
492 if (mrv_clk != NULL) {
493 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
494 clk_put(mrv_clk->pd_isp);
496 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
497 clk_put(mrv_clk->aclk_isp);
499 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
500 clk_put(mrv_clk->hclk_isp);
502 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
503 clk_put(mrv_clk->isp);
505 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
506 clk_put(mrv_clk->isp_jpe);
508 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
509 clk_put(mrv_clk->pclkin_isp);
511 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
512 clk_put(mrv_clk->cif_clk_out);
522 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);