V4L/DVB (12522): sh-mobile-ceu-camera: implement host-side cropping
[safe/jmp/linux-2.6] / drivers / media / video / sh_mobile_ceu_camera.c
1 /*
2  * V4L2 Driver for SuperH Mobile CEU interface
3  *
4  * Copyright (C) 2008 Magnus Damm
5  *
6  * Based on V4L2 Driver for PXA camera host - "pxa_camera.c",
7  *
8  * Copyright (C) 2006, Sascha Hauer, Pengutronix
9  * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  */
16
17 #include <linux/init.h>
18 #include <linux/module.h>
19 #include <linux/io.h>
20 #include <linux/delay.h>
21 #include <linux/dma-mapping.h>
22 #include <linux/errno.h>
23 #include <linux/fs.h>
24 #include <linux/interrupt.h>
25 #include <linux/kernel.h>
26 #include <linux/mm.h>
27 #include <linux/moduleparam.h>
28 #include <linux/time.h>
29 #include <linux/version.h>
30 #include <linux/device.h>
31 #include <linux/platform_device.h>
32 #include <linux/videodev2.h>
33 #include <linux/pm_runtime.h>
34
35 #include <media/v4l2-common.h>
36 #include <media/v4l2-dev.h>
37 #include <media/soc_camera.h>
38 #include <media/sh_mobile_ceu.h>
39 #include <media/videobuf-dma-contig.h>
40
41 /* register offsets for sh7722 / sh7723 */
42
43 #define CAPSR  0x00 /* Capture start register */
44 #define CAPCR  0x04 /* Capture control register */
45 #define CAMCR  0x08 /* Capture interface control register */
46 #define CMCYR  0x0c /* Capture interface cycle  register */
47 #define CAMOR  0x10 /* Capture interface offset register */
48 #define CAPWR  0x14 /* Capture interface width register */
49 #define CAIFR  0x18 /* Capture interface input format register */
50 #define CSTCR  0x20 /* Camera strobe control register (<= sh7722) */
51 #define CSECR  0x24 /* Camera strobe emission count register (<= sh7722) */
52 #define CRCNTR 0x28 /* CEU register control register */
53 #define CRCMPR 0x2c /* CEU register forcible control register */
54 #define CFLCR  0x30 /* Capture filter control register */
55 #define CFSZR  0x34 /* Capture filter size clip register */
56 #define CDWDR  0x38 /* Capture destination width register */
57 #define CDAYR  0x3c /* Capture data address Y register */
58 #define CDACR  0x40 /* Capture data address C register */
59 #define CDBYR  0x44 /* Capture data bottom-field address Y register */
60 #define CDBCR  0x48 /* Capture data bottom-field address C register */
61 #define CBDSR  0x4c /* Capture bundle destination size register */
62 #define CFWCR  0x5c /* Firewall operation control register */
63 #define CLFCR  0x60 /* Capture low-pass filter control register */
64 #define CDOCR  0x64 /* Capture data output control register */
65 #define CDDCR  0x68 /* Capture data complexity level register */
66 #define CDDAR  0x6c /* Capture data complexity level address register */
67 #define CEIER  0x70 /* Capture event interrupt enable register */
68 #define CETCR  0x74 /* Capture event flag clear register */
69 #define CSTSR  0x7c /* Capture status register */
70 #define CSRTR  0x80 /* Capture software reset register */
71 #define CDSSR  0x84 /* Capture data size register */
72 #define CDAYR2 0x90 /* Capture data address Y register 2 */
73 #define CDACR2 0x94 /* Capture data address C register 2 */
74 #define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
75 #define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
76
77 /* per video frame buffer */
78 struct sh_mobile_ceu_buffer {
79         struct videobuf_buffer vb; /* v4l buffer must be first */
80         const struct soc_camera_data_format *fmt;
81 };
82
83 struct sh_mobile_ceu_dev {
84         struct soc_camera_host ici;
85         struct soc_camera_device *icd;
86
87         unsigned int irq;
88         void __iomem *base;
89         unsigned long video_limit;
90
91         /* lock used to protect videobuf */
92         spinlock_t lock;
93         struct list_head capture;
94         struct videobuf_buffer *active;
95
96         struct sh_mobile_ceu_info *pdata;
97
98         unsigned int is_interlaced:1;
99         unsigned int image_mode:1;
100         unsigned int is_16bit:1;
101 };
102
103 struct sh_mobile_ceu_cam {
104         struct v4l2_rect camera_rect;
105         const struct soc_camera_data_format *extra_fmt;
106         const struct soc_camera_data_format *camera_fmt;
107 };
108
109 static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
110 {
111         unsigned long flags;
112
113         flags = SOCAM_MASTER |
114                 SOCAM_PCLK_SAMPLE_RISING |
115                 SOCAM_HSYNC_ACTIVE_HIGH |
116                 SOCAM_HSYNC_ACTIVE_LOW |
117                 SOCAM_VSYNC_ACTIVE_HIGH |
118                 SOCAM_VSYNC_ACTIVE_LOW |
119                 SOCAM_DATA_ACTIVE_HIGH;
120
121         if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
122                 flags |= SOCAM_DATAWIDTH_8;
123
124         if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
125                 flags |= SOCAM_DATAWIDTH_16;
126
127         if (flags & SOCAM_DATAWIDTH_MASK)
128                 return flags;
129
130         return 0;
131 }
132
133 static void ceu_write(struct sh_mobile_ceu_dev *priv,
134                       unsigned long reg_offs, u32 data)
135 {
136         iowrite32(data, priv->base + reg_offs);
137 }
138
139 static u32 ceu_read(struct sh_mobile_ceu_dev *priv, unsigned long reg_offs)
140 {
141         return ioread32(priv->base + reg_offs);
142 }
143
144 /*
145  *  Videobuf operations
146  */
147 static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
148                                         unsigned int *count,
149                                         unsigned int *size)
150 {
151         struct soc_camera_device *icd = vq->priv_data;
152         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
153         struct sh_mobile_ceu_dev *pcdev = ici->priv;
154         int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
155
156         *size = PAGE_ALIGN(icd->rect_current.width * icd->rect_current.height *
157                            bytes_per_pixel);
158
159         if (0 == *count)
160                 *count = 2;
161
162         if (pcdev->video_limit) {
163                 while (*size * *count > pcdev->video_limit)
164                         (*count)--;
165         }
166
167         dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
168
169         return 0;
170 }
171
172 static void free_buffer(struct videobuf_queue *vq,
173                         struct sh_mobile_ceu_buffer *buf)
174 {
175         struct soc_camera_device *icd = vq->priv_data;
176
177         dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
178                 &buf->vb, buf->vb.baddr, buf->vb.bsize);
179
180         if (in_interrupt())
181                 BUG();
182
183         videobuf_waiton(&buf->vb, 0, 0);
184         videobuf_dma_contig_free(vq, &buf->vb);
185         dev_dbg(&icd->dev, "%s freed\n", __func__);
186         buf->vb.state = VIDEOBUF_NEEDS_INIT;
187 }
188
189 #define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
190 #define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
191 #define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
192 #define CEU_CAPCR_CTNCP (1 << 16) /* continuous capture mode (if set) */
193
194
195 static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
196 {
197         struct soc_camera_device *icd = pcdev->icd;
198         dma_addr_t phys_addr_top, phys_addr_bottom;
199
200         /* The hardware is _very_ picky about this sequence. Especially
201          * the CEU_CETCR_MAGIC value. It seems like we need to acknowledge
202          * several not-so-well documented interrupt sources in CETCR.
203          */
204         ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_CPEIE);
205         ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & CEU_CETCR_MAGIC);
206         ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_CPEIE);
207         ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
208         ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
209
210         if (!pcdev->active)
211                 return;
212
213         phys_addr_top = videobuf_to_dma_contig(pcdev->active);
214         ceu_write(pcdev, CDAYR, phys_addr_top);
215         if (pcdev->is_interlaced) {
216                 phys_addr_bottom = phys_addr_top + icd->rect_current.width;
217                 ceu_write(pcdev, CDBYR, phys_addr_bottom);
218         }
219
220         switch (icd->current_fmt->fourcc) {
221         case V4L2_PIX_FMT_NV12:
222         case V4L2_PIX_FMT_NV21:
223         case V4L2_PIX_FMT_NV16:
224         case V4L2_PIX_FMT_NV61:
225                 phys_addr_top += icd->rect_current.width *
226                         icd->rect_current.height;
227                 ceu_write(pcdev, CDACR, phys_addr_top);
228                 if (pcdev->is_interlaced) {
229                         phys_addr_bottom = phys_addr_top +
230                                 icd->rect_current.width;
231                         ceu_write(pcdev, CDBCR, phys_addr_bottom);
232                 }
233         }
234
235         pcdev->active->state = VIDEOBUF_ACTIVE;
236         ceu_write(pcdev, CAPSR, 0x1); /* start capture */
237 }
238
239 static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
240                                           struct videobuf_buffer *vb,
241                                           enum v4l2_field field)
242 {
243         struct soc_camera_device *icd = vq->priv_data;
244         struct sh_mobile_ceu_buffer *buf;
245         int ret;
246
247         buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
248
249         dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
250                 vb, vb->baddr, vb->bsize);
251
252         /* Added list head initialization on alloc */
253         WARN_ON(!list_empty(&vb->queue));
254
255 #ifdef DEBUG
256         /* This can be useful if you want to see if we actually fill
257          * the buffer with something */
258         memset((void *)vb->baddr, 0xaa, vb->bsize);
259 #endif
260
261         BUG_ON(NULL == icd->current_fmt);
262
263         if (buf->fmt    != icd->current_fmt ||
264             vb->width   != icd->rect_current.width ||
265             vb->height  != icd->rect_current.height ||
266             vb->field   != field) {
267                 buf->fmt        = icd->current_fmt;
268                 vb->width       = icd->rect_current.width;
269                 vb->height      = icd->rect_current.height;
270                 vb->field       = field;
271                 vb->state       = VIDEOBUF_NEEDS_INIT;
272         }
273
274         vb->size = vb->width * vb->height * ((buf->fmt->depth + 7) >> 3);
275         if (0 != vb->baddr && vb->bsize < vb->size) {
276                 ret = -EINVAL;
277                 goto out;
278         }
279
280         if (vb->state == VIDEOBUF_NEEDS_INIT) {
281                 ret = videobuf_iolock(vq, vb, NULL);
282                 if (ret)
283                         goto fail;
284                 vb->state = VIDEOBUF_PREPARED;
285         }
286
287         return 0;
288 fail:
289         free_buffer(vq, buf);
290 out:
291         return ret;
292 }
293
294 /* Called under spinlock_irqsave(&pcdev->lock, ...) */
295 static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
296                                          struct videobuf_buffer *vb)
297 {
298         struct soc_camera_device *icd = vq->priv_data;
299         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
300         struct sh_mobile_ceu_dev *pcdev = ici->priv;
301
302         dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
303                 vb, vb->baddr, vb->bsize);
304
305         vb->state = VIDEOBUF_QUEUED;
306         list_add_tail(&vb->queue, &pcdev->capture);
307
308         if (!pcdev->active) {
309                 pcdev->active = vb;
310                 sh_mobile_ceu_capture(pcdev);
311         }
312 }
313
314 static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
315                                            struct videobuf_buffer *vb)
316 {
317         struct soc_camera_device *icd = vq->priv_data;
318         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
319         struct sh_mobile_ceu_dev *pcdev = ici->priv;
320         unsigned long flags;
321
322         spin_lock_irqsave(&pcdev->lock, flags);
323
324         if (pcdev->active == vb) {
325                 /* disable capture (release DMA buffer), reset */
326                 ceu_write(pcdev, CAPSR, 1 << 16);
327                 pcdev->active = NULL;
328         }
329
330         if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
331             !list_empty(&vb->queue)) {
332                 vb->state = VIDEOBUF_ERROR;
333                 list_del_init(&vb->queue);
334         }
335
336         spin_unlock_irqrestore(&pcdev->lock, flags);
337
338         free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb));
339 }
340
341 static struct videobuf_queue_ops sh_mobile_ceu_videobuf_ops = {
342         .buf_setup      = sh_mobile_ceu_videobuf_setup,
343         .buf_prepare    = sh_mobile_ceu_videobuf_prepare,
344         .buf_queue      = sh_mobile_ceu_videobuf_queue,
345         .buf_release    = sh_mobile_ceu_videobuf_release,
346 };
347
348 static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
349 {
350         struct sh_mobile_ceu_dev *pcdev = data;
351         struct videobuf_buffer *vb;
352         unsigned long flags;
353
354         spin_lock_irqsave(&pcdev->lock, flags);
355
356         vb = pcdev->active;
357         if (!vb)
358                 /* Stale interrupt from a released buffer */
359                 goto out;
360
361         list_del_init(&vb->queue);
362
363         if (!list_empty(&pcdev->capture))
364                 pcdev->active = list_entry(pcdev->capture.next,
365                                            struct videobuf_buffer, queue);
366         else
367                 pcdev->active = NULL;
368
369         sh_mobile_ceu_capture(pcdev);
370
371         vb->state = VIDEOBUF_DONE;
372         do_gettimeofday(&vb->ts);
373         vb->field_count++;
374         wake_up(&vb->done);
375
376 out:
377         spin_unlock_irqrestore(&pcdev->lock, flags);
378
379         return IRQ_HANDLED;
380 }
381
382 /* Called with .video_lock held */
383 static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
384 {
385         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
386         struct sh_mobile_ceu_dev *pcdev = ici->priv;
387
388         if (pcdev->icd)
389                 return -EBUSY;
390
391         dev_info(&icd->dev,
392                  "SuperH Mobile CEU driver attached to camera %d\n",
393                  icd->devnum);
394
395         clk_enable(pcdev->clk);
396
397         ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
398         while (ceu_read(pcdev, CSTSR) & 1)
399                 msleep(1);
400
401         pcdev->icd = icd;
402
403         return 0;
404 }
405
406 /* Called with .video_lock held */
407 static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
408 {
409         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
410         struct sh_mobile_ceu_dev *pcdev = ici->priv;
411         unsigned long flags;
412
413         BUG_ON(icd != pcdev->icd);
414
415         /* disable capture, disable interrupts */
416         ceu_write(pcdev, CEIER, 0);
417         ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
418
419         /* make sure active buffer is canceled */
420         spin_lock_irqsave(&pcdev->lock, flags);
421         if (pcdev->active) {
422                 list_del(&pcdev->active->queue);
423                 pcdev->active->state = VIDEOBUF_ERROR;
424                 wake_up_all(&pcdev->active->done);
425                 pcdev->active = NULL;
426         }
427         spin_unlock_irqrestore(&pcdev->lock, flags);
428
429         clk_disable(pcdev->clk);
430
431         dev_info(&icd->dev,
432                  "SuperH Mobile CEU driver detached from camera %d\n",
433                  icd->devnum);
434
435         pcdev->icd = NULL;
436 }
437
438 static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd,
439                                    struct v4l2_rect *rect)
440 {
441         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
442         struct sh_mobile_ceu_cam *cam = icd->host_priv;
443         struct sh_mobile_ceu_dev *pcdev = ici->priv;
444         int width, height, cfszr_width, cdwdr_width;
445         unsigned int left_offset, top_offset;
446         u32 camor;
447
448         if (rect->left > cam->camera_rect.left) {
449                 left_offset = rect->left - cam->camera_rect.left;
450         } else {
451                 left_offset = 0;
452                 rect->left = cam->camera_rect.left;
453         }
454
455         if (rect->top > cam->camera_rect.top) {
456                 top_offset = rect->top - cam->camera_rect.top;
457         } else {
458                 top_offset = 0;
459                 rect->top = cam->camera_rect.top;
460         }
461
462         dev_dbg(&icd->dev, "Offsets %u:%u\n", left_offset, top_offset);
463
464         if (pcdev->image_mode) {
465                 width = rect->width;
466                 if (!pcdev->is_16bit)
467                         width *= 2;
468                 cfszr_width = cdwdr_width = rect->width;
469         } else {
470                 width = rect->width *
471                         ((icd->current_fmt->depth + 7) >> 3);
472                 width = pcdev->is_16bit ? width / 2 : width;
473                 cfszr_width = pcdev->is_16bit ? width : width / 2;
474                 cdwdr_width = pcdev->is_16bit ? width * 2 : width;
475         }
476
477         height = rect->height;
478         if (pcdev->is_interlaced) {
479                 height /= 2;
480                 cdwdr_width *= 2;
481         }
482
483         camor = left_offset | (top_offset << 16);
484         ceu_write(pcdev, CAMOR, camor);
485         ceu_write(pcdev, CAPWR, (height << 16) | width);
486         ceu_write(pcdev, CFSZR, (height << 16) | cfszr_width);
487         ceu_write(pcdev, CDWDR, cdwdr_width);
488 }
489
490 static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
491 {
492         u32 capsr = ceu_read(pcdev, CAPSR);
493         ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
494         return capsr;
495 }
496
497 static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
498 {
499         unsigned long timeout = jiffies + 10 * HZ;
500
501         /*
502          * Wait until the end of the current frame. It can take a long time,
503          * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
504          */
505         while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
506                 msleep(1);
507
508         if (time_after(jiffies, timeout)) {
509                 dev_err(pcdev->ici.v4l2_dev.dev,
510                         "Timeout waiting for frame end! Interface problem?\n");
511                 return;
512         }
513
514         /* Wait until reset clears, this shall not hang... */
515         while (ceu_read(pcdev, CAPSR) & (1 << 16))
516                 udelay(10);
517
518         /* Anything to restore? */
519         if (capsr & ~(1 << 16))
520                 ceu_write(pcdev, CAPSR, capsr);
521 }
522
523 static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
524                                        __u32 pixfmt)
525 {
526         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
527         struct sh_mobile_ceu_dev *pcdev = ici->priv;
528         int ret;
529         unsigned long camera_flags, common_flags, value;
530         int yuv_lineskip;
531         struct sh_mobile_ceu_cam *cam = icd->host_priv;
532         u32 capsr = capture_save_reset(pcdev);
533
534         camera_flags = icd->ops->query_bus_param(icd);
535         common_flags = soc_camera_bus_param_compatible(camera_flags,
536                                                        make_bus_param(pcdev));
537         if (!common_flags)
538                 return -EINVAL;
539
540         ret = icd->ops->set_bus_param(icd, common_flags);
541         if (ret < 0)
542                 return ret;
543
544         switch (common_flags & SOCAM_DATAWIDTH_MASK) {
545         case SOCAM_DATAWIDTH_8:
546                 pcdev->is_16bit = 0;
547                 break;
548         case SOCAM_DATAWIDTH_16:
549                 pcdev->is_16bit = 1;
550                 break;
551         default:
552                 return -EINVAL;
553         }
554
555         ceu_write(pcdev, CRCNTR, 0);
556         ceu_write(pcdev, CRCMPR, 0);
557
558         value = 0x00000010; /* data fetch by default */
559         pcdev->image_mode = yuv_lineskip = 0;
560
561         switch (icd->current_fmt->fourcc) {
562         case V4L2_PIX_FMT_NV12:
563         case V4L2_PIX_FMT_NV21:
564                 yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */
565                 /* fall-through */
566         case V4L2_PIX_FMT_NV16:
567         case V4L2_PIX_FMT_NV61:
568                 pcdev->image_mode = 1;
569                 switch (cam->camera_fmt->fourcc) {
570                 case V4L2_PIX_FMT_UYVY:
571                         value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
572                         break;
573                 case V4L2_PIX_FMT_VYUY:
574                         value = 0x00000100; /* Cr0, Y0, Cb0, Y1 */
575                         break;
576                 case V4L2_PIX_FMT_YUYV:
577                         value = 0x00000200; /* Y0, Cb0, Y1, Cr0 */
578                         break;
579                 case V4L2_PIX_FMT_YVYU:
580                         value = 0x00000300; /* Y0, Cr0, Y1, Cb0 */
581                         break;
582                 default:
583                         BUG();
584                 }
585         }
586
587         if (icd->current_fmt->fourcc == V4L2_PIX_FMT_NV21 ||
588             icd->current_fmt->fourcc == V4L2_PIX_FMT_NV61)
589                 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
590
591         value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
592         value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
593         value |= pcdev->is_16bit ? 1 << 12 : 0;
594         ceu_write(pcdev, CAMCR, value);
595
596         ceu_write(pcdev, CAPCR, 0x00300000);
597         ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
598
599         mdelay(1);
600         sh_mobile_ceu_set_rect(icd, &icd->rect_current);
601
602         ceu_write(pcdev, CFLCR, 0); /* no scaling */
603
604         /* A few words about byte order (observed in Big Endian mode)
605          *
606          * In data fetch mode bytes are received in chunks of 8 bytes.
607          * D0, D1, D2, D3, D4, D5, D6, D7 (D0 received first)
608          *
609          * The data is however by default written to memory in reverse order:
610          * D7, D6, D5, D4, D3, D2, D1, D0 (D7 written to lowest byte)
611          *
612          * The lowest three bits of CDOCR allows us to do swapping,
613          * using 7 we swap the data bytes to match the incoming order:
614          * D0, D1, D2, D3, D4, D5, D6, D7
615          */
616         value = 0x00000017;
617         if (yuv_lineskip)
618                 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
619
620         ceu_write(pcdev, CDOCR, value);
621         ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
622
623         dev_dbg(&icd->dev, "S_FMT successful for %c%c%c%c %ux%u@%u.%u\n",
624                 pixfmt & 0xff, (pixfmt >> 8) & 0xff,
625                 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
626                 icd->rect_current.width, icd->rect_current.height,
627                 icd->rect_current.left, icd->rect_current.top);
628
629         capture_restore(pcdev, capsr);
630
631         /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
632         return 0;
633 }
634
635 static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
636 {
637         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
638         struct sh_mobile_ceu_dev *pcdev = ici->priv;
639         unsigned long camera_flags, common_flags;
640
641         camera_flags = icd->ops->query_bus_param(icd);
642         common_flags = soc_camera_bus_param_compatible(camera_flags,
643                                                        make_bus_param(pcdev));
644         if (!common_flags)
645                 return -EINVAL;
646
647         return 0;
648 }
649
650 static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
651         {
652                 .name           = "NV12",
653                 .depth          = 12,
654                 .fourcc         = V4L2_PIX_FMT_NV12,
655                 .colorspace     = V4L2_COLORSPACE_JPEG,
656         },
657         {
658                 .name           = "NV21",
659                 .depth          = 12,
660                 .fourcc         = V4L2_PIX_FMT_NV21,
661                 .colorspace     = V4L2_COLORSPACE_JPEG,
662         },
663         {
664                 .name           = "NV16",
665                 .depth          = 16,
666                 .fourcc         = V4L2_PIX_FMT_NV16,
667                 .colorspace     = V4L2_COLORSPACE_JPEG,
668         },
669         {
670                 .name           = "NV61",
671                 .depth          = 16,
672                 .fourcc         = V4L2_PIX_FMT_NV61,
673                 .colorspace     = V4L2_COLORSPACE_JPEG,
674         },
675 };
676
677 static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
678                                      struct soc_camera_format_xlate *xlate)
679 {
680         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
681         int ret, k, n;
682         int formats = 0;
683         struct sh_mobile_ceu_cam *cam;
684
685         ret = sh_mobile_ceu_try_bus_param(icd);
686         if (ret < 0)
687                 return 0;
688
689         if (!icd->host_priv) {
690                 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
691                 if (!cam)
692                         return -ENOMEM;
693
694                 icd->host_priv = cam;
695         } else {
696                 cam = icd->host_priv;
697         }
698
699         /* Beginning of a pass */
700         if (!idx)
701                 cam->extra_fmt = NULL;
702
703         switch (icd->formats[idx].fourcc) {
704         case V4L2_PIX_FMT_UYVY:
705         case V4L2_PIX_FMT_VYUY:
706         case V4L2_PIX_FMT_YUYV:
707         case V4L2_PIX_FMT_YVYU:
708                 if (cam->extra_fmt)
709                         goto add_single_format;
710
711                 /*
712                  * Our case is simple so far: for any of the above four camera
713                  * formats we add all our four synthesized NV* formats, so,
714                  * just marking the device with a single flag suffices. If
715                  * the format generation rules are more complex, you would have
716                  * to actually hang your already added / counted formats onto
717                  * the host_priv pointer and check whether the format you're
718                  * going to add now is already there.
719                  */
720                 cam->extra_fmt = (void *)sh_mobile_ceu_formats;
721
722                 n = ARRAY_SIZE(sh_mobile_ceu_formats);
723                 formats += n;
724                 for (k = 0; xlate && k < n; k++) {
725                         xlate->host_fmt = &sh_mobile_ceu_formats[k];
726                         xlate->cam_fmt = icd->formats + idx;
727                         xlate->buswidth = icd->formats[idx].depth;
728                         xlate++;
729                         dev_dbg(ici->v4l2_dev.dev, "Providing format %s using %s\n",
730                                 sh_mobile_ceu_formats[k].name,
731                                 icd->formats[idx].name);
732                 }
733         default:
734 add_single_format:
735                 /* Generic pass-through */
736                 formats++;
737                 if (xlate) {
738                         xlate->host_fmt = icd->formats + idx;
739                         xlate->cam_fmt = icd->formats + idx;
740                         xlate->buswidth = icd->formats[idx].depth;
741                         xlate++;
742                         dev_dbg(ici->v4l2_dev.dev,
743                                 "Providing format %s in pass-through mode\n",
744                                 icd->formats[idx].name);
745                 }
746         }
747
748         return formats;
749 }
750
751 static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
752 {
753         kfree(icd->host_priv);
754         icd->host_priv = NULL;
755 }
756
757 static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
758 {
759         return r1->width < r2->width || r1->height < r2->height;
760 }
761
762 static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
763                                   struct v4l2_rect *rect)
764 {
765         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
766         struct sh_mobile_ceu_dev *pcdev = ici->priv;
767         struct v4l2_rect cam_rect = *rect;
768         struct sh_mobile_ceu_cam *cam = icd->host_priv;
769         unsigned short width, height;
770         u32 capsr;
771         int ret;
772
773         capsr = capture_save_reset(pcdev);
774         dev_dbg(&icd->dev, "CAPSR %x\n", capsr);
775
776         ret = icd->ops->set_crop(icd, &cam_rect);
777         if (!ret && !memcmp(rect, &cam_rect, sizeof(*rect))) {
778                 dev_dbg(&icd->dev, "Camera S_CROP successful for %ux%u@%u.%u\n",
779                         cam_rect.width, cam_rect.height,
780                         cam_rect.left, cam_rect.top);
781                 goto ceu_set_rect;
782         }
783
784         /* Try to fix cropping, that camera hasn't managed to do */
785         dev_dbg(&icd->dev, "Fix camera S_CROP %d for %ux%u@%u.%u\n",
786                 ret, cam_rect.width, cam_rect.height,
787                 cam_rect.left, cam_rect.top);
788
789         /*
790          * Popular special case - some cameras can only handle fixed sizes like
791          * QVGA, VGA,... Take care to avoid infinite loop.
792          */
793         width = max(cam_rect.width, 1) * 2;
794         height = max(cam_rect.height, 1) * 2;
795         while (!ret && is_smaller(&cam_rect, rect) &&
796                (icd->rect_max.width >= width &&
797                 icd->rect_max.height >= height)) {
798                 cam_rect.width = width;
799                 cam_rect.height = height;
800
801                 if (cam_rect.width + cam_rect.left >
802                     icd->rect_max.width + icd->rect_max.left)
803                         cam_rect.left = icd->rect_max.width +
804                                 icd->rect_max.left - cam_rect.width;
805
806                 if (cam_rect.height + cam_rect.top >
807                     icd->rect_max.height + icd->rect_max.top)
808                         cam_rect.top = icd->rect_max.height +
809                                 icd->rect_max.top - cam_rect.height;
810
811                 ret = icd->ops->set_crop(icd, &cam_rect);
812                 dev_dbg(&icd->dev, "Camera S_CROP %d for %ux%u@%u.%u\n",
813                         ret, cam_rect.width, cam_rect.height,
814                         cam_rect.left, cam_rect.top);
815                 width *= 2;
816                 height *= 2;
817         }
818
819         /*
820          * If the camera failed to configure cropping, it should not modify the
821          * rectangle
822          */
823         if ((ret < 0 && is_smaller(&icd->rect_current, rect)) ||
824             is_smaller(&cam_rect, rect)) {
825                 /*
826                  * The camera failed to configure a suitable cropping,
827                  * we cannot use the current rectangle, set to max
828                  */
829                 cam_rect = icd->rect_max;
830                 ret = icd->ops->set_crop(icd, &cam_rect);
831                 dev_dbg(&icd->dev, "Camera S_CROP %d for max %ux%u@%u.%u\n",
832                         ret, cam_rect.width, cam_rect.height,
833                         cam_rect.left, cam_rect.top);
834                 if (ret < 0)
835                         /* All failed, hopefully resume current capture */
836                         goto resume_capture;
837         }
838
839         /* We now have a rectangle, larger than requested, let's crop */
840
841         /*
842          * We have to preserve camera rectangle between close() / open(),
843          * because soc-camera core calls .set_fmt() on each first open() with
844          * last before last close() _user_ rectangle, which can be different
845          * from camera rectangle.
846          */
847         dev_dbg(&icd->dev, "SH S_CROP from %ux%u@%u.%u to %ux%u@%u.%u\n",
848                 cam_rect.width, cam_rect.height, cam_rect.left, cam_rect.top,
849                 rect->width, rect->height, rect->left, rect->top);
850
851         ret = 0;
852
853 ceu_set_rect:
854         cam->camera_rect = cam_rect;
855
856         /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
857         if (pcdev->active)
858                 capsr |= 1;
859         sh_mobile_ceu_set_rect(icd, rect);
860         capture_restore(pcdev, capsr);
861
862 resume_capture:
863
864         /* Even if only camera cropping succeeded */
865         return ret;
866 }
867
868 static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
869                                  struct v4l2_format *f)
870 {
871         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
872         struct sh_mobile_ceu_cam *cam = icd->host_priv;
873         struct v4l2_pix_format *pix = &f->fmt.pix;
874         __u32 pixfmt = pix->pixelformat;
875         const struct soc_camera_format_xlate *xlate;
876         int ret;
877
878         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
879         if (!xlate) {
880                 dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
881                 return -EINVAL;
882         }
883
884         pix->pixelformat = xlate->cam_fmt->fourcc;
885         ret = v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, s_fmt, f);
886         pix->pixelformat = pixfmt;
887         if (!ret) {
888                 icd->buswidth = xlate->buswidth;
889                 icd->current_fmt = xlate->host_fmt;
890                 cam->camera_fmt = xlate->cam_fmt;
891                 cam->camera_rect.width = pix->width;
892                 cam->camera_rect.height = pix->height;
893                 cam->camera_rect.left = icd->rect_current.left;
894                 cam->camera_rect.top = icd->rect_current.top;
895         }
896
897         return ret;
898 }
899
900 static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
901                                  struct v4l2_format *f)
902 {
903         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
904         struct sh_mobile_ceu_dev *pcdev = ici->priv;
905         const struct soc_camera_format_xlate *xlate;
906         struct v4l2_pix_format *pix = &f->fmt.pix;
907         __u32 pixfmt = pix->pixelformat;
908         int ret;
909
910         xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
911         if (!xlate) {
912                 dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
913                 return -EINVAL;
914         }
915
916         /* FIXME: calculate using depth and bus width */
917
918         v4l_bound_align_image(&pix->width, 2, 2560, 1,
919                               &pix->height, 4, 1920, 2, 0);
920
921         pix->bytesperline = pix->width *
922                 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
923         pix->sizeimage = pix->height * pix->bytesperline;
924
925         pix->pixelformat = xlate->cam_fmt->fourcc;
926
927         /* limit to sensor capabilities */
928         ret = v4l2_device_call_until_err(&ici->v4l2_dev, (__u32)icd, video, try_fmt, f);
929         pix->pixelformat = pixfmt;
930         if (ret < 0)
931                 return ret;
932
933         switch (pix->field) {
934         case V4L2_FIELD_INTERLACED:
935                 pcdev->is_interlaced = 1;
936                 break;
937         case V4L2_FIELD_ANY:
938                 pix->field = V4L2_FIELD_NONE;
939                 /* fall-through */
940         case V4L2_FIELD_NONE:
941                 pcdev->is_interlaced = 0;
942                 break;
943         default:
944                 ret = -EINVAL;
945                 break;
946         }
947
948         return ret;
949 }
950
951 static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf,
952                                  struct v4l2_requestbuffers *p)
953 {
954         int i;
955
956         /* This is for locking debugging only. I removed spinlocks and now I
957          * check whether .prepare is ever called on a linked buffer, or whether
958          * a dma IRQ can occur for an in-work or unlinked buffer. Until now
959          * it hadn't triggered */
960         for (i = 0; i < p->count; i++) {
961                 struct sh_mobile_ceu_buffer *buf;
962
963                 buf = container_of(icf->vb_vidq.bufs[i],
964                                    struct sh_mobile_ceu_buffer, vb);
965                 INIT_LIST_HEAD(&buf->vb.queue);
966         }
967
968         return 0;
969 }
970
971 static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
972 {
973         struct soc_camera_file *icf = file->private_data;
974         struct sh_mobile_ceu_buffer *buf;
975
976         buf = list_entry(icf->vb_vidq.stream.next,
977                          struct sh_mobile_ceu_buffer, vb.stream);
978
979         poll_wait(file, &buf->vb.done, pt);
980
981         if (buf->vb.state == VIDEOBUF_DONE ||
982             buf->vb.state == VIDEOBUF_ERROR)
983                 return POLLIN|POLLRDNORM;
984
985         return 0;
986 }
987
988 static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
989                                   struct v4l2_capability *cap)
990 {
991         strlcpy(cap->card, "SuperH_Mobile_CEU", sizeof(cap->card));
992         cap->version = KERNEL_VERSION(0, 0, 5);
993         cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
994         return 0;
995 }
996
997 static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
998                                         struct soc_camera_device *icd)
999 {
1000         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1001         struct sh_mobile_ceu_dev *pcdev = ici->priv;
1002
1003         videobuf_queue_dma_contig_init(q,
1004                                        &sh_mobile_ceu_videobuf_ops,
1005                                        ici->v4l2_dev.dev, &pcdev->lock,
1006                                        V4L2_BUF_TYPE_VIDEO_CAPTURE,
1007                                        pcdev->is_interlaced ?
1008                                        V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
1009                                        sizeof(struct sh_mobile_ceu_buffer),
1010                                        icd);
1011 }
1012
1013 static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1014                                   struct v4l2_control *ctrl)
1015 {
1016         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1017         struct sh_mobile_ceu_dev *pcdev = ici->priv;
1018         u32 val;
1019
1020         switch (ctrl->id) {
1021         case V4L2_CID_SHARPNESS:
1022                 val = ceu_read(pcdev, CLFCR);
1023                 ctrl->value = val ^ 1;
1024                 return 0;
1025         }
1026         return -ENOIOCTLCMD;
1027 }
1028
1029 static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
1030                                   struct v4l2_control *ctrl)
1031 {
1032         struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1033         struct sh_mobile_ceu_dev *pcdev = ici->priv;
1034
1035         switch (ctrl->id) {
1036         case V4L2_CID_SHARPNESS:
1037                 switch (icd->current_fmt->fourcc) {
1038                 case V4L2_PIX_FMT_NV12:
1039                 case V4L2_PIX_FMT_NV21:
1040                 case V4L2_PIX_FMT_NV16:
1041                 case V4L2_PIX_FMT_NV61:
1042                         ceu_write(pcdev, CLFCR, !ctrl->value);
1043                         return 0;
1044                 }
1045                 return -EINVAL;
1046         }
1047         return -ENOIOCTLCMD;
1048 }
1049
1050 static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
1051         {
1052                 .id             = V4L2_CID_SHARPNESS,
1053                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
1054                 .name           = "Low-pass filter",
1055                 .minimum        = 0,
1056                 .maximum        = 1,
1057                 .step           = 1,
1058                 .default_value  = 0,
1059         },
1060 };
1061
1062 static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1063         .owner          = THIS_MODULE,
1064         .add            = sh_mobile_ceu_add_device,
1065         .remove         = sh_mobile_ceu_remove_device,
1066         .get_formats    = sh_mobile_ceu_get_formats,
1067         .put_formats    = sh_mobile_ceu_put_formats,
1068         .set_crop       = sh_mobile_ceu_set_crop,
1069         .set_fmt        = sh_mobile_ceu_set_fmt,
1070         .try_fmt        = sh_mobile_ceu_try_fmt,
1071         .set_ctrl       = sh_mobile_ceu_set_ctrl,
1072         .get_ctrl       = sh_mobile_ceu_get_ctrl,
1073         .reqbufs        = sh_mobile_ceu_reqbufs,
1074         .poll           = sh_mobile_ceu_poll,
1075         .querycap       = sh_mobile_ceu_querycap,
1076         .set_bus_param  = sh_mobile_ceu_set_bus_param,
1077         .init_videobuf  = sh_mobile_ceu_init_videobuf,
1078         .controls       = sh_mobile_ceu_controls,
1079         .num_controls   = ARRAY_SIZE(sh_mobile_ceu_controls),
1080 };
1081
1082 static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
1083 {
1084         struct sh_mobile_ceu_dev *pcdev;
1085         struct resource *res;
1086         void __iomem *base;
1087         unsigned int irq;
1088         int err = 0;
1089
1090         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1091         irq = platform_get_irq(pdev, 0);
1092         if (!res || !irq) {
1093                 dev_err(&pdev->dev, "Not enough CEU platform resources.\n");
1094                 err = -ENODEV;
1095                 goto exit;
1096         }
1097
1098         pcdev = kzalloc(sizeof(*pcdev), GFP_KERNEL);
1099         if (!pcdev) {
1100                 dev_err(&pdev->dev, "Could not allocate pcdev\n");
1101                 err = -ENOMEM;
1102                 goto exit;
1103         }
1104
1105         INIT_LIST_HEAD(&pcdev->capture);
1106         spin_lock_init(&pcdev->lock);
1107
1108         pcdev->pdata = pdev->dev.platform_data;
1109         if (!pcdev->pdata) {
1110                 err = -EINVAL;
1111                 dev_err(&pdev->dev, "CEU platform data not set.\n");
1112                 goto exit_kfree;
1113         }
1114
1115         base = ioremap_nocache(res->start, resource_size(res));
1116         if (!base) {
1117                 err = -ENXIO;
1118                 dev_err(&pdev->dev, "Unable to ioremap CEU registers.\n");
1119                 goto exit_kfree;
1120         }
1121
1122         pcdev->irq = irq;
1123         pcdev->base = base;
1124         pcdev->video_limit = 0; /* only enabled if second resource exists */
1125
1126         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1127         if (res) {
1128                 err = dma_declare_coherent_memory(&pdev->dev, res->start,
1129                                                   res->start,
1130                                                   resource_size(res),
1131                                                   DMA_MEMORY_MAP |
1132                                                   DMA_MEMORY_EXCLUSIVE);
1133                 if (!err) {
1134                         dev_err(&pdev->dev, "Unable to declare CEU memory.\n");
1135                         err = -ENXIO;
1136                         goto exit_iounmap;
1137                 }
1138
1139                 pcdev->video_limit = resource_size(res);
1140         }
1141
1142         /* request irq */
1143         err = request_irq(pcdev->irq, sh_mobile_ceu_irq, IRQF_DISABLED,
1144                           dev_name(&pdev->dev), pcdev);
1145         if (err) {
1146                 dev_err(&pdev->dev, "Unable to register CEU interrupt.\n");
1147                 goto exit_release_mem;
1148         }
1149
1150         pm_suspend_ignore_children(&pdev->dev, true);
1151         pm_runtime_enable(&pdev->dev);
1152         pm_runtime_resume(&pdev->dev);
1153
1154         pcdev->ici.priv = pcdev;
1155         pcdev->ici.v4l2_dev.dev = &pdev->dev;
1156         pcdev->ici.nr = pdev->id;
1157         pcdev->ici.drv_name = dev_name(&pdev->dev);
1158         pcdev->ici.ops = &sh_mobile_ceu_host_ops;
1159
1160         err = soc_camera_host_register(&pcdev->ici);
1161         if (err)
1162                 goto exit_free_irq;
1163
1164         return 0;
1165
1166 exit_free_irq:
1167         free_irq(pcdev->irq, pcdev);
1168 exit_release_mem:
1169         if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
1170                 dma_release_declared_memory(&pdev->dev);
1171 exit_iounmap:
1172         iounmap(base);
1173 exit_kfree:
1174         kfree(pcdev);
1175 exit:
1176         return err;
1177 }
1178
1179 static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
1180 {
1181         struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
1182         struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
1183                                         struct sh_mobile_ceu_dev, ici);
1184
1185         soc_camera_host_unregister(soc_host);
1186         free_irq(pcdev->irq, pcdev);
1187         if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
1188                 dma_release_declared_memory(&pdev->dev);
1189         iounmap(pcdev->base);
1190         kfree(pcdev);
1191         return 0;
1192 }
1193
1194 static int sh_mobile_ceu_runtime_nop(struct device *dev)
1195 {
1196         /* Runtime PM callback shared between ->runtime_suspend()
1197          * and ->runtime_resume(). Simply returns success.
1198          *
1199          * This driver re-initializes all registers after
1200          * pm_runtime_get_sync() anyway so there is no need
1201          * to save and restore registers here.
1202          */
1203         return 0;
1204 }
1205
1206 static struct dev_pm_ops sh_mobile_ceu_dev_pm_ops = {
1207         .runtime_suspend = sh_mobile_ceu_runtime_nop,
1208         .runtime_resume = sh_mobile_ceu_runtime_nop,
1209 };
1210
1211 static struct platform_driver sh_mobile_ceu_driver = {
1212         .driver         = {
1213                 .name   = "sh_mobile_ceu",
1214                 .pm     = &sh_mobile_ceu_dev_pm_ops,
1215         },
1216         .probe          = sh_mobile_ceu_probe,
1217         .remove         = __exit_p(sh_mobile_ceu_remove),
1218 };
1219
1220 static int __init sh_mobile_ceu_init(void)
1221 {
1222         return platform_driver_register(&sh_mobile_ceu_driver);
1223 }
1224
1225 static void __exit sh_mobile_ceu_exit(void)
1226 {
1227         platform_driver_unregister(&sh_mobile_ceu_driver);
1228 }
1229
1230 module_init(sh_mobile_ceu_init);
1231 module_exit(sh_mobile_ceu_exit);
1232
1233 MODULE_DESCRIPTION("SuperH Mobile CEU driver");
1234 MODULE_AUTHOR("Magnus Damm");
1235 MODULE_LICENSE("GPL");
1236 MODULE_ALIAS("platform:sh_mobile_ceu");