~ubuntu-branches/ubuntu/vivid/linux-fsl-imx51/vivid

« back to all changes in this revision

Viewing changes to drivers/media/video/mxc/capture/csi_v4l2_capture.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft, Amit Kucheria, Andy Whitcroft, Bryan Wu, Upstream Kernel Changes
  • Date: 2010-01-11 16:26:27 UTC
  • Revision ID: james.westby@ubuntu.com-20100111162627-1q2fl9tcuwcywt1e
Tags: 2.6.31-602.4
[ Amit Kucheria ]

* Update to official 2.6.31 BSP release from Freescale

[ Andy Whitcroft ]

* drop a number of modules no longer built

[ Bryan Wu ]

* [Config] Update configs after applying .31 patchset from Freescale
* [Config] Sync with imx51_defconfig from Freescale BSP

[ Upstream Kernel Changes ]

* Update to official 2.6.31 BSP release from Freescale.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
 
3
 */
 
4
 
 
5
/*
 
6
 * The code contained herein is licensed under the GNU General Public
 
7
 * License. You may obtain a copy of the GNU General Public License
 
8
 * Version 2 or later at the following locations:
 
9
 *
 
10
 * http://www.opensource.org/licenses/gpl-license.html
 
11
 * http://www.gnu.org/copyleft/gpl.html
 
12
 */
 
13
 
 
14
/*!
 
15
 * @file drivers/media/video/mxc/capture/csi_v4l2_capture.c
 
16
 * This file is derived from mxc_v4l2_capture.c
 
17
 *
 
18
 * @brief MX25 Video For Linux 2 driver
 
19
 *
 
20
 * @ingroup MXC_V4L2_CAPTURE
 
21
 */
 
22
#include <linux/version.h>
 
23
#include <linux/module.h>
 
24
#include <linux/init.h>
 
25
#include <linux/platform_device.h>
 
26
#include <linux/fs.h>
 
27
#include <linux/slab.h>
 
28
#include <linux/ctype.h>
 
29
#include <linux/io.h>
 
30
#include <linux/semaphore.h>
 
31
#include <linux/pagemap.h>
 
32
#include <linux/vmalloc.h>
 
33
#include <linux/types.h>
 
34
#include <linux/fb.h>
 
35
#include <linux/dma-mapping.h>
 
36
#include <media/v4l2-ioctl.h>
 
37
#include <media/v4l2-int-device.h>
 
38
#include <linux/mxcfb.h>
 
39
#include "mxc_v4l2_capture.h"
 
40
#include "fsl_csi.h"
 
41
 
 
42
static int video_nr = -1;
 
43
static cam_data *g_cam;
 
44
 
 
45
static int csi_v4l2_master_attach(struct v4l2_int_device *slave);
 
46
static void csi_v4l2_master_detach(struct v4l2_int_device *slave);
 
47
static u8 camera_power(cam_data *cam, bool cameraOn);
 
48
 
 
49
/*! Information about this driver. */
 
50
static struct v4l2_int_master csi_v4l2_master = {
 
51
        .attach = csi_v4l2_master_attach,
 
52
        .detach = csi_v4l2_master_detach,
 
53
};
 
54
 
 
55
static struct v4l2_int_device csi_v4l2_int_device = {
 
56
        .module = THIS_MODULE,
 
57
        .name = "csi_v4l2_cap",
 
58
        .type = v4l2_int_type_master,
 
59
        .u = {
 
60
              .master = &csi_v4l2_master,
 
61
              },
 
62
};
 
63
 
 
64
/*!
 
65
 * Camera V4l2 callback function.
 
66
 *
 
67
 * @param mask     u32
 
68
 * @param dev      void device structure
 
69
 *
 
70
 * @return none
 
71
 */
 
72
static void camera_callback(u32 mask, void *dev)
 
73
{
 
74
        struct mxc_v4l_frame *done_frame;
 
75
        struct mxc_v4l_frame *ready_frame;
 
76
        cam_data *cam;
 
77
 
 
78
        cam = (cam_data *) dev;
 
79
        if (cam == NULL)
 
80
                return;
 
81
 
 
82
        if (list_empty(&cam->working_q)) {
 
83
                pr_err("ERROR: v4l2 capture: %s: "
 
84
                                "working queue empty\n", __func__);
 
85
                return;
 
86
        }
 
87
 
 
88
        done_frame =
 
89
                list_entry(cam->working_q.next, struct mxc_v4l_frame, queue);
 
90
        if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
 
91
                done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
 
92
                done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
 
93
                if (list_empty(&cam->ready_q)) {
 
94
                        cam->skip_frame++;
 
95
                } else {
 
96
                        ready_frame = list_entry(cam->ready_q.next,
 
97
                                                 struct mxc_v4l_frame, queue);
 
98
                        list_del(cam->ready_q.next);
 
99
                        list_add_tail(&ready_frame->queue, &cam->working_q);
 
100
 
 
101
                        if (cam->ping_pong_csi == 1) {
 
102
                                __raw_writel(cam->frame[ready_frame->index].
 
103
                                             paddress, CSI_CSIDMASA_FB1);
 
104
                        } else {
 
105
                                __raw_writel(cam->frame[ready_frame->index].
 
106
                                             paddress, CSI_CSIDMASA_FB2);
 
107
                        }
 
108
                }
 
109
 
 
110
                /* Added to the done queue */
 
111
                list_del(cam->working_q.next);
 
112
                list_add_tail(&done_frame->queue, &cam->done_q);
 
113
                cam->enc_counter++;
 
114
                wake_up_interruptible(&cam->enc_queue);
 
115
        } else {
 
116
                pr_err("ERROR: v4l2 capture: %s: "
 
117
                                "buffer not queued\n", __func__);
 
118
        }
 
119
 
 
120
        return;
 
121
}
 
122
 
 
123
/*!
 
124
 * Make csi ready for capture image.
 
125
 *
 
126
 * @param cam      structure cam_data *
 
127
 *
 
128
 * @return status 0 success
 
129
 */
 
130
static int csi_cap_image(cam_data *cam)
 
131
{
 
132
        unsigned int value;
 
133
 
 
134
        value = __raw_readl(CSI_CSICR3);
 
135
        __raw_writel(value | BIT_DMA_REFLASH_RFF | BIT_FRMCNT_RST, CSI_CSICR3);
 
136
        value = __raw_readl(CSI_CSISR);
 
137
        __raw_writel(value, CSI_CSISR);
 
138
 
 
139
        return 0;
 
140
}
 
141
 
 
142
/***************************************************************************
 
143
 * Functions for handling Frame buffers.
 
144
 **************************************************************************/
 
145
 
 
146
/*!
 
147
 * Free frame buffers
 
148
 *
 
149
 * @param cam      Structure cam_data *
 
150
 *
 
151
 * @return status  0 success.
 
152
 */
 
153
static int csi_free_frame_buf(cam_data *cam)
 
154
{
 
155
        int i;
 
156
 
 
157
        pr_debug("MVC: In %s\n", __func__);
 
158
 
 
159
        for (i = 0; i < FRAME_NUM; i++) {
 
160
                if (cam->frame[i].vaddress != 0) {
 
161
                        dma_free_coherent(0, cam->frame[i].buffer.length,
 
162
                                             cam->frame[i].vaddress,
 
163
                                             cam->frame[i].paddress);
 
164
                        cam->frame[i].vaddress = 0;
 
165
                }
 
166
        }
 
167
 
 
168
        return 0;
 
169
}
 
170
 
 
171
/*!
 
172
 * Allocate frame buffers
 
173
 *
 
174
 * @param cam      Structure cam_data *
 
175
 * @param count    int number of buffer need to allocated
 
176
 *
 
177
 * @return status  -0 Successfully allocated a buffer, -ENOBUFS failed.
 
178
 */
 
179
static int csi_allocate_frame_buf(cam_data *cam, int count)
 
180
{
 
181
        int i;
 
182
 
 
183
        pr_debug("In MVC:%s- size=%d\n",
 
184
                 __func__, cam->v2f.fmt.pix.sizeimage);
 
185
        for (i = 0; i < count; i++) {
 
186
                cam->frame[i].vaddress = dma_alloc_coherent(0, PAGE_ALIGN
 
187
                                                               (cam->v2f.fmt.
 
188
                                                               pix.sizeimage),
 
189
                                                               &cam->frame[i].
 
190
                                                               paddress,
 
191
                                                               GFP_DMA |
 
192
                                                               GFP_KERNEL);
 
193
                if (cam->frame[i].vaddress == 0) {
 
194
                        pr_err("ERROR: v4l2 capture: "
 
195
                               "%s failed.\n", __func__);
 
196
                        csi_free_frame_buf(cam);
 
197
                        return -ENOBUFS;
 
198
                }
 
199
                cam->frame[i].buffer.index = i;
 
200
                cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
 
201
                cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
202
                cam->frame[i].buffer.length = PAGE_ALIGN(cam->v2f.fmt.
 
203
                                                         pix.sizeimage);
 
204
                cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
 
205
                cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
 
206
                cam->frame[i].index = i;
 
207
        }
 
208
 
 
209
        return 0;
 
210
}
 
211
 
 
212
/*!
 
213
 * Free frame buffers status
 
214
 *
 
215
 * @param cam    Structure cam_data *
 
216
 *
 
217
 * @return none
 
218
 */
 
219
static void csi_free_frames(cam_data *cam)
 
220
{
 
221
        int i;
 
222
 
 
223
        pr_debug("In MVC: %s\n", __func__);
 
224
 
 
225
        for (i = 0; i < FRAME_NUM; i++)
 
226
                cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
 
227
 
 
228
        cam->skip_frame = 0;
 
229
        INIT_LIST_HEAD(&cam->ready_q);
 
230
        INIT_LIST_HEAD(&cam->working_q);
 
231
        INIT_LIST_HEAD(&cam->done_q);
 
232
 
 
233
        return;
 
234
}
 
235
 
 
236
/*!
 
237
 * Return the buffer status
 
238
 *
 
239
 * @param cam      Structure cam_data *
 
240
 * @param buf      Structure v4l2_buffer *
 
241
 *
 
242
 * @return status  0 success, EINVAL failed.
 
243
 */
 
244
static int csi_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
 
245
{
 
246
        pr_debug("In MVC: %s\n", __func__);
 
247
 
 
248
        if (buf->index < 0 || buf->index >= FRAME_NUM) {
 
249
                pr_err("ERROR: v4l2 capture: %s buffers "
 
250
                                "not allocated\n", __func__);
 
251
                return -EINVAL;
 
252
        }
 
253
 
 
254
        memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
 
255
 
 
256
        return 0;
 
257
}
 
258
 
 
259
/*!
 
260
 * Indicates whether the palette is supported.
 
261
 *
 
262
 * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_UYVY or V4L2_PIX_FMT_YUV420
 
263
 *
 
264
 * @return 0 if failed
 
265
 */
 
266
static inline int valid_mode(u32 palette)
 
267
{
 
268
        return (palette == V4L2_PIX_FMT_RGB565) ||
 
269
            (palette == V4L2_PIX_FMT_UYVY) || (palette == V4L2_PIX_FMT_YUV420);
 
270
}
 
271
 
 
272
/*!
 
273
 * Start stream I/O
 
274
 *
 
275
 * @param cam      structure cam_data *
 
276
 *
 
277
 * @return status  0 Success
 
278
 */
 
279
static int csi_streamon(cam_data *cam)
 
280
{
 
281
        struct mxc_v4l_frame *frame;
 
282
 
 
283
        pr_debug("In MVC: %s\n", __func__);
 
284
 
 
285
        if (NULL == cam) {
 
286
                pr_err("ERROR: v4l2 capture: %s cam parameter is NULL\n",
 
287
                                __func__);
 
288
                return -1;
 
289
        }
 
290
 
 
291
        /* move the frame from readyq to workingq */
 
292
        if (list_empty(&cam->ready_q)) {
 
293
                pr_err("ERROR: v4l2 capture: %s: "
 
294
                                "ready_q queue empty\n", __func__);
 
295
                return -1;
 
296
        }
 
297
        frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
 
298
        list_del(cam->ready_q.next);
 
299
        list_add_tail(&frame->queue, &cam->working_q);
 
300
        __raw_writel(cam->frame[frame->index].paddress, CSI_CSIDMASA_FB1);
 
301
 
 
302
        if (list_empty(&cam->ready_q)) {
 
303
                pr_err("ERROR: v4l2 capture: %s: "
 
304
                                "ready_q queue empty\n", __func__);
 
305
                return -1;
 
306
        }
 
307
        frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
 
308
        list_del(cam->ready_q.next);
 
309
        list_add_tail(&frame->queue, &cam->working_q);
 
310
        __raw_writel(cam->frame[frame->index].paddress, CSI_CSIDMASA_FB2);
 
311
 
 
312
        cam->capture_pid = current->pid;
 
313
        cam->capture_on = true;
 
314
        csi_cap_image(cam);
 
315
        csi_enable_int(1);
 
316
 
 
317
        return 0;
 
318
}
 
319
 
 
320
/*!
 
321
 * Stop stream I/O
 
322
 *
 
323
 * @param cam      structure cam_data *
 
324
 *
 
325
 * @return status  0 Success
 
326
 */
 
327
static int csi_streamoff(cam_data *cam)
 
328
{
 
329
        unsigned int cr3;
 
330
 
 
331
        pr_debug("In MVC: %s\n", __func__);
 
332
 
 
333
        if (cam->capture_on == false)
 
334
                return 0;
 
335
 
 
336
        csi_disable_int();
 
337
        cam->capture_on = false;
 
338
 
 
339
        /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
 
340
        __raw_writel(0, CSI_CSIDMASA_FB1);
 
341
        __raw_writel(0, CSI_CSIDMASA_FB2);
 
342
        cr3 = __raw_readl(CSI_CSICR3);
 
343
        __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
 
344
 
 
345
        csi_free_frames(cam);
 
346
        csi_free_frame_buf(cam);
 
347
 
 
348
        return 0;
 
349
}
 
350
 
 
351
/*!
 
352
 * start the viewfinder job
 
353
 *
 
354
 * @param cam      structure cam_data *
 
355
 *
 
356
 * @return status  0 Success
 
357
 */
 
358
static int start_preview(cam_data *cam)
 
359
{
 
360
        unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base;
 
361
 
 
362
        __raw_writel(fb_addr, CSI_CSIDMASA_FB1);
 
363
        __raw_writel(fb_addr, CSI_CSIDMASA_FB2);
 
364
        __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
 
365
 
 
366
        csi_enable_int(0);
 
367
 
 
368
        return 0;
 
369
}
 
370
 
 
371
/*!
 
372
 * shut down the viewfinder job
 
373
 *
 
374
 * @param cam      structure cam_data *
 
375
 *
 
376
 * @return status  0 Success
 
377
 */
 
378
static int stop_preview(cam_data *cam)
 
379
{
 
380
        csi_disable_int();
 
381
 
 
382
        /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
 
383
        __raw_writel(0, CSI_CSIDMASA_FB1);
 
384
        __raw_writel(0, CSI_CSIDMASA_FB2);
 
385
        __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3);
 
386
 
 
387
        return 0;
 
388
}
 
389
 
 
390
/***************************************************************************
 
391
 * VIDIOC Functions.
 
392
 **************************************************************************/
 
393
 
 
394
/*!
 
395
 *
 
396
 * @param cam         structure cam_data *
 
397
 *
 
398
 * @param f           structure v4l2_format *
 
399
 *
 
400
 * @return  status    0 success, EINVAL failed
 
401
 */
 
402
static int csi_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
 
403
{
 
404
        int retval = 0;
 
405
 
 
406
        switch (f->type) {
 
407
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 
408
                pr_debug("   type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
 
409
                f->fmt.pix = cam->v2f.fmt.pix;
 
410
                break;
 
411
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 
412
                pr_debug("   type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
 
413
                f->fmt.win = cam->win;
 
414
                break;
 
415
        default:
 
416
                pr_debug("   type is invalid\n");
 
417
                retval = -EINVAL;
 
418
        }
 
419
 
 
420
        pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
 
421
                 __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
 
422
 
 
423
        return retval;
 
424
}
 
425
 
 
426
/*!
 
427
 * V4L2 - csi_v4l2_s_fmt function
 
428
 *
 
429
 * @param cam         structure cam_data *
 
430
 *
 
431
 * @param f           structure v4l2_format *
 
432
 *
 
433
 * @return  status    0 success, EINVAL failed
 
434
 */
 
435
static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
 
436
{
 
437
        int retval = 0;
 
438
        int size = 0;
 
439
        int bytesperline = 0;
 
440
        int *width, *height;
 
441
 
 
442
        pr_debug("In MVC: %s\n", __func__);
 
443
 
 
444
        switch (f->type) {
 
445
        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 
446
                pr_debug("   type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
 
447
                if (!valid_mode(f->fmt.pix.pixelformat)) {
 
448
                        pr_err("ERROR: v4l2 capture: %s: format "
 
449
                               "not supported\n", __func__);
 
450
                        return -EINVAL;
 
451
                }
 
452
 
 
453
                /* Handle case where size requested is larger than cuurent
 
454
                 * camera setting. */
 
455
                if ((f->fmt.pix.width > cam->crop_bounds.width)
 
456
                    || (f->fmt.pix.height > cam->crop_bounds.height)) {
 
457
                        /* Need the logic here, calling vidioc_s_param if
 
458
                         * camera can change. */
 
459
                        pr_debug("csi_v4l2_s_fmt size changed\n");
 
460
                }
 
461
                if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
 
462
                        height = &f->fmt.pix.width;
 
463
                        width = &f->fmt.pix.height;
 
464
                } else {
 
465
                        width = &f->fmt.pix.width;
 
466
                        height = &f->fmt.pix.height;
 
467
                }
 
468
 
 
469
                if ((cam->crop_bounds.width / *width > 8) ||
 
470
                    ((cam->crop_bounds.width / *width == 8) &&
 
471
                     (cam->crop_bounds.width % *width))) {
 
472
                        *width = cam->crop_bounds.width / 8;
 
473
                        if (*width % 8)
 
474
                                *width += 8 - *width % 8;
 
475
                        pr_err("ERROR: v4l2 capture: width exceeds limit "
 
476
                               "resize to %d.\n", *width);
 
477
                }
 
478
 
 
479
                if ((cam->crop_bounds.height / *height > 8) ||
 
480
                    ((cam->crop_bounds.height / *height == 8) &&
 
481
                     (cam->crop_bounds.height % *height))) {
 
482
                        *height = cam->crop_bounds.height / 8;
 
483
                        if (*height % 8)
 
484
                                *height += 8 - *height % 8;
 
485
                        pr_err("ERROR: v4l2 capture: height exceeds limit "
 
486
                               "resize to %d.\n", *height);
 
487
                }
 
488
 
 
489
                switch (f->fmt.pix.pixelformat) {
 
490
                case V4L2_PIX_FMT_RGB565:
 
491
                        size = f->fmt.pix.width * f->fmt.pix.height * 2;
 
492
                        csi_set_16bit_imagpara(f->fmt.pix.width,
 
493
                                               f->fmt.pix.height);
 
494
                        bytesperline = f->fmt.pix.width * 2;
 
495
                        break;
 
496
                case V4L2_PIX_FMT_UYVY:
 
497
                        size = f->fmt.pix.width * f->fmt.pix.height * 2;
 
498
                        csi_set_16bit_imagpara(f->fmt.pix.width,
 
499
                                               f->fmt.pix.height);
 
500
                        bytesperline = f->fmt.pix.width * 2;
 
501
                        break;
 
502
                case V4L2_PIX_FMT_YUV420:
 
503
                        size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
 
504
                        csi_set_12bit_imagpara(f->fmt.pix.width,
 
505
                                               f->fmt.pix.height);
 
506
                        bytesperline = f->fmt.pix.width;
 
507
                        break;
 
508
                case V4L2_PIX_FMT_YUV422P:
 
509
                case V4L2_PIX_FMT_RGB24:
 
510
                case V4L2_PIX_FMT_BGR24:
 
511
                case V4L2_PIX_FMT_BGR32:
 
512
                case V4L2_PIX_FMT_RGB32:
 
513
                case V4L2_PIX_FMT_NV12:
 
514
                default:
 
515
                        pr_debug("   case not supported\n");
 
516
                        break;
 
517
                }
 
518
 
 
519
                if (f->fmt.pix.bytesperline < bytesperline)
 
520
                        f->fmt.pix.bytesperline = bytesperline;
 
521
                else
 
522
                        bytesperline = f->fmt.pix.bytesperline;
 
523
 
 
524
                if (f->fmt.pix.sizeimage < size)
 
525
                        f->fmt.pix.sizeimage = size;
 
526
                else
 
527
                        size = f->fmt.pix.sizeimage;
 
528
 
 
529
                cam->v2f.fmt.pix = f->fmt.pix;
 
530
 
 
531
                if (cam->v2f.fmt.pix.priv != 0) {
 
532
                        if (copy_from_user(&cam->offset,
 
533
                                           (void *)cam->v2f.fmt.pix.priv,
 
534
                                           sizeof(cam->offset))) {
 
535
                                retval = -EFAULT;
 
536
                                break;
 
537
                        }
 
538
                }
 
539
                break;
 
540
        case V4L2_BUF_TYPE_VIDEO_OVERLAY:
 
541
                pr_debug("   type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
 
542
                cam->win = f->fmt.win;
 
543
                break;
 
544
        default:
 
545
                retval = -EINVAL;
 
546
        }
 
547
 
 
548
        pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
 
549
                 __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
 
550
 
 
551
        return retval;
 
552
}
 
553
 
 
554
/*!
 
555
 * V4L2 - csi_v4l2_s_param function
 
556
 * Allows setting of capturemode and frame rate.
 
557
 *
 
558
 * @param cam         structure cam_data *
 
559
 * @param parm        structure v4l2_streamparm *
 
560
 *
 
561
 * @return  status    0 success, EINVAL failed
 
562
 */
 
563
static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
 
564
{
 
565
        struct v4l2_ifparm ifparm;
 
566
        struct v4l2_format cam_fmt;
 
567
        struct v4l2_streamparm currentparm;
 
568
        int err = 0;
 
569
 
 
570
        pr_debug("In %s\n", __func__);
 
571
 
 
572
        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 
573
                pr_err(KERN_ERR "%s invalid type\n", __func__);
 
574
                return -EINVAL;
 
575
        }
 
576
 
 
577
        /* Stop the viewfinder */
 
578
        if (cam->overlay_on == true)
 
579
                stop_preview(cam);
 
580
 
 
581
        currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
582
 
 
583
        /* First check that this device can support the changes requested. */
 
584
        err = vidioc_int_g_parm(cam->sensor, &currentparm);
 
585
        if (err) {
 
586
                pr_err("%s: vidioc_int_g_parm returned an error %d\n",
 
587
                       __func__, err);
 
588
                goto exit;
 
589
        }
 
590
 
 
591
        pr_debug("   Current capabilities are %x\n",
 
592
                 currentparm.parm.capture.capability);
 
593
        pr_debug("   Current capturemode is %d  change to %d\n",
 
594
                 currentparm.parm.capture.capturemode,
 
595
                 parm->parm.capture.capturemode);
 
596
        pr_debug("   Current framerate is %d  change to %d\n",
 
597
                 currentparm.parm.capture.timeperframe.denominator,
 
598
                 parm->parm.capture.timeperframe.denominator);
 
599
 
 
600
        err = vidioc_int_s_parm(cam->sensor, parm);
 
601
        if (err) {
 
602
                pr_err("%s: vidioc_int_s_parm returned an error %d\n",
 
603
                       __func__, err);
 
604
                goto exit;
 
605
        }
 
606
 
 
607
        vidioc_int_g_ifparm(cam->sensor, &ifparm);
 
608
        cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
609
        pr_debug("   g_fmt_cap returns widthxheight of input as %d x %d\n",
 
610
                 cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
 
611
 
 
612
exit:
 
613
        return err;
 
614
}
 
615
 
 
616
/*!
 
617
 * Dequeue one V4L capture buffer
 
618
 *
 
619
 * @param cam         structure cam_data *
 
620
 * @param buf         structure v4l2_buffer *
 
621
 *
 
622
 * @return  status    0 success, EINVAL invalid frame number
 
623
 *                    ETIME timeout, ERESTARTSYS interrupted by user
 
624
 */
 
625
static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
 
626
{
 
627
        int retval = 0;
 
628
        struct mxc_v4l_frame *frame;
 
629
 
 
630
        if (!wait_event_interruptible_timeout(cam->enc_queue,
 
631
                                cam->enc_counter != 0, 10 * HZ)) {
 
632
                pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
 
633
                        "enc_counter %x\n", cam->enc_counter);
 
634
                return -ETIME;
 
635
        } else if (signal_pending(current)) {
 
636
                pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
 
637
                                "interrupt received\n");
 
638
                return -ERESTARTSYS;
 
639
        }
 
640
 
 
641
        cam->enc_counter--;
 
642
 
 
643
        frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
 
644
        list_del(cam->done_q.next);
 
645
 
 
646
        if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
 
647
                frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
 
648
        } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
 
649
                pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
 
650
                        "Buffer not filled.\n");
 
651
                frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
 
652
                retval = -EINVAL;
 
653
        } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
 
654
                pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
 
655
                        "Buffer not queued.\n");
 
656
                retval = -EINVAL;
 
657
        }
 
658
 
 
659
        buf->bytesused = cam->v2f.fmt.pix.sizeimage;
 
660
        buf->index = frame->index;
 
661
        buf->flags = frame->buffer.flags;
 
662
        buf->m = cam->frame[frame->index].buffer.m;
 
663
 
 
664
        return retval;
 
665
}
 
666
 
 
667
/*!
 
668
 * V4L interface - open function
 
669
 *
 
670
 * @param file         structure file *
 
671
 *
 
672
 * @return  status    0 success, ENODEV invalid device instance,
 
673
 *                    ENODEV timeout, ERESTARTSYS interrupted by user
 
674
 */
 
675
static int csi_v4l_open(struct file *file)
 
676
{
 
677
        struct v4l2_ifparm ifparm;
 
678
        struct v4l2_format cam_fmt;
 
679
        struct video_device *dev = video_devdata(file);
 
680
        cam_data *cam = video_get_drvdata(dev);
 
681
        int err = 0;
 
682
 
 
683
        pr_debug("   device name is %s\n", dev->name);
 
684
 
 
685
        if (!cam) {
 
686
                pr_err("ERROR: v4l2 capture: Internal error, "
 
687
                       "cam_data not found!\n");
 
688
                return -EBADF;
 
689
        }
 
690
 
 
691
        down(&cam->busy_lock);
 
692
        err = 0;
 
693
        if (signal_pending(current))
 
694
                goto oops;
 
695
 
 
696
        if (cam->open_count++ == 0) {
 
697
                wait_event_interruptible(cam->power_queue,
 
698
                                         cam->low_power == false);
 
699
 
 
700
                cam->enc_counter = 0;
 
701
                cam->skip_frame = 0;
 
702
                INIT_LIST_HEAD(&cam->ready_q);
 
703
                INIT_LIST_HEAD(&cam->working_q);
 
704
                INIT_LIST_HEAD(&cam->done_q);
 
705
 
 
706
                vidioc_int_g_ifparm(cam->sensor, &ifparm);
 
707
 
 
708
                cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
709
                csi_enable_mclk(CSI_MCLK_I2C, true, true);
 
710
                vidioc_int_init(cam->sensor);
 
711
        }
 
712
 
 
713
        file->private_data = dev;
 
714
 
 
715
oops:
 
716
        up(&cam->busy_lock);
 
717
        return err;
 
718
}
 
719
 
 
720
/*!
 
721
 * V4L interface - close function
 
722
 *
 
723
 * @param file     struct file *
 
724
 *
 
725
 * @return         0 success
 
726
 */
 
727
static int csi_v4l_close(struct file *file)
 
728
{
 
729
        struct video_device *dev = video_devdata(file);
 
730
        int err = 0;
 
731
        cam_data *cam = video_get_drvdata(dev);
 
732
 
 
733
        pr_debug("In MVC:%s\n", __func__);
 
734
 
 
735
        if (!cam) {
 
736
                pr_err("ERROR: v4l2 capture: Internal error, "
 
737
                       "cam_data not found!\n");
 
738
                return -EBADF;
 
739
        }
 
740
 
 
741
        /* for the case somebody hit the ctrl C */
 
742
        if (cam->overlay_pid == current->pid) {
 
743
                err = stop_preview(cam);
 
744
                cam->overlay_on = false;
 
745
        }
 
746
 
 
747
        if (--cam->open_count == 0) {
 
748
                wait_event_interruptible(cam->power_queue,
 
749
                                         cam->low_power == false);
 
750
                file->private_data = NULL;
 
751
                csi_enable_mclk(CSI_MCLK_I2C, false, false);
 
752
        }
 
753
 
 
754
        return err;
 
755
}
 
756
 
 
757
/*
 
758
 * V4L interface - read function
 
759
 *
 
760
 * @param file       struct file *
 
761
 * @param read buf   char *
 
762
 * @param count      size_t
 
763
 * @param ppos       structure loff_t *
 
764
 *
 
765
 * @return           bytes read
 
766
 */
 
767
static ssize_t csi_v4l_read(struct file *file, char *buf, size_t count,
 
768
                            loff_t *ppos)
 
769
{
 
770
        int err = 0;
 
771
        struct video_device *dev = video_devdata(file);
 
772
        cam_data *cam = video_get_drvdata(dev);
 
773
 
 
774
        if (down_interruptible(&cam->busy_lock))
 
775
                return -EINTR;
 
776
 
 
777
        /* Stop the viewfinder */
 
778
        if (cam->overlay_on == true)
 
779
                stop_preview(cam);
 
780
 
 
781
        if (cam->still_buf_vaddr == NULL) {
 
782
                cam->still_buf_vaddr = dma_alloc_coherent(0,
 
783
                                                          PAGE_ALIGN
 
784
                                                          (cam->v2f.fmt.
 
785
                                                           pix.sizeimage),
 
786
                                                          &cam->
 
787
                                                          still_buf,
 
788
                                                          GFP_DMA | GFP_KERNEL);
 
789
                if (cam->still_buf_vaddr == NULL) {
 
790
                        pr_err("alloc dma memory failed\n");
 
791
                        return -ENOMEM;
 
792
                }
 
793
                cam->still_counter = 0;
 
794
                __raw_writel(cam->still_buf, CSI_CSIDMASA_FB2);
 
795
                __raw_writel(cam->still_buf, CSI_CSIDMASA_FB1);
 
796
                __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
 
797
                             CSI_CSICR3);
 
798
                __raw_writel(__raw_readl(CSI_CSISR), CSI_CSISR);
 
799
                __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST,
 
800
                             CSI_CSICR3);
 
801
                csi_enable_int(1);
 
802
        }
 
803
 
 
804
        wait_event_interruptible(cam->still_queue, cam->still_counter);
 
805
        csi_disable_int();
 
806
        err = copy_to_user(buf, cam->still_buf_vaddr,
 
807
                           cam->v2f.fmt.pix.sizeimage);
 
808
 
 
809
        if (cam->still_buf_vaddr != NULL) {
 
810
                dma_free_coherent(0, PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
 
811
                                  cam->still_buf_vaddr, cam->still_buf);
 
812
                cam->still_buf = 0;
 
813
                cam->still_buf_vaddr = NULL;
 
814
        }
 
815
 
 
816
        if (cam->overlay_on == true)
 
817
                start_preview(cam);
 
818
 
 
819
        up(&cam->busy_lock);
 
820
        if (err < 0)
 
821
                return err;
 
822
 
 
823
        return cam->v2f.fmt.pix.sizeimage - err;
 
824
}
 
825
 
 
826
/*!
 
827
 * V4L interface - ioctl function
 
828
 *
 
829
 * @param file       struct file*
 
830
 *
 
831
 * @param ioctlnr    unsigned int
 
832
 *
 
833
 * @param arg        void*
 
834
 *
 
835
 * @return           0 success, ENODEV for invalid device instance,
 
836
 *                   -1 for other errors.
 
837
 */
 
838
static long csi_v4l_do_ioctl(struct file *file,
 
839
                            unsigned int ioctlnr, void *arg)
 
840
{
 
841
        struct video_device *dev = video_devdata(file);
 
842
        cam_data *cam = video_get_drvdata(dev);
 
843
        int retval = 0;
 
844
        unsigned long lock_flags;
 
845
 
 
846
        pr_debug("In MVC: %s, %x\n", __func__, ioctlnr);
 
847
        wait_event_interruptible(cam->power_queue, cam->low_power == false);
 
848
        /* make this _really_ smp-safe */
 
849
        if (down_interruptible(&cam->busy_lock))
 
850
                return -EBUSY;
 
851
 
 
852
        switch (ioctlnr) {
 
853
                /*!
 
854
                 * V4l2 VIDIOC_G_FMT ioctl
 
855
                 */
 
856
        case VIDIOC_G_FMT:{
 
857
                        struct v4l2_format *gf = arg;
 
858
                        pr_debug("   case VIDIOC_G_FMT\n");
 
859
                        retval = csi_v4l2_g_fmt(cam, gf);
 
860
                        break;
 
861
                }
 
862
 
 
863
                /*!
 
864
                 * V4l2 VIDIOC_S_FMT ioctl
 
865
                 */
 
866
        case VIDIOC_S_FMT:{
 
867
                        struct v4l2_format *sf = arg;
 
868
                        pr_debug("   case VIDIOC_S_FMT\n");
 
869
                        retval = csi_v4l2_s_fmt(cam, sf);
 
870
                        vidioc_int_s_fmt_cap(cam->sensor, sf);
 
871
                        break;
 
872
                }
 
873
 
 
874
                /*!
 
875
                 * V4l2 VIDIOC_OVERLAY ioctl
 
876
                 */
 
877
        case VIDIOC_OVERLAY:{
 
878
                        int *on = arg;
 
879
                        pr_debug("   case VIDIOC_OVERLAY\n");
 
880
                        if (*on) {
 
881
                                cam->overlay_on = true;
 
882
                                cam->overlay_pid = current->pid;
 
883
                                start_preview(cam);
 
884
                        }
 
885
                        if (!*on) {
 
886
                                stop_preview(cam);
 
887
                                cam->overlay_on = false;
 
888
                        }
 
889
                        break;
 
890
                }
 
891
 
 
892
                /*!
 
893
                 * V4l2 VIDIOC_G_FBUF ioctl
 
894
                 */
 
895
        case VIDIOC_G_FBUF:{
 
896
                        struct v4l2_framebuffer *fb = arg;
 
897
                        *fb = cam->v4l2_fb;
 
898
                        fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
 
899
                        break;
 
900
                }
 
901
 
 
902
                /*!
 
903
                 * V4l2 VIDIOC_S_FBUF ioctl
 
904
                 */
 
905
        case VIDIOC_S_FBUF:{
 
906
                        struct v4l2_framebuffer *fb = arg;
 
907
                        cam->v4l2_fb = *fb;
 
908
                        break;
 
909
                }
 
910
 
 
911
        case VIDIOC_G_PARM:{
 
912
                        struct v4l2_streamparm *parm = arg;
 
913
                        pr_debug("   case VIDIOC_G_PARM\n");
 
914
                        vidioc_int_g_parm(cam->sensor, parm);
 
915
                        break;
 
916
                }
 
917
 
 
918
        case VIDIOC_S_PARM:{
 
919
                        struct v4l2_streamparm *parm = arg;
 
920
                        pr_debug("   case VIDIOC_S_PARM\n");
 
921
                        retval = csi_v4l2_s_param(cam, parm);
 
922
                        break;
 
923
                }
 
924
 
 
925
        case VIDIOC_QUERYCAP:{
 
926
                        struct v4l2_capability *cap = arg;
 
927
                        pr_debug("   case VIDIOC_QUERYCAP\n");
 
928
                        strcpy(cap->driver, "csi_v4l2");
 
929
                        cap->version = KERNEL_VERSION(0, 1, 11);
 
930
                        cap->capabilities = V4L2_CAP_VIDEO_OVERLAY |
 
931
                            V4L2_CAP_VIDEO_OUTPUT_OVERLAY | V4L2_CAP_READWRITE;
 
932
                        cap->card[0] = '\0';
 
933
                        cap->bus_info[0] = '\0';
 
934
                        break;
 
935
                }
 
936
 
 
937
        case VIDIOC_S_CROP:
 
938
                pr_debug("   case not supported\n");
 
939
                break;
 
940
 
 
941
        case VIDIOC_REQBUFS: {
 
942
                struct v4l2_requestbuffers *req = arg;
 
943
                pr_debug("   case VIDIOC_REQBUFS\n");
 
944
 
 
945
                if (req->count > FRAME_NUM) {
 
946
                        pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
 
947
                                        "not enough buffers\n");
 
948
                        req->count = FRAME_NUM;
 
949
                }
 
950
 
 
951
                if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
 
952
                                (req->memory != V4L2_MEMORY_MMAP)) {
 
953
                        pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
 
954
                                        "wrong buffer type\n");
 
955
                        retval = -EINVAL;
 
956
                        break;
 
957
                }
 
958
 
 
959
                csi_streamoff(cam);
 
960
                csi_free_frame_buf(cam);
 
961
                cam->skip_frame = 0;
 
962
                INIT_LIST_HEAD(&cam->ready_q);
 
963
                INIT_LIST_HEAD(&cam->working_q);
 
964
                INIT_LIST_HEAD(&cam->done_q);
 
965
                retval = csi_allocate_frame_buf(cam, req->count);
 
966
                break;
 
967
        }
 
968
 
 
969
        case VIDIOC_QUERYBUF: {
 
970
                struct v4l2_buffer *buf = arg;
 
971
                int index = buf->index;
 
972
                pr_debug("   case VIDIOC_QUERYBUF\n");
 
973
 
 
974
                if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 
975
                        retval = -EINVAL;
 
976
                        break;
 
977
                }
 
978
 
 
979
                memset(buf, 0, sizeof(buf));
 
980
                buf->index = index;
 
981
                retval = csi_v4l2_buffer_status(cam, buf);
 
982
                break;
 
983
        }
 
984
 
 
985
        case VIDIOC_QBUF: {
 
986
                struct v4l2_buffer *buf = arg;
 
987
                int index = buf->index;
 
988
                pr_debug("   case VIDIOC_QBUF\n");
 
989
 
 
990
                spin_lock_irqsave(&cam->int_lock, lock_flags);
 
991
                cam->frame[index].buffer.m.offset = buf->m.offset;
 
992
                if ((cam->frame[index].buffer.flags & 0x7) ==
 
993
                                V4L2_BUF_FLAG_MAPPED) {
 
994
                        cam->frame[index].buffer.flags |= V4L2_BUF_FLAG_QUEUED;
 
995
                        if (cam->skip_frame > 0) {
 
996
                                list_add_tail(&cam->frame[index].queue,
 
997
                                              &cam->working_q);
 
998
                                cam->skip_frame = 0;
 
999
 
 
1000
                                if (cam->ping_pong_csi == 1) {
 
1001
                                        __raw_writel(cam->frame[index].paddress,
 
1002
                                                     CSI_CSIDMASA_FB1);
 
1003
                                } else {
 
1004
                                        __raw_writel(cam->frame[index].paddress,
 
1005
                                                     CSI_CSIDMASA_FB2);
 
1006
                                }
 
1007
                        } else {
 
1008
                                list_add_tail(&cam->frame[index].queue,
 
1009
                                              &cam->ready_q);
 
1010
                        }
 
1011
                } else if (cam->frame[index].buffer.flags &
 
1012
                                V4L2_BUF_FLAG_QUEUED) {
 
1013
                        pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
 
1014
                                        "buffer already queued\n");
 
1015
                        retval = -EINVAL;
 
1016
                } else if (cam->frame[index].buffer.
 
1017
                           flags & V4L2_BUF_FLAG_DONE) {
 
1018
                        pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
 
1019
                               "overwrite done buffer.\n");
 
1020
                        cam->frame[index].buffer.flags &=
 
1021
                            ~V4L2_BUF_FLAG_DONE;
 
1022
                        cam->frame[index].buffer.flags |=
 
1023
                            V4L2_BUF_FLAG_QUEUED;
 
1024
                        retval = -EINVAL;
 
1025
                }
 
1026
                buf->flags = cam->frame[index].buffer.flags;
 
1027
                spin_unlock_irqrestore(&cam->int_lock, lock_flags);
 
1028
 
 
1029
                break;
 
1030
        }
 
1031
 
 
1032
        case VIDIOC_DQBUF: {
 
1033
                struct v4l2_buffer *buf = arg;
 
1034
                pr_debug("   case VIDIOC_DQBUF\n");
 
1035
 
 
1036
                retval = csi_v4l_dqueue(cam, buf);
 
1037
 
 
1038
                break;
 
1039
        }
 
1040
 
 
1041
        case VIDIOC_STREAMON: {
 
1042
                pr_debug("   case VIDIOC_STREAMON\n");
 
1043
                retval = csi_streamon(cam);
 
1044
                break;
 
1045
        }
 
1046
 
 
1047
        case VIDIOC_STREAMOFF: {
 
1048
                pr_debug("   case VIDIOC_STREAMOFF\n");
 
1049
                retval = csi_streamoff(cam);
 
1050
                break;
 
1051
        }
 
1052
 
 
1053
        case VIDIOC_S_CTRL:
 
1054
        case VIDIOC_G_STD:
 
1055
        case VIDIOC_G_OUTPUT:
 
1056
        case VIDIOC_S_OUTPUT:
 
1057
        case VIDIOC_ENUMSTD:
 
1058
        case VIDIOC_G_CROP:
 
1059
        case VIDIOC_CROPCAP:
 
1060
        case VIDIOC_S_STD:
 
1061
        case VIDIOC_G_CTRL:
 
1062
        case VIDIOC_ENUM_FMT:
 
1063
        case VIDIOC_TRY_FMT:
 
1064
        case VIDIOC_QUERYCTRL:
 
1065
        case VIDIOC_ENUMINPUT:
 
1066
        case VIDIOC_G_INPUT:
 
1067
        case VIDIOC_S_INPUT:
 
1068
        case VIDIOC_G_TUNER:
 
1069
        case VIDIOC_S_TUNER:
 
1070
        case VIDIOC_G_FREQUENCY:
 
1071
        case VIDIOC_S_FREQUENCY:
 
1072
        case VIDIOC_ENUMOUTPUT:
 
1073
        default:
 
1074
                pr_debug("   case not supported\n");
 
1075
                retval = -EINVAL;
 
1076
                break;
 
1077
        }
 
1078
 
 
1079
        up(&cam->busy_lock);
 
1080
        return retval;
 
1081
}
 
1082
 
 
1083
/*
 
1084
 * V4L interface - ioctl function
 
1085
 *
 
1086
 * @return  None
 
1087
 */
 
1088
static long csi_v4l_ioctl(struct file *file,
 
1089
                         unsigned int cmd, unsigned long arg)
 
1090
{
 
1091
        return video_usercopy(file, cmd, arg, csi_v4l_do_ioctl);
 
1092
}
 
1093
 
 
1094
/*!
 
1095
 * V4L interface - mmap function
 
1096
 *
 
1097
 * @param file        structure file *
 
1098
 *
 
1099
 * @param vma         structure vm_area_struct *
 
1100
 *
 
1101
 * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error
 
1102
 */
 
1103
static int csi_mmap(struct file *file, struct vm_area_struct *vma)
 
1104
{
 
1105
        struct video_device *dev = video_devdata(file);
 
1106
        unsigned long size;
 
1107
        int res = 0;
 
1108
        cam_data *cam = video_get_drvdata(dev);
 
1109
 
 
1110
        pr_debug("%s\n", __func__);
 
1111
        pr_debug("\npgoff=0x%lx, start=0x%lx, end=0x%lx\n",
 
1112
                 vma->vm_pgoff, vma->vm_start, vma->vm_end);
 
1113
 
 
1114
        /* make this _really_ smp-safe */
 
1115
        if (down_interruptible(&cam->busy_lock))
 
1116
                return -EINTR;
 
1117
 
 
1118
        size = vma->vm_end - vma->vm_start;
 
1119
        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
 
1120
 
 
1121
        if (remap_pfn_range(vma, vma->vm_start,
 
1122
                            vma->vm_pgoff, size, vma->vm_page_prot)) {
 
1123
                pr_err("ERROR: v4l2 capture: %s : "
 
1124
                       "remap_pfn_range failed\n", __func__);
 
1125
                res = -ENOBUFS;
 
1126
                goto csi_mmap_exit;
 
1127
        }
 
1128
 
 
1129
        vma->vm_flags &= ~VM_IO;        /* using shared anonymous pages */
 
1130
 
 
1131
csi_mmap_exit:
 
1132
        up(&cam->busy_lock);
 
1133
        return res;
 
1134
}
 
1135
 
 
1136
/*!
 
1137
 * This structure defines the functions to be called in this driver.
 
1138
 */
 
1139
static struct v4l2_file_operations csi_v4l_fops = {
 
1140
        .owner = THIS_MODULE,
 
1141
        .open = csi_v4l_open,
 
1142
        .release = csi_v4l_close,
 
1143
        .read = csi_v4l_read,
 
1144
        .ioctl = csi_v4l_ioctl,
 
1145
        .mmap = csi_mmap,
 
1146
};
 
1147
 
 
1148
static struct video_device csi_v4l_template = {
 
1149
        .name = "Mx25 Camera",
 
1150
        .fops = &csi_v4l_fops,
 
1151
        .release = video_device_release,
 
1152
};
 
1153
 
 
1154
/*!
 
1155
 * This function can be used to release any platform data on closing.
 
1156
 */
 
1157
static void camera_platform_release(struct device *device)
 
1158
{
 
1159
}
 
1160
 
 
1161
/*! Device Definition for csi v4l2 device */
 
1162
static struct platform_device csi_v4l2_devices = {
 
1163
        .name = "csi_v4l2",
 
1164
        .dev = {
 
1165
                .release = camera_platform_release,
 
1166
                },
 
1167
        .id = 0,
 
1168
};
 
1169
 
 
1170
/*!
 
1171
 * initialize cam_data structure
 
1172
 *
 
1173
 * @param cam      structure cam_data *
 
1174
 *
 
1175
 * @return status  0 Success
 
1176
 */
 
1177
static void init_camera_struct(cam_data *cam)
 
1178
{
 
1179
        pr_debug("In MVC: %s\n", __func__);
 
1180
 
 
1181
        /* Default everything to 0 */
 
1182
        memset(cam, 0, sizeof(cam_data));
 
1183
 
 
1184
        init_MUTEX(&cam->param_lock);
 
1185
        init_MUTEX(&cam->busy_lock);
 
1186
 
 
1187
        cam->video_dev = video_device_alloc();
 
1188
        if (cam->video_dev == NULL)
 
1189
                return;
 
1190
 
 
1191
        *(cam->video_dev) = csi_v4l_template;
 
1192
 
 
1193
        video_set_drvdata(cam->video_dev, cam);
 
1194
        dev_set_drvdata(&csi_v4l2_devices.dev, (void *)cam);
 
1195
        cam->video_dev->minor = -1;
 
1196
 
 
1197
        init_waitqueue_head(&cam->enc_queue);
 
1198
        init_waitqueue_head(&cam->still_queue);
 
1199
 
 
1200
        cam->streamparm.parm.capture.capturemode = 0;
 
1201
 
 
1202
        cam->standard.index = 0;
 
1203
        cam->standard.id = V4L2_STD_UNKNOWN;
 
1204
        cam->standard.frameperiod.denominator = 30;
 
1205
        cam->standard.frameperiod.numerator = 1;
 
1206
        cam->standard.framelines = 480;
 
1207
        cam->standard_autodetect = true;
 
1208
        cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
1209
        cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
 
1210
        cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
 
1211
        cam->overlay_on = false;
 
1212
        cam->capture_on = false;
 
1213
        cam->skip_frame = 0;
 
1214
        cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
 
1215
 
 
1216
        cam->v2f.fmt.pix.sizeimage = 480 * 640 * 2;
 
1217
        cam->v2f.fmt.pix.bytesperline = 640 * 2;
 
1218
        cam->v2f.fmt.pix.width = 640;
 
1219
        cam->v2f.fmt.pix.height = 480;
 
1220
        cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
 
1221
        cam->win.w.width = 160;
 
1222
        cam->win.w.height = 160;
 
1223
        cam->win.w.left = 0;
 
1224
        cam->win.w.top = 0;
 
1225
        cam->still_counter = 0;
 
1226
 
 
1227
        cam->enc_callback = camera_callback;
 
1228
        csi_start_callback(cam);
 
1229
        init_waitqueue_head(&cam->power_queue);
 
1230
        spin_lock_init(&cam->int_lock);
 
1231
}
 
1232
 
 
1233
/*!
 
1234
 * camera_power function
 
1235
 *    Turns Sensor power On/Off
 
1236
 *
 
1237
 * @param       cam           cam data struct
 
1238
 * @param       cameraOn      true to turn camera on, false to turn off power.
 
1239
 *
 
1240
 * @return status
 
1241
 */
 
1242
static u8 camera_power(cam_data *cam, bool cameraOn)
 
1243
{
 
1244
        pr_debug("In MVC: %s on=%d\n", __func__, cameraOn);
 
1245
 
 
1246
        if (cameraOn == true) {
 
1247
                csi_enable_mclk(CSI_MCLK_I2C, true, true);
 
1248
                vidioc_int_s_power(cam->sensor, 1);
 
1249
        } else {
 
1250
                csi_enable_mclk(CSI_MCLK_I2C, false, false);
 
1251
                vidioc_int_s_power(cam->sensor, 0);
 
1252
        }
 
1253
        return 0;
 
1254
}
 
1255
 
 
1256
/*!
 
1257
 * This function is called to put the sensor in a low power state.
 
1258
 * Refer to the document driver-model/driver.txt in the kernel source tree
 
1259
 * for more information.
 
1260
 *
 
1261
 * @param   pdev  the device structure used to give information on which I2C
 
1262
 *                to suspend
 
1263
 * @param   state the power state the device is entering
 
1264
 *
 
1265
 * @return  The function returns 0 on success and -1 on failure.
 
1266
 */
 
1267
static int csi_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
 
1268
{
 
1269
        cam_data *cam = platform_get_drvdata(pdev);
 
1270
 
 
1271
        pr_debug("In MVC: %s\n", __func__);
 
1272
 
 
1273
        if (cam == NULL)
 
1274
                return -1;
 
1275
 
 
1276
        cam->low_power = true;
 
1277
 
 
1278
        if (cam->overlay_on == true)
 
1279
                stop_preview(cam);
 
1280
 
 
1281
        camera_power(cam, false);
 
1282
 
 
1283
        return 0;
 
1284
}
 
1285
 
 
1286
/*!
 
1287
 * This function is called to bring the sensor back from a low power state.
 
1288
 * Refer to the document driver-model/driver.txt in the kernel source tree
 
1289
 * for more information.
 
1290
 *
 
1291
 * @param   pdev   the device structure
 
1292
 *
 
1293
 * @return  The function returns 0 on success and -1 on failure
 
1294
 */
 
1295
static int csi_v4l2_resume(struct platform_device *pdev)
 
1296
{
 
1297
        cam_data *cam = platform_get_drvdata(pdev);
 
1298
 
 
1299
        pr_debug("In MVC: %s\n", __func__);
 
1300
 
 
1301
        if (cam == NULL)
 
1302
                return -1;
 
1303
 
 
1304
        cam->low_power = false;
 
1305
        wake_up_interruptible(&cam->power_queue);
 
1306
        camera_power(cam, true);
 
1307
 
 
1308
        if (cam->overlay_on == true)
 
1309
                start_preview(cam);
 
1310
 
 
1311
        return 0;
 
1312
}
 
1313
 
 
1314
/*!
 
1315
 * This structure contains pointers to the power management callback functions.
 
1316
 */
 
1317
static struct platform_driver csi_v4l2_driver = {
 
1318
        .driver = {
 
1319
                   .name = "csi_v4l2",
 
1320
                   },
 
1321
        .probe = NULL,
 
1322
        .remove = NULL,
 
1323
#ifdef CONFIG_PM
 
1324
        .suspend = csi_v4l2_suspend,
 
1325
        .resume = csi_v4l2_resume,
 
1326
#endif
 
1327
        .shutdown = NULL,
 
1328
};
 
1329
 
 
1330
/*!
 
1331
 * Initializes the camera driver.
 
1332
 */
 
1333
static int csi_v4l2_master_attach(struct v4l2_int_device *slave)
 
1334
{
 
1335
        cam_data *cam = slave->u.slave->master->priv;
 
1336
        struct v4l2_format cam_fmt;
 
1337
 
 
1338
        pr_debug("In MVC: %s\n", __func__);
 
1339
        pr_debug("   slave.name = %s\n", slave->name);
 
1340
        pr_debug("   master.name = %s\n", slave->u.slave->master->name);
 
1341
 
 
1342
        cam->sensor = slave;
 
1343
        if (slave == NULL) {
 
1344
                pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
 
1345
                return -1;
 
1346
        }
 
1347
 
 
1348
        csi_enable_mclk(CSI_MCLK_I2C, true, true);
 
1349
        vidioc_int_dev_init(slave);
 
1350
        csi_enable_mclk(CSI_MCLK_I2C, false, false);
 
1351
        cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
1352
 
 
1353
        /* Used to detect TV in (type 1) vs. camera (type 0) */
 
1354
        cam->device_type = cam_fmt.fmt.pix.priv;
 
1355
 
 
1356
        pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
 
1357
                 __func__, cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
 
1358
 
 
1359
        return 0;
 
1360
}
 
1361
 
 
1362
/*!
 
1363
 * Disconnects the camera driver.
 
1364
 */
 
1365
static void csi_v4l2_master_detach(struct v4l2_int_device *slave)
 
1366
{
 
1367
        pr_debug("In MVC: %s\n", __func__);
 
1368
 
 
1369
        vidioc_int_dev_exit(slave);
 
1370
}
 
1371
 
 
1372
/*!
 
1373
 * Entry point for the V4L2
 
1374
 *
 
1375
 * @return  Error code indicating success or failure
 
1376
 */
 
1377
static __init int camera_init(void)
 
1378
{
 
1379
        u8 err = 0;
 
1380
 
 
1381
        /* Register the device driver structure. */
 
1382
        err = platform_driver_register(&csi_v4l2_driver);
 
1383
        if (err != 0) {
 
1384
                pr_err("ERROR: v4l2 capture:camera_init: "
 
1385
                       "platform_driver_register failed.\n");
 
1386
                return err;
 
1387
        }
 
1388
 
 
1389
        /* Create g_cam and initialize it. */
 
1390
        g_cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
 
1391
        if (g_cam == NULL) {
 
1392
                pr_err("ERROR: v4l2 capture: failed to register camera\n");
 
1393
                platform_driver_unregister(&csi_v4l2_driver);
 
1394
                return -1;
 
1395
        }
 
1396
        init_camera_struct(g_cam);
 
1397
 
 
1398
        /* Set up the v4l2 device and register it */
 
1399
        csi_v4l2_int_device.priv = g_cam;
 
1400
        /* This function contains a bug that won't let this be rmmod'd. */
 
1401
        v4l2_int_device_register(&csi_v4l2_int_device);
 
1402
 
 
1403
        /* Register the platform device */
 
1404
        err = platform_device_register(&csi_v4l2_devices);
 
1405
        if (err != 0) {
 
1406
                pr_err("ERROR: v4l2 capture: camera_init: "
 
1407
                       "platform_device_register failed.\n");
 
1408
                platform_driver_unregister(&csi_v4l2_driver);
 
1409
                kfree(g_cam);
 
1410
                g_cam = NULL;
 
1411
                return err;
 
1412
        }
 
1413
 
 
1414
        /* register v4l video device */
 
1415
        if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
 
1416
            == -1) {
 
1417
                platform_device_unregister(&csi_v4l2_devices);
 
1418
                platform_driver_unregister(&csi_v4l2_driver);
 
1419
                kfree(g_cam);
 
1420
                g_cam = NULL;
 
1421
                pr_err("ERROR: v4l2 capture: video_register_device failed\n");
 
1422
                return -1;
 
1423
        }
 
1424
        pr_debug("   Video device registered: %s #%d\n",
 
1425
                 g_cam->video_dev->name, g_cam->video_dev->minor);
 
1426
 
 
1427
        return err;
 
1428
}
 
1429
 
 
1430
/*!
 
1431
 * Exit and cleanup for the V4L2
 
1432
 */
 
1433
static void __exit camera_exit(void)
 
1434
{
 
1435
        pr_debug("In MVC: %s\n", __func__);
 
1436
 
 
1437
        if (g_cam->open_count) {
 
1438
                pr_err("ERROR: v4l2 capture:camera open "
 
1439
                       "-- setting ops to NULL\n");
 
1440
        } else {
 
1441
                pr_info("V4L2 freeing image input device\n");
 
1442
                v4l2_int_device_unregister(&csi_v4l2_int_device);
 
1443
                csi_stop_callback(g_cam);
 
1444
                video_unregister_device(g_cam->video_dev);
 
1445
                platform_driver_unregister(&csi_v4l2_driver);
 
1446
                platform_device_unregister(&csi_v4l2_devices);
 
1447
 
 
1448
                kfree(g_cam);
 
1449
                g_cam = NULL;
 
1450
        }
 
1451
}
 
1452
 
 
1453
module_init(camera_init);
 
1454
module_exit(camera_exit);
 
1455
 
 
1456
module_param(video_nr, int, 0444);
 
1457
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 
1458
MODULE_DESCRIPTION("V4L2 capture driver for Mx25 based cameras");
 
1459
MODULE_LICENSE("GPL");
 
1460
MODULE_SUPPORTED_DEVICE("video");