1 #include "camsys_marvin.h"
2 #include "camsys_soc_priv.h"
4 #include <linux/rockchip/common.h>
5 #include <dt-bindings/clock/rk_system_status.h>
7 extern int rockchip_set_system_status(unsigned long status);
8 extern int rockchip_clear_system_status(unsigned long status);
10 static const char miscdev_name[] = CAMSYS_MARVIN_DEVNAME;
12 static int camsys_mrv_iomux_cb(camsys_extdev_t *extdev,void *ptr)
14 struct pinctrl *pinctrl;
15 struct pinctrl_state *state;
17 char state_str[20] = {0};
18 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
19 struct device *dev = &(extdev->pdev->dev);
20 camsys_soc_priv_t *soc;
24 if (extdev->phy.type == CamSys_Phy_Cif) {
26 switch (extdev->phy.info.cif.fmt)
28 case CamSys_Fmt_Raw_8b:
29 case CamSys_Fmt_Yuv420_8b:
30 case CamSys_Fmt_Yuv422_8b:
32 if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit0) {
33 strcpy(state_str,"isp_dvp8bit0");
34 } else if (extdev->phy.info.cif.cifio == CamSys_SensorBit0_CifBit2) {
35 strcpy(state_str,"isp_dvp8bit2");
37 camsys_err("extdev->phy.info.cif.cifio: 0x%x is invalidate!", extdev->phy.info.cif.cifio);
44 case CamSys_Fmt_Raw_10b:
46 strcpy(state_str,"isp_dvp10bit");
50 case CamSys_Fmt_Raw_12b:
52 strcpy(state_str,"isp_dvp12bit");
58 camsys_err("extdev->phy.info.cif.fmt: 0x%x is invalidate!",extdev->phy.info.cif.fmt);
63 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
64 if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
65 strcpy(state_str,"isp_mipi_fl_prefl");
67 strcpy(state_str,"isp_mipi_fl");
70 strcpy(state_str,"default");
74 camsys_trace(1,"marvin pinctrl select: %s", state_str);
76 pinctrl = devm_pinctrl_get(dev);
77 if (IS_ERR(pinctrl)) {
78 camsys_err("devm_pinctrl_get failed!");
81 state = pinctrl_lookup_state(pinctrl,
84 camsys_err("pinctrl_lookup_state failed!");
89 retval = pinctrl_select_state(pinctrl, state);
91 camsys_err("pinctrl_select_state failed!");
96 if (camsys_dev->soc) {
97 soc = (camsys_soc_priv_t*)camsys_dev->soc;
99 (soc->soc_cfg)(Cif_IoDomain_Cfg,(void*)&extdev->dovdd.min_uv);
100 (soc->soc_cfg)(Clk_DriverStrength_Cfg,(void*)&extdev->clk.driver_strength);
102 camsys_err("camsys_dev->soc->soc_cfg is NULL!");
105 camsys_err("camsys_dev->soc is NULL!");
113 static int camsys_mrv_reset_cb(void *ptr,unsigned int on)
115 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
116 camsys_soc_priv_t *soc;
118 if (camsys_dev->soc) {
119 soc = (camsys_soc_priv_t*)camsys_dev->soc;
121 (soc->soc_cfg)(Isp_SoftRst,(void*)on);
123 camsys_err("camsys_dev->soc->soc_cfg is NULL!");
126 camsys_err("camsys_dev->soc is NULL!");
132 static int camsys_mrv_clkin_cb(void *ptr, unsigned int on)
134 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
135 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
137 if (on && !clk->in_on) {
138 rockchip_set_system_status(SYS_STATUS_ISP);
140 clk_prepare_enable(clk->aclk_isp);
141 clk_prepare_enable(clk->hclk_isp);
142 clk_prepare_enable(clk->isp);
143 clk_prepare_enable(clk->isp_jpe);
144 clk_prepare_enable(clk->clk_mipi_24m);
145 clk_prepare_enable(clk->pclkin_isp);
146 clk_prepare_enable(clk->pd_isp);
150 camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
151 camsys_mrv_reset_cb(ptr,1);
153 camsys_mrv_reset_cb(ptr,0);
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);
166 rockchip_clear_system_status(SYS_STATUS_ISP);
168 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
174 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on,unsigned int inclk)
176 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
177 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
179 mutex_lock(&clk->lock);
180 if (on && (clk->out_on != on)) {
182 clk_set_rate(clk->cif_clk_out,inclk);
183 clk_prepare_enable(clk->cif_clk_out);
186 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
188 } else if (!on && clk->out_on) {
189 if(!IS_ERR_OR_NULL(clk->cif_clk_pll)) {
190 clk_set_parent(clk->cif_clk_out, clk->cif_clk_pll);
192 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
195 clk_disable_unprepare( clk->cif_clk_out);
199 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
201 mutex_unlock(&clk->lock);
205 static irqreturn_t camsys_mrv_irq(int irq, void *data)
207 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
208 camsys_irqstas_t *irqsta;
209 camsys_irqpool_t *irqpool;
210 unsigned int isp_mis,mipi_mis,mi_mis,*mis;
212 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
213 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
214 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
216 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
217 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
218 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
220 spin_lock(&camsys_dev->irq.lock);
221 if (!list_empty(&camsys_dev->irq.irq_pool)) {
222 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
223 if (irqpool->pid != 0) {
245 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
251 spin_lock(&irqpool->lock);
252 if (!list_empty(&irqpool->deactive)) {
253 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
254 irqsta->sta.mis = *mis;
255 list_del_init(&irqsta->list);
256 list_add_tail(&irqsta->list,&irqpool->active);
257 wake_up(&irqpool->done);
259 spin_unlock(&irqpool->lock);
265 spin_unlock(&camsys_dev->irq.lock);
269 static int camsys_mrv_remove_cb(struct platform_device *pdev)
271 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
272 camsys_mrv_clk_t *mrv_clk=NULL;
274 if (camsys_dev->clk != NULL) {
276 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
278 camsys_mrv_clkout_cb(mrv_clk,0,0);
280 camsys_mrv_clkin_cb(mrv_clk,0);
282 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
283 devm_clk_put(&pdev->dev,mrv_clk->pd_isp);
285 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
286 devm_clk_put(&pdev->dev,mrv_clk->aclk_isp);
288 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
289 devm_clk_put(&pdev->dev,mrv_clk->hclk_isp);
291 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
292 devm_clk_put(&pdev->dev,mrv_clk->isp);
294 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
295 devm_clk_put(&pdev->dev,mrv_clk->isp_jpe);
297 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
298 devm_clk_put(&pdev->dev,mrv_clk->pclkin_isp);
300 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
301 devm_clk_put(&pdev->dev,mrv_clk->cif_clk_out);
310 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
313 camsys_mrv_clk_t *mrv_clk=NULL;
315 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
317 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
322 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
323 if (mrv_clk == NULL) {
324 camsys_err("Allocate camsys_mrv_clk_t failed!");
329 mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
330 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
331 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
332 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
333 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
334 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
335 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
336 mrv_clk->cif_clk_pll = devm_clk_get(&pdev->dev, "clk_cif_pll");
337 mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m");
339 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) ||
340 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) ||
341 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
342 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
347 clk_set_rate(mrv_clk->isp,210000000);
348 clk_set_rate(mrv_clk->isp_jpe, 210000000);
350 mutex_init(&mrv_clk->lock);
352 mrv_clk->in_on = false;
355 camsys_dev->clk = (void*)mrv_clk;
356 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
357 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
358 camsys_dev->reset_cb = camsys_mrv_reset_cb;
359 camsys_dev->iomux = camsys_mrv_iomux_cb;
361 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
362 camsys_dev->miscdev.name = miscdev_name;
363 camsys_dev->miscdev.nodename = miscdev_name;
364 camsys_dev->miscdev.fops = &camsys_fops;
366 err = misc_register(&camsys_dev->miscdev);
368 camsys_err("misc register %s failed!",miscdev_name);
369 goto misc_register_failed;
373 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
374 camsys_dev->platform_remove = camsys_mrv_remove_cb;
378 misc_register_failed:
379 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
380 misc_deregister(&camsys_dev->miscdev);
384 if (mrv_clk != NULL) {
385 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
386 clk_put(mrv_clk->pd_isp);
388 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
389 clk_put(mrv_clk->aclk_isp);
391 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
392 clk_put(mrv_clk->hclk_isp);
394 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
395 clk_put(mrv_clk->isp);
397 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
398 clk_put(mrv_clk->isp_jpe);
400 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
401 clk_put(mrv_clk->pclkin_isp);
403 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
404 clk_put(mrv_clk->cif_clk_out);
414 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);