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;
125 // spin_lock(&clk->lock);
126 if (on && !clk->in_on) {
127 clk_set_rate(clk->isp,180000000);
128 clk_set_rate(clk->isp_jpe, 180000000);
129 // clk_set_rate(clk->aclk_isp,24000000);
130 // clk_set_rate(clk->hclk_isp,24000000);
133 clk_prepare_enable(clk->aclk_isp);
134 clk_prepare_enable(clk->hclk_isp);
135 clk_prepare_enable(clk->isp);
136 clk_prepare_enable( clk->isp_jpe);
139 // clk_enable(clk->pd_isp);
140 // clk_enable(clk->aclk_isp);
141 // clk_enable(clk->hclk_isp);
142 // clk_enable(clk->isp);
143 // clk_enable(clk->isp_jpe);
144 // clk_enable(clk->pclkin_isp);
148 camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
149 camsys_mrv_reset_cb(ptr);
151 } else if (!on && clk->in_on) {
154 clk_disable_unprepare(clk->aclk_isp);
155 clk_disable_unprepare(clk->hclk_isp);
156 clk_disable_unprepare(clk->isp);
157 clk_disable_unprepare( clk->isp_jpe);
159 // clk_disable(clk->pd_isp);
160 // clk_disable(clk->aclk_isp);
161 // clk_disable(clk->hclk_isp);
162 // clk_disable(clk->isp);
163 // clk_disable(clk->isp_jpe);
164 // clk_disable(clk->pclkin_isp);
167 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
169 // spin_unlock(&clk->lock);
173 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on)
175 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
176 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
177 struct clk *cif_clk_out_div;
179 spin_lock(&clk->lock);
180 if (on && (clk->out_on != on)) {
181 clk_prepare_enable(clk->cif_clk_out);
183 // clk_enable(clk->cif_clk_out);
184 clk_set_rate(clk->cif_clk_out,on);
187 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
189 } else if (!on && clk->out_on) {
190 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
191 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
192 cif_clk_out_div = clk_get(NULL, "cif_out_div");
195 if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
196 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
197 clk_put(cif_clk_out_div);
199 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
202 clk_disable_unprepare( clk->cif_clk_out);
203 // clk_disable(clk->cif_clk_out);
207 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
209 spin_unlock(&clk->lock);
213 static irqreturn_t camsys_mrv_irq(int irq, void *data)
215 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
216 camsys_irqstas_t *irqsta;
217 camsys_irqpool_t *irqpool;
218 unsigned int isp_mis,mipi_mis,mi_mis,*mis;
220 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
221 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
222 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
224 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
225 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
226 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
228 spin_lock(&camsys_dev->irq.lock);
229 if (!list_empty(&camsys_dev->irq.irq_pool)) {
230 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
231 if (irqpool->pid != 0) {
253 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
259 spin_lock(&irqpool->lock);
260 if (!list_empty(&irqpool->deactive)) {
261 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
262 irqsta->sta.mis = *mis;
263 list_del_init(&irqsta->list);
264 list_add_tail(&irqsta->list,&irqpool->active);
265 wake_up(&irqpool->done);
267 spin_unlock(&irqpool->lock);
273 spin_unlock(&camsys_dev->irq.lock);
277 static int camsys_mrv_remove_cb(struct platform_device *pdev)
279 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
280 camsys_mrv_clk_t *mrv_clk=NULL;
282 if (camsys_dev->clk != NULL) {
284 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
286 camsys_mrv_clkout_cb(mrv_clk,0);
288 camsys_mrv_clkin_cb(mrv_clk,0);
290 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
291 clk_put(mrv_clk->pd_isp);
293 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
294 clk_put(mrv_clk->aclk_isp);
296 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
297 clk_put(mrv_clk->hclk_isp);
299 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
300 clk_put(mrv_clk->isp);
302 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
303 clk_put(mrv_clk->isp_jpe);
305 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
306 clk_put(mrv_clk->pclkin_isp);
308 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
309 clk_put(mrv_clk->cif_clk_out);
318 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
321 camsys_mrv_clk_t *mrv_clk=NULL;
322 //struct clk *clk_parent;
324 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
326 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
331 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
332 if (mrv_clk == NULL) {
333 camsys_err("Allocate camsys_mrv_clk_t failed!");
338 // mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
339 mrv_clk->pd_isp = NULL;
340 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "g_aclk_isp");
341 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "g_hclk_isp");
342 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
343 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
344 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
345 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
347 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) ||
348 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) /*|| IS_ERR_OR_NULL(mrv_clk->pclkin_isp)*/ ||
349 IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
350 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
356 // clk_set_rate(mrv_clk->isp,1800000000);
357 // clk_set_rate(mrv_clk->isp_jpe,180000000);
359 spin_lock_init(&mrv_clk->lock);
361 mrv_clk->in_on = false;
364 camsys_dev->clk = (void*)mrv_clk;
365 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
366 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
367 camsys_dev->reset_cb = camsys_mrv_reset_cb;
368 camsys_dev->iomux = camsys_mrv_iomux_cb;
370 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
371 camsys_dev->miscdev.name = miscdev_name;
372 camsys_dev->miscdev.nodename = miscdev_name;
373 camsys_dev->miscdev.fops = &camsys_fops;
375 err = misc_register(&camsys_dev->miscdev);
377 camsys_err("misc register %s failed!",miscdev_name);
378 goto misc_register_failed;
382 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
383 camsys_dev->platform_remove = camsys_mrv_remove_cb;
386 misc_register_failed:
387 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
388 misc_deregister(&camsys_dev->miscdev);
392 if (mrv_clk != NULL) {
393 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
394 clk_put(mrv_clk->pd_isp);
396 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
397 clk_put(mrv_clk->aclk_isp);
399 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
400 clk_put(mrv_clk->hclk_isp);
402 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
403 clk_put(mrv_clk->isp);
405 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
406 clk_put(mrv_clk->isp_jpe);
408 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
409 clk_put(mrv_clk->pclkin_isp);
411 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
412 clk_put(mrv_clk->cif_clk_out);
422 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);