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);
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);
158 clk_disable_unprepare(clk->clk_mipi_24m);
160 // clk_disable(clk->pd_isp);
161 // clk_disable(clk->aclk_isp);
162 // clk_disable(clk->hclk_isp);
163 // clk_disable(clk->isp);
164 // clk_disable(clk->isp_jpe);
165 // clk_disable(clk->pclkin_isp);
168 camsys_trace(1, "%s clock in turn off",dev_name(camsys_dev->miscdev.this_device));
170 // spin_unlock(&clk->lock);
174 static int camsys_mrv_clkout_cb(void *ptr, unsigned int on)
176 camsys_dev_t *camsys_dev = (camsys_dev_t*)ptr;
177 camsys_mrv_clk_t *clk = (camsys_mrv_clk_t*)camsys_dev->clk;
178 struct clk *cif_clk_out_div;
180 spin_lock(&clk->lock);
181 if (on && (clk->out_on != on)) {
182 clk_prepare_enable(clk->cif_clk_out);
184 // clk_enable(clk->cif_clk_out);
185 clk_set_rate(clk->cif_clk_out,on);
188 camsys_trace(1, "%s clock out(rate: %dHz) turn on",dev_name(camsys_dev->miscdev.this_device),
190 } else if (!on && clk->out_on) {
191 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
192 if(IS_ERR_OR_NULL(cif_clk_out_div)) {
193 cif_clk_out_div = clk_get(NULL, "cif_out_div");
196 if(!IS_ERR_OR_NULL(cif_clk_out_div)) {
197 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
198 clk_put(cif_clk_out_div);
200 camsys_warn("%s clock out may be not off!", dev_name(camsys_dev->miscdev.this_device));
203 clk_disable_unprepare( clk->cif_clk_out);
204 // clk_disable(clk->cif_clk_out);
208 camsys_trace(1, "%s clock out turn off",dev_name(camsys_dev->miscdev.this_device));
210 spin_unlock(&clk->lock);
214 static irqreturn_t camsys_mrv_irq(int irq, void *data)
216 camsys_dev_t *camsys_dev = (camsys_dev_t*)data;
217 camsys_irqstas_t *irqsta;
218 camsys_irqpool_t *irqpool;
219 unsigned int isp_mis,mipi_mis,mi_mis,*mis;
221 isp_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_MIS));
222 mipi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_MIS));
223 mi_mis = __raw_readl((void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_MIS));
225 __raw_writel(isp_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_ISP_ICR));
226 __raw_writel(mipi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MIPI_ICR));
227 __raw_writel(mi_mis, (void volatile *)(camsys_dev->devmems.registermem->vir_base + MRV_MI_ICR));
229 spin_lock(&camsys_dev->irq.lock);
230 if (!list_empty(&camsys_dev->irq.irq_pool)) {
231 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
232 if (irqpool->pid != 0) {
254 camsys_trace(2,"Thread(pid:%d) irqpool mis(%d) is invalidate",irqpool->pid,irqpool->mis);
260 spin_lock(&irqpool->lock);
261 if (!list_empty(&irqpool->deactive)) {
262 irqsta = list_first_entry(&irqpool->deactive, camsys_irqstas_t, list);
263 irqsta->sta.mis = *mis;
264 list_del_init(&irqsta->list);
265 list_add_tail(&irqsta->list,&irqpool->active);
266 wake_up(&irqpool->done);
268 spin_unlock(&irqpool->lock);
274 spin_unlock(&camsys_dev->irq.lock);
278 static int camsys_mrv_remove_cb(struct platform_device *pdev)
280 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
281 camsys_mrv_clk_t *mrv_clk=NULL;
283 if (camsys_dev->clk != NULL) {
285 mrv_clk = (camsys_mrv_clk_t*)camsys_dev->clk;
287 camsys_mrv_clkout_cb(mrv_clk,0);
289 camsys_mrv_clkin_cb(mrv_clk,0);
291 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
292 clk_put(mrv_clk->pd_isp);
294 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
295 clk_put(mrv_clk->aclk_isp);
297 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
298 clk_put(mrv_clk->hclk_isp);
300 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
301 clk_put(mrv_clk->isp);
303 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
304 clk_put(mrv_clk->isp_jpe);
306 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
307 clk_put(mrv_clk->pclkin_isp);
309 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
310 clk_put(mrv_clk->cif_clk_out);
319 int camsys_mrv_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
322 camsys_mrv_clk_t *mrv_clk=NULL;
323 //struct clk *clk_parent;
325 err = request_irq(camsys_dev->irq.irq_id, camsys_mrv_irq, 0, CAMSYS_MARVIN_IRQNAME,camsys_dev);
327 camsys_err("request irq for %s failed",CAMSYS_MARVIN_IRQNAME);
332 mrv_clk = kzalloc(sizeof(camsys_mrv_clk_t),GFP_KERNEL);
333 if (mrv_clk == NULL) {
334 camsys_err("Allocate camsys_mrv_clk_t failed!");
339 // mrv_clk->pd_isp = devm_clk_get(&pdev->dev, "pd_isp");
340 mrv_clk->pd_isp = NULL;
341 mrv_clk->aclk_isp = devm_clk_get(&pdev->dev, "aclk_isp");
342 mrv_clk->hclk_isp = devm_clk_get(&pdev->dev, "hclk_isp");
343 mrv_clk->isp = devm_clk_get(&pdev->dev, "clk_isp");
344 mrv_clk->isp_jpe = devm_clk_get(&pdev->dev, "clk_isp_jpe");
345 mrv_clk->pclkin_isp = devm_clk_get(&pdev->dev, "pclkin_isp");
346 mrv_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_vipout");
347 mrv_clk->clk_mipi_24m = devm_clk_get(&pdev->dev,"clk_mipi_24m");
348 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) ||
349 IS_ERR_OR_NULL(mrv_clk->isp) || IS_ERR_OR_NULL(mrv_clk->isp_jpe) /*|| IS_ERR_OR_NULL(mrv_clk->pclkin_isp)*/ ||
350 IS_ERR_OR_NULL(mrv_clk->cif_clk_out) || IS_ERR_OR_NULL(mrv_clk->clk_mipi_24m)) {
351 camsys_err("Get %s clock resouce failed!\n",miscdev_name);
357 // clk_set_rate(mrv_clk->isp,1800000000);
358 // clk_set_rate(mrv_clk->isp_jpe,180000000);
360 spin_lock_init(&mrv_clk->lock);
362 mrv_clk->in_on = false;
365 camsys_dev->clk = (void*)mrv_clk;
366 camsys_dev->clkin_cb = camsys_mrv_clkin_cb;
367 camsys_dev->clkout_cb = camsys_mrv_clkout_cb;
368 camsys_dev->reset_cb = camsys_mrv_reset_cb;
369 camsys_dev->iomux = camsys_mrv_iomux_cb;
371 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
372 camsys_dev->miscdev.name = miscdev_name;
373 camsys_dev->miscdev.nodename = miscdev_name;
374 camsys_dev->miscdev.fops = &camsys_fops;
376 err = misc_register(&camsys_dev->miscdev);
378 camsys_err("misc register %s failed!",miscdev_name);
379 goto misc_register_failed;
383 camsys_dev->dev_id = CAMSYS_DEVID_MARVIN;
384 camsys_dev->platform_remove = camsys_mrv_remove_cb;
387 misc_register_failed:
388 if (!IS_ERR_OR_NULL(camsys_dev->miscdev.this_device)) {
389 misc_deregister(&camsys_dev->miscdev);
393 if (mrv_clk != NULL) {
394 if (!IS_ERR_OR_NULL(mrv_clk->pd_isp)) {
395 clk_put(mrv_clk->pd_isp);
397 if (!IS_ERR_OR_NULL(mrv_clk->aclk_isp)) {
398 clk_put(mrv_clk->aclk_isp);
400 if (!IS_ERR_OR_NULL(mrv_clk->hclk_isp)) {
401 clk_put(mrv_clk->hclk_isp);
403 if (!IS_ERR_OR_NULL(mrv_clk->isp)) {
404 clk_put(mrv_clk->isp);
406 if (!IS_ERR_OR_NULL(mrv_clk->isp_jpe)) {
407 clk_put(mrv_clk->isp_jpe);
409 if (!IS_ERR_OR_NULL(mrv_clk->pclkin_isp)) {
410 clk_put(mrv_clk->pclkin_isp);
412 if (!IS_ERR_OR_NULL(mrv_clk->cif_clk_out)) {
413 clk_put(mrv_clk->cif_clk_out);
423 EXPORT_SYMBOL_GPL(camsys_mrv_probe_cb);