]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/media/platform/marvell-ccic/mmp-driver.c
media: marvell-ccic/mmp: add devicetree support
[linux.git] / drivers / media / platform / marvell-ccic / mmp-driver.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Support for the camera device found on Marvell MMP processors; known
4  * to work with the Armada 610 as used in the OLPC 1.75 system.
5  *
6  * Copyright 2011 Jonathan Corbet <corbet@lwn.net>
7  */
8
9 #include <linux/init.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/i2c.h>
13 #include <linux/interrupt.h>
14 #include <linux/spinlock.h>
15 #include <linux/slab.h>
16 #include <linux/videodev2.h>
17 #include <media/v4l2-device.h>
18 #include <linux/platform_data/media/mmp-camera.h>
19 #include <linux/device.h>
20 #include <linux/of.h>
21 #include <linux/of_platform.h>
22 #include <linux/platform_device.h>
23 #include <linux/gpio.h>
24 #include <linux/io.h>
25 #include <linux/delay.h>
26 #include <linux/list.h>
27 #include <linux/pm.h>
28 #include <linux/clk.h>
29
30 #include "mcam-core.h"
31
32 MODULE_ALIAS("platform:mmp-camera");
33 MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
34 MODULE_LICENSE("GPL");
35
36 static char *mcam_clks[] = {"axi", "func", "phy"};
37
38 struct mmp_camera {
39         void __iomem *power_regs;
40         struct platform_device *pdev;
41         struct mcam_camera mcam;
42         struct list_head devlist;
43         struct clk *mipi_clk;
44         int irq;
45 };
46
47 static inline struct mmp_camera *mcam_to_cam(struct mcam_camera *mcam)
48 {
49         return container_of(mcam, struct mmp_camera, mcam);
50 }
51
52 /*
53  * A silly little infrastructure so we can keep track of our devices.
54  * Chances are that we will never have more than one of them, but
55  * the Armada 610 *does* have two controllers...
56  */
57
58 static LIST_HEAD(mmpcam_devices);
59 static struct mutex mmpcam_devices_lock;
60
61 static void mmpcam_add_device(struct mmp_camera *cam)
62 {
63         mutex_lock(&mmpcam_devices_lock);
64         list_add(&cam->devlist, &mmpcam_devices);
65         mutex_unlock(&mmpcam_devices_lock);
66 }
67
68 static void mmpcam_remove_device(struct mmp_camera *cam)
69 {
70         mutex_lock(&mmpcam_devices_lock);
71         list_del(&cam->devlist);
72         mutex_unlock(&mmpcam_devices_lock);
73 }
74
75 /*
76  * Platform dev remove passes us a platform_device, and there's
77  * no handy unused drvdata to stash a backpointer in.  So just
78  * dig it out of our list.
79  */
80 static struct mmp_camera *mmpcam_find_device(struct platform_device *pdev)
81 {
82         struct mmp_camera *cam;
83
84         mutex_lock(&mmpcam_devices_lock);
85         list_for_each_entry(cam, &mmpcam_devices, devlist) {
86                 if (cam->pdev == pdev) {
87                         mutex_unlock(&mmpcam_devices_lock);
88                         return cam;
89                 }
90         }
91         mutex_unlock(&mmpcam_devices_lock);
92         return NULL;
93 }
94
95
96
97
98 /*
99  * Power-related registers; this almost certainly belongs
100  * somewhere else.
101  *
102  * ARMADA 610 register manual, sec 7.2.1, p1842.
103  */
104 #define CPU_SUBSYS_PMU_BASE     0xd4282800
105 #define REG_CCIC_DCGCR          0x28    /* CCIC dyn clock gate ctrl reg */
106 #define REG_CCIC_CRCR           0x50    /* CCIC clk reset ctrl reg      */
107
108 static void mcam_clk_enable(struct mcam_camera *mcam)
109 {
110         unsigned int i;
111
112         for (i = 0; i < NR_MCAM_CLK; i++) {
113                 if (!IS_ERR(mcam->clk[i]))
114                         clk_prepare_enable(mcam->clk[i]);
115         }
116 }
117
118 static void mcam_clk_disable(struct mcam_camera *mcam)
119 {
120         int i;
121
122         for (i = NR_MCAM_CLK - 1; i >= 0; i--) {
123                 if (!IS_ERR(mcam->clk[i]))
124                         clk_disable_unprepare(mcam->clk[i]);
125         }
126 }
127
128 /*
129  * Power control.
130  */
131 static void mmpcam_power_up_ctlr(struct mmp_camera *cam)
132 {
133         iowrite32(0x3f, cam->power_regs + REG_CCIC_DCGCR);
134         iowrite32(0x3805b, cam->power_regs + REG_CCIC_CRCR);
135         mdelay(1);
136 }
137
138 static int mmpcam_power_up(struct mcam_camera *mcam)
139 {
140         struct mmp_camera *cam = mcam_to_cam(mcam);
141         struct mmp_camera_platform_data *pdata;
142
143 /*
144  * Turn on power and clocks to the controller.
145  */
146         mmpcam_power_up_ctlr(cam);
147         mcam_clk_enable(mcam);
148 /*
149  * Provide power to the sensor.
150  */
151         mcam_reg_write(mcam, REG_CLKCTRL, 0x60000002);
152         pdata = cam->pdev->dev.platform_data;
153         gpio_set_value(pdata->sensor_power_gpio, 1);
154         mdelay(5);
155         mcam_reg_clear_bit(mcam, REG_CTRL1, 0x10000000);
156         gpio_set_value(pdata->sensor_reset_gpio, 0); /* reset is active low */
157         mdelay(5);
158         gpio_set_value(pdata->sensor_reset_gpio, 1); /* reset is active low */
159         mdelay(5);
160
161         return 0;
162 }
163
164 static void mmpcam_power_down(struct mcam_camera *mcam)
165 {
166         struct mmp_camera *cam = mcam_to_cam(mcam);
167         struct mmp_camera_platform_data *pdata;
168 /*
169  * Turn off clocks and set reset lines
170  */
171         iowrite32(0, cam->power_regs + REG_CCIC_DCGCR);
172         iowrite32(0, cam->power_regs + REG_CCIC_CRCR);
173 /*
174  * Shut down the sensor.
175  */
176         pdata = cam->pdev->dev.platform_data;
177         gpio_set_value(pdata->sensor_power_gpio, 0);
178         gpio_set_value(pdata->sensor_reset_gpio, 0);
179
180         mcam_clk_disable(mcam);
181 }
182
183 /*
184  * calc the dphy register values
185  * There are three dphy registers being used.
186  * dphy[0] - CSI2_DPHY3
187  * dphy[1] - CSI2_DPHY5
188  * dphy[2] - CSI2_DPHY6
189  * CSI2_DPHY3 and CSI2_DPHY6 can be set with a default value
190  * or be calculated dynamically
191  */
192 static void mmpcam_calc_dphy(struct mcam_camera *mcam)
193 {
194         struct mmp_camera *cam = mcam_to_cam(mcam);
195         struct mmp_camera_platform_data *pdata = cam->pdev->dev.platform_data;
196         struct device *dev = &cam->pdev->dev;
197         unsigned long tx_clk_esc;
198
199         if (!pdata)
200                 return;
201
202         /*
203          * If CSI2_DPHY3 is calculated dynamically,
204          * pdata->lane_clk should be already set
205          * either in the board driver statically
206          * or in the sensor driver dynamically.
207          */
208         /*
209          * dphy[0] - CSI2_DPHY3:
210          *  bit 0 ~ bit 7: HS Term Enable.
211          *   defines the time that the DPHY
212          *   wait before enabling the data
213          *   lane termination after detecting
214          *   that the sensor has driven the data
215          *   lanes to the LP00 bridge state.
216          *   The value is calculated by:
217          *   (Max T(D_TERM_EN)/Period(DDR)) - 1
218          *  bit 8 ~ bit 15: HS_SETTLE
219          *   Time interval during which the HS
220          *   receiver shall ignore any Data Lane
221          *   HS transitions.
222          *   The value has been calibrated on
223          *   different boards. It seems to work well.
224          *
225          *  More detail please refer
226          *  MIPI Alliance Spectification for D-PHY
227          *  document for explanation of HS-SETTLE
228          *  and D-TERM-EN.
229          */
230         switch (pdata->dphy3_algo) {
231         case DPHY3_ALGO_PXA910:
232                 /*
233                  * Calculate CSI2_DPHY3 algo for PXA910
234                  */
235                 pdata->dphy[0] =
236                         (((1 + (pdata->lane_clk * 80) / 1000) & 0xff) << 8)
237                         | (1 + pdata->lane_clk * 35 / 1000);
238                 break;
239         case DPHY3_ALGO_PXA2128:
240                 /*
241                  * Calculate CSI2_DPHY3 algo for PXA2128
242                  */
243                 pdata->dphy[0] =
244                         (((2 + (pdata->lane_clk * 110) / 1000) & 0xff) << 8)
245                         | (1 + pdata->lane_clk * 35 / 1000);
246                 break;
247         default:
248                 /*
249                  * Use default CSI2_DPHY3 value for PXA688/PXA988
250                  */
251                 dev_dbg(dev, "camera: use the default CSI2_DPHY3 value\n");
252         }
253
254         /*
255          * mipi_clk will never be changed, it is a fixed value on MMP
256          */
257         if (IS_ERR(cam->mipi_clk))
258                 return;
259
260         /* get the escape clk, this is hard coded */
261         clk_prepare_enable(cam->mipi_clk);
262         tx_clk_esc = (clk_get_rate(cam->mipi_clk) / 1000000) / 12;
263         clk_disable_unprepare(cam->mipi_clk);
264         /*
265          * dphy[2] - CSI2_DPHY6:
266          * bit 0 ~ bit 7: CK Term Enable
267          *  Time for the Clock Lane receiver to enable the HS line
268          *  termination. The value is calculated similarly with
269          *  HS Term Enable
270          * bit 8 ~ bit 15: CK Settle
271          *  Time interval during which the HS receiver shall ignore
272          *  any Clock Lane HS transitions.
273          *  The value is calibrated on the boards.
274          */
275         pdata->dphy[2] =
276                 ((((534 * tx_clk_esc) / 2000 - 1) & 0xff) << 8)
277                 | (((38 * tx_clk_esc) / 1000 - 1) & 0xff);
278
279         dev_dbg(dev, "camera: DPHY sets: dphy3=0x%x, dphy5=0x%x, dphy6=0x%x\n",
280                 pdata->dphy[0], pdata->dphy[1], pdata->dphy[2]);
281 }
282
283 static irqreturn_t mmpcam_irq(int irq, void *data)
284 {
285         struct mcam_camera *mcam = data;
286         unsigned int irqs, handled;
287
288         spin_lock(&mcam->dev_lock);
289         irqs = mcam_reg_read(mcam, REG_IRQSTAT);
290         handled = mccic_irq(mcam, irqs);
291         spin_unlock(&mcam->dev_lock);
292         return IRQ_RETVAL(handled);
293 }
294
295 static void mcam_init_clk(struct mcam_camera *mcam)
296 {
297         unsigned int i;
298
299         for (i = 0; i < NR_MCAM_CLK; i++) {
300                 if (mcam_clks[i] != NULL) {
301                         /* Some clks are not necessary on some boards
302                          * We still try to run even it fails getting clk
303                          */
304                         mcam->clk[i] = devm_clk_get(mcam->dev, mcam_clks[i]);
305                         if (IS_ERR(mcam->clk[i]))
306                                 dev_warn(mcam->dev, "Could not get clk: %s\n",
307                                                 mcam_clks[i]);
308                 }
309         }
310 }
311
312 static int mmpcam_probe(struct platform_device *pdev)
313 {
314         struct mmp_camera *cam;
315         struct mcam_camera *mcam;
316         struct resource *res;
317         struct mmp_camera_platform_data *pdata;
318         int ret;
319
320         cam = devm_kzalloc(&pdev->dev, sizeof(*cam), GFP_KERNEL);
321         if (cam == NULL)
322                 return -ENOMEM;
323         cam->pdev = pdev;
324         INIT_LIST_HEAD(&cam->devlist);
325
326         mcam = &cam->mcam;
327         mcam->plat_power_up = mmpcam_power_up;
328         mcam->plat_power_down = mmpcam_power_down;
329         mcam->calc_dphy = mmpcam_calc_dphy;
330         mcam->dev = &pdev->dev;
331         mcam->use_smbus = 0;
332         pdata = pdev->dev.platform_data;
333         if (pdata) {
334                 mcam->mclk_src = pdata->mclk_src;
335                 mcam->mclk_div = pdata->mclk_div;
336                 mcam->bus_type = pdata->bus_type;
337                 mcam->dphy = pdata->dphy;
338                 mcam->lane = pdata->lane;
339         } else {
340                 /*
341                  * These are values that used to be hardcoded in mcam-core and
342                  * work well on a OLPC XO 1.75 with a parallel bus sensor.
343                  * If it turns out other setups make sense, the values should
344                  * be obtained from the device tree.
345                  */
346                 mcam->mclk_src = 3;
347                 mcam->mclk_div = 2;
348         }
349         if (mcam->bus_type == V4L2_MBUS_CSI2_DPHY) {
350                 cam->mipi_clk = devm_clk_get(mcam->dev, "mipi");
351                 if ((IS_ERR(cam->mipi_clk) && mcam->dphy[2] == 0))
352                         return PTR_ERR(cam->mipi_clk);
353         }
354         mcam->mipi_enabled = false;
355         mcam->chip_id = MCAM_ARMADA610;
356         mcam->buffer_mode = B_DMA_sg;
357         strscpy(mcam->bus_info, "platform:mmp-camera", sizeof(mcam->bus_info));
358         spin_lock_init(&mcam->dev_lock);
359         /*
360          * Get our I/O memory.
361          */
362         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
363         mcam->regs = devm_ioremap_resource(&pdev->dev, res);
364         if (IS_ERR(mcam->regs))
365                 return PTR_ERR(mcam->regs);
366         mcam->regs_size = resource_size(res);
367         /*
368          * Power/clock memory is elsewhere; get it too.  Perhaps this
369          * should really be managed outside of this driver?
370          */
371         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
372         cam->power_regs = devm_ioremap_resource(&pdev->dev, res);
373         if (IS_ERR(cam->power_regs))
374                 return PTR_ERR(cam->power_regs);
375         /*
376          * Find the i2c adapter.  This assumes, of course, that the
377          * i2c bus is already up and functioning.
378          */
379         mcam->i2c_adapter = platform_get_drvdata(pdata->i2c_device);
380         if (mcam->i2c_adapter == NULL) {
381                 dev_err(&pdev->dev, "No i2c adapter\n");
382                 return -ENODEV;
383         }
384         /*
385          * Sensor GPIO pins.
386          */
387         ret = devm_gpio_request(&pdev->dev, pdata->sensor_power_gpio,
388                                                         "cam-power");
389         if (ret) {
390                 dev_err(&pdev->dev, "Can't get sensor power gpio %d",
391                                 pdata->sensor_power_gpio);
392                 return ret;
393         }
394         gpio_direction_output(pdata->sensor_power_gpio, 0);
395         ret = devm_gpio_request(&pdev->dev, pdata->sensor_reset_gpio,
396                                                         "cam-reset");
397         if (ret) {
398                 dev_err(&pdev->dev, "Can't get sensor reset gpio %d",
399                                 pdata->sensor_reset_gpio);
400                 return ret;
401         }
402         gpio_direction_output(pdata->sensor_reset_gpio, 0);
403
404         mcam_init_clk(mcam);
405
406         /*
407          * Power the device up and hand it off to the core.
408          */
409         ret = mmpcam_power_up(mcam);
410         if (ret)
411                 return ret;
412         ret = mccic_register(mcam);
413         if (ret)
414                 goto out_power_down;
415         /*
416          * Finally, set up our IRQ now that the core is ready to
417          * deal with it.
418          */
419         res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
420         if (res == NULL) {
421                 ret = -ENODEV;
422                 goto out_unregister;
423         }
424         cam->irq = res->start;
425         ret = devm_request_irq(&pdev->dev, cam->irq, mmpcam_irq, IRQF_SHARED,
426                                         "mmp-camera", mcam);
427         if (ret == 0) {
428                 mmpcam_add_device(cam);
429                 return 0;
430         }
431
432 out_unregister:
433         mccic_shutdown(mcam);
434 out_power_down:
435         mmpcam_power_down(mcam);
436         return ret;
437 }
438
439
440 static int mmpcam_remove(struct mmp_camera *cam)
441 {
442         struct mcam_camera *mcam = &cam->mcam;
443
444         mmpcam_remove_device(cam);
445         mccic_shutdown(mcam);
446         mmpcam_power_down(mcam);
447         return 0;
448 }
449
450 static int mmpcam_platform_remove(struct platform_device *pdev)
451 {
452         struct mmp_camera *cam = mmpcam_find_device(pdev);
453
454         if (cam == NULL)
455                 return -ENODEV;
456         return mmpcam_remove(cam);
457 }
458
459 /*
460  * Suspend/resume support.
461  */
462 #ifdef CONFIG_PM
463
464 static int mmpcam_suspend(struct platform_device *pdev, pm_message_t state)
465 {
466         struct mmp_camera *cam = mmpcam_find_device(pdev);
467
468         if (state.event != PM_EVENT_SUSPEND)
469                 return 0;
470         mccic_suspend(&cam->mcam);
471         return 0;
472 }
473
474 static int mmpcam_resume(struct platform_device *pdev)
475 {
476         struct mmp_camera *cam = mmpcam_find_device(pdev);
477
478         /*
479          * Power up unconditionally just in case the core tries to
480          * touch a register even if nothing was active before; trust
481          * me, it's better this way.
482          */
483         mmpcam_power_up_ctlr(cam);
484         return mccic_resume(&cam->mcam);
485 }
486
487 #endif
488
489 static const struct of_device_id mmpcam_of_match[] = {
490         { .compatible = "marvell,mmp2-ccic", },
491         {},
492 };
493
494 static struct platform_driver mmpcam_driver = {
495         .probe          = mmpcam_probe,
496         .remove         = mmpcam_platform_remove,
497 #ifdef CONFIG_PM
498         .suspend        = mmpcam_suspend,
499         .resume         = mmpcam_resume,
500 #endif
501         .driver = {
502                 .name   = "mmp-camera",
503                 .of_match_table = of_match_ptr(mmpcam_of_match),
504         }
505 };
506
507
508 static int __init mmpcam_init_module(void)
509 {
510         mutex_init(&mmpcam_devices_lock);
511         return platform_driver_register(&mmpcam_driver);
512 }
513
514 static void __exit mmpcam_exit_module(void)
515 {
516         platform_driver_unregister(&mmpcam_driver);
517         /*
518          * platform_driver_unregister() should have emptied the list
519          */
520         if (!list_empty(&mmpcam_devices))
521                 printk(KERN_ERR "mmp_camera leaving devices behind\n");
522 }
523
524 module_init(mmpcam_init_module);
525 module_exit(mmpcam_exit_module);