1 #include "camsys_cif.h"
3 static const char miscdev_cif0_name[] = CAMSYS_CIF0_DEVNAME;
4 static const char miscdev_cif1_name[] = CAMSYS_CIF1_DEVNAME;
6 static int camsys_cif_iomux_cb(camsys_extdev_t *extdev, void *ptr)
8 unsigned int cif_vol_sel;
10 if (extdev->dev_cfg & CAMSYS_DEVCFG_FLASHLIGHT) {
11 iomux_set(ISP_FLASH_TRIG);
12 if (extdev->fl.fl.io != 0xffffffff) {
13 iomux_set(ISP_FL_TRIG);
17 if (extdev->dev_cfg & CAMSYS_DEVCFG_PREFLASHLIGHT) {
18 iomux_set(ISP_PRELIGHT_TRIG);
21 if (extdev->dev_cfg & CAMSYS_DEVCFG_SHUTTER) {
22 iomux_set(ISP_SHUTTER_OPEN);
23 iomux_set(ISP_SHUTTER_TRIG);
26 iomux_set(CIF0_CLKOUT);
29 struct pinctrl *pinctrl;
30 struct pinctrl_state *state;
32 char state_str[20] = {0};
34 struct device *dev = &(extdev->pdev->dev);
36 if (extdev->phy.type == CamSys_Phy_Cif) {
37 if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_8b) &&
38 (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
40 strcpy(state_str, "isp_dvp8bit");
44 if ((extdev->phy.info.cif.fmt >= CamSys_Fmt_Raw_10b) &&
45 (extdev->phy.info.cif.fmt <= CamSys_Fmt_Raw_12b)) {
46 strcpy(state_str, "isp_dvp10bit");
49 if (extdev->phy.info.cif.fmt == CamSys_Fmt_Raw_12b) {
50 strcpy(state_str, "isp_dvp12bit");
54 strcpy(state_str, "default");
59 pinctrl = devm_pinctrl_get(dev);
60 if (IS_ERR(pinctrl)) {
61 camsys_err("%s:Get pinctrl failed!\n", __func__);
64 state = pinctrl_lookup_state(pinctrl,
68 "%s:could not get %s pinstate\n",
74 retval = pinctrl_select_state(pinctrl, state);
77 "%s:could not set %s pins\n",
84 /*set 1.8v vol domain for rk32*/
85 __raw_writel(((1<<1)|(1<<(1+16))), RK_GRF_VIRT+0x0380);
86 __raw_writel(0xffffffff, RK_GRF_VIRT+0x01d4);
88 /*set cif vol domain*/
89 if (extdev->phy.type == CamSys_Phy_Cif) {
92 if (!IS_ERR_OR_NULL(extdev->dovdd.ldo)) {
93 if (extdev->dovdd.max_uv >= 25000000) {
94 __raw_writel(((1<<1)|(1<<(1+16))),
95 RK30_GRF_BASE+0x018c);
97 __raw_writel((1<<(1+16)), RK30_GRF_BASE+0x018c);
100 __raw_writel(((1<<1)|(1<<(1+16))),
101 RK30_GRF_BASE+0x018c);
105 /*set 1.8v vol domain*/
106 __raw_writel(((1<<1)|(1<<(1+16))), RK_GRF_VIRT+0x0380);
109 /*set driver strength*/
110 /* __raw_writel(0xffffffff, RK_GRF_VIRT+0x01dc);*/
115 static int camsys_cif_clkin_cb(void *ptr, unsigned int on)
117 camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
118 camsys_cif_clk_t *clk = (camsys_cif_clk_t *)camsys_dev->clk;
120 spin_lock(&clk->lock);
121 if (on && !clk->in_on) {
122 clk_prepare_enable(clk->aclk_cif);
123 clk_prepare_enable(clk->hclk_cif);
124 clk_prepare_enable(clk->cif_clk_in);
127 camsys_trace(1, "%s clock in turn on",
128 dev_name(camsys_dev->miscdev.this_device));
129 } else if (!on && clk->in_on) {
130 clk_disable_unprepare(clk->hclk_cif);
131 clk_disable_unprepare(clk->cif_clk_in);
132 clk_disable_unprepare(clk->pd_cif);
134 camsys_trace(1, "%s clock in turn off",
135 dev_name(camsys_dev->miscdev.this_device));
137 spin_unlock(&clk->lock);
141 static int camsys_cif_clkout_cb(void *ptr, unsigned int on, unsigned int clkin)
143 camsys_dev_t *camsys_dev = (camsys_dev_t *)ptr;
144 camsys_cif_clk_t *clk = (camsys_cif_clk_t *)camsys_dev->clk;
145 struct clk *cif_clk_out_div;
147 spin_lock(&clk->lock);
148 if (on && (clk->out_on != on)) {
149 clk_prepare_enable(clk->cif_clk_out);
150 clk_set_rate(clk->cif_clk_out, clkin);
153 camsys_trace(1, "%s clock out(rate: %dHz) turn on",
154 dev_name(camsys_dev->miscdev.this_device),
156 } else if (!on && clk->out_on) {
157 if (strcmp(dev_name(camsys_dev->miscdev.this_device),
158 miscdev_cif1_name) == 0) {
159 cif_clk_out_div = clk_get(NULL, "cif1_out_div");
161 cif_clk_out_div = clk_get(NULL, "cif0_out_div");
162 if (IS_ERR_OR_NULL(cif_clk_out_div)) {
164 clk_get(NULL, "cif_out_div");
168 if (!IS_ERR_OR_NULL(cif_clk_out_div)) {
169 clk_set_parent(clk->cif_clk_out, cif_clk_out_div);
170 clk_put(cif_clk_out_div);
172 camsys_warn("%s clock out may be not off!",
173 dev_name(camsys_dev->miscdev.this_device));
175 clk_disable_unprepare(clk->cif_clk_out);
178 camsys_trace(1, "%s clock out turn off",
179 dev_name(camsys_dev->miscdev.this_device));
181 spin_unlock(&clk->lock);
183 /* __raw_writel(0x00, CRU_PCLK_REG30+RK30_CRU_BASE);*/
188 static irqreturn_t camsys_cif_irq(int irq, void *data)
190 camsys_dev_t *camsys_dev = (camsys_dev_t *)data;
191 camsys_irqstas_t *irqsta;
192 camsys_irqpool_t *irqpool;
193 unsigned int intsta, frmsta;
195 intsta = __raw_readl(camsys_dev->devmems.registermem->vir_base +
197 frmsta = __raw_readl(camsys_dev->devmems.registermem->vir_base +
199 printk("get oneframe, intsta = 0x%x \n", intsta);
201 if (intsta & 0x200) {
203 camsys_dev->devmems.registermem->vir_base +
206 camsys_dev->devmems.registermem->vir_base +
212 camsys_dev->devmems.registermem->vir_base +
215 camsys_dev->devmems.registermem->vir_base +
218 camsys_dev->devmems.registermem->vir_base +
222 spin_lock(&camsys_dev->irq.lock);
223 list_for_each_entry(irqpool, &camsys_dev->irq.irq_pool, list) {
224 spin_lock(&irqpool->lock);
225 if (!list_empty(&irqpool->deactive)) {
226 irqsta = list_first_entry
227 (&irqpool->deactive, camsys_irqstas_t, list);
228 irqsta->sta.mis = intsta;
229 irqsta->sta.ris = intsta;
230 list_del_init(&irqsta->list);
231 list_add_tail(&irqsta->list, &irqpool->active);
232 irqsta = list_first_entry
233 (&irqpool->active, camsys_irqstas_t, list);
234 /*wake_up_all(&camsys_dev->irq.irq_done);*/
235 wake_up(&irqpool->done);
237 spin_unlock(&irqpool->lock);
239 spin_unlock(&camsys_dev->irq.lock);
244 static int camsys_cif_remove(struct platform_device *pdev)
246 camsys_dev_t *camsys_dev = platform_get_drvdata(pdev);
247 camsys_cif_clk_t *cif_clk;
249 if (camsys_dev->clk != NULL) {
250 cif_clk = (camsys_cif_clk_t *)camsys_dev->clk;
252 camsys_cif_clkout_cb(camsys_dev->clk, 0, 0);
254 camsys_cif_clkin_cb(camsys_dev->clk, 0);
257 clk_put(cif_clk->pd_cif);
258 if (cif_clk->aclk_cif)
259 clk_put(cif_clk->aclk_cif);
260 if (cif_clk->hclk_cif)
261 clk_put(cif_clk->hclk_cif);
262 if (cif_clk->cif_clk_in)
263 clk_put(cif_clk->cif_clk_in);
264 if (cif_clk->cif_clk_out)
265 clk_put(cif_clk->cif_clk_out);
274 int camsys_cif_probe_cb(struct platform_device *pdev, camsys_dev_t *camsys_dev)
277 camsys_cif_clk_t *cif_clk;
280 err = request_irq(camsys_dev->irq.irq_id,
281 camsys_cif_irq, 0, CAMSYS_CIF_IRQNAME,
284 camsys_err("request irq for %s failed", CAMSYS_CIF_IRQNAME);
288 /*Clk and Iomux init*/
289 cif_clk = kzalloc(sizeof(camsys_cif_clk_t), GFP_KERNEL);
290 if (cif_clk == NULL) {
291 camsys_err("Allocate camsys_cif_clk_t failed!");
296 if (strcmp(dev_name(&pdev->dev), CAMSYS_PLATFORM_CIF1_NAME) == 0) {
297 cif_clk->aclk_cif = devm_clk_get(&pdev->dev, "g_aclk_vip");
298 cif_clk->hclk_cif = devm_clk_get(&pdev->dev, "g_hclk_vip");
299 cif_clk->cif_clk_in = devm_clk_get(&pdev->dev, "g_pclkin_cif");
300 cif_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
301 spin_lock_init(&cif_clk->lock);
302 cif_clk->in_on = false;
303 cif_clk->out_on = false;
305 cif_clk->aclk_cif = devm_clk_get(&pdev->dev, "g_aclk_vip");
306 cif_clk->hclk_cif = devm_clk_get(&pdev->dev, "g_hclk_vip");
307 cif_clk->cif_clk_in = devm_clk_get(&pdev->dev, "g_pclkin_ci");
308 cif_clk->cif_clk_out = devm_clk_get(&pdev->dev, "clk_cif_out");
309 spin_lock_init(&cif_clk->lock);
310 cif_clk->in_on = false;
311 cif_clk->out_on = false;
315 *clk_prepare_enable(cif_clk->aclk_cif);
316 clk_prepare_enable(cif_clk->hclk_cif);
317 clk_prepare_enable(cif_clk->cif_clk_in);
318 clk_prepare_enable(cif_clk->cif_clk_out);
321 camsys_dev->clk = (void *)cif_clk;
322 camsys_dev->clkin_cb = camsys_cif_clkin_cb;
323 camsys_dev->clkout_cb = camsys_cif_clkout_cb;
324 camsys_dev->iomux = camsys_cif_iomux_cb;
327 camsys_dev->miscdev.minor = MISC_DYNAMIC_MINOR;
328 if (strcmp(dev_name(&pdev->dev), CAMSYS_PLATFORM_CIF1_NAME) == 0) {
329 camsys_dev->miscdev.name = miscdev_cif1_name;
330 camsys_dev->miscdev.nodename = miscdev_cif1_name;
332 camsys_dev->miscdev.name = miscdev_cif0_name;
333 camsys_dev->miscdev.nodename = miscdev_cif0_name;
335 camsys_dev->miscdev.fops = &camsys_fops;
336 err = misc_register(&camsys_dev->miscdev);
339 "Register /dev/%s misc device failed",
340 camsys_dev->miscdev.name);
341 goto misc_register_failed;
344 "Register /dev/%s misc device success",
345 camsys_dev->miscdev.name);
349 if (strcmp(dev_name(&pdev->dev), CAMSYS_PLATFORM_CIF1_NAME) == 0) {
350 camsys_dev->dev_id = CAMSYS_DEVID_CIF_1;
352 camsys_dev->dev_id = CAMSYS_DEVID_CIF_0;
354 camsys_dev->platform_remove = camsys_cif_remove;
358 misc_register_failed:
359 if (!IS_ERR(camsys_dev->miscdev.this_device)) {
360 misc_deregister(&camsys_dev->miscdev);
366 clk_put(cif_clk->pd_cif);
367 if (cif_clk->aclk_cif)
368 clk_put(cif_clk->aclk_cif);
369 if (cif_clk->hclk_cif)
370 clk_put(cif_clk->hclk_cif);
371 if (cif_clk->cif_clk_in)
372 clk_put(cif_clk->cif_clk_in);
373 if (cif_clk->cif_clk_out)
374 clk_put(cif_clk->cif_clk_out);
383 EXPORT_SYMBOL_GPL(camsys_cif_probe_cb);