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);
137 clk_prepare_enable(clk->clk_mipi_24m);
138 clk_prepare_enable(clk->pclkin_isp);
142 // clk_enable(clk->pd_isp);
143 // clk_enable(clk->aclk_isp);
144 // clk_enable(clk->hclk_isp);
145 // clk_enable(clk->isp);
146 // clk_enable(clk->isp_jpe);
147 // clk_enable(clk->pclkin_isp);
151 camsys_trace(1, "%s clock in turn on",dev_name(camsys_dev->miscdev.this_device));
152 camsys_mrv_reset_cb(ptr);
154 } else if (!on && clk->in_on) {
157 clk_disable_unprepare(clk->aclk_isp);
158 clk_disable_unprepare(clk->hclk_isp);
159 clk_disable_unprepare(clk->isp);
160 clk_disable_unprepare(clk->isp_jpe);
161 clk_disable_unprepare(clk->clk_mipi_24m);
162 clk_disable_unprepare(clk->pclkin_isp);
164 // clk_disable(clk->pd_isp);
165 // clk_disable(clk->aclk_isp);
166 // clk_disable(clk->hclk_isp);
167 // clk_disable(clk->isp);
168 // clk_disable(clk->isp_jpe);
169 // clk_disable(clk->pclkin_isp);
172 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
174 // spin_unlock(&clk->lock);
178 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on)
180 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
181 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
182 struct clk *cif_clk_out_div;
184 spin_lock(&clk->lock);
185 if (on && (clk->out_on != on)) {
186 clk_prepare_enable(clk->cif_clk_out);
188 // clk_enable(clk->cif_clk_out);
189 clk_set_rate(clk->cif_clk_out,on);
192 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
194 } else if (!on && clk->out_on) {
195 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
196 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
197 cif_clk_out_div = clk_get(NULL, "cif_out_div");
200 if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
201 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
202 clk_put(cif_clk_out_div);
204 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
207 clk_disable_unprepare( clk->cif_clk_out);
208 // clk_disable(clk->cif_clk_out);
212 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
214 spin_unlock(&clk->lock);
218 static irqreturn_t camsys_mrv_irq(int irq, void *data)
220 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
221 camsys_irqstas_t *irqsta;
222 camsys_irqpool_t *irqpool;
223 unsigned int isp_mis,mipi_mis,mi_mis,*mis;
225 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
226 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
227 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
229 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
230 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
231 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
233 spin_lock(&camsys_dev->irq.lock);
234 if (!list_empty(&camsys_dev->irq.irq_pool)) {
235 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
236 if (irqpool->pid != 0) {
258 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
264 spin_lock(&irqpool->lock);
265 if (!list_empty(&irqpool->deactive)) {
266 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
267 irqsta->sta.mis = *mis;
268 list_del_init(&irqsta->list);
269 list_add_tail(&irqsta->list,&irqpool->active);
270 wake_up(&irqpool->done);
272 spin_unlock(&irqpool->lock);
278 spin_unlock(&camsys_dev->irq.lock);
282 static int camsys_mrv_remove_cb(struct platform_device *pdev)
284 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
285 camsys_mrv_clk_t *mrv_clk=NULL;
287 if (camsys_dev->clk != NULL) {
289 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
291 camsys_mrv_clkout_cb(mrv_clk,0);
293 camsys_mrv_clkin_cb(mrv_clk,0);
295 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
296 clk_put(mrv_clk->pd_isp);
298 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
299 clk_put(mrv_clk->aclk_isp);
301 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
302 clk_put(mrv_clk->hclk_isp);
304 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
305 clk_put(mrv_clk->isp);
307 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
308 clk_put(mrv_clk->isp_jpe);
310 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
311 clk_put(mrv_clk->pclkin_isp);
313 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
314 clk_put(mrv_clk->cif_clk_out);
323 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
326 camsys_mrv_clk_t *mrv_clk=NULL;
327 //struct clk *clk_parent;
329 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
331 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
336 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
337 if (mrv_clk == NULL) {
338 camsys_err("Allocate camsys_mrv_clk_t failed!");
343 // mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
344 mrv_clk->pd_isp = NULL;
345 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
346 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
347 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
348 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
349 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
350 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_vipout");
351 mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m");
352 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) ||
353 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) || IS_ERR_OR_NULL(mrv_clk->pclkin_isp) ||
354 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
355 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
361 // clk_set_rate(mrv_clk->isp,1800000000);
362 // clk_set_rate(mrv_clk->isp_jpe,180000000);
364 spin_lock_init(&mrv_clk->lock);
366 mrv_clk->in_on = false;
369 camsys_dev->clk = (void*)mrv_clk;
370 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
371 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
372 camsys_dev->reset_cb = camsys_mrv_reset_cb;
373 camsys_dev->iomux = camsys_mrv_iomux_cb;
375 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
376 camsys_dev->miscdev.name = miscdev_name;
377 camsys_dev->miscdev.nodename = miscdev_name;
378 camsys_dev->miscdev.fops = &camsys_fops;
380 err = misc_register(&camsys_dev->miscdev);
382 camsys_err("misc register %s failed!",miscdev_name);
383 goto misc_register_failed;
387 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
388 camsys_dev->platform_remove = camsys_mrv_remove_cb;
391 misc_register_failed:
392 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
393 misc_deregister(&camsys_dev->miscdev);
397 if (mrv_clk != NULL) {
398 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
399 clk_put(mrv_clk->pd_isp);
401 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
402 clk_put(mrv_clk->aclk_isp);
404 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
405 clk_put(mrv_clk->hclk_isp);
407 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
408 clk_put(mrv_clk->isp);
410 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
411 clk_put(mrv_clk->isp_jpe);
413 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
414 clk_put(mrv_clk->pclkin_isp);
416 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
417 clk_put(mrv_clk->cif_clk_out);
427 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);